Kaynağa Gözat

Merge branch 'feature/v4.7.55' of http://192.168.3.207:8080/qmx/jy into feature/v4.7.55

WH01243 2 yıl önce
ebeveyn
işleme
c84b9a4cd1
33 değiştirilmiş dosya ile 1332 ekleme ve 232 silme
  1. 1 1
      src/config.yaml
  2. 2 2
      src/go.mod
  3. 4 4
      src/go.sum
  4. 19 7
      src/jfw/active/21yearEndReport.go
  5. 0 78
      src/jfw/filter/baseuserfilter.go
  6. 3 4
      src/jfw/filter/filter.go
  7. 63 44
      src/jfw/filter/phonefilter.go
  8. 41 10
      src/jfw/front/front.go
  9. 3 2
      src/jfw/front/org_structure.go
  10. 4 0
      src/jfw/grpc/usercenter.go
  11. 3 2
      src/jfw/jyutil/jyutil.go
  12. 23 4
      src/jfw/modules/app/src/app/active/21yearEndReport.go
  13. 53 40
      src/jfw/modules/app/src/app/filter/phonefilter.go
  14. 1 1
      src/jfw/modules/app/src/web/staticres/jyapp/me/js/phone_bind.js
  15. 16 1
      src/jfw/modules/app/src/web/templates/frontRouter/userMerge/free/confirm.html
  16. 8 2
      src/jfw/modules/app/src/web/templates/frontRouter/userMerge/free/index.html
  17. 149 0
      src/jfw/modules/app/src/web/templates/frontRouter/verify/free/index.html
  18. 1 1
      src/jfw/modules/bigmember/src/service/report/report.go
  19. 4 5
      src/jfw/modules/distribution/src/service/filter/phonefilter.go
  20. 3 0
      src/jfw/modules/subscribepay/src/a/init.go
  21. 1 1
      src/jfw/modules/subscribepay/src/report/report.go
  22. 79 0
      src/jfw/modules/subscribepay/src/service/exceptionVerification.go
  23. 27 21
      src/jfw/modules/subscribepay/src/service/phoneCollent.go
  24. 312 0
      src/web/staticres/common-module/account/js/verify.js
  25. 1 1
      src/web/staticres/common-module/share/js/invite-friends.js
  26. BIN
      src/web/staticres/commonFunctions/wm-team-reports.png
  27. BIN
      src/web/staticres/docs/aaaa.docx
  28. BIN
      src/web/staticres/docs/个人年终报告.docx
  29. 7 0
      src/web/staticres/frontRouter/pc/collection/css/index-pc.css
  30. 1 1
      src/web/templates/frontRouter/pc/brand/free/index.html
  31. 4 0
      src/web/templates/frontRouter/pc/userMerge/sess/bind.html
  32. 353 0
      src/web/templates/frontRouter/pc/userMerge/sess/verify.html
  33. 146 0
      src/web/templates/frontRouter/wx/verify/free/index.html

+ 1 - 1
src/config.yaml

@@ -1,4 +1,4 @@
 etcd:
   hosts:
-  - 192.168.3.206:2379
+  - 127.0.0.1:2379
 userCenterKey: "usercenter.rpc" #用户中台rpc

+ 2 - 2
src/go.mod

@@ -4,8 +4,8 @@ go 1.18
 
 require (
 	app.yhyue.com/moapp/jybase v0.0.0-20221230025810-b88f2a62c467
-	app.yhyue.com/moapp/jypkg v0.0.0-20221230080706-5ea76d175cfb
-	bp.jydev.jianyu360.cn/BaseService/userCenter v0.0.0-20230104094847-fcff4cb37001
+	app.yhyue.com/moapp/jypkg v0.0.0-20230106052209-eac08caf4909
+	bp.jydev.jianyu360.cn/BaseService/userCenter v0.0.0-20230106055052-2d0ef74d88df
 	github.com/SKatiyar/qr v0.0.0-20151201054752-25b6bdf44e67
 	github.com/dchest/captcha v1.0.0
 	github.com/fsnotify/fsnotify v1.6.0

+ 4 - 4
src/go.sum

@@ -4,12 +4,12 @@ app.yhyue.com/moapp/jyPoints v1.1.1/go.mod h1:SvP8p5L3jGrejHiH2LXfgCg/NPlFiKBC5Y
 app.yhyue.com/moapp/jybase v0.0.0-20220427020729-974c1a148186/go.mod h1:qNRA0sHuYqcLoYoP8irpaWnW9YsXixe6obBIkwaXpD0=
 app.yhyue.com/moapp/jybase v0.0.0-20221230025810-b88f2a62c467 h1:MTZBSIzrqrwieb1gLhls3Wjz0Q2u75n+O2jfPw40iEA=
 app.yhyue.com/moapp/jybase v0.0.0-20221230025810-b88f2a62c467/go.mod h1:zB47XTeJvpcbtBRYgkQuxOICWNexiZfbUO+7aUf6mNs=
-app.yhyue.com/moapp/jypkg v0.0.0-20221230080706-5ea76d175cfb h1:EpO8FAT6xsnaZW3TuLVz8RrDff1c7eXwgGqmlBtUUyQ=
-app.yhyue.com/moapp/jypkg v0.0.0-20221230080706-5ea76d175cfb/go.mod h1:CkGGBvyteATKUfm7n0SqAm1LlCftmiWwlFGR80YEkWo=
+app.yhyue.com/moapp/jypkg v0.0.0-20230106052209-eac08caf4909 h1:O5sFspDefzt8MCYHRgX3UsOI0yOOFcj3QH4xO9QqeEk=
+app.yhyue.com/moapp/jypkg v0.0.0-20230106052209-eac08caf4909/go.mod h1:CkGGBvyteATKUfm7n0SqAm1LlCftmiWwlFGR80YEkWo=
 app.yhyue.com/moapp/message v0.0.0-20221202072401-d825fc65512c h1:CrcvbsXZ4aQkNikBi7FUUQZNnY8hKsNo2LLe/SqeXs8=
 app.yhyue.com/moapp/message v0.0.0-20221202072401-d825fc65512c/go.mod h1:b0zZHev3gmJao1Fo+2Z2KPVjsuLOJVvVxf+kCnu9WkA=
-bp.jydev.jianyu360.cn/BaseService/userCenter v0.0.0-20230104094847-fcff4cb37001 h1:WkAsidnmT4TSfN6BA4NlL2NLHNerjn2+qbe5qzd4rEY=
-bp.jydev.jianyu360.cn/BaseService/userCenter v0.0.0-20230104094847-fcff4cb37001/go.mod h1:w4/29SqTHYIEeZSKOelOB9AAZLSh3d/QzI3swWc3B8E=
+bp.jydev.jianyu360.cn/BaseService/userCenter v0.0.0-20230106055052-2d0ef74d88df h1:Y3CYTqp/faiQIwKku5xEzegHloIgexmrcT/BDmbLeLs=
+bp.jydev.jianyu360.cn/BaseService/userCenter v0.0.0-20230106055052-2d0ef74d88df/go.mod h1:w4/29SqTHYIEeZSKOelOB9AAZLSh3d/QzI3swWc3B8E=
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=

+ 19 - 7
src/jfw/active/21yearEndReport.go

@@ -5,15 +5,10 @@ import (
 	"jy/src/jfw/config"
 	"net/url"
 	"time"
-
 	"jy/src/jfw/jyutil"
-
 	"app.yhyue.com/moapp/jypkg/public"
-
 	qutil "app.yhyue.com/moapp/jybase/common"
-
 	"app.yhyue.com/moapp/jybase/redis"
-
 	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
 	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
 	"go.mongodb.org/mongo-driver/bson"
@@ -48,10 +43,27 @@ func init() {
 //YearEndReport 21年,年终报告
 type YearEndReport struct {
 	*xweb.Action
-	yearEndReportPage   xweb.Mapper `xweb:"/active/yearEndReport"`       //21年终报告wx页面
-	yearEndReportResult xweb.Mapper `xweb:"/active/yearEndReportResult"` //21年终报告wx结果页面
+	yearEndReportPage     xweb.Mapper `xweb:"/active/yearEndReport"`       //21年终报告wx页面
+	yearEndReportResult   xweb.Mapper `xweb:"/active/yearEndReportResult"` //21年终报告wx结果页面
+	yearEndReportPageBy22 xweb.Mapper `xweb:"/active/yearEndReportBy22"`   //22年终报告wx页面
+}
+
+//
+func (this *YearEndReport) YearEndReportPageBy22() error {
+	phone := qutil.ObjToString(this.Session().Get("phone"))
+	//session 中没有手机号 直接跳首页
+	if phone == "" {
+		return this.Redirect("/jylab/mainSearch")
+	}
+	//有手机号 查询企业报告是否有权限
+	if count := public.Mysql.CountBySql(`SELECT COUNT(id) FROM  entniche_user WHERE phone = ?`, phone); count > 0 {
+		return this.Redirect("/succbi/nzbg/app/nzbg.app/nzbg_entrance_app_td.spg")
+	}
+	//企业年终报告无权限--添加企业
+	return this.Redirect("/page_entniche_new/page/loading.html?source=report")
 }
 
+//
 func (this *YearEndReport) YearEndReportResult() error {
 	return this.Render("/active/yearEndReport/result.html")
 }

+ 0 - 78
src/jfw/filter/baseuserfilter.go

@@ -1,78 +0,0 @@
-package filter
-
-import (
-	"jy/src/jfw/config"
-	"log"
-	"net/http"
-
-	"app.yhyue.com/moapp/jybase/usercenter"
-
-	"app.yhyue.com/moapp/jypkg/public"
-
-	util "app.yhyue.com/moapp/jybase/common"
-
-	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
-)
-
-type baseUserFilter struct {
-	W          http.ResponseWriter
-	R          *http.Request
-	Session    *httpsession.Session
-	GetSession map[string]interface{}
-}
-
-//判断session中是否存在base_user_id 不存在则更新
-
-func (this *baseUserFilter) Do() bool {
-	if flag, _ := config.Sysconfig["baseUserFilterFlag"].(bool); !flag {
-		return true
-	}
-	if this.R.Method == "POST" {
-		return true
-	}
-	if uid := this.GetSession["userId"]; uid != nil && uid != "" {
-		baseUserId := this.GetSession["base_user_id"]
-		if baseUserId == nil || baseUserId == 0 {
-			data, ok := public.MQFW.FindById("user", util.ObjToString(uid), `{"base_user_id":1}`)
-			if data != nil && ok && len(*data) > 0 {
-				if base_user_id := util.Int64All((*data)["base_user_id"]); base_user_id > 0 {
-					baseUserId = base_user_id
-					this.Session.Set("base_user_id", (*data)["base_user_id"])
-				} else {
-					log.Printf("%s用户暂无base_user_id", uid)
-				}
-			}
-		}
-		personId := this.GetSession["personId"]
-		if personId == nil || personId == 0 {
-			//获取自然人id,个人账户id,企业账户id,企业雇员职位id,企业雇员账户id,个人职位id
-			ck := &http.Cookie{}
-			entId := util.Int64All(this.GetSession["entId"])
-			identity := usercenter.GetUserIdentity(util.ObjToString(config.Sysconfig["userCenterApi"]), util.ObjToString(uid), util.Int64All(baseUserId), entId, ck)
-			if identity != nil {
-				if identity.PersonId > 0 {
-					this.Session.Set("personId", identity.PersonId)
-				}
-				if identity.UserName != "" {
-					this.Session.Set("userName", identity.UserName)
-				}
-				if identity.PersonId > 0 {
-					this.Session.Set("userAccountId", identity.PersonId)
-				}
-				if identity.EntAccountId > 0 {
-					this.Session.Set("entAccountId", identity.EntAccountId)
-				}
-				if identity.EntUserAccountId > 0 {
-					this.Session.Set("entUserAccountId", identity.EntUserAccountId)
-				}
-				if identity.UserPositionId > 0 {
-					this.Session.Set("userPositionId", identity.UserPositionId)
-				}
-				if identity.EntUserPositionId > 0 {
-					this.Session.Set("entUserPositionId", identity.EntUserPositionId)
-				}
-			}
-		}
-	}
-	return true
-}

+ 3 - 4
src/jfw/filter/filter.go

@@ -39,7 +39,9 @@ type Filter struct {
 func (f *Filter) Do(w http.ResponseWriter, r *http.Request) bool {
 	session := xweb.RootApp().SessionManager.Session(r, w)
 	getSession := session.GetMultiple()
-	//session.Set("userId", "61ea6adf2295bbfea3416a75")
+	if getSession["userId"] != nil && getSession["mgoUserId"] == nil && util.Int64All(getSession["positionType"]) == 0 {
+		session.Set("mgoUserId", getSession["userId"])
+	}
 	if !(&logFilter{w, r, session, getSession, make(map[string]interface{})}).Do() {
 		return false
 	}
@@ -55,9 +57,6 @@ func (f *Filter) Do(w http.ResponseWriter, r *http.Request) bool {
 	if !(&pcFilter{w, r, session, getSession}).Do() {
 		return false
 	}
-	if !(&baseUserFilter{w, r, session, getSession}).Do() {
-		return false
-	}
 	if !(&salesFilter{w, r, session, getSession}).Do() {
 		return false
 	}

+ 63 - 44
src/jfw/filter/phonefilter.go

@@ -45,26 +45,33 @@ func init() {
 }
 
 func (l *phoneFilter) Do() bool {
-	if !initflag {
-		return true
-	}
-	if flag, _ := config.Sysconfig["phoneFilterFlag"].(bool); !flag {
-		return true
-	}
-	if l.R.Method == "POST" {
-		return true
-	}
-	href := "/swordfish/frontPage/userMerge/sess/bind" //pc
-	for _, v := range bindurl {
-		if v.MatchString(l.R.URL.Path) && !strings.Contains(l.R.URL.Path, "bidedoc") && !strings.Contains(l.R.URL.Path, "squeeze") && !strings.Contains(l.R.URL.Path, "partner") {
+	userId, _ := l.GetSession["userId"].(string)
+	// 请求过滤
+	pass := func() bool {
+		if !initflag || l.R.Method == "POST" || userId == "" {
+			return true
+		}
+		if flag, _ := config.Sysconfig["phoneFilterFlag"].(bool); !flag {
 			return true
 		}
+		for _, v := range bindurl {
+			if v.MatchString(l.R.URL.Path) && !strings.Contains(l.R.URL.Path, "bidedoc") && !strings.Contains(l.R.URL.Path, "squeeze") && !strings.Contains(l.R.URL.Path, "partner") {
+				return true
+			}
+		}
+		return false
+	}()
+	if pass {
+		return true
 	}
-	if uid := l.GetSession["userId"]; uid != nil && uid != "" {
+
+	//是否需要跳转绑定手机号
+	needBindPhone := func() bool {
+		//绑定手机号判断
 		if phone := l.GetSession["phone"]; phone != nil && phone != "" {
-			return true
+			return false
 		}
-		if person, sessionVal := jyutil.GetSessionVal(map[string]interface{}{"_id": mongodb.StringTOBsonId(qu.ObjToString(uid))}); len(sessionVal) > 0 && person != nil {
+		if person, sessionVal := jyutil.GetSessionVal(map[string]interface{}{"_id": mongodb.StringTOBsonId(qu.ObjToString(userId))}); len(sessionVal) > 0 && person != nil {
 			s_phone := qu.ObjToString((*person)["s_phone"])
 			if s_phone == "" {
 				s_phone = qu.ObjToString((*person)["s_m_phone"])
@@ -72,58 +79,70 @@ func (l *phoneFilter) Do() bool {
 			if s_phone != "" {
 				sessionVal["phone"] = s_phone
 				l.Session.SetMultiple(sessionVal)
-				return true
-			}
-			if userAgent := l.R.UserAgent(); mobileReg.MatchString(userAgent) {
-				href = "/front/account/phone/bind?mode=mergeBind" //wx
-				redirectTo := l.R.URL.String()
-				href += "&redirectTo=" + encodeURIComponent(redirectTo) //加密 前端用于返回
+				return false
 			}
 			regtime := qu.Int64All((*person)["l_registedate"])
 			reg := time.Unix(regtime, 0)
 			//新用户时间
 			accountMergeOnline, _ := config.Sysconfig["accountMergeOnline"].(string)
 			onLineTime, _ := time.ParseInLocation(Date_Full_Layout, accountMergeOnline, time.Local)
-			if remind, _ := (*person)["b_merge_remind"].(bool); remind { //不再提醒
-				return true
-			}
 			//取关用户
 			if i_ispush := qu.IntAll((*person)["i_ispush"]); i_ispush == 0 {
-				return true
+				return false
 			}
 			if onLineTime.After(reg) { //老用户
-				if !urls.MatchString(l.R.URL.Path) {
-					return true
-				}
 				dbname, _ := config.Sysconfig["bindPopRedis"].(string)
-				bindPopNum := redis.GetInt(dbname, fmt.Sprintf("bindPop_%s", uid))
-				key := fmt.Sprintf("bindPop_%s", uid)
-				if redis.Incr(dbname, key) == 1 {
-					_ = redis.SetExpire(dbname, key, GetExpire())
-				}
-				if bindPopNum != (qu.IntAll(config.Sysconfig["firstBindPop"]))-1 &&
-					bindPopNum < (qu.IntAll(config.Sysconfig["maxBindPop"]))-1 {
+				key := fmt.Sprintf("bindPop_new_%s", userId)
+				if redis.GetInt(dbname, key) >= qu.IntAll(config.Sysconfig["maxBindPop"]) {
 					return true
 				}
+				if urls.MatchString(l.R.URL.Path) {
+					bindPopNum := redis.Incr(dbname, key)
+					if bindPopNum == qu.Int64All(config.Sysconfig["firstBindPop"]) ||
+						bindPopNum > qu.Int64All(config.Sysconfig["maxBindPop"]) {
+						return true
+					}
+				}
+				return false
 			}
 			//设置cookie 前端跳转
 			SetCookie(l.R.URL.String(), int(time.Hour*24/time.Second), l.W)
-		} else {
 			return true
 		}
+		return false
+	}()
+
+	var href string
+	// 跳转绑定手机号页面
+	if needBindPhone {
+		if mobileReg.MatchString(l.R.UserAgent()) {
+			href = "/front/account/phone/bind?mode=mergeBind&redirectTo=" + encodeURIComponent(l.R.URL.String())
+		} else {
+			href = "/swordfish/frontPage/userMerge/sess/bind"
+		}
 	} else {
-		return true
+		// 是否需要验证手机号
+		if exists, _ := redis.Exists("newother", fmt.Sprintf("abnormal_trigger_%s", userId)); exists {
+			if mobileReg.MatchString(l.R.UserAgent()) {
+				href = "/weixin/frontPage/verify/free/index?redirectTo=" + encodeURIComponent(l.R.URL.String())
+			} else {
+				href = "/swordfish/frontPage/userMerge/sess/verify?redirectTo=" + encodeURIComponent(l.R.URL.String())
+			}
+		}
 	}
-	http.Redirect(l.W, l.R, href, 302)
-	return false
+	if href != "" {
+		http.Redirect(l.W, l.R, href, 302)
+		return false
+	}
+	return true
 }
 
 //获取当天结束时间 单位秒
-func GetExpire() int {
-	t, _ := time.ParseInLocation(Date_Short_Layout, time.Now().AddDate(0, 0, 1).Format(Date_Short_Layout), time.Local)
-	t2, _ := time.ParseInLocation(Date_Full_Layout, time.Now().Format(Date_Full_Layout), time.Local)
-	return int(t.Unix() - t2.Unix())
-}
+//func GetExpire() int {
+//	t, _ := time.ParseInLocation(qu.Date_Short_Layout, time.Now().AddDate(0, 0, 1).Format(qu.Date_Short_Layout), time.Local)
+//	t2, _ := time.ParseInLocation(qu.Date_Full_Layout, time.Now().Format(qu.Date_Full_Layout), time.Local)
+//	return int(t.Unix() - t2.Unix())
+//}
 
 //文章三级页跳转设置cookie
 func SetCookie(value string, timeout int, w http.ResponseWriter) {

+ 41 - 10
src/jfw/front/front.go

@@ -20,10 +20,12 @@ import (
 	. "app.yhyue.com/moapp/jybase/date"
 	"app.yhyue.com/moapp/jybase/encrypt"
 	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
+	"app.yhyue.com/moapp/jypkg/identity"
 	"app.yhyue.com/moapp/jypkg/public"
 
-	elastic "app.yhyue.com/moapp/jybase/esv1"
+	. "jy/src/jfw/grpc"
 
+	elastic "app.yhyue.com/moapp/jybase/esv1"
 	"app.yhyue.com/moapp/jybase/redis"
 
 	mgdb "app.yhyue.com/moapp/jybase/mongodb"
@@ -616,18 +618,19 @@ func (f *Front) Login(key string) error {
 
 //用户是否登录
 func (f *Front) HasSign() error {
-	if userId, _ := f.GetSession("userId").(string); userId != "" {
+	sessVal := f.Session().GetMultiple()
+	if userId, _ := sessVal["userId"].(string); userId != "" {
 		//微信昵称>手机号>剑鱼昵称
-		nickname := util.ObjToString(f.GetSession("s_nickname"))
-		phone, _ := f.GetSession("phone").(string)
-		jyname := util.ObjToString(f.GetSession("s_jyname"))
+		nickname := util.ObjToString(sessVal["s_nickname"])
+		phone, _ := sessVal["phone"].(string)
+		jyname := util.ObjToString(sessVal["s_jyname"])
 		if nickname == "" && phone != "" {
 			nickname = string(phone[0:3]) + "****" + string(phone[(len(phone)-4):])
 		}
 		m := map[string]interface{}{
 			"result":      "ok",
 			"s_nickname":  util.If(nickname != "", nickname, jyname), //昵称:dev4.6.4
-			"s_headimage": f.GetSession("s_avatar"),                  //详细见:jyutil.go - GetSessionVal()
+			"s_headimage": sessVal["s_avatar"],                       //详细见:jyutil.go - GetSessionVal()
 			"encryptId":   se.EncodeString(userId),
 		}
 		//是否需要重新登录,企业基础架构给虚拟账号重置密码后,需要重新登录
@@ -636,9 +639,32 @@ func (f *Front) HasSign() error {
 			redis.Del("session", f.Session().Id())
 			m["resetpwd"] = resetpwd
 		}
-		if openid, _ := f.GetSession("s_m_openid").(string); openid != "" {
+		if openid, _ := sessVal["s_m_openid"].(string); openid != "" {
 			m["openid"] = se.EncodeString(openid)
 		}
+		if base_user_id := util.Int64All(sessVal["base_user_id"]); base_user_id > 0 {
+			identitys := []map[string]interface{}{}
+			for _, v := range UserCenter.IdentityList(base_user_id) {
+				identitys = append(identitys, map[string]interface{}{
+					"name":  v.Name,
+					"entId": encrypt.SE.Encode2HexByCheck(fmt.Sprint(v.EntId)),
+					"type":  v.PositionType,
+					"token": identity.Encode(&identity.Identity{
+						Name:         v.Name,
+						PersonId:     v.PersonId,
+						UserName:     v.UserName,
+						AccountId:    v.AccountId,
+						EntAccountId: v.EntAccountId,
+						PositionId:   v.PositionId,
+						PositionType: v.PositionType,
+						EntId:        v.EntId,
+						EntUserId:    v.EntUserId,
+						EntUserName:  v.EntUserName,
+					}),
+				})
+			}
+			m["identitys"] = identitys
+		}
 		f.ServeJson(m)
 	}
 	return nil
@@ -1569,12 +1595,17 @@ func NeedBind(uid string) bool {
 			//新用户时间
 			accountMergeOnline, _ := config.Sysconfig["accountMergeOnline"].(string)
 			onLineTime, _ := time.ParseInLocation(Date_Full_Layout, accountMergeOnline, time.Local)
-			if remind, _ := (*person)["b_merge_remind"].(bool); remind { //不再提醒
-				return false
-			}
+			//if remind, _ := (*person)["b_merge_remind"].(bool); remind { //不再提醒
+			//	return false
+			//}
 			if onLineTime.Before(reg) { //新用户
 				return true
 			}
+			dbname, _ := config.Sysconfig["bindPopRedis"].(string)
+			key := fmt.Sprintf("bindPop_new_%s", uid)
+			if redis.GetInt(dbname, key) >= util.IntAll(config.Sysconfig["maxBindPop"]) {
+				return true
+			}
 		}
 	}
 	return false

+ 3 - 2
src/jfw/front/org_structure.go

@@ -68,10 +68,11 @@ func (this *OrgStructure) InvitationPage() error {
 	depcname := this.GetString("depcname")
 	registered := "0"                                        //是否是剑鱼用户:0:未关注; 1:已关注
 	entUserId_str := encrypt.SE.Decode4HexByCheck(entUserId) //解密
+	source := this.GetString("source")
 	entUserId_sess := this.GetSession("entUserId")
-	OrgUrl := util.ObjToString(config.Sysconfig["wxOrgUrl"]) + "?entUserId=" + entUserId + "&depId=" + depId + "&entId=" + entId + "&depcname=" + depcname
+	OrgUrl := util.ObjToString(config.Sysconfig["wxOrgUrl"]) + "?entUserId=" + entUserId + "&depId=" + depId + "&entId=" + entId + "&depcname=" + depcname + "&source=" + source
 	if !mobileReg.MatchString(client) {
-		OrgUrl = util.ObjToString(config.Sysconfig["pcOrgUrl"]) + "?entUserId=" + entUserId + "&depId=" + depId + "&entId=" + entId + "&depcname=" + depcname
+		OrgUrl = util.ObjToString(config.Sysconfig["pcOrgUrl"]) + "?entUserId=" + entUserId + "&depId=" + depId + "&entId=" + entId + "&depcname=" + depcname + "&source=" + source
 	} else if entUserId_sess == nil || util.ObjToString(entUserId_sess) != entUserId_str {
 		userId := util.ObjToString(this.Session().Get("userId"))
 		openId := util.ObjToString(this.Session().Get("s_m_openid"))

+ 4 - 0
src/jfw/grpc/usercenter.go

@@ -32,5 +32,9 @@ func (u *userCenter) IdentityList(userId int64) []*pb.Identity {
 	resp, err := usercenter.NewUserCenter(client).IdentityList(context.Background(), &pb.IdentityReq{
 		UserId: userId,
 	})
+	if err != nil {
+		log.Println(err)
+		return nil
+	}
 	return resp.Identitys
 }

+ 3 - 2
src/jfw/jyutil/jyutil.go

@@ -85,7 +85,7 @@ func Getopenid(code string) (openid string) {
 
 //
 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}`)
+	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,"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
@@ -119,7 +119,7 @@ func GetSessionVal(q map[string]interface{}) (*map[string]interface{}, map[strin
 	}
 	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 
+		sql := `SELECT a.id,a.name,a.startdate,a.enddate,a.quota,c.id as dept_id,b.id as user_id,b.name as user_name 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)  
@@ -133,6 +133,7 @@ func GetSessionVal(q map[string]interface{}) (*map[string]interface{}, map[strin
 				sessionVal["entId"] = util.IntAll(v["id"])
 				sessionVal["entName"] = util.ObjToString(v["name"])
 				sessionVal["entUserId"] = util.IntAll(v["user_id"])
+				sessionVal["entUserName"] = util.ObjToString(v["user_name"])
 				sessionVal["frameworkEntId"] = util.IntAll(v["id"])
 				sessionVal["frameworkEntName"] = util.ObjToString(v["name"])
 				break

+ 23 - 4
src/jfw/modules/app/src/app/active/21yearEndReport.go

@@ -1,9 +1,11 @@
 package active
 
 import (
-	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
-	qutil "app.yhyue.com/moapp/jybase/common"
 	"time"
+
+	qutil "app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
+	"app.yhyue.com/moapp/jypkg/public"
 )
 
 const (
@@ -34,10 +36,27 @@ func init() {
 //YearEndReport 21年,年终报告
 type YearEndReport struct {
 	*xweb.Action
-	yearEndReportPage   xweb.Mapper `xweb:"/jyapp/active/yearEndReport"`       //21年终报告app页面
-	yearEndReportResult xweb.Mapper `xweb:"/jyapp/active/yearEndReportResult"` //21年终报告app结果页面
+	yearEndReportPage     xweb.Mapper `xweb:"/jyapp/active/yearEndReport"`       //21年终报告app页面
+	yearEndReportResult   xweb.Mapper `xweb:"/jyapp/active/yearEndReportResult"` //21年终报告app结果页面
+	yearEndReportPageBy22 xweb.Mapper `xweb:"/jyapp/active/yearEndReportBy22"`   //22年终报告app页面-团队报告
+}
+
+//22年终报告app页面-团队报告
+func (this *YearEndReport) YearEndReportPageBy22() error {
+	phone := qutil.ObjToString(this.Session().Get("phone"))
+	//session 中没有手机号 直接跳首页
+	if phone == "" {
+		return this.Redirect("/jyapp/jylab/mainSearch")
+	}
+	//有手机号 查询企业报告是否有权限
+	if count := public.Mysql.CountBySql(`SELECT COUNT(id) FROM  entniche_user WHERE phone = ?`, phone); count > 0 {
+		return this.Redirect("/succbi/nzbg/app/nzbg.app/nzbg_entrance_app_td.spg")
+	}
+	//企业年终报告无权限--添加企业
+	return this.Redirect("/page_entniche_new/page/loading.html?source=report")
 }
 
+//
 func (this *YearEndReport) YearEndReportResult() error {
 	return this.Render("/active/yearEndReport/result.html")
 }

+ 53 - 40
src/jfw/modules/app/src/app/filter/phonefilter.go

@@ -42,72 +42,85 @@ func init() {
 }
 
 func (l *phoneFilter) Do() bool {
-	if flag, _ := config.Sysconfig["phoneFilterFlag"].(bool); !flag {
-		return true
-	}
-	if l.R.Method == "POST" || !initflag {
-		return true
-	}
-	href := "/jyapp/account/phone/bind?mode=mergeBind"
-	for _, v := range bindurl {
-		if v.MatchString(l.R.URL.Path) && !strings.Contains(l.R.URL.Path, "squeeze") {
+
+	userId, _ := l.GetSession["userId"].(string)
+	// 请求过滤
+	pass := func() bool {
+		if !initflag || l.R.Method == "POST" || userId == "" {
+			return true
+		}
+		if flag, _ := config.Sysconfig["phoneFilterFlag"].(bool); !flag {
 			return true
 		}
+		for _, v := range bindurl {
+			if v.MatchString(l.R.URL.Path) && !strings.Contains(l.R.URL.Path, "squeeze") {
+				return true
+			}
+		}
+		return false
+	}()
+	if pass {
+		return true
 	}
-	if uid := l.GetSession["userId"]; uid != nil && uid != "" {
+	isNewUser := false
+	//是否需要跳转绑定手机号
+	needBindPhone := func() bool {
 		if phone := l.GetSession["phone"]; phone != nil && phone != "" {
-			return true
+			return false
 		}
-		if person, ok := public.MQFW.FindById("user", mongodb.BsonIdToSId(qu.ObjToString(uid)), `{"s_phone":1,"s_m_phone":1,"l_registedate":1,"b_merge_remind":1}`); person != nil && ok {
+		if person, ok := public.MQFW.FindById("user", mongodb.BsonIdToSId(qu.ObjToString(userId)), `{"s_phone":1,"s_m_phone":1,"l_registedate":1}`); person != nil && ok {
 			s_phone := qu.ObjToString((*person)["s_phone"])
 			if s_phone == "" {
 				s_phone = qu.ObjToString((*person)["s_m_phone"])
 			}
 			if s_phone != "" {
 				l.Session.Set("phone", s_phone)
-				return true
+				return false
 			}
 			regtime := qu.Int64All((*person)["l_registedate"])
 			reg := time.Unix(regtime, 0)
 			//新用户时间
 			accountMergeOnline, _ := config.Sysconfig["accountMergeOnline"].(string)
 			onLineTime, _ := time.ParseInLocation(Date_Full_Layout, accountMergeOnline, time.Local)
-			if remind, _ := (*person)["b_merge_remind"].(bool); remind { //不再提醒
-				return true
-			}
 			if onLineTime.After(reg) { //老用户
-				if !articleUrl.MatchString(l.R.URL.Path) {
-					return true
-				}
 				dbname, _ := config.Sysconfig["bindPopRedis"].(string)
-				key := fmt.Sprintf("bindPop_%s", uid)
-				bindPopNum := redis.GetInt(dbname, key)
-				if redis.Incr(dbname, key) == 1 {
-					_ = redis.SetExpire(dbname, key, GetExpire())
-				}
-				if bindPopNum != (qu.IntAll(config.Sysconfig["firstBindPop"]))-1 &&
-					bindPopNum < (qu.IntAll(config.Sysconfig["maxBindPop"]))-1 {
+				key := fmt.Sprintf("bindPop_new_%s", userId)
+				if redis.GetInt(dbname, key) >= qu.IntAll(config.Sysconfig["maxBindPop"]) {
 					return true
 				}
-				//设置cookie 前端跳转
-				SetCookie(l.R.URL.String(), int(time.Hour*24/time.Second), l.W)
+				if articleUrl.MatchString(l.R.URL.Path) {
+					bindPopNum := redis.Incr(dbname, key)
+					if bindPopNum == qu.Int64All(config.Sysconfig["firstBindPop"]) ||
+						bindPopNum > qu.Int64All(config.Sysconfig["maxBindPop"]) {
+						return true
+					}
+				}
+				return false
 			} else {
-				//新用户
-				href += "&act=logout"
+				isNewUser = true
 			}
+			//设置cookie 前端跳转
+			SetCookie(l.R.URL.String(), int(time.Hour*24/time.Second), l.W)
+			return true
+		}
+		return false
+	}()
+	var href string
+	if needBindPhone {
+		href = "/jyapp/account/phone/bind?mode=mergeBind"
+		if isNewUser {
+			href += "&act=logout"
 		}
 	} else {
-		return true
+		if exists, _ := redis.Exists("newother", fmt.Sprintf("abnormal_trigger_%s", userId)); exists {
+			href = "/jyapp/frontPage/verify/free/index?mode=phoneCheck"
+		}
 	}
-	http.Redirect(l.W, l.R, href, 302)
-	return false
-}
-
-//获取当天结束时间 单位秒
-func GetExpire() int {
-	t, _ := time.ParseInLocation(Date_Short_Layout, time.Now().AddDate(0, 0, 1).Format(Date_Short_Layout), time.Local)
-	t2, _ := time.ParseInLocation(Date_Full_Layout, time.Now().Format(Date_Full_Layout), time.Local)
-	return int(t.Unix() - t2.Unix())
+	if href != "" {
+		http.Redirect(l.W, l.R, href, 302)
+		return false
+	}
+	return true
 }
 
 //文章三级页跳转设置cookie

+ 1 - 1
src/jfw/modules/app/src/web/staticres/jyapp/me/js/phone_bind.js

@@ -386,7 +386,7 @@ var vm = new Vue({
                             _this.afterSetPhoneSuccess()
                         }
                     } else if (state == 2) {
-                        location.replace('/jyapp/frontPage/userMerge/free/index?token=' + _this.token)
+                        location.replace('/jyapp/frontPage/userMerge/free/index?from=bindPhone&token=' + _this.token)
                     }
                 })
             } else {

+ 16 - 1
src/jfw/modules/app/src/web/templates/frontRouter/userMerge/free/confirm.html

@@ -96,6 +96,8 @@
             data: {
                 neverRemind: false, // 不再提醒
                 checkedColor: '#2CB7CA',
+                // from默认为'', 值为bindPhone时表示从手机号绑定页面/jyapp/account/phone/bind?mode=mergeBind过来的
+                from: '',
                 token: '',
                 userName:{
                     wx:'',
@@ -118,6 +120,10 @@
             },
             created () {
                 this.token = utils.getParam('token')
+                var from = utils.getParam('from')
+                if (from) {
+                    this.from = from
+                }
                 this.getInfo()
             },
             methods: {
@@ -237,7 +243,16 @@
                     this.confirmRequest(this.successCallback)
                 },
                 successCallback: function () {
-                    history.go(-2)
+                    if (this.from === 'bindPhone') {
+                        // 清空缓存,并回首页
+                        sessionStorage.clear()
+                        JyObj.backUrl('H')
+                        JyObj.refreshAppointTab('subscribe', 1)
+                        JyObj.refreshAppointTab('box', 1)
+                        JyObj.refreshAppointTab('me', 1)
+                    } else {
+                        history.go(-2)
+                    }
                 },
                 noticeHandle: function(){
                     var html = '<p>合并须知:</p><p>1.账号合并为手机号和微信号进行合并绑定,两个账号内功能、剑鱼币、优惠券等均可合并。</p><p>2.账号信息将根据您选择的账号进行保留,未被选择的账号信息将被舍弃,请慎重选择。</p><p>3.账号合并后,您使用微信或手机号进行登录,将看到并使用相同的功能设置,共同使用账号内的功能、剑鱼币、优惠券等。</p><p>4.如您选择确认合并,则默认为您已阅读并同意此须知。</p>'

+ 8 - 2
src/jfw/modules/app/src/web/templates/frontRouter/userMerge/free/index.html

@@ -68,6 +68,8 @@
             delimiters: ['${', '}'],
             el: '#merge-prompt',
             data: {
+                // from默认为'', 值为bindPhone时表示从手机号绑定页面/jyapp/account/phone/bind?mode=mergeBind过来的
+                from: '',
                 token: '',
                 userName:{
                     wx:'',
@@ -114,6 +116,10 @@
             },
             created () {
                 this.token = utils.getParam('token')
+                var from = utils.getParam('from')
+                if (from) {
+                    this.from = from
+                }
                 this.getInfo()
             },
             methods: {
@@ -176,9 +182,9 @@
                     }
                 },
                 nextStep: function () {
-                    var url = './confirm'
+                    var url = `./confirm?from=${this.from}`
                     if (this.token) {
-                        url = './confirm?token=' + this.token
+                        url = `./confirm?token=${this.token}&from=${this.from}`
                     }
                     location.href = url
                 },

+ 149 - 0
src/jfw/modules/app/src/web/templates/frontRouter/verify/free/index.html

@@ -0,0 +1,149 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+
+<head>
+    <!--引入公共资源头部-->
+    {{include "/big-member/meta.html"}}
+    <title>账号异常验证</title>
+
+    <!--S-当前页面的css资源-->
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/reset-css/5.0.1/reset.min.css />
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/index.css />
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/icon/local.css />
+    <style>
+        .auth-tip{
+            padding: .48rem 0 .36rem;
+        }
+        .auth-tip p{
+            color: #9B9CA3;
+            font-size: .28rem;
+            line-height: .4rem;
+            text-align: center;
+        }
+        .auth-phone{
+            padding-bottom: .48rem;
+            color: #5F5E64;
+            font-size: .4rem;
+            line-height: .6rem;
+            text-align: center;
+        }
+        .picture-code{
+            width: 90px;
+            height: 30px;
+            background: #F5F6F7;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+        }
+        .van-field__label{
+            font-size: .3rem;
+        }
+        .van-field__control{
+            font-size: .32rem;
+        }
+        .van-field--error .van-field__control, .van-field--error .van-field__control::placeholder{
+            color: #171826;
+        }
+        .send_btn{
+            background-color: transparent;
+            color: #2ABED1;
+            border: 0;
+            font-size: .28rem;
+            height: unset;
+        }
+        .send_btn:disabled{
+            color: #9B9CA3;
+        }
+        .picture-cell{
+            padding: .28rem .32rem;
+        }
+        .code-cell{
+            padding: .32rem;
+        }
+        .unbind-dialog .van-dialog__header{
+            font-weight: bold;
+            font-size: .36rem;
+        }
+        .unbind-dialog .van-dialog__message{
+            padding: .16rem 0 .44rem;
+            color: #5F5E64;
+            font-size: .3rem;
+        }
+        .unbind-dialog .van-button{
+            font-size: .36rem;
+        }
+    </style>
+</head>
+
+<body>
+    <div class="j-container"  id="auth" v-cloak>
+        <div class="j-header jy-app-header" style="background: #fff;">
+          <span class="header-left" @click="goBack()">
+              <span class="icon-back j-icon base-icon" style="color: #5F5E64;"></span>
+          </span>
+          <span class="header-title" style="color: #171826;">账号异常验证</span>
+          <span class="header-right"></span>
+        </div>
+        <div class="j-main">
+            <div class="auth-tip">
+              <p>您好,系统识别到您的账号异常,</p>
+              <p>请您对登录手机号进行验证。</p>
+            </div>
+            <div class="auth-phone">${phoneFn(info.phone)}</div>
+            <div class="auth-form">
+                <van-form ref="phoneForm" @submit="submitForm">
+                    <van-field
+                        v-if="cur.showCaptcha"
+                        center
+                        class="picture-cell"
+                        v-model.trim="pictureCode"
+                        type="number"
+                        name="picture"
+                        placeholder="图形验证码"
+                        :rules="pictureRules"
+                        @input="inputPicture(pictureCode)"
+                    >
+                        <template #button>
+                            <div class="picture-code">
+                                <img v-if="cur.imgSrc" :src="'data:image/png;base64,' + cur.imgSrc" alt="图形验证码" width="90" height="30" @click="refreshPicture" key="picCode" />
+                                <van-loading size="24" v-else key="picCode"></van-loading>
+                            </div>
+                        </template>
+                    </van-field>
+                    <van-field
+                        center
+                        class="code-cell"
+                        v-model.trim="msgCode"
+                        type="number"
+                        name="code"
+                        label="验证码"
+                        placeholder="请输入验证码"
+                        :rules="regCodeRules"
+                        @input="inputCode(msgCode)"
+                    >
+                        <template #button>
+                            <van-button native-type="button" v-show="sendCodeBtn" class="send_btn" slot="button"  size="small" @click="sendMobileCode" type="button">发送验证码</van-button>
+                            <van-button native-type="button" v-show="!sendCodeBtn" class="send_btn gray" slot="button" size="small" disabled type="button">重新发送(${countdown}s)</van-button>
+                        </template>
+                    </van-field>
+                    <div class="j-footer j-button-group" style="background-color: transparent;padding: .64rem .32rem;">
+                        <button class="j-button-confirm" native-type="submit" :disabled="!btnStatus">立即验证</button>
+                    </div>
+                </van-form>
+            </div>
+        </div>
+
+    </div>
+
+    <!--S-当前页面的资源-->
+    <script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js></script>
+    <script src=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/vant.min.js></script>
+    <script src=//cdn-common.jianyu360.com/cdn/lib/zepto/1.2.0/zepto.min.js></script>
+    <!--E-当前页面的资源-->
+    {{include "/big-member/commonjs.html"}}
+    <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/account/js/verify.js?v={{Msg "seo" "version"}}'></script>
+    {{include "/common/baiducc.html"}}
+
+</body>
+
+</html>

+ 1 - 1
src/jfw/modules/bigmember/src/service/report/report.go

@@ -572,7 +572,7 @@ func isFree(userId string) bool {
 
 //
 func getQuery(sess *httpsession.Session) (string, string, interface{}) {
-	sessMap := sess.GetMultiple("userId", "entUserId")
+	sessMap := sess.GetMultiple()
 	userId := util.ObjToString(sessMap["userId"])
 	user, ok := Mgo.FindById("user", userId, `{"s_phone":1,"s_m_phone":1}`)
 	if !ok || user == nil {

+ 4 - 5
src/jfw/modules/distribution/src/service/filter/phonefilter.go

@@ -8,7 +8,6 @@ import (
 	"regexp"
 	"strings"
 	"time"
-
 	qu "app.yhyue.com/moapp/jybase/common"
 	. "app.yhyue.com/moapp/jybase/date"
 	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
@@ -71,7 +70,7 @@ func (l *phoneFilter) Do() bool {
 	}
 	href := Sysconfig.Webdomain + "/front/account/phone/bind?mode=mergeBind&redirectTo=" + encodeURIComponent(l.R.URL.String()) //wx 加密 前端用于返回
 	if uid := l.GetSession["userId"]; uid != nil && uid != "" {
-		if person, ok := MQFW.FindById("user", mongodb.BsonIdToSId(qu.ObjToString(uid)), `{"s_phone":1,"s_m_phone":1,"l_registedate":1,"b_merge_remind":1,"i_ispush":1}`); person != nil && ok {
+		if person, ok := MQFW.FindById("user", mongodb.BsonIdToSId(qu.ObjToString(uid)), `{"s_phone":1,"s_m_phone":1,"l_registedate":1,"i_ispush":1}`); person != nil && ok {
 			s_phone := qu.ObjToString((*person)["s_phone"])
 			if s_phone == "" {
 				s_phone = qu.ObjToString((*person)["s_m_phone"])
@@ -87,9 +86,9 @@ func (l *phoneFilter) Do() bool {
 			if onLineTime.After(reg) {
 				return true
 			}
-			if remind, _ := (*person)["b_merge_remind"].(bool); remind { //不再提醒
-				return true
-			}
+			//if remind, _ := (*person)["b_merge_remind"].(bool); remind { //不再提醒
+			//	return true
+			//}
 			//取关用户
 			if i_ispush := qu.IntAll((*person)["i_ispush"]); i_ispush == 0 {
 				return true

+ 3 - 0
src/jfw/modules/subscribepay/src/a/init.go

@@ -34,6 +34,9 @@ func init() {
 	xweb.AddRouter("/subscribepay", &service.OrderDetail{})      //订单详情(详情页统一接口)
 	xweb.AddRouter("/subscribepay", &service.SubscribeChange{})  //续费&升级&订阅修改
 
+	//手机号异常验证
+	xweb.AddRouter("/subscribepay", &service.ExceptionVerification{}) //虚拟手机号验证
+
 	xweb.AddRouter("/subscribepay", &report.Report{}) //订阅报告
 	//p1
 	xweb.AddRouter("/subscribepay", &service.IndexSearch{}) //续费&升级

+ 1 - 1
src/jfw/modules/subscribepay/src/report/report.go

@@ -500,7 +500,7 @@ func getColl(referer, t string, flag bool) string {
 
 //
 func getQuery(sess *httpsession.Session) (string, string, interface{}) {
-	sessMap := sess.GetMultiple("userId", "entUserId")
+	sessMap := sess.GetMultiple()
 	userId := qutil.ObjToString(sessMap["userId"])
 	user, ok := util.MQFW.FindById("user", userId, `{"s_phone":1,"s_m_phone":1}`)
 	if !ok || user == nil {

+ 79 - 0
src/jfw/modules/subscribepay/src/service/exceptionVerification.go

@@ -0,0 +1,79 @@
+package service
+
+import (
+	. "api"
+	"config"
+	"fmt"
+	"github.com/go-xweb/xweb"
+	"log"
+	qutil "qfw/util"
+	"qfw/util/jy"
+	"qfw/util/redis"
+	"time"
+	"util"
+)
+
+type ExceptionVerification struct {
+	*xweb.Action
+	phoneVerification xweb.Mapper `xweb:"/exception/verification"` //虚拟网段手机号异常验证
+}
+
+func init() {
+	xweb.AddAction(&ExceptionVerification{})
+}
+
+const (
+	virtualPhoneFlag = "virtualIdentCode"
+	AbnormalTrigger  = "abnormal_trigger_%s"
+)
+
+func (this *ExceptionVerification) PhoneVerification() {
+	defer qutil.Catch()
+	userId, _ := this.GetSession("userId").(string)
+	reqType := this.GetString("reqType")
+	rData, errMsg := func() (interface{}, error) {
+		if userId == "" {
+			return nil, fmt.Errorf("未登录")
+		}
+		switch reqType {
+		case "sendIdentCode":
+			phone, _ := this.GetSession("phone").(string)
+			if phone == "" {
+				if res, _ := util.MQFW.FindById("user", userId, `{"s_phone":1,"s_m_phone":1}`); res != nil && len(*res) > 0 {
+					if resPhone := qutil.ObjToString((*res)["s_phone"]); resPhone != "" {
+						phone = resPhone
+					} else if resPhone := qutil.ObjToString((*res)["s_m_phone"]); resPhone != "" {
+						phone = resPhone
+					}
+				}
+			}
+			if phone == "" {
+				return nil, fmt.Errorf("未查询到手机号")
+			}
+			if !jy.SendPhoneIdentCode(config.Config.SmsServiceRpc, phone, this.Session(), virtualPhoneFlag) {
+				return nil, fmt.Errorf("验证码发送频繁")
+			}
+		case "codeVerification":
+			reqCode := this.GetString("reqCode")
+			if reqCode == "" {
+				return nil, fmt.Errorf("请输入验证码")
+			}
+			logTime := qutil.Int64All(this.Session().Get(fmt.Sprintf("%sTime", virtualPhoneFlag)))
+			if time.Now().Unix()-logTime > 60 {
+				return nil, fmt.Errorf("验证码超时")
+			}
+			if jy.CheckPhoneIdent(this.Session(), reqCode, virtualPhoneFlag) == "" {
+				return nil, fmt.Errorf("验证码校验失败")
+			}
+			jy.ClearPhoneIdentSession(this.Session(), virtualPhoneFlag)
+			redis.Del("newother", fmt.Sprintf(AbnormalTrigger, userId)) //验证成功清空redis
+		default:
+			return nil, fmt.Errorf("未知请求")
+		}
+		return true, nil
+	}()
+	if errMsg != nil {
+		log.Printf("%s ExceptionVerification PhoneVerification %s异常:%s\n", userId, reqType, errMsg.Error())
+	}
+	this.ServeJson(NewResult(rData, errMsg))
+}

+ 27 - 21
src/jfw/modules/subscribepay/src/service/phoneCollent.go

@@ -17,9 +17,9 @@ import (
 type PhoneCollent struct {
 	*xweb.Action
 	//合并 手机手机号
-	collectPhone xweb.Mapper `xweb:"/userMsg/collect"`     //收集手机号
-	neverRemind  xweb.Mapper `xweb:"/userMsg/neverRemind"` //不再提醒
-	needBind     xweb.Mapper `xweb:"/userMsg/needBind"`    //是否需要进入到绑定手机号
+	collectPhone xweb.Mapper `xweb:"/userMsg/collect"` //收集手机号
+	//neverRemind  xweb.Mapper `xweb:"/userMsg/neverRemind"` //不再提醒
+	needBind xweb.Mapper `xweb:"/userMsg/needBind"` //是否需要进入到绑定手机号
 }
 
 func (this *PhoneCollent) CollectPhone() {
@@ -54,30 +54,32 @@ func (this *PhoneCollent) CollectPhone() {
 	}()
 	this.ServeJson(NewResult(r, msg))
 }
-func (this *PhoneCollent) NeverRemind() {
-	if !R.CheckReqParam(this.ResponseWriter, this.Request, "merge_remind") {
-		return
-	}
-	userId := qutil.ObjToString(this.GetSession("userId"))
-	checkout, _ := this.GetBool("merge_remind")
-	if util.MQFW.UpdateById("user", userId, map[string]interface{}{
-		"$set": map[string]interface{}{
-			"b_merge_remind": checkout,
-		},
-	}) {
-		this.ServeJson(NewResult(map[string]interface{}{
-			"status": 1,
-		}, nil))
-	}
-	this.ServeJson(NewResult(nil, fmt.Errorf("保存失败")))
-}
+
+//func (this *PhoneCollent) NeverRemind() {
+//    if !R.CheckReqParam(this.ResponseWriter, this.Request, "merge_remind") {
+//        return
+//    }
+//    userId := qutil.ObjToString(this.GetSession("userId"))
+//    checkout, _ := this.GetBool("merge_remind")
+//    if util.MQFW.UpdateById("user", userId, map[string]interface{}{
+//        "$set": map[string]interface{}{
+//            "b_merge_remind": checkout,
+//        },
+//    }) {
+//        this.ServeJson(NewResult(map[string]interface{}{
+//            "status": 1,
+//        }, nil))
+//    }
+//    this.ServeJson(NewResult(nil, fmt.Errorf("保存失败")))
+//}
+
 func (this *PhoneCollent) NeedBind() {
 	r := func() bool {
 		uid, _ := this.GetSession("userId").(string)
 		if uid == "" {
 			return false
 		}
-		if person, ok := util.MQFW.FindById("user", uid, `{"s_phone":1,"s_m_phone":1,"b_merge_remind":1,"l_registedate":1}`); person != nil && len(*person) > 0 && ok {
+		if person, ok := util.MQFW.FindById("user", uid, `{"s_phone":1,"s_m_phone":1,"l_registedate":1}`); person != nil && len(*person) > 0 && ok {
 			s_phone := qutil.ObjToString((*person)["s_phone"])
 			if s_phone == "" {
 				s_phone = qutil.ObjToString((*person)["s_m_phone"])
@@ -89,10 +91,14 @@ func (this *PhoneCollent) NeedBind() {
 			reg := time.Unix(regtime, 0)
 			//新用户时间
 			accountMergeOnline := config.Config.AccountMergeOnline
+<<<<<<< HEAD
 			onLineTime, _ := time.ParseInLocation(Date_Full_Layout, accountMergeOnline, time.Local)
 			if remind, _ := (*person)["b_merge_remind"].(bool); remind { //不再提醒
 				return false
 			}
+=======
+			onLineTime, _ := time.ParseInLocation(qutil.Date_Full_Layout, accountMergeOnline, time.Local)
+>>>>>>> master
 			if onLineTime.Before(reg) { //新用户
 				return true
 			}

+ 312 - 0
src/web/staticres/common-module/account/js/verify.js

@@ -0,0 +1,312 @@
+var vNode = {
+  delimiters: ['${', '}'],
+  el: '#auth',
+  data: function (){
+      var _this = this;
+      return {
+          act: '',  // 是否要做某些操作
+          mode: '',  // 是否跳转强制绑定
+          from: '',  // 是否通过iframe进入
+          redirectTo: '',
+          info:{
+              phone: '',
+              email: ''
+          },
+          // 当前图形验证码信息
+          cur:{
+              showCaptcha: false,
+              imgSrc: ''
+          },
+          // 缓存起来的图形验证码信息
+          next:{
+              showCaptcha: false,
+              imgSrc: ''
+          },
+          pictureCode:'', // 图形验证码
+          msgCode:'', // 短信验证码
+          countdown: 0, // 倒计时
+          beforeTime: -1,
+          sendCodeBtn: true, // 显示发送短信按钮
+          nextStatus: [false, false],
+          pictureRules:[{
+              validator: function (val) {
+                  var status = /\d{4}/.test(val)
+                  _this.setNextStatus(status, 0)
+                  if (val === '') {
+                      return true
+                  }
+                  return status
+              },
+              message: '图形验证码格式错误'
+          }],
+          regCodeRules: [{
+              validator: function(val) {
+                  var status = /\d{6}/.test(val)
+                  _this.setNextStatus(status, 1)
+                  if (val === '') {
+                      return true
+                  }
+                  return status
+              },
+              message: '验证码格式错误'
+          }]
+      };
+  },
+  computed: {
+      btnStatus: function () {
+          if (!this.cur.showCaptcha) {
+              this.nextStatus[0] = true
+          }
+          return this.nextStatus.every(function(v) { return v} ) && (this.msgCode && this.msgCode.length === 6)
+      }
+  },
+  created () {
+      this.getUserInfo();
+      this.from = utils.getParam('from')
+      this.mode = utils.getParam('mode')
+      this.act = utils.getParam('act')
+      this.redirectTo = utils.getParam('redirectTo')
+      if (this.redirectTo) {
+        this.redirectTo = decodeURIComponent(this.redirectTo)
+      }
+  },
+  mounted() {
+      // this.getPicture()
+      // this.setHistory()
+      try {
+        JyObj.hiddenBottom('0')
+      } catch (e) {
+        console.warn(e)
+      }
+  },
+  methods: {
+      // 获取手机号
+      getUserInfo: function() {
+          var _this = this;
+          $.ajax({
+              url: "/jypay/user/getAccountInfo?t=" + Date.now(),
+              type: "GET",
+              success: function(res){
+                  if(res.error_code == 0){
+                      _this.info.phone = res.data.phone;
+                      _this.info.email = res.data.email;
+                  } else {
+                      _this.$toast(res.error_msg)
+                  }
+              }
+          });
+      },
+      // 加载loading
+      showLoading: function() {
+          var loading = this.$toast.loading({
+              duration: 0,
+              forbidClick: true,
+              message: 'loading...',
+          })
+          return loading
+      },
+      // 手机号截取
+      phoneFn: function(phone) {
+          phone = phone.replace(/(\d{3})\d{4}(\d{4})/, '$1 xxxx $2');
+          return phone;
+      },
+      setNextStatus:function (status, i) {
+          this.nextStatus.splice(i, 1, status)
+      },
+      // 图形验证码输入
+      inputPicture: function(val){
+          if (val === '') {
+              this.setNextStatus(false, 0)
+          } else {
+              this.setNextStatus(true, 0)
+          }
+      },
+      // 短信验证码输入
+      inputCode: function (val) { 
+          if (val === '') {
+              this.setNextStatus(false, 1)
+          } else {
+              this.setNextStatus(true, 1)
+          }
+      },
+      // 第一次出现图形验证码时获取图形验证码
+      getPicture: function (isCache) {
+          var _this = this;
+          if (_this.next.imgSrc) {
+              _this.cur.imgSrc = _this.next.imgSrc;
+              _this.cur.showCaptcha = _this.next.showCaptcha;
+              _this.next.imgSrc = ''
+              return;
+          }
+          $.ajax({
+              url: "/jypay/user/phone/imgCaptcha?t=" + Date.now(),
+              type: "GET",
+              success: function(res){
+                  if(res.error_code == 0 && res.data){
+                      if(res.data.needVerify) {
+                          // 如果需要显示图形验证码,则需要校验,也需要赋值图片地址
+                          _this.pictureCode ? _this.setNextStatus(true, 0) : _this.setNextStatus(false, 0)
+                      } else {
+                          // 如果不需要显示图形验证码,则无需校验,无需图片
+                          _this.setNextStatus(true, 0)
+                      }
+                      // 如果需要缓存图片
+                      if (isCache == 'cache') {
+                          // 将下一张图片的状态缓存
+                          _this.next.imgSrc = res.data.imageData
+                          _this.next.showCaptcha = res.data.needVerify
+                      } else {
+                          _this.cur.showCaptcha = res.data.needVerify;
+                          _this.cur.imgSrc = res.data.imageData
+                      }
+                  } else {
+                      _this.$toast(res.error_msg)
+                  }
+              }
+          });
+      },
+      // 改变图形验证码
+      refreshPicture: function(){
+          this.cur.imgSrc = '';
+          this.getPicture()
+      },
+      // 身份验证请求封装(1.发送验证码 、 2.验证身份)
+      validStatus: function(step,code,callback) {
+          // reqType: reqType==sendIdentCode发短信;reqType == codeVerification验证;reqCode: 图形验证码或短信验证码  callback:请求成功回调
+          var _this = this;
+          var data =  {
+              reqType: step,
+              reqCode: code
+          }
+          var loading = _this.showLoading();
+          $.ajax({
+              url: '/subscribepay/exception/verification',
+              type:'POST',
+              data: data,
+              success: function(res) {
+                  loading.clear()
+                  callback && callback(res)
+              }
+          })
+      },
+      // 发送短信验证码(第一次请求 reqType==sendIdentCode 传图形验证码)
+      sendMobileCode: function(){
+          // if(this.cur.showCaptcha && this.pictureCode == '') {
+          //     return;
+          // }
+          var tempRefs = this.$refs.phoneForm;
+          var _this = this;
+          var validArr = _this.cur.showCaptcha ? [tempRefs.validate('picture')] : []
+          Promise.all(validArr).then(function() {
+              _this.countdown = new Date().getTime()
+              // 发送手机验证码
+              _this.validStatus('sendIdentCode',_this.pictureCode,function(res){
+                if(res.error_code == 0 && res.data) {
+                    _this.sendCodeBtn = false
+                    _this.startTimer()
+                } else {
+                    _this.$toast(res.error_msg)
+                }
+            })
+          })
+      },
+      // 开始倒计时,倒计时结束将缓存的图片赋值并清空
+      startTimer: function() {
+          var _this = this;
+          _this.countdown = 60
+          _this.beforeTime = new Date().getTime()
+          var timeInt = setInterval(function() {
+              if (_this.beforeTime !== -1) {
+                  var nowCount = 60 - Math.ceil((new Date().getTime() - _this.beforeTime) / 1000)
+                  if (nowCount < _this.countdown) {
+                      _this.countdown = nowCount
+                  }
+              }
+              _this.countdown--
+              if (_this.countdown <= 0) {
+                  _this.sendCodeBtn = true
+                  _this.beforeTime = -1
+                  // _this.cur.imgSrc = _this.next.imgSrc;
+                  // _this.cur.showCaptcha = _this.next.showCaptcha;
+                  // _this.next.imgSrc = ''
+                  window.clearInterval(timeInt)
+              }
+          }, 1000)
+      },
+      // 提交验证(第二次请求:tep=codeVerification 传短信验证码)
+      submitForm: function () {
+          var _this = this;
+          var loading = _this.showLoading();
+          _this.validStatus('codeVerification',_this.msgCode,function(res){
+              if (res.error_code === 0 && res.data) {
+                  loading.clear();
+                  // 验证成功 返回上一页
+                  _this.afterSetPhoneSuccess()
+              } else {
+                  _this.$toast(res.error_msg);
+              }
+          })
+      },
+      // 手机号绑定或者更换成功后的操作
+      afterSetPhoneSuccess: function () {
+          var _this = this
+          _this.$toast({
+              message: '验证成功',
+              duration: 1500,
+              forbidClick: true,
+              onClose: function () {
+                  // 是否通过iframe打开
+                  if (_this.from == 'iframe') {
+                      window.parent.postMessage({
+                          action: 'success'
+                      }, location.origin)
+                  } else if (_this.act == 'logout') {
+                      try {
+                          JyObj.backUrl('H')
+                          JyObj.refreshAppointTab('subscribe', 1)
+                          JyObj.refreshAppointTab('box', 1)
+                          JyObj.refreshAppointTab('me', 1)
+                      } catch (error) {}
+                  } else if (_this.redirectTo) {
+                      location.replace(_this.redirectTo)
+                  } else {
+                      history.back()
+                  }
+              }
+          })
+      },
+      // 如果是强制绑定重定向过来的,返回时候就回到首页
+      setHistory: function () {
+        var _this = this
+        // act=logout,返回则退出登录,绑定成功则回到首页
+        if (this.act == 'logout') {
+            setTimeout(function () {
+                history.pushState({ act: _this.act }, '', '')
+                _this.onPopstate()
+            }, 300)
+        }
+      },
+      removePopstate: function () {
+          $(window).off('popstate')
+          $('.j-header .header-left').on('click', goBack)
+      },
+      onPopstate: function () {
+          $(window).on('popstate', function () {
+              try {
+                  appQuit(false)
+              } catch (error) {}
+          })
+      },
+      goBack: function () {
+          if(history.length === 1) {
+            try {
+              JyObj.backUrl('')
+            } catch (error) {}
+          } else {
+            history.back()
+          }
+          window.afterClickBack && window.afterClickBack()
+      }
+  }
+}
+var verify = new Vue(vNode)

+ 1 - 1
src/web/staticres/common-module/share/js/invite-friends.js

@@ -148,7 +148,7 @@ var shareContent = new Vue({
                         var userInfo = res
                         if (userInfo) {
                             if (!userInfo.headImage) {
-                                userInfo.headImage = '/images/auto.png'
+                                userInfo.headImage = '/common-module/public/image/auto.png'
                             }
                             Object.assign(_this.userInfo, userInfo)
                         }

BIN
src/web/staticres/commonFunctions/wm-team-reports.png


BIN
src/web/staticres/docs/aaaa.docx


BIN
src/web/staticres/docs/个人年终报告.docx


+ 7 - 0
src/web/staticres/frontRouter/pc/collection/css/index-pc.css

@@ -380,6 +380,13 @@
   box-sizing: content-box;
   min-width: 42px;
 }
+.body.in-iframe.in-bi {
+  background-color: transparent !important;
+}
+.in-bi .no-data {
+  padding-top: 100px;
+  margin-top: 0;
+}
 /* .bi-report-inject-button[disabled] {
   opacity: 0.6;
   cursor: not-allowed;

+ 1 - 1
src/web/templates/frontRouter/pc/brand/free/index.html

@@ -389,7 +389,7 @@
         <p class="name">服务热线</p>
         <img src="{{Msg "seo" "cdn"}}/brand/img/kefuQR.png?v={{Msg "seo" "version"}}" alt="" class="qr">
         <p class="phone">400-108-6670</p>
-        <p class="desc">8:50-18:00</p>
+        <p class="desc">工作日:9:00-17:40</p>
       </div>
       <div class="item">
         <p class="tit">市场合作</p>

+ 4 - 0
src/web/templates/frontRouter/pc/userMerge/sess/bind.html

@@ -14,6 +14,10 @@
   <script type="text/javascript" src="{{Msg "seo" "cdn"}}/js/public-nav.js?v={{Msg "seo" "version"}}"></script>
 </head>
 <style>
+    html,
+    body.in-iframe{
+      background-color: #fff!important;
+    }
     .public-nav{
         border-bottom: 1px solid #e0e0e0;
     }

+ 353 - 0
src/web/templates/frontRouter/pc/userMerge/sess/verify.html

@@ -0,0 +1,353 @@
+<html>
+<head>
+    <title>账号异常验证</title>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1" />
+    <meta name="renderer" content="webkit">
+    <meta content="telephone=no" name="format-detection"/>
+    <meta content="light" theme="light" name="enable-header"/>
+    {{include "/common/pnc.html"}}
+    <link href="{{Msg "seo" "cdn"}}/css/pc.css?v={{Msg "seo" "version"}}" rel="stylesheet">
+    <link href="{{Msg "seo" "cdn"}}/css/dev2/reset_pc.css?v={{Msg "seo" "version"}}" rel="stylesheet">
+    <script src="{{Msg "seo" "cdn"}}/js/jquery.cookie.js"></script>
+  <link rel="stylesheet" type="text/css" href="{{Msg "seo" "cdn"}}/pccss/public-nav.css?v={{Msg "seo" "version"}}" />
+  <link rel="stylesheet" type="text/css" href="{{Msg "seo" "cdn"}}/pccss/public-nav-1200.css?v={{Msg "seo" "version"}}" />
+  <script type="text/javascript" src="{{Msg "seo" "cdn"}}/js/public-nav.js?v={{Msg "seo" "version"}}"></script>
+</head>
+<style>
+    html,
+    body.in-iframe{
+      background-color: #fff!important;
+    }
+    .public-nav{
+        border-bottom: 1px solid #e0e0e0;
+    }
+    .in-iframe .bind_page{
+        padding-top:0;
+    }.bind_page{
+        padding-top:76px;
+    }
+    .bind_page>.login-dig-phone-bind-box{
+        margin: 20px 0px 50px 0px;
+    }
+    .login-dig-phone-bind-box {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        font-family: Microsoft YaHei,sans-serif;
+        padding-bottom: 220px;
+    }
+
+    .login-dig-phone-bind-box .register-step-title {
+        font-size: 14px;
+        line-height: 24px;
+        color: #999999;
+    }
+
+    .login-dig-phone-bind-box .register-step-title div {
+        color: #1D1D1D;
+        font-size: 24px;
+        line-height: 36px;
+        text-align: left;
+        min-width: 340px;
+    }
+
+
+    .login-dig-phone-bind-box  .login-dig-input-box {
+        width: 340px;
+    }
+
+    .login-dig-phone-bind-box  button {
+        width: 340px;
+        margin-top: 32px;
+    }
+    .autocomplete-item {
+        position: relative;
+    }
+    .autocomplete-box {
+        display: none;
+        background: #fff;
+        position: absolute;
+        bottom: -213px;
+        left: 0;
+        width: 100%;
+        height: 205px;
+        max-height: 205px;
+        overflow: hidden;
+        overflow-y: auto;
+        z-index: 666;
+        box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.08);
+        border-radius: 8px;
+    }
+    .autocomplete-box li:hover {
+        background: #F6F6F6;
+    }
+    .autocomplete-box li:last-child {
+        border-bottom: none;
+    }
+    .autocomplete-box li {
+        width: 100%;
+        box-sizing: border-box;
+        color: #1D1D1D;
+        font-family: Microsoft YaHei,sans-serif;
+        font-size: 14px;
+        line-height: 24px;
+        letter-spacing: 0px;
+        text-align: left;
+        padding: 10px 20px;
+        border-bottom: 1px solid rgba(0, 0, 0, 0.05);
+        cursor: pointer;
+    }
+    .login-dig-submit-button:disabled {
+        background: #87DFEA;
+        border-color: #87DFEA;
+    }
+
+    .bind-title-group {
+        width: 100%;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+    }
+    .bind-title-group p {
+        font-family: Microsoft YaHei,sans-serif;
+        font-style: normal;
+        font-weight: normal;
+        font-size: 14px;
+        line-height: 24px;
+        text-align: center;
+        color: #686868;
+    }
+    .bind-title-group div {
+        margin-top: 67px;
+        margin-bottom: 40px;
+        max-width: 1200px;
+        text-align: center;
+        font-family: Microsoft YaHei,sans-serif;
+        font-style: normal;
+        font-weight: normal;
+        font-size: 16px;
+        line-height: 40px;
+        color: #1D1D1D;
+        width: 100%;
+        border-bottom: 1px solid #EBEBEB;
+    }
+    .custom-toast .toast-container {
+      position: fixed;
+      top: 50%;
+      left: 50%;
+      width: auto;
+      padding: 16px 32px;
+      font-size: 16px;
+      background: rgba(0, 0, 0, 0.65);
+      border-radius: 8px;
+      color: #fff;
+      transform: translateX(-50%) translateY(-50%);
+      z-index: 99;
+    }
+    .custom-toast .mask{
+      position: fixed;
+      width: 100%;
+      height: 100%;
+      top: 0;
+      bottom: 0;
+      left: 0;
+      right: 0;
+      z-index: 98;
+      background: transparent;
+    }
+    .login-dig-success-toast{
+      margin-top: -140px!important;
+    }
+</style>
+<body>
+{{include "/common/pchead.html"}}
+<script>
+  $("div#bidLogin").remove()
+</script>
+<section class="bind_page" id="verify-account" v-cloak>
+    <div class="login-dig-tabbar-navbar"></div>
+    <div class="login-dig-success-toast" v-show="showSuccess">
+        <i class="login-dig-icon-success"></i>
+        <span>验证成功</span>
+    </div>
+    <div class="login-dig-phone-bind-box">
+        <div class="bind-title-group">
+            <div>账号异常验证</div>
+            <p>您好,系统识别到您的账号异常,请您对登录手机号进行验证。</p>
+        </div>
+        <div class="login-dig-tabbar-content is-active" data-name="code">
+            <div class="login-dig-input-box" style="background-color: transparent;border: 0;">
+                <i class="login-dig-icon-phone"></i>
+                <input v-model="formatVerifyPhone" autocomplete="off" disabled type="tel">
+            </div>
+            <div class="login-dig-input-box" :class="{'is-focus': codeFocus}" data-error="短信验证码输入错误">
+                <i class="login-dig-icon-guard"></i>
+                <input
+                  v-model="msgCode"
+                  @blur="onCodeBlur"
+                  @focus="onCodeFocus"
+                  autocomplete="off"
+                  name="verify_sms"
+                  type="text"
+                  placeholder="输入短信验证码"
+                  maxlength="6"
+                >
+                <div class="after-input-box">
+                    <span v-if="sendCodeBtn" class="l-get-sms" :class="formatVerifyPhone ? '' : 'is-stop'" @click="sendMobileCode">获取验证码</span>
+                    <span v-else class="l-get-sms is-stop">重新获取(${countdown}s)</span>
+                </div>
+            </div>
+            <button class="login-dig-submit-button" :disabled="verifyStatus" @click="submitForm">立即验证</button>
+        </div>
+    </div>
+</section>
+{{include "/common/pcbottom.html"}}
+{{include "/common/baiducc.html"}}
+<script src="//cdn-common.jianyu360.com/cdn/lib/vue/2.6.14/vue.min.js"></script>
+<script type="text/javascript">
+  $(function(){
+    haslogin({{.T.logid}});
+
+    var verifyAccount = new Vue({
+      el: '#verify-account',
+      delimiters: ['${', '}'],
+      data: {
+        showSuccess: false,
+        verifyPhone: '',
+        codeFocus: false,
+        msgCode: '',
+        countdown: 0,
+        beforeTime: -1,
+        sendCodeBtn: true,
+      },
+      computed: {
+        formatVerifyPhone () {
+          return this.addConfusionForTel(this.verifyPhone)
+        },
+        verifyStatus () {
+          return !(this.msgCode && this.msgCode.length === 6)
+        }
+      },
+      created () {
+        this.getVerifyPhone()
+      },
+      mounted() {},
+      methods: {
+        // 手机号中间4位加*
+        addConfusionForTel: function (tel) {
+          var reg = /^(\d{3})\d{4}(\d{4})$/
+          return tel.replace(reg, '$1****$2')
+        },
+        getVerifyPhone: function () {
+          var _this = this
+          $.ajax({
+            url: '/jypay/user/getAccountInfo?t=' + Date.now(),
+            success: function (r) {
+              if (r && r.data) {
+                if (r.data.phone) {
+                  _this.verifyPhone = r.data.phone
+                }
+              }
+            }
+          })
+        },
+        // 验证请求封装(1.发送验证码 、 2.验证身份)
+        validStatus: function(type, code, callback) {
+          // reqType: reqType==sendIdentCode发短信;reqType == codeVerification验证;reqCode: 图形验证码或短信验证码  callback:请求成功回调
+          var _this = this;
+          var data =  {
+              reqType: type,
+              reqCode: code
+          }
+          $.ajax({
+              url: '/subscribepay/exception/verification',
+              type:'POST',
+              data: data,
+              success: function(res) {
+                callback && callback(res)
+              }
+          })
+        },
+        // 发送短信验证码(第一次请求 reqType==sendIdentCode 传图形验证码)
+        sendMobileCode: function() {
+            var _this = this;
+            _this.countdown = new Date().getTime()
+            // 发送手机验证码
+            _this.validStatus('sendIdentCode', '', function(res){
+              if(res.error_code === 0 && res.data) {
+                  _this.sendCodeBtn = false
+                  _this.startTimer()
+              } else {
+                  _this.toastFn(res.error_msg)
+              }
+          })
+        },
+        // 提交验证(第二次请求:tep=codeVerification 传短信验证码)
+        submitForm: function () {
+            if(!this.msgCode) return
+            var redirectTo = getParam('redirectTo')
+            var _this = this;
+            _this.validStatus('codeVerification', _this.msgCode,function(res){
+                if (res.error_code === 0 && res.data) {
+                  // 验证成功 返回上一页
+                  _this.showSuccess = true
+                  setTimeout(function () {
+                    _this.showSuccess = false
+                    // 非工作桌面重定向到传过来的上一页
+                    if (!goTemplateData.inIframe) {
+                      window.location.replace(redirectTo)
+                    } else {
+                      // 在工作桌面内跳转
+                      window.location.replace(redirectTo)
+                      // window.location.replace('/page_workDesktop/work-bench/page?link=' + encodeURIComponent(redirectTo))
+                    }
+                  }, 1500)
+                } else {
+                  _this.toastFn(res.error_msg)
+                }
+            })
+        },
+        // 开始倒计时,倒计时结束将缓存的图片赋值并清空
+        startTimer: function() {
+            var _this = this;
+            _this.countdown = 60
+            _this.beforeTime = new Date().getTime()
+            var timeInt = setInterval(function() {
+                if (_this.beforeTime !== -1) {
+                    var nowCount = 60 - Math.ceil((new Date().getTime() - _this.beforeTime) / 1000)
+                    if (nowCount < _this.countdown) {
+                        _this.countdown = nowCount
+                    }
+                }
+                _this.countdown--
+                if (_this.countdown <= 0) {
+                    _this.sendCodeBtn = true
+                    _this.beforeTime = -1
+                    window.clearInterval(timeInt)
+                }
+            }, 1000)
+        },
+        onCodeFocus: function () {
+          this.codeFocus = true
+        },
+        onCodeBlur: function () {
+          this.codeFocus = false
+        },
+        toastFn: function (text, duration) {
+          if (!duration) {
+            duration = 2000
+          }
+          var _html = ""
+          _html+='<div class="custom-toast"><div class="mask" style="background-color: transparent;"></div><div class="toast-container">'
+          _html+='<span>' + text + '</span></div></div>'
+          $('body').append(_html)
+          setTimeout(function () {
+            $(".custom-toast").fadeOut().remove();
+          }, duration)
+        }
+      }
+    })
+  });
+</script>
+</body>
+</html>

+ 146 - 0
src/web/templates/frontRouter/wx/verify/free/index.html

@@ -0,0 +1,146 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <meta charset="utf-8">
+    <meta name="keywords" content="剑鱼标讯">
+    <meta name="description" content="剑鱼标讯">
+    <meta name="author" content="剑鱼标讯">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
+    <meta name="browsermode" content="application">
+    <meta name="x5-orientation" content="portrait">
+    <meta name="screen-orientation" content="portrait">
+    <meta name="x5-page-mode" content="app">
+    <meta name="apple-mobile-web-app-capable" content="yes">
+    <meta name="apple-mobile-web-app-status-bar-style" content="black">
+    <meta name="format-detection" content="telephone=no">
+    <title>账号异常验证</title>
+    <link rel="icon" href="/favicon.ico">
+    <script src="/js/rem.js"></script>
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/reset-css/5.0.1/reset.min.css />
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/index.css />
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/icon/local.css />
+    <link rel="stylesheet" href="/big-member/css/public.css?v={{Msg "seo" "version"}}" />
+    <link rel="stylesheet" href="/big-member/css/j-icons.css?v={{Msg "seo" "version"}}" />
+    <style>
+        .auth-tip {
+            padding: .48rem 0 .36rem;
+        }
+
+        .auth-tip p {
+            color: #9B9CA3;
+            font-size: .28rem;
+            line-height: .4rem;
+            text-align: center;
+        }
+
+        .auth-phone {
+            padding-bottom: .48rem;
+            color: #5F5E64;
+            font-size: .4rem;
+            line-height: .6rem;
+            text-align: center;
+            word-break: break-all;
+        }
+        .picture-code{
+            width: 90px;
+            height: 30px;
+            background: #F5F6F7;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+        }
+        .van-field__label {
+            font-size: .3rem;
+        }
+
+        .van-field__control {
+            font-size: .32rem;
+        }
+
+        .van-field--error .van-field__control,
+        .van-field--error .van-field__control::placeholder {
+            color: #171826;
+        }
+
+        .send_btn {
+            background-color: transparent;
+            color: #2ABED1;
+            border: 0;
+            font-size: .28rem;
+            height: unset;
+        }
+
+        .send_btn:disabled {
+            color: #9B9CA3;
+        }
+
+        .picture-cell {
+            padding: .28rem .32rem;
+        }
+
+        .code-cell {
+            padding: .32rem;
+        }
+    </style>
+</head>
+
+<body>
+    <div class="j-container">
+        <div class="j-main" id="auth" v-cloak>
+            <div class="auth-tip">
+              <p>您好,系统识别到您的账号异常,</p>
+              <p>请您对登录手机号进行验证。</p>
+            </div>
+            <div class="auth-phone">${phoneFn(info.phone)}</div>
+            <div class="auth-form">
+                <van-form ref="phoneForm" @submit="submitForm">
+                    <van-field
+                        v-if="cur.showCaptcha"
+                        center
+                        class="picture-cell"
+                        v-model.trim="pictureCode"
+                        type="number"
+                        name="picture"
+                        placeholder="图形验证码"
+                        :rules="pictureRules"
+                        @input="inputPicture(pictureCode)"
+                    >
+                        <template #button>
+                            <div class="picture-code">
+                                <img v-if="cur.imgSrc" :src="'data:image/png;base64,' + cur.imgSrc" alt="图形验证码" width="90" height="30" @click="refreshPicture" key="picCode" />
+                                <van-loading size="24" v-else key="picCode"></van-loading>
+                            </div>
+                        </template>
+                    </van-field>
+                    <van-field
+                        center
+                        class="code-cell"
+                        v-model.trim="msgCode"
+                        type="number"
+                        name="code"
+                        label="验证码"
+                        placeholder="请输入验证码"
+                        :rules="regCodeRules"
+                        @input="inputCode(msgCode)"
+                    >
+                        <template #button>
+                            <van-button native-type="button" v-show="sendCodeBtn" class="send_btn" slot="button"  size="small" @click="sendMobileCode" type="button">发送验证码</van-button>
+                            <van-button native-type="button" v-show="!sendCodeBtn" class="send_btn gray" slot="button" size="small" disabled type="button">重新发送(${countdown}s)</van-button>
+                        </template>
+                    </van-field>
+                    <div class="j-footer j-button-group" style="background-color: transparent;padding: .64rem .32rem;">
+                        <button class="j-button-confirm" native-type="submit" :disabled="!btnStatus">立即验证</button>
+                    </div>
+                </van-form>
+            </div>
+        </div>
+    </div>
+    <script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js></script>
+    <script src=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/vant.min.js></script>
+    <script src=//cdn-common.jianyu360.com/cdn/lib/zepto/1.2.0/zepto.min.js></script>
+    <script src='/big-member/js/utils.js?v={{Msg "seo" "version"}}'></script>
+    <script src='{{Msg "seo" "cdn"}}/common-module/account/js/verify.js?v={{Msg "seo" "version"}}'></script>
+</body>
+{{include "/common/baiducc.html"}}
+</html>