Browse Source

wip:冲突

wangshan 5 months ago
parent
commit
e2bd99c3bd
100 changed files with 3876 additions and 1368 deletions
  1. 2 1
      src/config.json
  2. 6 6
      src/config.yaml
  3. 32 34
      src/db.json
  4. BIN
      src/fonts/D3Parallelism.ttf
  5. BIN
      src/fonts/Flim-Flam.ttf
  6. BIN
      src/fonts/chromohv.ttf
  7. 14 10
      src/go.mod
  8. 31 21
      src/go.sum
  9. 24 3
      src/jfw/active/active.go
  10. 9 0
      src/jfw/config/config.go
  11. 4 3
      src/jfw/filter/cookie.go
  12. 1 1
      src/jfw/filter/filter.go
  13. 1 1
      src/jfw/filter/pcUserSalesFilter.go
  14. 12 12
      src/jfw/filter/pcfilter.go
  15. 2 1
      src/jfw/filter/phonefilter.go
  16. 3 2
      src/jfw/filter/wxUserSalesFilter.go
  17. 1 1
      src/jfw/front/applysub.go
  18. 6 1
      src/jfw/front/dataExport.go
  19. 16 0
      src/jfw/front/dataMarket.go
  20. 10 3
      src/jfw/front/dataPackRouter.go
  21. 130 22
      src/jfw/front/dataServiceArea.go
  22. 25 20
      src/jfw/front/front.go
  23. 5 1
      src/jfw/front/frontRouter.go
  24. 26 6
      src/jfw/front/index.go
  25. 41 14
      src/jfw/front/login.go
  26. 3 1
      src/jfw/front/nzjProject.go
  27. 1 1
      src/jfw/front/org_structure.go
  28. 20 16
      src/jfw/front/otherAct.go
  29. 19 1
      src/jfw/front/partner.go
  30. 2 2
      src/jfw/front/pchelper.go
  31. 13 14
      src/jfw/front/recommendationProject.go
  32. 170 0
      src/jfw/front/returnMoneyPage.go
  33. 10 1
      src/jfw/front/shorturl.go
  34. 28 6
      src/jfw/front/singleLogin.go
  35. 333 320
      src/jfw/front/supsearch.go
  36. 25 21
      src/jfw/front/swordfish.go
  37. 56 18
      src/jfw/front/tags.go
  38. 34 2
      src/jfw/front/vipsubscribe.go
  39. 15 0
      src/jfw/front/websocket.go
  40. 3 0
      src/jfw/front/ws_dataExport.go
  41. 2 2
      src/jfw/front/wxkeyset.go
  42. 4 3
      src/jfw/modules/app/src/app/filter/cookie.go
  43. 1 1
      src/jfw/modules/app/src/app/filter/filter.go
  44. 1 0
      src/jfw/modules/app/src/app/filter/loginfilter.go
  45. 0 1
      src/jfw/modules/app/src/app/front/activity.go
  46. 7 2
      src/jfw/modules/app/src/app/front/commonPay.go
  47. 4 2
      src/jfw/modules/app/src/app/front/dataPackRouter.go
  48. 4 3
      src/jfw/modules/app/src/app/front/errLogsReceive.go
  49. 11 7
      src/jfw/modules/app/src/app/front/front.go
  50. 130 36
      src/jfw/modules/app/src/app/front/login.go
  51. 18 19
      src/jfw/modules/app/src/app/front/me.go
  52. 7 0
      src/jfw/modules/app/src/app/front/shorturl.go
  53. 27 19
      src/jfw/modules/app/src/app/front/swordfish.go
  54. 2 3
      src/jfw/modules/app/src/app/front/vipsubscribe.go
  55. 3 0
      src/jfw/modules/app/src/app/front/ws_dataExport.go
  56. 19 2
      src/jfw/modules/app/src/app/front/wx.go
  57. 305 305
      src/jfw/modules/app/src/app/front/wxkeyset.go
  58. 24 0
      src/jfw/modules/app/src/app/jyutil/rpccall.go
  59. 239 219
      src/jfw/modules/app/src/app/jyutil/util.go
  60. 352 0
      src/jfw/modules/app/src/app/miniprogram/miniprogram.go
  61. 1 0
      src/jfw/modules/app/src/app/tag/ad.go
  62. 12 1
      src/jfw/modules/app/src/config.yaml
  63. 64 64
      src/jfw/modules/app/src/db.json
  64. 12 6
      src/jfw/modules/app/src/go.mod
  65. 24 14
      src/jfw/modules/app/src/go.sum
  66. 2 0
      src/jfw/modules/app/src/jfw/config/config.go
  67. 1 0
      src/jfw/modules/app/src/main.go
  68. 53 1
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/css/ent_follow.css
  69. 69 3
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/css/ent_portrait.css
  70. 128 4
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/ent_follow.js
  71. 323 19
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/ent_portrait.js
  72. 288 4
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/potential_cor_list.js
  73. 1 1
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/report_analysis.js
  74. 20 0
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/unit_portrayal.js
  75. 1 1
      src/jfw/modules/app/src/web/staticres/jyapp/css/wxinfocontent.css
  76. 49 1
      src/jfw/modules/app/src/web/staticres/jyapp/followent/css/follow.css
  77. 2 0
      src/jfw/modules/app/src/web/staticres/jyapp/js/common.js
  78. 159 0
      src/jfw/modules/app/src/web/staticres/jyapp/js/slide-verify.js
  79. 15 2
      src/jfw/modules/app/src/web/staticres/jyapp/me/css/forgetPwd.css
  80. 36 8
      src/jfw/modules/app/src/web/staticres/jyapp/me/css/login.css
  81. 2 2
      src/jfw/modules/app/src/web/staticres/jyapp/me/js/login.js
  82. 7 0
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/base.css
  83. 12 1
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/keyWord.css
  84. 6 7
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/keyword-common.css
  85. 19 2
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/vip_index_new.css
  86. 6 0
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/vip_pay_success.css
  87. BIN
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/image/v_vip_icon.png
  88. 8 2
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/keyWord.js
  89. 26 1
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/vip_index_new.js
  90. 13 4
      src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/vip_order_detail.js
  91. 52 9
      src/jfw/modules/app/src/web/templates/areaPack/page_set_area.html
  92. 6 3
      src/jfw/modules/app/src/web/templates/big-member/page_bigvip_viewpage.html
  93. 35 1
      src/jfw/modules/app/src/web/templates/big-member/page_ent_follow.html
  94. 59 5
      src/jfw/modules/app/src/web/templates/big-member/page_ent_portrait.html
  95. 24 3
      src/jfw/modules/app/src/web/templates/big-member/page_landingPage.html
  96. 3 1
      src/jfw/modules/app/src/web/templates/big-member/page_orderdetail_aiForecastPack.html
  97. 11 5
      src/jfw/modules/app/src/web/templates/big-member/page_orderdetail_member.html
  98. 9 2
      src/jfw/modules/app/src/web/templates/big-member/page_orderdetail_subAccount.html
  99. 22 1
      src/jfw/modules/app/src/web/templates/big-member/page_potential_cor_list.html
  100. 3 0
      src/jfw/modules/app/src/web/templates/big-member/page_pro_follow_detail.html

+ 2 - 1
src/config.json

@@ -63,7 +63,8 @@
     "weChatUrlEnt": "/jy_mobile/project/joined/list?identity=ent",
     "weChatUrl": "/jy_mobile/project/joined/list",
     "agencyInfo": "/jy_mobile/message/todoList?msgType=11",
-    "report_analysis": "/jyapp/big/page/report_analysis?id=%s"
+    "report_analysis": "/jyapp/big/page/report_analysis?id=%s",
+    "subVipSetPage": "/front/vipsubscribe/toSubVipSetPage?vSwitch=v"
   },
   "jy_activeset": {
     "activitystartcode": "3201000000",

+ 6 - 6
src/config.yaml

@@ -1,17 +1,17 @@
 etcd:
   hosts:
-    - 192.168.3.207:2379
-    - 192.168.3.165:2379
-    - 192.168.3.204:2379
+    - 172.31.31.204:2379
 userCenterKey: "usercenter.rpc" #用户中台rpc
 powerCheckCenterKey: "powercheck.rpc" #权益校验中台
 resourceCenterKey: "resource.rpc" #资源中台
 entManageApplication: "entmanageapplication.rpc" #企业管理中台
-activityKey: "activity.rpc2" #营销中台rpc
+activityKey: "activity.rpc" #营销中台rpc
 publicserviceKey: "publicservice.rpc"
 
-
 database:
   default:
-    link: "clickhouse:jytop:pwdTopJy123@tcp(192.168.3.207:19000)/jyseo_test?dial_timeout=2000ms&max_execution_time=60"
+    #link: "clickhouse:jianyu_appl:Cli3#fkh4ouSe@tcp(cc-2zelp3xmkmsrtjhgp.public.clickhouse.ads.aliyuncs.com:9000)/jyseo_test?dial_timeout=2000ms&max_execution_time=60"
+    link: "clickhouse:jytop:pwdTopJy123@tcp(172.20.45.129:19000)/jyseo_test?dial_timeout=2000ms&max_execution_time=60"
     debug: true
+
+GuideRegistedate: 1734451200  #该时间之前注册的付费用户不用进订阅向导

+ 32 - 34
src/db.json

@@ -1,93 +1,91 @@
 {
   "mongodb": {
     "main": {
-      "address": "192.168.3.206:27080",
-      "size": 10,
+      "address": "172.20.45.129:27002,172.20.45.130:27080",
+      "size": 20,
       "dbName": "qfw"
     },
     "log": {
-      "address": "192.168.3.206:27090",
+      "address": "172.20.45.129:27002,172.20.45.130:27080",
       "size": 5,
       "dbName": "qfw",
-      "userName": "admin",
-      "password": "123456"
+      "userName": "",
+      "password": ""
     },
     "ent": {
-      "address": "192.168.3.206:27002",
+      "address": "172.20.45.129:27002,172.20.45.130:27080",
       "size": 5,
       "dbName": "mixdata",
-      "userName": "jyDevGroup",
-      "password": "jy@DevGroup"
+      "userName": "",
+      "password": ""
     },
     "bidding": {
-      "address": "192.168.3.206:27002",
+      "address": "172.20.45.129:27002,172.20.45.130:27080",
       "size": 5,
       "dbName": "qfw_data",
       "replSet": "",
       "collection": "bidding",
       "collection_back": "bidding_back",
-      "userName": "jyDevGroup",
-      "password": "jy@DevGroup"
+      "userName": "",
+      "password": ""
     }
   },
   "elasticsearch": {
     "main": {
-      "address": "http://192.168.3.149:9200",
+      "address": "http://172.20.45.129:9206,http://172.20.45.130:9306",
       "size": 30,
       "version": "v7",
       "userName": "",
-      "password": "",
-      "esIndex": "bidding",
-      "esType": "bidding"
+      "password": ""
     },
     "other": {
-      "address": "http://192.168.3.149:9200",
+      "address": "http://172.20.45.129:9206,http://172.20.45.130:9306",
       "size": 30,
       "version": "v7",
       "userName": "",
       "password": "",
-      "esIndex": "bidding_year",
-      "esType": "bidding_year"
+      "esIndex": "bidding_free",
+      "esType": "bidding_free"
     },
     "free": {
-      "address": "http://192.168.3.149:9200",
+      "address": "http://172.20.45.129:9206,http://172.20.45.130:9306",
       "size": 30,
       "version": "v7",
       "userName": "",
       "password": "",
-      "esIndex": "bidding",
-      "esType": "bidding"
+      "esIndex": "bidding_free",
+      "esType": "bidding_free"
     },
     "doc": {
-      "address": "http://192.168.3.242:9200",
+      "address": "http://172.20.45.129:9206,http://172.20.45.130:9306",
       "size": 30,
       "version": "v7",
-      "userName": "elastic",
-      "password": "elastic",
+      "userName": "",
+      "password": "",
       "esIndex": "jydoc",
       "esType": "jydoc"
     }
   },
   "redis": {
-    "main": {
-      "address": "other=192.168.3.149:1712,sso=192.168.3.149:1713,push=192.168.3.149:1711,session=192.168.3.149:1713,recovery=192.168.3.149:1715,merge=192.168.3.206:2711,newother=192.168.3.149:1712,poly=192.168.3.149:1713,seoCache=192.168.3.149:1713,limitation=192.168.3.149:1713"
+    "main":{
+      "address": "other=172.20.45.129:1712,sso=172.20.45.129:1713,push=172.20.45.129:1711,session=172.20.45.129:1713,recovery=172.20.45.129:1715,merge=172.20.45.129:1712,newother=172.20.45.129:1712,poly=172.20.45.129:1713,seoCache=172.20.45.129:1713,limitation=172.20.45.129:1713"
     },
     "login": {
-      "address": "login=192.168.3.149:1712"
+      "address": "login=172.20.45.129:1712"
     }
   },
   "mysql": {
     "main": {
       "dbName": "jianyu",
-      "address": "192.168.3.217:4000",
-      "userName": "root",
-      "passWord": "=PDT49#80Z!RVv52_z",
-      "maxOpenConns": 10,
-      "maxIdleConns": 5
+      "address": "172.20.45.129:4000",
+      "userName": "jianyu",
+      "passWord": "Topnet123",
+      "maxOpenConns": 500,
+      "maxIdleConns": 200
     },
     "base": {
       "dBName": "base_service",
-      "address" : "192.168.3.14:4000",
+      "address" : "172.20.45.129:4000",
       "userName": "root",
       "passWord": "=PDT49#80Z!RVv52_z",
       "maxOpenConns": 5,
@@ -95,7 +93,7 @@
     },
     "globalCommon": {
       "dBName": "global_common_data",
-      "address": "192.168.3.217:4000",
+      "address": "172.20.45.129:4000",
       "userName": "root",
       "passWord": "=PDT49#80Z!RVv52_z",
       "maxOpenConns": 5,

BIN
src/fonts/D3Parallelism.ttf


BIN
src/fonts/Flim-Flam.ttf


BIN
src/fonts/chromohv.ttf


+ 14 - 10
src/go.mod

@@ -4,10 +4,10 @@ go 1.20
 
 require (
 	app.yhyue.com/moapp/jyMarketing v0.0.2-0.20230308011651-df591d32df88
-	app.yhyue.com/moapp/jybase v0.0.0-20240412015757-6d8429bb4dae
+	app.yhyue.com/moapp/jybase v0.0.0-20250225094323-2f6419d0d916
 	app.yhyue.com/moapp/jylog v0.0.0-20230522075550-05d7230ca545
-	app.yhyue.com/moapp/jypkg v1.22.3
-	bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.20
+	app.yhyue.com/moapp/jypkg v1.31.8
+	bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.21
 	github.com/SKatiyar/qr v0.0.0-20151201054752-25b6bdf44e67
 	github.com/bwmarrin/snowflake v0.3.0
 	github.com/fsnotify/fsnotify v1.7.0
@@ -25,7 +25,7 @@ require (
 	app.yhyue.com/moapp/message v0.0.0-20231204024949-8c7145bfc161 // indirect
 	bp.jydev.jianyu360.cn/BaseService/entManageApplication v0.0.0-20231226074509-942d80dc34eb // indirect
 	bp.jydev.jianyu360.cn/BaseService/jyMicroservices v0.0.2 // indirect
-	bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20240607062231-ae1d02891843 // indirect
+	bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20241213060113-ac41966a58ec // indirect
 	bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.1.3 // indirect
 	filippo.io/edwards25519 v1.1.0 // indirect
 	github.com/BurntSushi/toml v1.2.0 // indirect
@@ -50,6 +50,7 @@ require (
 	github.com/go-openapi/swag v0.22.4 // indirect
 	github.com/go-sql-driver/mysql v1.8.1 // indirect
 	github.com/gogo/protobuf v1.3.2 // indirect
+	github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
 	github.com/golang/mock v1.6.0 // indirect
 	github.com/golang/protobuf v1.5.4 // indirect
 	github.com/golang/snappy v0.0.4 // indirect
@@ -106,6 +107,8 @@ require (
 	github.com/subosito/gotenv v1.4.2 // indirect
 	github.com/tealeg/xlsx v1.0.5 // indirect
 	github.com/thinxer/go-word2vec v0.0.0-20150917053916-5c19ec7379ed // indirect
+	github.com/wenlng/go-captcha-assets v1.0.1 // indirect
+	github.com/wenlng/go-captcha/v2 v2.0.3 // indirect
 	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
 	github.com/xdg-go/scram v1.1.2 // indirect
 	github.com/xdg-go/stringprep v1.0.4 // indirect
@@ -130,13 +133,14 @@ require (
 	go.uber.org/automaxprocs v1.5.3 // indirect
 	go.uber.org/multierr v1.9.0 // indirect
 	go.uber.org/zap v1.24.0 // indirect
-	golang.org/x/crypto v0.22.0 // indirect
-	golang.org/x/net v0.24.0 // indirect
+	golang.org/x/crypto v0.23.0 // indirect
+	golang.org/x/image v0.24.0 // indirect
+	golang.org/x/net v0.25.0 // indirect
 	golang.org/x/oauth2 v0.17.0 // indirect
-	golang.org/x/sync v0.6.0 // indirect
-	golang.org/x/sys v0.19.0 // indirect
-	golang.org/x/term v0.19.0 // indirect
-	golang.org/x/text v0.14.0 // indirect
+	golang.org/x/sync v0.11.0 // indirect
+	golang.org/x/sys v0.20.0 // indirect
+	golang.org/x/term v0.20.0 // indirect
+	golang.org/x/text v0.22.0 // indirect
 	golang.org/x/time v0.5.0 // indirect
 	google.golang.org/appengine v1.6.8 // indirect
 	google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect

+ 31 - 21
src/go.sum

@@ -15,13 +15,13 @@ app.yhyue.com/moapp/jybase v0.0.0-20230117032034-ad7c00ffe11a/go.mod h1:zB47XTeJ
 app.yhyue.com/moapp/jybase v0.0.0-20230419121327-bedf77840ba6/go.mod h1:zB47XTeJvpcbtBRYgkQuxOICWNexiZfbUO+7aUf6mNs=
 app.yhyue.com/moapp/jybase v0.0.0-20230901064756-2fc66b18db40/go.mod h1:Hv9U/7oHRucqH315Tr1+d03NCvS9mOKPfk8pwwlOIwQ=
 app.yhyue.com/moapp/jybase v0.0.0-20231025021840-2f91c944ecdd/go.mod h1:Hv9U/7oHRucqH315Tr1+d03NCvS9mOKPfk8pwwlOIwQ=
-app.yhyue.com/moapp/jybase v0.0.0-20240412015757-6d8429bb4dae h1:zprLO87oURhdr/ccUORXvuZ7zp/LBGxMqUZUzQemISw=
-app.yhyue.com/moapp/jybase v0.0.0-20240412015757-6d8429bb4dae/go.mod h1:XHNATN6tsJKHdCB0DbUtFdPPHXexTUFyB3RlO+lUUoM=
+app.yhyue.com/moapp/jybase v0.0.0-20250225094323-2f6419d0d916 h1:uhzwulALpCu8gZN6O6V/jo9sbbgxQqLNX3dd4qN4Ick=
+app.yhyue.com/moapp/jybase v0.0.0-20250225094323-2f6419d0d916/go.mod h1:/HT/UZ4dKuUKAQqqKrzBBfIZ4vD56DPV4u2QyfH+kbU=
 app.yhyue.com/moapp/jyfs v0.0.0-20231024061508-480c270480d4/go.mod h1:61hzZ3dZHXL28BNl8BOgZsvM2S5UVY5YFzOkEUPrSu4=
 app.yhyue.com/moapp/jylog v0.0.0-20230522075550-05d7230ca545 h1:+Lak4m1zgsigQloOsvp8AJ+0XeX/+PGp9QP550xlbBQ=
 app.yhyue.com/moapp/jylog v0.0.0-20230522075550-05d7230ca545/go.mod h1:uFrsdUBFbETiJlEmr4PtJWPsZlUpPj2bHQRhryu6ggk=
-app.yhyue.com/moapp/jypkg v1.22.3 h1:iD5eC6JuF4eQV80lvTu3/D4qZeuogWpW4XkCG9TKO9Y=
-app.yhyue.com/moapp/jypkg v1.22.3/go.mod h1:FylaC4MJ4G36WndktgeZfc8jTq3uvBGWIwbk02xfdQI=
+app.yhyue.com/moapp/jypkg v1.31.8 h1:nbdjgRCvtVLA/27lM9WqoNqhU1sIb7qcOO5WnxX3MGg=
+app.yhyue.com/moapp/jypkg v1.31.8/go.mod h1:bdHYv0sag7HhH89ft9nbOXHk21cNKes4xu1Ocpc021Y=
 app.yhyue.com/moapp/message v0.0.0-20231204024949-8c7145bfc161 h1:WGi4OEIoqw6NpNFGioUEBZnjK9aBa+xJqf/5WY+QyhM=
 app.yhyue.com/moapp/message v0.0.0-20231204024949-8c7145bfc161/go.mod h1:0Oj8SB4pVjdCLD28sy2zyM3hS0WHGpNuVcakLW43GmI=
 bp.jydev.jianyu360.cn/BP/jynsq v0.0.0-20220222052708-ebc43af90698/go.mod h1:ojo/AUH9Yr1wzarEjOaNMkj1Cet/9r8IgLyba64Z52E=
@@ -31,8 +31,8 @@ bp.jydev.jianyu360.cn/BaseService/gateway v0.0.0-20220419090715-88ddb32961be/go.
 bp.jydev.jianyu360.cn/BaseService/gateway v1.3.4/go.mod h1:BMLd/5wb3BIEGhnEgF9y1sJN9P5/Dw9kYsoiE9V8I9g=
 bp.jydev.jianyu360.cn/BaseService/jyMicroservices v0.0.2 h1:Qi8C7gZeR7+kjOtSl9ilR5HwbjCe8GO1RuotFb4+kFA=
 bp.jydev.jianyu360.cn/BaseService/jyMicroservices v0.0.2/go.mod h1:v8y7FCbkKEIRP4Ie9ZM8NtoRP+Fk4O3C1hnexNusYIQ=
-bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20240607062231-ae1d02891843 h1:u+8k/T0D6EUjj9BhI5RJdRa+8v4FZbyZhaNcm66L6Vs=
-bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20240607062231-ae1d02891843/go.mod h1:rCCaOSWBYfQabf/yIvSVheSPtN2THnHeTl2J5/RrcuU=
+bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20241213060113-ac41966a58ec h1:oCO36pHkEHQa5+Z/DU83T5xT5NKptVbw5UVQSN6lJjw=
+bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20241213060113-ac41966a58ec/go.mod h1:rCCaOSWBYfQabf/yIvSVheSPtN2THnHeTl2J5/RrcuU=
 bp.jydev.jianyu360.cn/BaseService/pushpkg v0.0.0-20230911091604-2faa31032743/go.mod h1:1SQIPPL5Ya5BzQdByFKtTkXrXTWBv+PDqWIhNknLnZw=
 bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.0.0-20220418005748-8ba5d936dd53/go.mod h1:E5lcDI3k4FESLxiAetCfWQTq8qfpy9cv0yN1oKoEO34=
 bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.0.0-20220419023723-0b32d4a41751/go.mod h1:6KL5LMEku83uRbre0W/bj5kXG2I6pJGBFtktmtp51yM=
@@ -41,8 +41,8 @@ bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.1.3 h1:lk3he0hY+8VK1/Hm+ZSlc
 bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.1.3/go.mod h1:rRiGzKG4F/fmkNxXQCxrkxNWc8yf1SmW8qWCKfGIQSM=
 bp.jydev.jianyu360.cn/BaseService/userCenter v0.0.0-20220418072311-2062bed1e700/go.mod h1:KjcrxTzM96tBc6G4B8tlLBn1lrVy5UJYF8+eTdP4xAE=
 bp.jydev.jianyu360.cn/BaseService/userCenter v0.0.0-20220421015128-4a36f3eac5c5/go.mod h1:GT0QC4aaKDuXxAvaU4G02XjCc31TU1ctqBGqxQYOfC4=
-bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.20 h1:CbqAy+9NFPMApXgLa77KM3Rnb+DOKsY2JLP8VAKfEFY=
-bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.20/go.mod h1:KANYV7j5Xw6KQPk+o4rOftQF8mTEv198xZGiTRrkyU8=
+bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.21 h1:XWTYzWEOPedM0CNjtqya+VTpYQl5rL4MMmlqmuasIK0=
+bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.21/go.mod h1:UB56iVLBV0H06VbTdXychssHSaGoqZMThfOuXZyrUAs=
 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=
@@ -1021,6 +1021,7 @@ github.com/gin-contrib/sessions v0.0.5/go.mod h1:vYAuaUPqie3WUSsft6HUlCjlwwoJQs9
 github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
 github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
 github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
+github.com/go-bindata/go-bindata v3.1.2+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo=
 github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=
 github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks=
 github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=
@@ -1133,6 +1134,7 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69
 github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
 github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
 github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
@@ -1743,6 +1745,10 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY
 github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
 github.com/urfave/cli/v2 v2.11.0/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo=
 github.com/wader/gormstore/v2 v2.0.0/go.mod h1:3BgNKFxRdVo2E4pq3e/eiim8qRDZzaveaIcIvu2T8r0=
+github.com/wenlng/go-captcha-assets v1.0.1 h1:AdjRFMKmadPRWRTv0XEYfjDvcaayZ2yExITDvlK/7bk=
+github.com/wenlng/go-captcha-assets v1.0.1/go.mod h1:yQqc7rRbxgLCg+tWtVp+7Y317D1wIZDan/yIwt8wSac=
+github.com/wenlng/go-captcha/v2 v2.0.3 h1:QTZ39/gVDisPSgvL9O2X2HbTuj5P/z8QsdGB/aayg9c=
+github.com/wenlng/go-captcha/v2 v2.0.3/go.mod h1:5hac1em3uXoyC5ipZ0xFv9umNM/waQvYAQdr0cx/h34=
 github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
 github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
 github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
@@ -1939,8 +1945,8 @@ golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIi
 golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
 golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
 golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
-golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
-golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
+golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
+golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
 golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -1969,6 +1975,9 @@ golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeap
 golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
 golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
 golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
+golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs=
+golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ=
+golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -2084,8 +2093,8 @@ golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
 golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
 golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
 golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
-golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
-golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
+golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
+golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -2141,8 +2150,8 @@ golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
-golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
-golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
+golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -2266,8 +2275,8 @@ golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
-golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -2286,8 +2295,8 @@ golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
 golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
 golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
 golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
-golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
-golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
+golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
+golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -2309,8 +2318,9 @@ golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
+golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -2406,7 +2416,7 @@ golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
 golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
 golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
 golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
-golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA=
+golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
 golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

+ 24 - 3
src/jfw/active/active.go

@@ -1,7 +1,10 @@
 package active
 
 import (
+	"app.yhyue.com/moapp/jybase/redis"
+	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
 	"app.yhyue.com/moapp/jypkg/public"
+	"fmt"
 	"regexp"
 
 	util "app.yhyue.com/moapp/jybase/common"
@@ -48,9 +51,12 @@ type Active struct {
 
 }
 
-var mongodb = public.MQFW
-var se = encrypt.SimpleEncrypt{Key: "topnet2015topnet2015"}
-var mobileReg = regexp.MustCompile("(?i)(Android|Mobile|Phone)")
+var (
+	mongodb      = public.MQFW
+	se           = encrypt.SimpleEncrypt{Key: "topnet2015topnet2015"}
+	mobileReg    = regexp.MustCompile("(?i)(Android|Mobile|Phone)")
+	cacheTimeOut = 3 * 24 * 60 * 60 //三天
+)
 
 func init() {
 	//添加模块解析
@@ -73,6 +79,15 @@ func (a *Active) TransitRoute(key string) error {
 			if !bm { //如果电脑端 访问电脑端
 				return a.Redirect("/active/transit/day01")
 			}
+		case "day04": //PC
+			if bm { //如果是移动端 访问移动端
+				return a.Redirect("/active/transit/day06")
+			}
+		case "day06": //WX
+			if !bm { //如果电脑端 访问电脑端
+				return a.Redirect("/active/transit/day04")
+			}
+
 		}
 		shortUrls := public.Mysql.SelectBySql(`SELECT * FROM short_url WHERE mold = 1 AND code = ?`, key)
 		if shortUrls != nil && len(*shortUrls) > 0 {
@@ -86,6 +101,12 @@ func (a *Active) TransitRoute(key string) error {
 				redirectUrl = util.ObjToString(shortUrl["href"])
 			}
 		}
+		//未登录
+		if userId, _ := a.GetSession("userId").(string); userId == "" {
+			jy.SetCookieValue(a.ResponseWriter, jy.ChannelCookieName, key, cacheTimeOut)                      //三天
+			redis.Put("limitation", fmt.Sprintf("firstVisitTagByWX_%s", a.Session().Id()), key, cacheTimeOut) //登录注册 用户标识
+			return a.Redirect(redirectUrl)
+		}
 	}
 	return a.Redirect(redirectUrl)
 }

+ 9 - 0
src/jfw/config/config.go

@@ -2,6 +2,7 @@ package config
 
 import (
 	util "app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/gocaptcha"
 	"app.yhyue.com/moapp/jybase/ipmatch"
 	"app.yhyue.com/moapp/jybase/mail"
 	"app.yhyue.com/moapp/jypkg/middleground"
@@ -34,6 +35,8 @@ var (
 	JyAnonymousLimit     *anonymousLimit
 	AreaCity             areaInfo
 	SampleReport         SampleReportConfig
+	GuideRegistedate     int64 //该时间之前注册的付费用户不用进订阅向导
+
 )
 
 // 样例报告
@@ -84,6 +87,7 @@ func init() {
 	util.ReadConfig("./city.json", &AreaCity)
 	util.ReadConfig("./sample_report.json", &SampleReport)
 	IpInit()
+	CaptchaInit()
 	//log.Println("sysconfig:", Sysconfig)
 	WeixinConfig, _ = Sysconfig["wxJianyu"].(map[string]interface{})
 	Wxoauth = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=` + util.ObjToString(WeixinConfig["appid"]) + `&redirect_uri=%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect`
@@ -119,6 +123,7 @@ func init() {
 		RegEntManageApplication(g.Cfg().MustGet(ctx, "entManageApplication").String()).
 		RegPublicservice(g.Cfg().MustGet(ctx, "publicserviceKey").String())
 	//SubjectMatter = GetLetterMap(util.InterfaceToStr(Sysconfig["hotSubjectMatter"]))
+	GuideRegistedate = g.Cfg().MustGet(ctx, "GuideRegistedate").Int64()
 }
 
 func IpInit() {
@@ -141,3 +146,7 @@ func IpInit() {
 }
 
 var DigitalEnglish = map[string]string{"0": "L", "1": "Y", "2": "E", "3": "S", "4": "S", "5": "W", "6": "L", "7": "Q", "8": "B", "9": "J"}
+
+func CaptchaInit() {
+	gocaptcha.InitCaptcha()
+}

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

@@ -8,13 +8,14 @@ import (
 
 // CookieInfo 信息
 type CookieInfo struct {
-	W http.ResponseWriter
-	R *http.Request
+	W       http.ResponseWriter
+	R       *http.Request
+	IsLogin bool
 }
 
 // Do 继承过滤器方法
 func (ci *CookieInfo) Do() {
-	if crr := ci.R.Referer(); crr != "" {
+	if crr := ci.R.Referer(); !ci.IsLogin && crr != "" {
 		if strings.Contains(crr, "cooperate") {
 			match := strings.Split(crr, "cooperate/")
 			if len(match) > 1 {

+ 1 - 1
src/jfw/filter/filter.go

@@ -58,7 +58,7 @@ func (f *Filter) Do(w http.ResponseWriter, r *http.Request) bool {
 	if !(&AnonymousAuth{w, r, session, getSession, make(map[string]interface{})}).Do() {
 		return false
 	}
-	(&CookieInfo{w, r}).Do()
+	(&CookieInfo{w, r, getSession["userId"] != nil}).Do()
 
 	if !(&logFilter{w, r, session, getSession, make(map[string]interface{})}).Do() {
 		return false

+ 1 - 1
src/jfw/filter/pcUserSalesFilter.go

@@ -35,7 +35,7 @@ func (l *pcSalesFilter) Do() bool {
 		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") {
+		if (v.MatchString(l.R.URL.Path) || v.MatchString(l.R.URL.String())) && !strings.Contains(l.R.URL.Path, "bidedoc") && !strings.Contains(l.R.URL.Path, "squeeze") && !strings.Contains(l.R.URL.Path, "partner") {
 			return true
 		}
 	}

+ 12 - 12
src/jfw/filter/pcfilter.go

@@ -1,21 +1,21 @@
 package filter
 
 import (
-	"fmt"
-	"jy/src/jfw/config"
-	"jy/src/jfw/jyutil"
-	"net/http"
-	"strings"
-	"time"
+    "fmt"
+    "jy/src/jfw/config"
+    "jy/src/jfw/jyutil"
+    "net/http"
+    "strings"
+    "time"
 
-	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
-	"app.yhyue.com/moapp/jypkg/public"
+    "app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
+    "app.yhyue.com/moapp/jypkg/public"
 
-	util "app.yhyue.com/moapp/jybase/common"
+    util "app.yhyue.com/moapp/jybase/common"
 
-	"app.yhyue.com/moapp/jybase/redis"
+    "app.yhyue.com/moapp/jybase/redis"
 
-	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
+    "app.yhyue.com/moapp/jybase/go-xweb/httpsession"
 )
 
 type pcFilter struct {
@@ -43,7 +43,7 @@ func (this *pcFilter) Do() bool {
 	//企业搜索
 	if strings.Contains(this.R.RequestURI, "/jylab/entSearch/index.html") ||
 		strings.Contains(this.R.RequestURI, "/swordfish/page_big_pc/ent_portrait/") ||
-		strings.Contains(this.R.RequestURI, "/swordfish/page_big_pc/svip/ent_ser_portrait/") {
+		strings.Contains(this.R.RequestURI, "/swordfish/page_big_pc/svip/ent_ser_portrait/") || strings.Contains(this.R.URL.Path, "/swordfish/page_big_pc/doc/api") {
 		return true
 	}
 	//pc助手订阅消息、招标搜索两个菜单链接过滤掉

+ 2 - 1
src/jfw/filter/phonefilter.go

@@ -60,9 +60,10 @@ func (l *phoneFilter) Do() bool {
 		}
 		//会展活动 未绑定手机号 不用到绑定手机号页面
 		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") {
+			if (v.MatchString(l.R.URL.Path) || v.MatchString(l.R.URL.String())) && !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
 	}()

+ 3 - 2
src/jfw/filter/wxUserSalesFilter.go

@@ -1,13 +1,14 @@
 package filter
 
 import (
-	"app.yhyue.com/moapp/jypkg/public"
 	"jy/src/jfw/config"
 	"jy/src/jfw/jyutil"
 	"net/http"
 	"strings"
 	"time"
 
+	"app.yhyue.com/moapp/jypkg/public"
+
 	qu "app.yhyue.com/moapp/jybase/common"
 
 	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
@@ -32,7 +33,7 @@ func (l *salesFilter) Do() bool {
 		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") {
+		if (v.MatchString(l.R.URL.Path) || v.MatchString(l.R.URL.String())) && !strings.Contains(l.R.URL.Path, "bidedoc") && !strings.Contains(l.R.URL.Path, "squeeze") && !strings.Contains(l.R.URL.Path, "partner") {
 			return true
 		}
 	}

+ 1 - 1
src/jfw/front/applysub.go

@@ -122,7 +122,7 @@ func (a *Applysub) SendMsg() error {
 				session.Set("phoneNum", phoneNum)
 				session.Set("lastSendMsgTime", time.Now().Unix())
 				go func() {
-					jy.SendSMS(util.ObjToString(config.Sysconfig["smsServiceRpc"]), phoneNum, MsgCode)
+					jy.SendSMS(a.Request, util.ObjToString(config.Sysconfig["smsServiceRpc"]), phoneNum, MsgCode)
 				}()
 				log.Println("手机号码", phoneNum, "验证码", MsgCode)
 			} else {

+ 6 - 1
src/jfw/front/dataExport.go

@@ -296,12 +296,14 @@ func (d *DataExport) SieveData() {
 		//从500条数据中筛选字段最全五条
 		scd := dataexport.GetSqlObjFromId(public.MQFW, _id)
 		kws := scd.Keyword
+		tm := time.Now()
 		res, err := dataexport.GetDataExportSearchResult(public.Mgo_Bidding, public.DbConf.Mongodb.Bidding.DbName, public.DbConf.Elasticsearch.Main.Address, scd, dataType, -1)
 		if res == nil || err != nil {
 			_res["error_msg"] = "无数据"
 			d.ServeJson(_res)
 			return
 		}
+		log.Println(fmt.Sprintf("id:%s 查询耗时:%s", _id, time.Now().Sub(tm)))
 		//格式化字段
 		res_screen := dataexport.ScreenData(res, dataType, 20, kws)
 		var EntArr = []string{}
@@ -315,6 +317,7 @@ func (d *DataExport) SieveData() {
 		}
 
 		list := dataexport.FormatExportData(public.Mgo_Ent, &res_screen, config.Sysconfig["webdomain"].(string), dataType, true)
+		log.Println(fmt.Sprintf("id:%s 格式化耗时:%s", _id, time.Now().Sub(tm)))
 		/*if msgCount > 20000 {
 			msgCount = 20000
 		}*/
@@ -779,15 +782,17 @@ func (d *DataExport) PreviewData(source, _id string) error {
 	//从500条数据中筛选字段最全五条
 	scd := dataexport.GetSqlObjFromId(public.MQFW, _id)
 	kws := scd.Keyword
+	tm := time.Now()
 	res, err := dataexport.GetDataExportSearchResult(public.Mgo_Bidding, public.DbConf.Mongodb.Bidding.DbName, public.DbConf.Elasticsearch.Main.Address, scd, dataType, -1)
 	if res == nil || err != nil {
 		log.Println("PreviewData查询出错", res)
 		return d.Render("/pc/dataExport_noDataErr.html", &d.T)
 	}
+	log.Println(fmt.Sprintf("id:%s 查询耗时:%s", _id, time.Now().Sub(tm)))
 	//格式化字段
 	res_screen := dataexport.ScreenData(res, dataType, 20, kws)
 	list := dataexport.FormatExportData(public.Mgo_Ent, &res_screen, config.Sysconfig["webdomain"].(string), dataType, true)
-
+	log.Println(fmt.Sprintf("id:%s 格式化耗时:%s", _id, time.Now().Sub(tm)))
 	d.T["data"] = subUrl(list, dataType)
 	d.T["dataType"] = dataType
 	d.T["ttf"] = public.GetFontVersion() + "_" + public.PC

+ 16 - 0
src/jfw/front/dataMarket.go

@@ -30,6 +30,22 @@ func (this *DataMarket) Index() {
 
 // CustomExport 数据定制导出
 func (this *DataMarket) CustomExport() {
+	sessVal := this.Session().GetMultiple()
+	if entUserId := common.Int64All(sessVal["entUserId"]); entUserId > 0 {
+		if resp := config.Middleground.ResourceCenter.Haspowers(common.Int64All(sessVal["accountId"]), common.Int64All(sessVal["entAccountId"]), common.Int64All(sessVal["entId"]), entUserId); resp != nil {
+			for _, v := range resp.Powers {
+				if v != "qysjllb" {
+					continue
+				}
+				if common.IntAll(sessVal["entRole"]) == 1 {
+					this.Redirect("/seplatform/admin/index")
+				} else {
+					this.Redirect("/seplatform/personnel/index")
+				}
+				return
+			}
+		}
+	}
 	showA := false
 	if uA := this.Header("User-Agent"); uA != "" {
 		fmt.Println(int(uA[len(uA)-1])/10, "<", common.IntAll(config.Sysconfig["dataMarketShowAB"]), int(uA[len(uA)-1])/10 < common.IntAll(config.Sysconfig["dataMarketShowAB"]))

+ 10 - 3
src/jfw/front/dataPackRouter.go

@@ -23,7 +23,12 @@ func init() {
 
 // pc端
 func (this *DataPackRouter) PcIndex() {
-	this.Render("/pc/dataPack/index.html")
+	//this.Render("/pc/dataPack/index.html")
+	if this.GetString("type") == "history" {
+		this.Redirect("/page_workDesktop/work-bench/app/big/data_pack/history")
+	} else {
+		this.Redirect("/page_workDesktop/work-bench/app/big/data_pack/index")
+	}
 }
 
 func (this *DataPackRouter) PcCreateOrder() {
@@ -40,7 +45,8 @@ func (this *DataPackRouter) PcPackDetail() {
 
 // wx端
 func (this *DataPackRouter) WxIndex() {
-	this.Render("/weixin/dataPack/index.html")
+	//this.Render("/weixin/dataPack/index.html")
+	this.Redirect("/jy_mobile/packs/data-pack/index")
 }
 
 func (this *DataPackRouter) WxCreateOrder() {
@@ -48,7 +54,8 @@ func (this *DataPackRouter) WxCreateOrder() {
 }
 
 func (this *DataPackRouter) WxRecordList() {
-	this.Render("/weixin/dataPack/recordList.html")
+	//this.Render("/weixin/dataPack/recordList.html")
+	this.Redirect("/jy_mobile/packs/data-pack/record")
 }
 
 func (this *DataPackRouter) PcDownloadPack() {

+ 130 - 22
src/jfw/front/dataServiceArea.go

@@ -7,6 +7,7 @@ import (
 	"encoding/json"
 	"fmt"
 	"jy/src/jfw/jyutil"
+	"math/rand"
 	"strings"
 	//_ "github.com/gogf/gf/contrib/drivers/clickhouse/v2"
 	"github.com/gogf/gf/v2/frame/g"
@@ -27,11 +28,12 @@ type (
 	}
 
 	KeyWordSiteNode struct {
-		Code               string `json:"code" doc:"代码"`
-		Alias              string `json:"alias" doc:"名称"`
-		AreaKeyWord        string `json:"areaKeyword" doc:"省份关键词"`
-		CityKeyWord        string `json:"cityKeyword" doc:"城市关键词"`
-		CitySpecialKeyWord string `json:"citySpecialKeyword" doc:"直辖市关键词"`
+		Code               string          `json:"code" doc:"代码"`
+		Alias              string          `json:"alias" doc:"名称"`
+		AreaKeyWord        string          `json:"areaKeyword" doc:"省份关键词"`
+		CityKeyWord        string          `json:"cityKeyword" doc:"城市关键词"`
+		CitySpecialKeyWord string          `json:"citySpecialKeyword" doc:"直辖市关键词"`
+		NotShowCityCode    map[string]bool `json:"notShowCityCode" doc:"不展示的城市,因数据量少"`
 	}
 
 	KeyWordSiteShow struct {
@@ -60,19 +62,27 @@ var (
 	specialArea       = map[string]bool{"北京": true, "上海": true, "天津": true, "重庆": true}
 	KeyBiddingAreaMap []keyBidding
 	KeyFwArr          []keyFw
+	KeyJyMap          map[string]string
+	DistrictSArr      []keyFw
 )
 
 func init() {
 	siteCodeMap = make(map[string]*KeyWordSiteNode)
+	KeyJyMap = make(map[string]string)
 	res, err := g.DB().Query(gctx.New(), `SELECT * FROM seo_siteKeywords_splicing order by site_code asc`)
 	if err == nil && len(res.List()) > 0 {
 		for _, m := range res.List() {
+			notShowCityCodeMap := map[string]bool{}
+			for _, cityCode := range strings.Split(gconv.String(m["notShowCityCode"]), ",") {
+				notShowCityCodeMap[cityCode] = true
+			}
 			node := &KeyWordSiteNode{
 				Code:               fmt.Sprintf("S%s", gconv.String(m["site_code"])),
 				Alias:              gconv.String(m["alias"]),
 				AreaKeyWord:        gconv.String(m["area"]),
 				CityKeyWord:        gconv.String(m["city"]),
 				CitySpecialKeyWord: gconv.String(m["city_special"]),
+				NotShowCityCode:    notShowCityCodeMap,
 			}
 			siteCodeMap[node.Code] = node
 		}
@@ -89,7 +99,15 @@ func init() {
 			})
 		}
 	}
-
+	districtSData, err := g.DB().Query(gctx.New(), `SELECT site_code,keywords,alias  FROM seo_siteKeywords_district where  site_code = 1 `)
+	if err == nil && !districtSData.IsEmpty() {
+		for _, m := range districtSData.List() {
+			DistrictSArr = append(DistrictSArr, keyFw{
+				keyword: gconv.String(m["keywords"]),
+				code:    fmt.Sprintf("%s_S%d", m["alias"], m["site_code"]),
+			})
+		}
+	}
 	fwResArr, err := g.DB().Query(gctx.New(), `SELECT  id, keyword  FROM new_keyword_unified where  unifiedSign = 'fw' and state = 1`)
 	if err == nil && !fwResArr.IsEmpty() {
 		for _, m := range fwResArr.List() {
@@ -99,6 +117,19 @@ func init() {
 			})
 		}
 	}
+	//区县教育局
+	districtJyResArr, err := g.DB().Query(gctx.New(), `SELECT  alias,keywords  FROM seo_siteKeywords_district where  site_code = 12`)
+	if err == nil && !districtJyResArr.IsEmpty() {
+		for _, m := range districtJyResArr.List() {
+			KeyJyMap[gconv.String(m["alias"])] = gconv.String(m["keywords"])
+		}
+	}
+}
+
+type ClassCode struct {
+	Class int
+	Code  string
+	Url   string
 }
 
 // 政府招标
@@ -112,15 +143,25 @@ func GovernmentTender(number int) []argument {
 			return signature
 		}
 	}
-	areaM := make(map[string]string)
-	//省份
-	areaMap, _ := config.Seoconfig["area"].(map[string]interface{})
-	if areaMap != nil && len(areaMap) > 0 {
-		for k, v := range areaMap {
-			area := v.(map[string]interface{})
-			name := common.ObjToString(area["NAME"])
-			if name != "全国" && name != "香港" && name != "澳门" && name != "台湾" {
-				areaM[name] = k
+	areaM := make(map[string]ClassCode)
+	res, err := g.DB().Query(gctx.New(), `SELECT area,city,pcode,class  FROM seo_area_code where state = 1 and (class = 1 or class = 2 or class = 3)`)
+	if !res.IsEmpty() && len(res.List()) > 0 && err == nil {
+		for _, v := range res.List() {
+			switch common.IntAll(v["class"]) {
+			case 1, 3:
+				name := common.ObjToString(v["area"])
+				areaM[name] = ClassCode{
+					Class: common.IntAll(v["class"]),
+					Code:  common.ObjToString(v["pcode"]),
+					Url:   "/list/area/%s_%s/",
+				}
+			default:
+				name := common.ObjToString(v["city"])
+				areaM[name] = ClassCode{
+					Class: common.IntAll(v["class"]),
+					Code:  common.ObjToString(v["pcode"]),
+					Url:   "/list/city/%s_%s/",
+				}
 			}
 		}
 	}
@@ -137,15 +178,25 @@ func GovernmentTender(number int) []argument {
 		if len(siteCode) < len(siteCodeMap) {
 			for code, node := range siteCodeMap {
 				var tagName string
+				if node.NotShowCityCode[acronym.Code] {
+					continue
+				}
 				if !siteCode[code] {
 					if node.Alias != "" {
 						tagName = node.Alias
 					} else {
-						tagName = common.If(specialArea[name], node.CitySpecialKeyWord, node.AreaKeyWord).(string)
+						switch acronym.Class {
+						case 1:
+							tagName = node.AreaKeyWord
+						case 2:
+							tagName = node.CityKeyWord
+						case 3:
+							tagName = node.CitySpecialKeyWord
+						}
 					}
 					data = append(data, argument{
 						fmt.Sprintf("%s%s", name, tagName),
-						fmt.Sprintf("/list/area/%s_%s", acronym, code),
+						fmt.Sprintf(acronym.Url, acronym.Code, code),
 					})
 					siteCode[code] = true
 					break
@@ -154,21 +205,44 @@ func GovernmentTender(number int) []argument {
 		} else {
 			for code, node := range siteCodeMap {
 				var tagName string
+				if node.NotShowCityCode[acronym.Code] {
+					continue
+				}
 				if node.Alias != "" {
 					tagName = node.Alias
 				} else {
-					tagName = common.If(specialArea[name], node.CitySpecialKeyWord, node.AreaKeyWord).(string)
+					switch acronym.Class {
+					case 1:
+						tagName = node.AreaKeyWord
+					case 2:
+						tagName = node.CityKeyWord
+					case 3:
+						tagName = node.CitySpecialKeyWord
+					}
 				}
 				data = append(data, argument{
 					fmt.Sprintf("%s%s", name, tagName),
-					fmt.Sprintf("/list/area/%s_%s", acronym, code),
+					fmt.Sprintf(acronym.Url, acronym.Code, code),
 				})
 				break
 			}
 		}
-
 	}
-	redis.Put(RedisNameNew, redisKey, data, RedisTimeout)
+	//随机获取10个区县教育局单位
+	var count int
+	for m, n := range KeyJyMap {
+		count++
+		if count > number {
+			break
+		}
+		data = append(data, argument{
+			n,
+			fmt.Sprintf("/list/city/%s_S12/", m),
+		})
+	}
+	if len(data) > 0 {
+		redis.Put(RedisNameNew, redisKey, data, RedisTimeout)
+	}
 	return data
 }
 
@@ -200,6 +274,33 @@ func DistrictsTender(number int) []argument {
 	return data
 }
 
+func DistrictsSList(number int) []argument {
+	redisKey := "districtsSList"
+	redisData := redis.Get(RedisNameNew, redisKey)
+	if redisData != nil {
+		if d, err := json.Marshal(redisData); err == nil {
+			var signature []argument
+			json.Unmarshal(d, &signature)
+			return signature
+		}
+	}
+
+	var (
+		data []argument
+	)
+	for _, i2 := range jyutil.GenerateRandomNumber(0, len(DistrictSArr), number) {
+		acronym := DistrictSArr[i2]
+		data = append(data, argument{
+			acronym.keyword,
+			fmt.Sprintf("/list/city/%s/", acronym.code),
+		})
+	}
+	if data != nil && len(data) > 0 {
+		redis.Put(RedisNameNew, redisKey, data, RedisTimeout)
+	}
+	return data
+}
+
 /*
 const (
 	PSearch_DecMust = `"bidstatus": ["中标","成交","合同","单一"]`
@@ -394,7 +495,14 @@ func PurchasingData() []map[string]interface{} {
 	var keyWords []map[string]interface{}
 	data := public.BaseMysql.SelectBySql("SELECT keyword FROM data_supermarket GROUP BY keyword")
 	if data != nil && len(*data) > 0 {
-		for _, m := range *data {
+		listData := []map[string]interface{}{}
+		if len(*data) > 30 {
+			r := rand.Intn(len(*data) - 30)
+			listData = (*data)[r : r+30]
+		} else {
+			listData = *data
+		}
+		for _, m := range listData {
 			keyWords = append(keyWords, map[string]interface{}{
 				"keyword": common.InterfaceToStr(m["keyword"]),
 				"url":     fmt.Sprintf("/datasmt/index_1?searchValue=%s", common.InterfaceToStr(m["keyword"])),

+ 25 - 20
src/jfw/front/front.go

@@ -701,6 +701,13 @@ func (f *Front) SignOut() error {
 func (f *Front) GetLoginNum(prestr string) error {
 	var oid = f.GetString("oid")
 	var Rref = f.GetString("rref")
+	if prestr == "" || prestr == "null" {
+		prestr = "101"
+		log.Println("refer:", f.Request.Referer())
+	}
+	if Rref == "" {
+		Rref = f.Request.Referer()
+	}
 	f.SetSession("Rref", Rref)
 	shareid, shareidot := qrmanager.QrCodeManager.GetQRCode(oid, prestr, f.Session(), f.Request)
 
@@ -856,6 +863,7 @@ func CreateSession(q map[string]interface{}, sess *httpsession.Session, typ stri
 		"s_nickname":  s_nickname,
 		"s_headimage": sessionVal["s_avatar"],
 		"phone":       sessionVal["phone"],
+		"registedate": sessionVal["registedate"],
 	}
 	if openid, _ := (*person)["s_m_openid"].(string); openid != "" {
 		infoData["openid"] = se.EncodeString(openid)
@@ -886,7 +894,6 @@ func (m *Front) Sess(ostr string) error {
 			ok = true
 		} else {
 			var identity *pb.Identity
-
 			if str[1] == "userId" || str[1] == "entUserId" || str[1] == "positionId" {
 				if str[1] == "userId" {
 					identity = config.Middleground.UserCenter.IdentityByUserId(util.Int64All(userFlag))
@@ -901,13 +908,11 @@ func (m *Front) Sess(ostr string) error {
 			} else {
 				hasIdentity := false
 				if str[1] == "_id" {
-					if ok, _, _ = FindUserAndCreateSessById(mgdb.StringTOBsonId(userFlag), m.Session(), false, !hasIdentity); ok {
-						hasIdentity = true
-					}
+					ok, _, _ = FindUserAndCreateSessById(mgdb.StringTOBsonId(userFlag), m.Session(), false, false)
 				} else {
 					//P387用户身份及搜索模式优化-微信公众号点击菜单重新获取上次身份
 					if userFlag != "" {
-						if ok, _, _ = FindUserAndCreateSess(userFlag, m.Session(), "wx", false, !hasIdentity); ok {
+						if ok, _, _ = FindUserAndCreateSess(userFlag, m.Session(), "wx", false, true); ok {
 							hasIdentity = true
 						}
 					}
@@ -1100,7 +1105,7 @@ func (m *Front) Isrecord(name string) {
 	}
 }
 
-// 招标订阅向导
+// 招标订阅向导  p618已弃用
 func (f *Front) TSGuide() error {
 	defer util.Catch()
 	sessVal := f.Session().GetMultiple()
@@ -1109,7 +1114,7 @@ func (f *Front) TSGuide() error {
 		return f.Redirect("/swordfish/share/-1")
 	}
 	if f.Method() == "GET" {
-		if !isInTSguide(userid) {
+		if !isInTSguide(userid, f.Session()) {
 			return f.Redirect("/wxkeyset/keyset/index")
 		}
 		f.T["signature"] = wx.SignJSSDK(f.Site() + f.Url())
@@ -1194,23 +1199,23 @@ func (f *Front) TSGuide() error {
 	return nil
 }
 
-func isInTSguide(userid string) bool {
+const tsGuideFinished = 1 // 完成订阅向导设置
+
+func isInTSguide(userid string, session *httpsession.Session) bool {
 	if userid == "" {
 		return false
 	}
-	data := jyutil.Compatible.Select(userid, `{"o_jy":1,"i_ts_guide":1,"":1,"i_member_status":1,"i_vip_status":1}`)
-	if data != nil {
-		//付费用户无免费订阅,不进入订阅向导页面
-		if util.IntAll((*data)["i_member_status"]) > 0 || util.IntAll((*data)["i_vip_status"]) > 0 {
-			return false
-		}
-		o_jy, _ := (*data)["o_jy"].(map[string]interface{})
-		i_ts_guide := util.IntAll((*data)["i_ts_guide"])
-		if i_ts_guide == 2 || (i_ts_guide == 0 && len(o_jy) == 0) {
-			return true
-		}
+	data := jy.GetBigVipUserBaseMsg(session, *config.Middleground)
+	//p618发版之前注册的付费用户不进入订阅向导页面
+	userdata := jyutil.Compatible.Select(userid, `{"i_ts_guide":1,"l_registedate":1}`)
+	if userdata == nil || len(*userdata) == 0 {
+		return false
 	}
-	return false
+	registedate := util.Int64All((*userdata)["l_registedate"])
+	if (!data.Data.Free.IsFree && registedate < config.GuideRegistedate) || util.Int64All((*userdata)["i_ts_guide"]) == tsGuideFinished {
+		return false
+	}
+	return true
 }
 
 // 查看原文中转

+ 5 - 1
src/jfw/front/frontRouter.go

@@ -230,7 +230,11 @@ func (this *CommonRouter) doPcBigPage(pageSign, types string) error {
 	//page := pageSign
 	userid, _ := this.GetSession("userId").(string)
 	//没有登录跳转登录页面(采购单位画像| 企业画像 除外)
-	if !strings.Contains(pageSign, "nzj") && !strings.Contains(pageSign, "supply") && !strings.Contains(pageSign, "unit_portrayal") && !strings.Contains(pageSign, "ent_portrait") && !strings.Contains(pageSign, "ent_ser_portrait") && userid == "" {
+	if !strings.Contains(pageSign, "nzj") && !strings.Contains(pageSign, "supply") &&
+		!strings.Contains(pageSign, "unit_portrayal") && !strings.Contains(pageSign, "ent_portrait") &&
+		!strings.Contains(pageSign, "ent_ser_portrait") && !strings.Contains(pageSign, "search/sun") &&
+		!strings.Contains(pageSign, "doc/api") &&
+		userid == "" {
 		return this.Redirect("/notin/page")
 	}
 	if userid == "" {

+ 26 - 6
src/jfw/front/index.go

@@ -266,11 +266,12 @@ func (nIndex *NewIndex) NewIndex() error {
 	//剑鱼课堂
 	nIndex.T["jySchool"] = jyutil.Course(6, 3)
 	// 政府招标
-	nIndex.T["governmentBidding"] = GovernmentTender(15)
+	nIndex.T["governmentBidding"] = GovernmentTender(10)
 	// 服务类采购
-	nIndex.T["serviceProcurement"] = ServiceProcurement(15)
+	nIndex.T["serviceProcurement"] = ServiceProcurement(20)
 	//区县招标
-	nIndex.T["districtsBidding"] = DistrictsTender(15)
+	nIndex.T["districtsBidding"] = DistrictsTender(25)
+	nIndex.T["districtsSList"] = DistrictsSList(10)
 	nIndex.T["importBidding"] = GetImportBidding()
 	//nIndex.T["biddingTrend"] = HomeBiddingTrends()
 	nIndex.T["hotBuyerData"] = PurchasingData()
@@ -513,7 +514,7 @@ func GetIndexProjectList(typ, pageSize int, resArr []map[string]interface{}) (da
 	if len(resArr) > 5 {
 		return resArr[:5], types
 	}
-	res, err := g.DB().Query(gctx.New(), fmt.Sprintf(`SELECT bid_id,publish_time,bitmapToArray(sign) FROM new_bid_sign WHERE bitmapContains(sign, %d) ORDER BY publish_time DESC LIMIT %d, %d`, typ, pageSize-10, 10))
+	res, err := g.DB().Query(gctx.New(), fmt.Sprintf(`SELECT bid_id,publish_time,bitmapToArray(sign) FROM new_bid_sign WHERE bitmapContains(sign, %d) and publish_time > '%s' ORDER BY publish_time DESC LIMIT %d, %d`, typ, time.Now().AddDate(0, -6, 0).Format(time.DateTime), pageSize-10, 10))
 	if err != nil || res.IsEmpty() {
 		return nil, types
 	}
@@ -641,8 +642,27 @@ func GetImportBidding() []*hotKeyWord {
 			return hotKW
 		}
 	}
-	randomNumber := rand.Intn(len(subjectMatter) - 30)
-	res := subjectMatter[randomNumber : randomNumber+30]
+	res := []*hotKeyWord{}
+	data, ok := public.MQFW.FindOneByField("ad", `{"s_code":"pc_index_import_bidding"}`, `{"a_son":1}`)
+	if ok && data != nil && (*data)["a_son"] != nil {
+		if a, ok := (*data)["a_son"].([]interface{}); ok {
+			result := make([]map[string]interface{}, 20)
+			dataArr := util.ObjArrToMapArr(a)
+			if len(dataArr) <= 20 {
+				result = dataArr
+			} else {
+				index := rand.Intn(len(dataArr) - 20)
+				result = dataArr[index : index+20]
+			}
+			for _, v := range result {
+				res = append(res, &hotKeyWord{
+					Name: util.ObjToString(v["s_remark"]),
+					Url:  util.ObjToString(v["s_link"]),
+				})
+			}
+		}
+	}
+
 	if len(res) > 0 {
 		redis.Put(RedisNameNew, "pcIndexImportBidding", res, RedisTimeout+rand.Intn(100))
 	}

+ 41 - 14
src/jfw/front/login.go

@@ -1,6 +1,8 @@
 package front
 
 import (
+	"app.yhyue.com/moapp/jybase/captcha"
+	"app.yhyue.com/moapp/jybase/gocaptcha"
 	"fmt"
 	"jy/src/jfw/config"
 	jutil "jy/src/jfw/jyutil"
@@ -14,7 +16,6 @@ import (
 	"github.com/gogf/gf/v2/util/gconv"
 
 	qutil "app.yhyue.com/moapp/jybase/common"
-	"app.yhyue.com/moapp/jybase/dchest/captcha"
 	"app.yhyue.com/moapp/jybase/encrypt"
 	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
 	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
@@ -137,18 +138,25 @@ func (l *Login) Login() error {
 			}
 			if !phoneReg.MatchString(phone) {
 				return -1, false
-			} else if tmp := l.GetSession("CheckCodeId"); tmp == nil || !captcha.VerifyString(tmp.(string), l.GetString("code")) {
+			} else if tmp := l.GetSession("CheckCodeId"); tmp == nil || !gocaptcha.VerifyString(tmp.(string), l.GetString("code")) { //!captcha.VerifyString(tmp.(string), l.GetString("code"))
+				log.Println(tmp.(string), "----", l.GetString("code"))
 				return -2, false
-			} else if jy.SendPhoneIdentCode(qutil.ObjToString(config.Sysconfig["smsServiceRpc"]), phone, l.Session()) {
-				return 1, false
+				//} else if jy.SendPhoneIdentCode(l.Request, qutil.ObjToString(config.Sysconfig["smsServiceRpc"]), phone, l.Session()) {
+				//	return 1, false
 			}
 			return 0, false
 		} else if reqType == "identCodeLogin" { //短信验证码登录
-			sessVal := l.Session().GetMultiple()
-			phone := qutil.ObjToString(sessVal["identCodeKey"])
-			if phone == "" || sessVal["identCodeValue"] == nil || l.GetString("identCode") != sessVal["identCodeValue"] { //验证码不正确
+			phone := l.GetString("phone")           //手机号参数
+			captchaKey := l.GetString("captchaKey") //图形验证码key
+			identCode := l.GetString("identCode")   //短信验证码
+			if strings.TrimSpace(phone) == "" || strings.TrimSpace(captchaKey) == "" || strings.TrimSpace(identCode) == "" {
+				return -1, false
+			}
+			captchaPhone := jy.CheckPhoneIdent(l.Session(), identCode, fmt.Sprintf(captcha.SendCodeKey, captchaKey, phone))
+			if phone != captchaPhone { //验证码不正确
 				return -1, false
 			} else {
+				sessVal := l.Session().GetMultiple()
 				//用户不存在
 				datas, _ := mongodb.Find("user", map[string]interface{}{
 					"i_appid": 2,
@@ -175,6 +183,7 @@ func (l *Login) Login() error {
 						"s_regsource": "pc",
 						"s_platform":  "pc",
 						"s_sourceid":  channelCode,
+						"s_rsource":   channelCode,
 					}
 					//注册邮箱
 					email := l.GetString("email")
@@ -211,8 +220,9 @@ func (l *Login) Login() error {
 					}
 					_id := mongodb.Save("user", data)
 					if _id != "" {
+						redis.Del("limitation", fmt.Sprintf("firstVisitTagByWX_%s", l.Session().Id()))
 						//用户日志保存
-						jy.SaveUserLog(public.Mgo_Log, _id, phone, "phone", "pc", source, "", gconv.String(l.GetSession("RSource")), gconv.String(sessVal["RSource"]), qutil.GetIp(l.Request), l.UserAgent(), "jybx", "")
+						go jy.SaveUserLog(public.Mgo_Log, _id, phone, "phone", "pc", source, "", gconv.String(l.GetSession("RSource")), gconv.String(sessVal["RSource"]), qutil.GetIp(l.Request), l.UserAgent(), "jybx", "")
 						jy.ClearPhoneIdentSession(l.Session())
 						ok, _, userInfo := afterLogin(l.Request, phone, l.Session(), false)
 						userInfo["isNewUser"] = true
@@ -297,6 +307,10 @@ func (l *Login) Login() error {
 				jutil.SetCookieValueForAutoLogin(l.ResponseWriter, baseUserId)
 			}
 		}
+		//登录 注册后 清除合作商来源标识
+		if channelCode != "" {
+			jutil.ClearCookie(l.ResponseWriter, jy.ChannelCookieName)
+		}
 		status = 1
 	}
 	result["status"] = status
@@ -328,19 +342,32 @@ func (l *Login) ForgetPwd() error {
 			if !phoneReg.MatchString(phone) {
 				return "phoneError"
 			}
-			if tmp := l.GetSession("CheckCodeId"); tmp == nil || !captcha.VerifyString(tmp.(string), l.GetString("code")) {
-				return "codeError"
-			}
+			//if tmp := l.GetSession("CheckCodeId"); tmp == nil || !gocaptcha.VerifyString(tmp.(string), l.GetString("code")) { //!captcha.VerifyString(tmp.(string), l.GetString("code"))
+			//	log.Println(tmp.(string), "----", l.GetString("code"))
+			//	return "codeError"
+			//}
 			//手机号是否已被注册
 			if !phoneIsExists(phone) {
 				return "phoneNotExists"
-			} else if jy.SendPhoneIdentCode(qutil.ObjToString(config.Sysconfig["smsServiceRpc"]), phone, l.Session()) {
-				return "y"
+				//} else if jy.SendPhoneIdentCode(l.Request, qutil.ObjToString(config.Sysconfig["smsServiceRpc"]), phone, l.Session()) {
+				//	return "y"
 			}
 		} else if reqType == "nextStep" {
-			if l.GetSession("identCodeValue") == nil || l.GetString("identCode") != l.GetSession("identCodeValue") { //验证码不正确
+			phone := l.GetString("phone")           //手机号参数
+			captchaKey := l.GetString("captchaKey") //图形验证码key
+			identCode := l.GetString("identCode")   //短信验证码
+			log.Println(phone, captchaKey, identCode)
+			log.Println(strings.TrimSpace(phone) == "", strings.TrimSpace(captchaKey) == "", strings.TrimSpace(identCode) == "")
+			if strings.TrimSpace(phone) == "" || strings.TrimSpace(captchaKey) == "" || strings.TrimSpace(identCode) == "" {
+				return "缺少参数"
+			}
+			captchaPhone := jy.CheckPhoneIdent(l.Session(), identCode, fmt.Sprintf(captcha.SendCodeKey, captchaKey, phone))
+			if phone != captchaPhone { //验证码不正确
 				return "identCodeError"
 			}
+			//if l.GetSession("identCodeValue") == nil || l.GetString("identCode") != l.GetSession("identCodeValue") { //验证码不正确
+			//	return "identCodeError"
+			//}
 			l.SetSession("forgetPwdStep", "2")
 			return "y"
 		} else if reqType == "save" {

+ 3 - 1
src/jfw/front/nzjProject.go

@@ -9,8 +9,10 @@ import (
 	"app.yhyue.com/moapp/jybase/redis"
 	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
 	"app.yhyue.com/moapp/jypkg/public"
+	"context"
 	"encoding/json"
 	"fmt"
+	"github.com/gogf/gf/v2/frame/g"
 	"jy/src/jfw/config"
 	"math/rand"
 	"sort"
@@ -743,7 +745,7 @@ func NewHotEnt(isWinner bool, number int) (data []map[string]interface{}) {
 		} else {
 			data = redisData
 		}
-		redis.Put("newother", redisKey, data, RedisTimeout)
+		redis.Put("newother", redisKey, data, g.Cfg("index").MustGet(context.Background(), "indexBiddingCacheTime", 1800).Int())
 	}
 	return
 }

+ 1 - 1
src/jfw/front/org_structure.go

@@ -197,7 +197,7 @@ func (this *OrgStructure) AutoLogon() error {
 			}); resp != nil && resp.Data.Id > 0 {
 				data["base_user_id"] = resp.Data.Id
 				if id := mongodb.Save("user", data); id != "" {
-					jy.SaveUserLog(public.Mgo_Log, id, openId, "wx", "pc", source, openId, gconv.String(this.GetSession("RSource")), gconv.String(this.GetSession("RSource")), util.GetIp(this.Request), this.UserAgent(), "jybx", "")
+					go jy.SaveUserLog(public.Mgo_Log, id, openId, "wx", "pc", source, openId, gconv.String(this.GetSession("RSource")), gconv.String(this.GetSession("RSource")), util.GetIp(this.Request), this.UserAgent(), "jybx", "")
 					nsqPath, _ := config.Sysconfig["nsq"].(string)
 					nsq_topic, _ := config.Sysconfig["nsq_topic"].(string)
 					jy.Publish(public.Mgo_Log, nsqPath, nsq_topic, "task", id, jy.Jyweb_node2, map[string]interface{}{

+ 20 - 16
src/jfw/front/otherAct.go

@@ -1,10 +1,12 @@
 package front
 
 import (
+	"app.yhyue.com/moapp/jybase/gocaptcha"
 	"app.yhyue.com/moapp/jypkg/public"
 	"fmt"
 	"github.com/gogf/gf/v2/util/gconv"
 	"jy/src/jfw/config"
+	"log"
 	"regexp"
 	"time"
 
@@ -12,7 +14,6 @@ import (
 
 	util "app.yhyue.com/moapp/jybase/common"
 
-	"app.yhyue.com/moapp/jybase/dchest/captcha"
 	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
 )
 
@@ -34,18 +35,20 @@ func (f *Front) CheckPhoneNum() error {
 }
 
 // 图片验证码
-func (c *Front) Captcha() error {
-	id := captcha.NewLen(4) //此id为生成验证码的ID,并不是实际显示的数字,在提交校验时,需要根据此ID进行查询。
-	c.SetSession("CheckCodeId", id)
-	//校验时调用以下代码
-	//ccid,_:=c.GetSession("CheckCodeId").(string)
-	//captcha.VerifyString(ccid,"用户输入的校验码")//返回bool
-	w := c.ResponseWriter
-	w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
-	w.Header().Set("Pragma", "no-cache")
-	w.Header().Set("Expires", "0")
-	w.Header().Set("Content-Type", "image/png")
-	return captcha.WriteImage(w, id, 90, 30)
+func (c *Front) Captcha() {
+	gocaptcha.Get(c.Session(), "CheckCodeId", c.ResponseWriter, c.Request)
+	//return
+	//id := captcha.NewLen(4) //此id为生成验证码的ID,并不是实际显示的数字,在提交校验时,需要根据此ID进行查询。
+	//c.SetSession("CheckCodeId", id)
+	////校验时调用以下代码
+	////ccid,_:=c.GetSession("CheckCodeId").(string)
+	////captcha.VerifyString(ccid,"用户输入的校验码")//返回bool
+	//w := c.ResponseWriter
+	//w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
+	//w.Header().Set("Pragma", "no-cache")
+	//w.Header().Set("Expires", "0")
+	//w.Header().Set("Content-Type", "image/png")
+	//return captcha.WriteImage(w, id, 90, 30)
 }
 
 // 发送短信验证
@@ -59,7 +62,8 @@ func (f *Front) SendMessage() {
 	ccid, _ := getsession["CheckCodeId"].(string)
 	lastSendMsgTime := util.Int64All(getsession["lastSendMsgTime"])
 	//通过图片验证
-	if captcha.VerifyString(ccid, imgCancode) {
+	log.Println(ccid, "---", imgCancode)
+	if gocaptcha.VerifyString(ccid, imgCancode) { //captcha.VerifyString(ccid, imgCancode)
 		//当前时间-上次发送时间>60s
 		if time.Now().Unix()-lastSendMsgTime > 60 {
 			if !userIsExists(phoneNum) && phoneReg.MatchString(phoneNum) {
@@ -70,7 +74,7 @@ func (f *Front) SendMessage() {
 				session.Set("phoneNum", phoneNum)
 				session.Set("lastSendMsgTime", time.Now().Unix())
 				go func() {
-					jy.SendSMS(util.ObjToString(config.Sysconfig["smsServiceRpc"]), phoneNum, MsgCode)
+					jy.SendSMS(f.Request, util.ObjToString(config.Sysconfig["smsServiceRpc"]), phoneNum, MsgCode)
 				}()
 				fmt.Println("手机号码", phoneNum, "验证码", MsgCode)
 			} else {
@@ -151,7 +155,7 @@ func (f *Front) Lpsubmit() error {
 			_id := mongodb.Save("user", data)
 			if _id != "" {
 				//用户日志保存
-				jy.SaveUserLog(public.Mgo_Log, _id, phone, "phone", "pc", "landPage", "", gconv.String(f.GetSession("RSource")), util.ObjToString(f.GetSession("RSource")), util.GetIp(f.Request), f.UserAgent(), "jybx", "")
+				go jy.SaveUserLog(public.Mgo_Log, _id, phone, "phone", "pc", "landPage", "", gconv.String(f.GetSession("RSource")), util.ObjToString(f.GetSession("RSource")), util.GetIp(f.Request), f.UserAgent(), "jybx", "")
 				deleteIdentSession(f.Session())
 				return "y"
 			}

+ 19 - 1
src/jfw/front/partner.go

@@ -1,9 +1,11 @@
 package front
 
 import (
+	util "app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
 	"app.yhyue.com/moapp/jybase/redis"
 	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
+	"app.yhyue.com/moapp/jypkg/public"
 	"fmt"
 	"jy/src/jfw/config"
 	"log"
@@ -29,10 +31,26 @@ func (p *Partner) PartnerInfo(source string) error {
 	if bm := mobileReg.MatchString(p.Header("User-Agent")); bm {
 		return p.Redirect(fmt.Sprintf("%s/jyapp/new/%s", config.Sysconfig["h5"].(string), source))
 	}
+	var (
+		shortInfos = public.Mysql.SelectBySql(`SELECT * FROM short_url WHERE mold = 2 AND code = ?`, source)
+		noLoginUrl = fmt.Sprintf("/jylab/supsearch/index.html?keywords=&selectType=title&searchGroup=1&partner=%s", source)
+		loginUrl   = fmt.Sprintf("/jylab/supsearch/index.html?keywords=&selectType=title&searchGroup=1&partner=%s", source)
+	)
+	if shortInfos != nil && len(*shortInfos) > 0 {
+		shortInfo := (*shortInfos)[0]
+		loginUrl = util.ObjToString(shortInfo["url"])    //已登录用
+		noLoginUrl = util.ObjToString(shortInfo["href"]) //未登录
+		go func(source string) {
+			if ui := public.Mysql.UpdateOrDeleteBySql(`update short_url SET visits=visits+1 WHERE mold = 2 AND code = ?;`, source); ui <= 0 {
+				log.Println("update short_url visits false ,source:", source)
+			}
+		}(source)
+	}
 	//未登录
 	if userId, _ := p.GetSession("userId").(string); userId == "" {
 		jy.SetCookieValue(p.ResponseWriter, jy.ChannelCookieName, source, cacheTimeOut)                      //三天
 		redis.Put("limitation", fmt.Sprintf("firstVisitTagByWX_%s", p.Session().Id()), source, cacheTimeOut) //登录注册 用户标识
+		return p.Redirect(noLoginUrl)
 	}
-	return p.Redirect("/jylab/supsearch/index.html?keywords=&selectType=title&searchGroup=1&partner=" + source)
+	return p.Redirect(loginUrl)
 }

+ 2 - 2
src/jfw/front/pchelper.go

@@ -154,7 +154,7 @@ func (l *PcHelper) Login() error {
 						}
 						_id := mongodb.Save("user", data)
 						if _id != "" {
-							jy.SaveUserLog(public.Mgo_Log, _id, phone, "phone", "pc", "pc", "", gconv.String(l.GetSession("RSource")), gconv.String(l.GetSession("RSource")), util.GetIp(l.Request), l.UserAgent(), "jybx", "")
+							go jy.SaveUserLog(public.Mgo_Log, _id, phone, "phone", "pc", "pc", "", gconv.String(l.GetSession("RSource")), gconv.String(l.GetSession("RSource")), util.GetIp(l.Request), l.UserAgent(), "jybx", "")
 							jy.ClearPhoneIdentSession(l.Session())
 							reToken = getUToken(mac, phone)
 							reOpenId = phone
@@ -195,7 +195,7 @@ func (l *PcHelper) Login() error {
 				return -2
 			} else if !phoneReg.MatchString(phone) {
 				return -1
-			} else if jy.SendPhoneIdentCode(util.ObjToString(config.Sysconfig["smsServiceRpc"]), phone, l.Session()) {
+			} else if jy.SendPhoneIdentCode(l.Request, util.ObjToString(config.Sysconfig["smsServiceRpc"]), phone, l.Session()) {
 				return 1
 			}
 			return 0

+ 13 - 14
src/jfw/front/recommendationProject.go

@@ -3,7 +3,6 @@ package front
 import (
 	"app.yhyue.com/moapp/jybase/common"
 	elastic "app.yhyue.com/moapp/jybase/es"
-	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
 	"app.yhyue.com/moapp/jybase/redis"
 	"fmt"
 	"github.com/gogf/gf/v2/util/gconv"
@@ -24,24 +23,24 @@ var (
 	WinnerRecommend, BuyerRecommend []map[string]interface{}
 )
 
-type RecommendationProject struct {
-	*xweb.Action
-	portraitRecommendation xweb.Mapper `xweb:"/front/bootstrap/specification"` //画像登录右侧推荐
-}
+//type RecommendationProject struct {
+//	*xweb.Action
+//	portraitRecommendation xweb.Mapper `xweb:"/front/bootstrap/specification"` //画像登录右侧推荐
+//}
 
 func init() {
-	xweb.AddAction(&RecommendationProject{})
+	//xweb.AddAction(&RecommendationProject{})
 	InitEnterprises()
 }
 
-func (l *RecommendationProject) PortraitRecommendation() {
-	l.GetString("isWinner")
-	l.ServeJson(map[string]interface{}{
-		"error_code": 0,
-		"error_msg":  nil,
-		"data":       config.Sysconfig["bootstrap_specification"],
-	})
-}
+//func (l *RecommendationProject) PortraitRecommendation() {
+//	//l.GetString("isWinner")
+//	l.ServeJson(map[string]interface{}{
+//		"error_code": 0,
+//		"error_msg":  nil,
+//		"data":       config.Sysconfig["bootstrap_specification"],
+//	})
+//}
 
 func InitEnterprises() {
 	winnerConfig := strings.Split(common.InterfaceToStr(config.Sysconfig["winner"]), ",")

+ 170 - 0
src/jfw/front/returnMoneyPage.go

@@ -0,0 +1,170 @@
+package front
+
+import (
+	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
+	"app.yhyue.com/moapp/jybase/redis"
+	"app.yhyue.com/moapp/jypkg/public"
+	"errors"
+	"fmt"
+	"github.com/gogf/gf/v2/util/gconv"
+	"jy/src/jfw/config"
+	"jy/src/jfw/jyutil"
+	"jy/src/jfw/wx"
+	"net/url"
+	"regexp"
+	"strings"
+	"time"
+)
+
+type (
+	ReturnMoneyPage struct {
+		*xweb.Action
+		wxReturnMoney  xweb.Mapper `xweb:"/weixin/pay/returnMoney"` //微信数据导出-支付页面
+		aliReturnMoney xweb.Mapper `xweb:"/returnMoney/aliPage"`    //剑鱼管理后台微信支付回款
+	}
+
+	returnMoney struct {
+		PayWay string
+		Price  string
+	}
+)
+
+func init() {
+	xweb.AddAction(&ReturnMoneyPage{})
+}
+
+func (this *ReturnMoneyPage) WxReturnMoney() {
+	err := func() error {
+		var (
+			getSession = this.Session().GetMultiple()
+			openid     = gconv.String(getSession["s_m_openid"])
+			data       = map[string]interface{}{
+				"token": this.GetString("token"),
+			}
+		)
+		//没有用户session 或  有session但是没有关注(刚刚取关 session信息存留)
+		if openid == "" || (openid != "" && !CheckUserIsSubscribe(openid)) {
+			stateKey := this.GetString("state")
+			if stateKey == "" { //公众号回调
+				stateKey = getTmpKey()
+				//暂存参数
+				for k, v := range this.Request.Form {
+					if len(v) > 0 {
+						data[k] = v[0]
+					}
+				}
+				redis.Put("other", stateKey, data, 60*5) //存储信息
+				return this.Redirect(fmt.Sprintf(config.Wxoauth, url.QueryEscape(this.Site()+this.Url()), stateKey), 302)
+			}
+			//获取wx跳转前参数
+			if redisValue := redis.Get("other", stateKey); redisValue != nil {
+				if param, ok := redisValue.(map[string]interface{}); ok {
+					data = param
+				}
+			}
+			//获取用户openid
+			openid = jyutil.Getopenid(this.GetString("code"))
+		}
+
+		if openid == "" {
+			return fmt.Errorf("<p>请在微信端打开</p>")
+		}
+		this.Session().Set("openid_returnMoney", openid)
+
+		token := gconv.String(data["token"])
+		rData, err := getReturnPayDetail(token)
+		if err != nil {
+			return err
+		}
+
+		this.T["token"] = token
+		this.T["data"] = rData
+		this.T["signature"] = wx.SignJSSDK(this.Site() + this.Url())
+		return this.Render("/common/returnMoney/wxReturnMoney.html", &this.T)
+	}()
+	if err != nil {
+		this.T["note"] = err.Error()
+		this.Render("/weixin/commonPay/orderStatus.html", &this.T)
+	}
+}
+
+func (this *ReturnMoneyPage) AliReturnMoney() {
+	err := func() error {
+		token := this.GetString("token")
+		rData, err := getReturnPayDetail(token)
+		if err != nil {
+			return err
+		}
+		this.T["token"] = token
+		this.T["data"] = formatShow(rData)
+		return this.Render("/common/returnMoney/aliReturnMoney.html", &this.T)
+	}()
+	if err != nil {
+		this.T["note"] = err.Error()
+		this.Render("/weixin/commonPay/orderStatus.html", &this.T)
+	}
+}
+
+func getReturnPayDetail(token string) (map[string]interface{}, error) {
+	if token == "" {
+		return nil, errors.New("<p>参数异常</p>")
+	}
+	rList := public.Mysql.SelectBySql("SELECT d.order_status,d.product_type,d.user_phone,d.company_name,r.return_money,r.expire_time,r.status FROM dataexport_order d inner join return_money_online r on (d.order_code=r.order_code) WHERE r.token=? ", token)
+	if rList == nil || len(*rList) == 0 {
+		return nil, fmt.Errorf("<p>未知回款单</p>")
+	}
+
+	var (
+		rMap        = (*rList)[0]
+		expire_time = gconv.String(rMap["expire_time"])
+		status      = gconv.Int64(rMap["status"])
+		orderStatus = gconv.Int64(rMap["order_status"])
+	)
+	if orderStatus == -2 {
+		return nil, fmt.Errorf("<p>该订单已取消,如有问题<br>请联系您的客户经理</p>")
+	}
+	if status > 0 {
+		return nil, fmt.Errorf("<p>您已完成支付!</p>")
+	} else if status == -1 {
+		return nil, fmt.Errorf("<p>支付二维码已过期,请联<br>系您的客户经理重新提供</p>")
+	}
+
+	if expire, err := time.ParseInLocation(time.DateTime, expire_time, time.Local); err == nil {
+		if time.Now().After(expire) {
+			go public.Mysql.Update("return_money_online", map[string]interface{}{"token": token, "status": 0}, map[string]interface{}{"status": -1})
+			return nil, fmt.Errorf("<p>支付二维码已过期,请联<br>系您的客户经理重新提供</p>")
+		}
+	}
+	return rMap, nil
+}
+
+func formatShow(orderMap map[string]interface{}) map[string]interface{} {
+	var (
+		account string
+		rMap    = map[string]interface{}{}
+	)
+	if company_name := gconv.String(orderMap["company_name"]); company_name != "" {
+		account = company_name
+	} else if phone := gconv.String(orderMap["user_phone"]); len(phone) == 11 && !strings.HasPrefix(phone, "9") {
+		account = maskPhoneNumber(phone)
+	}
+	rMap["account"] = account
+
+	product := gconv.String(orderMap["product_type"])
+	if product == "VIP订阅" {
+		product = "超级订阅"
+	}
+	rMap["product"] = product
+
+	t, _ := time.Parse(time.DateTime, gconv.String(orderMap["expire_time"]))
+	rMap["expire_time"] = t.Format("2006年01月02日")
+
+	rMap["price"] = gconv.Float64(orderMap["return_money"]) / 100.0
+	return rMap
+}
+
+func maskPhoneNumber(phoneNumber string) string {
+	re := regexp.MustCompile(`(\d{3})\d{4}(\d{4})`)
+	maskedNumber := re.ReplaceAllString(phoneNumber, "$1****$2")
+	return maskedNumber
+}

+ 10 - 1
src/jfw/front/shorturl.go

@@ -188,6 +188,12 @@ func (s *Short) Article(stype, id string) error {
 		if len(sids) == 0 || (len(sids) > 0 && sids[0] == "") {
 			return s.Redirect(getErrPageUrl(bm, DecodeErr), 302)
 		}
+		//2024.11.26 增加新标讯未登录 /article/content 302 到seo/nologin/content
+		if mgoId := sids[0]; stype == "content" && mgoId != "" {
+			if bid := mg.StringTOBsonId(mgoId); bid.Timestamp().Unix() > 1732550400 {
+				return s.Redirect(fmt.Sprintf("/nologin/content/%s.html", id), 302)
+			}
+		}
 		return s.NologinCommon("", stype, id, sids[0], bm)
 	}
 	return s.LoginCommon(sess, stype, id, bm)
@@ -1385,6 +1391,10 @@ func (s *Short) NologinCommon(userId, stype, id, sid string, isMobile bool) erro
 		s.DisableHttpCache()
 		po, bo, wo, obj := pcVRT(sid, industry, stype, false, false)
 		if obj != nil && len(obj) > 0 {
+			//阳光采购 网站的数据 未登录不能访问
+			if util.InterfaceToStr(obj["infoattribute"]) == "zc_cgxx" { //&& util.IntAll(obj["is_yg_new"]) == 1
+				return s.Redirect("/", 301)
+			}
 			// p397 未登录不能查看拟建项目
 			if !ipTrue && (obj["subtype"] == "采购意向" || obj["subtype"] == "拟建") { //未登录拟建 采购意向 遮罩
 				obj = map[string]interface{}{
@@ -1447,7 +1457,6 @@ func (s *Short) NologinCommon(userId, stype, id, sid string, isMobile bool) erro
 	} else {
 		return s.SetBody([]byte(res.(string)))
 	}
-	return nil
 }
 
 /*

+ 28 - 6
src/jfw/front/singleLogin.go

@@ -144,19 +144,36 @@ func (this *SingleLogin) KeyPhrases(key string) error {
 
 // ShortUrl
 // 短地址跳转
-func (this *SingleLogin) ShortUrl(key string) error {
+func (this *SingleLogin) ShortUrl(source string) error {
 	defer qutil.Catch()
-	var redirectUrl = "/swordfish/about"
-	if key != "" {
-		shortUrls := public.Mysql.SelectBySql(`SELECT * FROM short_url WHERE mold = 1 AND code = ?`, key)
+	var (
+		noLoginUrl = fmt.Sprintf("/swordfish/about?partner=%s", source)
+		loginUrl   = noLoginUrl
+	)
+	if source != "" {
+		shortUrls := public.Mysql.SelectBySql(`SELECT * FROM short_url WHERE mold = 1 AND code = ?`, source)
 		if shortUrls != nil && len(*shortUrls) > 0 {
 			shortUrl := (*shortUrls)[0]
 			if qutil.ObjToString(shortUrl["url"]) != "" {
-				redirectUrl = qutil.ObjToString(shortUrl["url"])
+				loginUrl = qutil.ObjToString(shortUrl["url"])
+			}
+			if qutil.ObjToString(shortUrl["href"]) != "" {
+				noLoginUrl = qutil.ObjToString(shortUrl["href"])
 			}
+			go func(source string) {
+				if ui := public.Mysql.UpdateOrDeleteBySql(`update short_url SET visits=visits+1 WHERE mold = 1 AND code = ? ;`, source); ui <= 0 {
+					log.Println("update short_url visits false ,source:", source)
+				}
+			}(source)
 		}
 	}
-	return this.Redirect(redirectUrl)
+	//未登录
+	if userId, _ := this.GetSession("userId").(string); userId == "" {
+		jy.SetCookieValue(this.ResponseWriter, jy.ChannelCookieName, source, cacheTimeOut)                      //三天
+		redis.Put("limitation", fmt.Sprintf("firstVisitTagByWX_%s", this.Session().Id()), source, cacheTimeOut) //登录注册 用户标识
+		return this.Redirect(noLoginUrl)
+	}
+	return this.Redirect(loginUrl)
 }
 
 // SingleLogin
@@ -220,6 +237,11 @@ func (this *SingleLogin) SingleLogin() error {
 			}, this.Session(), "singleLogin", false, true)
 			//loginCreateSess(openid, this.Session())
 		}
+		if this.GetString("toHref") == "/weixin/frontPage/activity/free/register" {
+			if phone := this.GetSession("phone"); phone != "" {
+				data["toHref"] = "/jy_mobile/tabbar/home?toast=r"
+			}
+		}
 		return this.Redirect(qutil.ObjToString(data["toHref"]))
 	}
 	//未关注跳转

+ 333 - 320
src/jfw/front/supsearch.go

@@ -388,313 +388,9 @@ func (p *Pcsearch) SearchPower(module string) {
 // PcSearchIndex 路由搜索
 func (p *Pcsearch) PcSearchIndex(module string) error {
 	defer util.Catch()
-	//页面重构后 前端中转页 P480#2
-	//if !strings.Contains(p.Request.URL.String(), "useOld") {
-	return p.Render("/pc/search/index.html", &p.T)
-	//}
 	sessVal := p.Session().GetMultiple()
-	p.T["logid"] = config.Seoconfig["jysslby"].(string)
-	pageSize, _ := p.GetInteger("pageSize")
-	if pageSize == 0 {
-		pageSize = 50
-	}
-	accountId := util.Int64All(sessVal["accountId"])
-	entAccountId := util.Int64All(sessVal["entAccountId"])
-	entId := util.Int64All(sessVal["entId"])
-	entUserId := util.Int64All(sessVal["entUserId"])
-	keywords := p.GetString("keywords")
-	industry := strings.TrimSpace(p.GetString("industry")) //选中的行业
-	area := p.GetString("area")                            //地区
-	publishtime := p.GetString("publishtime")              //发布时间
-	timeslot := p.GetString("timeslot")                    //显示选择时间
-	toptype := p.GetString("toptype")                      //信息类型
-	subtype := p.GetString("subtype")                      //信息类型
-	minprice := p.GetString("minprice")                    //最低价格
-	maxprice := p.GetString("maxprice")                    //最高价格
-	fileExists := p.GetString("fileExists")                //是否有附件--所有用户都可用此功能 0:全部;1:有附件;-1:无附件
-	//搜索优化P260--start--
-	searchGroup, _ := p.GetInteger("searchGroup")     //搜索分组;默认0:全部;1:招标采购搜索;2:超前项目。
-	searchMode, _ := p.GetInteger("searchMode")       //搜索模式;默认0:精准模式(不进行系统分词);1:模糊模式(进行系统分词)。
-	wordsMode, _ := p.GetInteger("wordsMode")         //搜索关键词模式;默认0:包含所有关键词;1:包含任意关键词。
-	additionalWords := p.GetString("additionalWords") //关键词:附加关键词(副:五组,每组最多15个字符 每组,号隔开)
-	//--end--
-	//userId, _ := p.GetSession("userId").(string)
-	//phone, _ := p.GetSession("phone").(string)
 	userId := util.ObjToString(sessVal["userId"])
-	phone := util.ObjToString(sessVal["phone"])
-	selectType := p.GetString("selectType") //搜索范围
-	if selectType == "" {
-		selectType = "title,content"
-	}
-	//p353包含采购意向与拟建
-	noLoginBl := false
-	if userId == "" {
-		//未登录用户访问全部信息类型 需要过滤掉 拟建
-		// p397 未登录用户收回查看拟建权限
-		if searchGroup < 2 {
-			if strings.Contains(subtype, "采购意向") || strings.Contains(subtype, "拟建") {
-				var ss []string
-				for _, v := range strings.Split(subtype, ",") {
-					if v != "采购意向" && !strings.Contains(v, "拟建") {
-						ss = append(ss, v)
-					}
-				}
-				subtype = strings.Join(ss, ",")
-			}
-			if subtype == "" {
-				subtype = "招标预告,招标公告,招标结果,招标信用信息"
-				noLoginBl = true
-			}
-		}
-		//未登录用户搜索范围 标题和 正文
-		var selectTypeArr []string
-		selectTypeSplit := strings.Split(selectType, ",")
-		// 未登录用户只能搜标题和正文
-		for i := 0; i < len(selectTypeSplit); i++ {
-			if selectTypeSplit[i] == "title" || selectTypeSplit[i] == "content" {
-				selectTypeArr = append(selectTypeArr, selectTypeSplit[i])
-			}
-		}
-		if len(selectTypeArr) > 0 {
-			selectType = strings.Join(selectTypeArr, ",")
-		}
-		if publishtime != "" {
-			publishtime = ""
-		}
-	}
-	//高级筛选 仅vip用户可查询
-	var (
-		hasBuyerTel, hasWinnerTel = "", "" //是否有采购单位电话、是否有中标单位电话 y:有 n:没有
-		buyerclass                = ""     //采购单位类别
-		notkey                    = ""     //排除词
-		city                      = ""     //城市 付费用户可用
-		district                  = ""
-		regionMap                 = ""
-		buyer                     = ""
-		winner                    = ""
-		agency                    = ""
-		mobileTag                 []string //P513中国移动定制招标采购搜索
-	)
-	// 领域化标识
-	territorialization := p.GetString("bid_field")
-	switch module {
-	case "medical": // 领域类型  医疗-0101
-		if territorialization == "" {
-			territorialization = "0101"
-		}
-	case "BIProperty":
-		territorialization = territorialization
-	default:
-		territorialization = ""
-	}
-	if territorialization == "" {
-		territorialization = p.GetString("property")
-	}
-	userInfo := jy.GetVipState(p.Session(), *config.Middleground, userId)
-	queryItems := userInfo.GetQueryItems(selectType, util.Int64All(config.Sysconfig["bidSearchOldUserLimit"]))
-	isPayedUser := userInfo.IsPayedUser()
-	if isPayedUser {
-		buyerclass = p.GetString("buyerclass")
-		hasBuyerTel, hasWinnerTel = p.GetString("buyertel"), p.GetString("winnertel")
-		notkey = p.GetString("notkey")
-		city = p.GetString("city") //城市 付费用户可用
-		district = p.GetString("district")
-		regionMap = p.GetString("regionMap")
-		//P492招标采购搜索匹配采购单位等优化
-		buyer = p.GetString("buyer")   //采购单位
-		winner = p.GetString("winner") //中标企业
-		agency = p.GetString("agency") //招标代理机构
-	}
-	//历史导出数据回显
-	if strings.Contains(p.Url(), "?goback") {
-		keywords = util.ObjToString(sessVal["Echo_keywords"])
-		publishtime = util.ObjToString(sessVal["Echo_publishtime"])
-		area = util.ObjToString(sessVal["Echo_area"])
-		subtype = util.ObjToString(sessVal["Echo_subtype"])
-		minprice = util.ObjToString(sessVal["Echo_minprice"])
-		maxprice = util.ObjToString(sessVal["Echo_maxprice"])
-		buyerclass = util.ObjToString(sessVal["Echo_buyerclass"])
-		selectType = util.ObjToString(sessVal["Echo_selectType"])
-		timeslot = util.ObjToString(sessVal["Echo_timeslot"])
-		hasBuyerTel = util.ObjToString(sessVal["Echo_hasBuyertel"])
-		hasWinnerTel = util.ObjToString(sessVal["Echo_hasWinnertel"])
-		industry = util.ObjToString(sessVal["Echo_industry"])
-		notkey = util.ObjToString(sessVal["Echo_notkey"])
-		fileExists = util.ObjToString(sessVal["Echo_fileExists"])
-		city = util.ObjToString(sessVal["Echo_city"])
-		district = util.ObjToString(sessVal["Echo_district"])
-		regionMap = util.ObjToString(sessVal["Echo_regionMap"])
-		bidField = util.ObjToString(sessVal["Echo_bid_field"])              // 领域化数据 0101-医疗行业
-		territorialization = util.ObjToString(sessVal["Echo_bid_field"])    // 领域化数据 0101-医疗行业
-		searchGroup = util.IntAll(sessVal["Echo_searchGroup"])              //搜索分组;默认0:全部;1:招标采购搜索;2:超前项目。
-		searchMode = util.IntAll(sessVal["Echo_searchMode"])                //搜索模式;默认0:精准模式(不进行系统分词);1:模糊模式(进行系统分词)。
-		wordsMode = util.IntAll(sessVal["Echo_wordsMode"])                  //搜索关键词模式;默认0:包含所有关键词;1:包含任意关键词。
-		additionalWords = util.ObjToString(sessVal["Echo_additionalWords"]) //关键词:附加关键词(副:五组,每组最多15个字符 每组,号隔开)
-		queryItems = userInfo.GetQueryItems(selectType, util.Int64All(config.Sysconfig["bidSearchOldUserLimit"]))
-		//P492招标采购搜索匹配采购单位等优化
-		buyer = util.ObjToString(sessVal["Echo_buyer"])
-		winner = util.ObjToString(sessVal["Echo_winner"])
-		agency = util.ObjToString(sessVal["Echo_agency"])
-	}
-	keywordsLimit := util.IntAllDef(config.Sysconfig["keywordsLimit"], 35)
-	searchLimit := public.IsSearchLimit(queryItems)
-	//-----------------------------未登录用户支持非单字符查询--------------------------
-	if userId == "" {
-		keywordsLimit = util.IntAllDef(config.Sysconfig["keywordsLimitNologin"], 25)
-		//未登录用户标题、正文都限制,已登录用户只限制正文
-		searchLimit = true
-		if len([]rune(keywords)) == 1 {
-			//未登录用户搜索不让搜索单字
-			keywords = ""
-		}
-	}
-	var (
-		list                               []*map[string]interface{}
-		count, total, bCount               int64
-		secondFlag                         = ""
-		isSearch                           = true
-		b_word, a_word, s_word, heightKeys = "", "", "", ""
-	)
-	onList, _ := jyutil.IsOnTheWhitelist(p.Session())
-	if keywords != "" {
-		// p329 非白名单用户 处理通用词
-		if !onList && len(industry) == 0 {
-			keywords = jyutil.FilterGeneric(keywords)                         // 关键词处理通用词
-			additionalWords = jyutil.AdditionalFilterGeneric(additionalWords) // 附加词处理通用词
-		}
-		b_word, a_word, s_word = jy.InterceptSearchKW(keywords, keywordsLimit, len(industry) == 0)
-	}
-	if strings.Index(p.Refer(), "/page_workDesktop/work-bench") > -1 {
-		//超级搜索页面 移动定制搜索标签(仅工作台内展示)
-		mobileTag = p.GetSlice("mobileTag[]")
-		//if len(mobileTag) > 0 { //当无该权限,把此字段置空
-		if !jy.HasBidFieldPower(config.Middleground, p.Session(), MobileTagSearchFunctionCode) {
-			mobileTag = []string{}
-		} else if (len(mobileTag) > 0 && mobileTag[0] == "all") || len(mobileTag) == 0 {
-			mobileTag = mobileTagItemsValOptionsAll
-		}
-		//}
-	}
-
-	//医疗领域化信息 用户前提是大会员 超级订阅,才有领域化功能的权限
-	if territorialization != "" && territorialization != "BIProperty" {
-		isSearch = false
-		userInfo := jy.GetVipState(p.Session(), *config.Middleground, userId)
-		if userInfo.BigMember > 0 || userInfo.VipState > 0 {
-			if jy.HasBidFieldPower(config.Middleground, p.Session(), MedicalFunctionCode) {
-				isSearch = true
-			}
-		}
-	}
-	isLimit := 1
-	if isSearch {
-		searchTypeSwitch, _ := config.Sysconfig["searchTypeSwitch"].(bool)
-		so := NewSearchOptimize(mobileTag, userId, phone, area, city, district, subtype, toptype, publishtime, strings.Join(queryItems, ","), fmt.Sprintf("%s-%s", minprice, maxprice), industry, buyerclass, hasBuyerTel, hasWinnerTel, fileExists, s_word, additionalWords, notkey, "PC", territorialization, "", "", "",
-			0, pageSize, searchGroup, searchMode, wordsMode, "", "", 0, 0,
-			*userInfo, searchTypeSwitch, p.Request, accountId, entAccountId, entId, entUserId, buyer, winner, agency)
-		heightKeys = so.HeightKeys //主关键词和附加词合并,多组空格隔开,作为前端渲染高亮关键词使用
-		//关键词  行业 附加词
-		//放开用户不输入关键词可搜索 --P297需求
-		// p329 反爬白名单用户放开  非反爬白名单用户不放开未输入关键词
-		if len(s_word) > 0 || (len(s_word) == 0 && onList) || len(industry) > 0 || strings.TrimSpace(so.AdditionalWords) != "" || len(so.MobileTag) > 0 {
-			if searchLimit {
-				isLimit = public.Lst.IsLimited(p.Request, p.ResponseWriter, p.Session(), isPayedUser)
-				if isLimit == 1 { //没有被限制
-					defer public.Lst.Limit()
-				}
-			}
-			if isLimit == 1 {
-				count, total, list = so.GetBidSearchList(false)
-				if total < util.Int64All(config.Sysconfig["precisionNum"]) && so.SearchMode == 0 && so.KeyWords != "" {
-					soBlur := NewSearchOptimize(mobileTag, userId, phone, area, city, district, subtype, toptype, publishtime, strings.Join(queryItems, ","), fmt.Sprintf("%s-%s", minprice, maxprice), industry, buyerclass, hasBuyerTel, hasWinnerTel, fileExists, s_word, additionalWords, notkey, "PC", territorialization, "", "", "",
-						0, pageSize, searchGroup, 1, wordsMode, "", "", 0, 0,
-						*userInfo, searchTypeSwitch, p.Request, accountId, entAccountId, entId, entUserId, buyer, winner, agency)
-					bCount = soBlur.FuzzySearchNumber()
-				}
-			}
-		} else {
-			p.DisableHttpCache()
-			list, count, total = so.GetBidSearchListByCache()
-		}
-	}
-	if noLoginBl {
-		subtype = ""
-	}
-	if userId == "" {
-		for _, v := range list {
-			*v = SearchFilter(*v)
-		}
-	}
-	p.T["bCount"] = bCount
-	p.T["list"] = list
-	p.T["secondFlag"] = secondFlag
-	p.T["area"] = area
-	p.T["publishtime"] = publishtime
-	p.T["timeslot"] = timeslot
-	p.T["toptype"] = toptype
-	p.T["subtype"] = subtype
-	p.T["searchvalue"] = keywords //搜索关键词
-	p.T["minprice"] = minprice
-	p.T["maxprice"] = maxprice
-	p.T["buyerclass"] = buyerclass
-	p.T["buyertel"] = hasBuyerTel
-	p.T["winnertel"] = hasWinnerTel
-	p.T["notkey"] = notkey
-	p.T["fileExists"] = fileExists
-	p.T["city"] = city
-	p.T["district"] = district
-	p.T["regionMap"] = regionMap
-	p.T["bid_field"] = territorialization
-	p.SetSession("paramkey", b_word)
-	switch publishtime {
-	case "lately-7":
-		p.SetSession("parampublishtime", "最近7天")
-	case "lately-30":
-		p.SetSession("parampublishtime", "最近30天")
-	case "thisyear":
-		p.SetSession("parampublishtime", "近一年")
-	case "threeyear":
-		p.SetSession("parampublishtime", "近三年")
-	case "fiveyear":
-		p.SetSession("parampublishtime", "近五年")
-	default:
-		p.SetSession("parampublishtime", publishtime)
-	}
-	p.SetSession("paramarea", area)
-	if subtype != "" {
-		p.SetSession("paraminfotype", subtype)
-	} else {
-		p.SetSession("paraminfotype", toptype)
-	}
-	//}
-	p.T["selectType"] = selectType
-	p.T["login"] = p.Session().Get("user")
-	p.T["count"] = count
-	p.T["totalPage"] = (count + 1) / int64(pageSize)
-	p.T["keywords"] = keywords      //搜索关键词
-	p.T["heightWords"] = heightKeys //主关键词和附加词合并后
-	p.T["industry"] = industry
-	p.T["industrylist"] = industrylist
-	p.T["sortArray"] = sortArray
-	p.T["showVipScreen"] = isPayedUser
-	p.T["bidField"] = territorialization
-	p.T["module"] = module
-	p.T["interceptKeyWords"] = b_word   //超出限制关键词限制长度 截取后
-	p.T["interceptOtherWords"] = a_word //超出限制关键词限制长度 截取后 提示关键词
-	p.T["interceptLimit"] = keywordsLimit
-	//
-	p.T["searchGroup"] = searchGroup
-	p.T["searchMode"] = searchMode
-	p.T["wordsMode"] = wordsMode
-	p.T["additionalWords"] = additionalWords
-	p.T["total"] = total
-
-	p.T["isVip"] = userInfo.VipState > 0
-	p.T["isMember"] = userInfo.BigMember > 0
-	p.T["isEntniche"] = userInfo.EntMember > 0
-	p.T["isEntnicheNew"] = userInfo.IsNewEnt
-	p.T["isEntService"] = userInfo.EntService
-	p.T["vipBefore202209"] = userInfo.VipState > 0 && userInfo.VipStartData < util.Int64All(config.Sysconfig["contextOldVipLimit"]) //超级订阅 超强项目
+	//页面重构后 前端中转页 P480#2
 	//
 	cooperateCode := ""
 	if userId != "" {
@@ -705,22 +401,339 @@ func (p *Pcsearch) PcSearchIndex(module string) error {
 			cooperateCode = cc.Value
 		}
 	}
+	p.T["logid"] = config.Seoconfig["jysslby"].(string)
 	p.T["cooperateCode"] = cooperateCode
-	p.T["isLimit"] = isLimit
-	if module == "supsearch" {
-		p.T["simpleTemplateData"] = map[string]interface{}{
-			"isEntniche":      p.T["isEntniche"],
-			"isVip":           p.T["isVip"],
-			"isMember":        p.T["isMember"],
-			"vipBefore202209": p.T["vipBefore202209"],
-			"searchMode":      searchMode,
-			"searchvalue":     keywords,
-			"additionalWords": additionalWords,
-			"listLength":      util.If(list != nil, len(list), 0),
-		}
-	}
-	//老版搜索页面
-	return p.Render("/pc/supsearch.html", &p.T)
+	//if !strings.Contains(p.Request.URL.String(), "useOld") {
+	return p.Render("/pc/search/index.html", &p.T)
+	//}
+	//sessVal := p.Session().GetMultiple()
+	//pageSize, _ := p.GetInteger("pageSize")
+	//if pageSize == 0 {
+	//	pageSize = 50
+	//}
+	//accountId := util.Int64All(sessVal["accountId"])
+	//entAccountId := util.Int64All(sessVal["entAccountId"])
+	//entId := util.Int64All(sessVal["entId"])
+	//entUserId := util.Int64All(sessVal["entUserId"])
+	//keywords := p.GetString("keywords")
+	//industry := strings.TrimSpace(p.GetString("industry")) //选中的行业
+	//area := p.GetString("area")                            //地区
+	//publishtime := p.GetString("publishtime")              //发布时间
+	//timeslot := p.GetString("timeslot")                    //显示选择时间
+	//toptype := p.GetString("toptype")                      //信息类型
+	//subtype := p.GetString("subtype")                      //信息类型
+	//minprice := p.GetString("minprice")                    //最低价格
+	//maxprice := p.GetString("maxprice")                    //最高价格
+	//fileExists := p.GetString("fileExists")                //是否有附件--所有用户都可用此功能 0:全部;1:有附件;-1:无附件
+	////搜索优化P260--start--
+	//searchGroup, _ := p.GetInteger("searchGroup")     //搜索分组;默认0:全部;1:招标采购搜索;2:超前项目。
+	//searchMode, _ := p.GetInteger("searchMode")       //搜索模式;默认0:精准模式(不进行系统分词);1:模糊模式(进行系统分词)。
+	//wordsMode, _ := p.GetInteger("wordsMode")         //搜索关键词模式;默认0:包含所有关键词;1:包含任意关键词。
+	//additionalWords := p.GetString("additionalWords") //关键词:附加关键词(副:五组,每组最多15个字符 每组,号隔开)
+	////--end--
+	////userId, _ := p.GetSession("userId").(string)
+	////phone, _ := p.GetSession("phone").(string)
+	//userId := util.ObjToString(sessVal["userId"])
+	//phone := util.ObjToString(sessVal["phone"])
+	//selectType := p.GetString("selectType") //搜索范围
+	//if selectType == "" {
+	//	selectType = "title,content"
+	//}
+	////p353包含采购意向与拟建
+	//noLoginBl := false
+	//if userId == "" {
+	//	//未登录用户访问全部信息类型 需要过滤掉 拟建
+	//	// p397 未登录用户收回查看拟建权限
+	//	if searchGroup < 2 {
+	//		if strings.Contains(subtype, "采购意向") || strings.Contains(subtype, "拟建") {
+	//			var ss []string
+	//			for _, v := range strings.Split(subtype, ",") {
+	//				if v != "采购意向" && !strings.Contains(v, "拟建") {
+	//					ss = append(ss, v)
+	//				}
+	//			}
+	//			subtype = strings.Join(ss, ",")
+	//		}
+	//		if subtype == "" {
+	//			subtype = "招标预告,招标公告,招标结果,招标信用信息"
+	//			noLoginBl = true
+	//		}
+	//	}
+	//	//未登录用户搜索范围 标题和 正文
+	//	var selectTypeArr []string
+	//	selectTypeSplit := strings.Split(selectType, ",")
+	//	// 未登录用户只能搜标题和正文
+	//	for i := 0; i < len(selectTypeSplit); i++ {
+	//		if selectTypeSplit[i] == "title" || selectTypeSplit[i] == "content" {
+	//			selectTypeArr = append(selectTypeArr, selectTypeSplit[i])
+	//		}
+	//	}
+	//	if len(selectTypeArr) > 0 {
+	//		selectType = strings.Join(selectTypeArr, ",")
+	//	}
+	//	if publishtime != "" {
+	//		publishtime = ""
+	//	}
+	//}
+	////高级筛选 仅vip用户可查询
+	//var (
+	//	hasBuyerTel, hasWinnerTel = "", "" //是否有采购单位电话、是否有中标单位电话 y:有 n:没有
+	//	buyerclass                = ""     //采购单位类别
+	//	notkey                    = ""     //排除词
+	//	city                      = ""     //城市 付费用户可用
+	//	district                  = ""
+	//	regionMap                 = ""
+	//	buyer                     = ""
+	//	winner                    = ""
+	//	agency                    = ""
+	//	mobileTag                 []string //P513中国移动定制招标采购搜索
+	//)
+	//// 领域化标识
+	//territorialization := p.GetString("bid_field")
+	//switch module {
+	//case "medical": // 领域类型  医疗-0101
+	//	if territorialization == "" {
+	//		territorialization = "0101"
+	//	}
+	//case "BIProperty":
+	//	territorialization = territorialization
+	//default:
+	//	territorialization = ""
+	//}
+	//if territorialization == "" {
+	//	territorialization = p.GetString("property")
+	//}
+	//userInfo := jy.GetVipState(p.Session(), *config.Middleground, userId)
+	//queryItems := userInfo.GetQueryItems(selectType, util.Int64All(config.Sysconfig["bidSearchOldUserLimit"]))
+	//isPayedUser := userInfo.IsPayedUser()
+	//if isPayedUser {
+	//	buyerclass = p.GetString("buyerclass")
+	//	hasBuyerTel, hasWinnerTel = p.GetString("buyertel"), p.GetString("winnertel")
+	//	notkey = p.GetString("notkey")
+	//	city = p.GetString("city") //城市 付费用户可用
+	//	district = p.GetString("district")
+	//	regionMap = p.GetString("regionMap")
+	//	//P492招标采购搜索匹配采购单位等优化
+	//	buyer = p.GetString("buyer")   //采购单位
+	//	winner = p.GetString("winner") //中标企业
+	//	agency = p.GetString("agency") //招标代理机构
+	//}
+	////历史导出数据回显
+	//if strings.Contains(p.Url(), "?goback") {
+	//	keywords = util.ObjToString(sessVal["Echo_keywords"])
+	//	publishtime = util.ObjToString(sessVal["Echo_publishtime"])
+	//	area = util.ObjToString(sessVal["Echo_area"])
+	//	subtype = util.ObjToString(sessVal["Echo_subtype"])
+	//	minprice = util.ObjToString(sessVal["Echo_minprice"])
+	//	maxprice = util.ObjToString(sessVal["Echo_maxprice"])
+	//	buyerclass = util.ObjToString(sessVal["Echo_buyerclass"])
+	//	selectType = util.ObjToString(sessVal["Echo_selectType"])
+	//	timeslot = util.ObjToString(sessVal["Echo_timeslot"])
+	//	hasBuyerTel = util.ObjToString(sessVal["Echo_hasBuyertel"])
+	//	hasWinnerTel = util.ObjToString(sessVal["Echo_hasWinnertel"])
+	//	industry = util.ObjToString(sessVal["Echo_industry"])
+	//	notkey = util.ObjToString(sessVal["Echo_notkey"])
+	//	fileExists = util.ObjToString(sessVal["Echo_fileExists"])
+	//	city = util.ObjToString(sessVal["Echo_city"])
+	//	district = util.ObjToString(sessVal["Echo_district"])
+	//	regionMap = util.ObjToString(sessVal["Echo_regionMap"])
+	//	bidField = util.ObjToString(sessVal["Echo_bid_field"])              // 领域化数据 0101-医疗行业
+	//	territorialization = util.ObjToString(sessVal["Echo_bid_field"])    // 领域化数据 0101-医疗行业
+	//	searchGroup = util.IntAll(sessVal["Echo_searchGroup"])              //搜索分组;默认0:全部;1:招标采购搜索;2:超前项目。
+	//	searchMode = util.IntAll(sessVal["Echo_searchMode"])                //搜索模式;默认0:精准模式(不进行系统分词);1:模糊模式(进行系统分词)。
+	//	wordsMode = util.IntAll(sessVal["Echo_wordsMode"])                  //搜索关键词模式;默认0:包含所有关键词;1:包含任意关键词。
+	//	additionalWords = util.ObjToString(sessVal["Echo_additionalWords"]) //关键词:附加关键词(副:五组,每组最多15个字符 每组,号隔开)
+	//	queryItems = userInfo.GetQueryItems(selectType, util.Int64All(config.Sysconfig["bidSearchOldUserLimit"]))
+	//	//P492招标采购搜索匹配采购单位等优化
+	//	buyer = util.ObjToString(sessVal["Echo_buyer"])
+	//	winner = util.ObjToString(sessVal["Echo_winner"])
+	//	agency = util.ObjToString(sessVal["Echo_agency"])
+	//}
+	//keywordsLimit := util.IntAllDef(config.Sysconfig["keywordsLimit"], 35)
+	//searchLimit := public.IsSearchLimit(queryItems)
+	////-----------------------------未登录用户支持非单字符查询--------------------------
+	//if userId == "" {
+	//	keywordsLimit = util.IntAllDef(config.Sysconfig["keywordsLimitNologin"], 25)
+	//	//未登录用户标题、正文都限制,已登录用户只限制正文
+	//	searchLimit = true
+	//	if len([]rune(keywords)) == 1 {
+	//		//未登录用户搜索不让搜索单字
+	//		keywords = ""
+	//	}
+	//}
+	//var (
+	//	list                               []*map[string]interface{}
+	//	count, total, bCount               int64
+	//	secondFlag                         = ""
+	//	isSearch                           = true
+	//	b_word, a_word, s_word, heightKeys = "", "", "", ""
+	//)
+	//onList, _ := jyutil.IsOnTheWhitelist(p.Session())
+	//if keywords != "" {
+	//	// p329 非白名单用户 处理通用词
+	//	if !onList && len(industry) == 0 {
+	//		keywords = jyutil.FilterGeneric(keywords)                         // 关键词处理通用词
+	//		additionalWords = jyutil.AdditionalFilterGeneric(additionalWords) // 附加词处理通用词
+	//	}
+	//	b_word, a_word, s_word = jy.InterceptSearchKW(keywords, keywordsLimit, len(industry) == 0)
+	//}
+	//if strings.Index(p.Refer(), "/page_workDesktop/work-bench") > -1 {
+	//	//超级搜索页面 移动定制搜索标签(仅工作台内展示)
+	//	mobileTag = p.GetSlice("mobileTag[]")
+	//	//if len(mobileTag) > 0 { //当无该权限,把此字段置空
+	//	if !jy.HasBidFieldPower(config.Middleground, p.Session(), MobileTagSearchFunctionCode) {
+	//		mobileTag = []string{}
+	//	} else if (len(mobileTag) > 0 && mobileTag[0] == "all") || len(mobileTag) == 0 {
+	//		mobileTag = mobileTagItemsValOptionsAll
+	//	}
+	//	//}
+	//}
+	//
+	////医疗领域化信息 用户前提是大会员 超级订阅,才有领域化功能的权限
+	//if territorialization != "" && territorialization != "BIProperty" {
+	//	isSearch = false
+	//	userInfo := jy.GetVipState(p.Session(), *config.Middleground, userId)
+	//	if userInfo.BigMember > 0 || userInfo.VipState > 0 {
+	//		if jy.HasBidFieldPower(config.Middleground, p.Session(), MedicalFunctionCode) {
+	//			isSearch = true
+	//		}
+	//	}
+	//}
+	//isLimit := 1
+	//if isSearch {
+	//	searchTypeSwitch, _ := config.Sysconfig["searchTypeSwitch"].(bool)
+	//	so := NewSearchOptimize(mobileTag, userId, phone, area, city, district, subtype, toptype, publishtime, strings.Join(queryItems, ","), fmt.Sprintf("%s-%s", minprice, maxprice), industry, buyerclass, hasBuyerTel, hasWinnerTel, fileExists, s_word, additionalWords, notkey, "PC", territorialization, "", "", "",
+	//		0, pageSize, searchGroup, searchMode, wordsMode, "", "", 0, 0,
+	//		*userInfo, searchTypeSwitch, p.Request, accountId, entAccountId, entId, entUserId, buyer, winner, agency)
+	//	heightKeys = so.HeightKeys //主关键词和附加词合并,多组空格隔开,作为前端渲染高亮关键词使用
+	//	//关键词  行业 附加词
+	//	//放开用户不输入关键词可搜索 --P297需求
+	//	// p329 反爬白名单用户放开  非反爬白名单用户不放开未输入关键词
+	//	if len(s_word) > 0 || (len(s_word) == 0 && onList) || len(industry) > 0 || strings.TrimSpace(so.AdditionalWords) != "" || len(so.MobileTag) > 0 {
+	//		if searchLimit {
+	//			isLimit = public.Lst.IsLimited(p.Request, p.ResponseWriter, p.Session(), isPayedUser)
+	//			if isLimit == 1 { //没有被限制
+	//				defer public.Lst.Limit()
+	//			}
+	//		}
+	//		if isLimit == 1 {
+	//			count, total, list = so.GetBidSearchList(false)
+	//			if total < util.Int64All(config.Sysconfig["precisionNum"]) && so.SearchMode == 0 && so.KeyWords != "" {
+	//				soBlur := NewSearchOptimize(mobileTag, userId, phone, area, city, district, subtype, toptype, publishtime, strings.Join(queryItems, ","), fmt.Sprintf("%s-%s", minprice, maxprice), industry, buyerclass, hasBuyerTel, hasWinnerTel, fileExists, s_word, additionalWords, notkey, "PC", territorialization, "", "", "",
+	//					0, pageSize, searchGroup, 1, wordsMode, "", "", 0, 0,
+	//					*userInfo, searchTypeSwitch, p.Request, accountId, entAccountId, entId, entUserId, buyer, winner, agency)
+	//				bCount = soBlur.FuzzySearchNumber()
+	//			}
+	//		}
+	//	} else {
+	//		p.DisableHttpCache()
+	//		list, count, total = so.GetBidSearchListByCache()
+	//	}
+	//}
+	//if noLoginBl {
+	//	subtype = ""
+	//}
+	//if userId == "" {
+	//	for _, v := range list {
+	//		*v = SearchFilter(*v)
+	//	}
+	//}
+	//p.T["bCount"] = bCount
+	//p.T["list"] = list
+	//p.T["secondFlag"] = secondFlag
+	//p.T["area"] = area
+	//p.T["publishtime"] = publishtime
+	//p.T["timeslot"] = timeslot
+	//p.T["toptype"] = toptype
+	//p.T["subtype"] = subtype
+	//p.T["searchvalue"] = keywords //搜索关键词
+	//p.T["minprice"] = minprice
+	//p.T["maxprice"] = maxprice
+	//p.T["buyerclass"] = buyerclass
+	//p.T["buyertel"] = hasBuyerTel
+	//p.T["winnertel"] = hasWinnerTel
+	//p.T["notkey"] = notkey
+	//p.T["fileExists"] = fileExists
+	//p.T["city"] = city
+	//p.T["district"] = district
+	//p.T["regionMap"] = regionMap
+	//p.T["bid_field"] = territorialization
+	//p.SetSession("paramkey", b_word)
+	//switch publishtime {
+	//case "lately-7":
+	//	p.SetSession("parampublishtime", "最近7天")
+	//case "lately-30":
+	//	p.SetSession("parampublishtime", "最近30天")
+	//case "thisyear":
+	//	p.SetSession("parampublishtime", "近一年")
+	//case "threeyear":
+	//	p.SetSession("parampublishtime", "近三年")
+	//case "fiveyear":
+	//	p.SetSession("parampublishtime", "近五年")
+	//default:
+	//	p.SetSession("parampublishtime", publishtime)
+	//}
+	//p.SetSession("paramarea", area)
+	//if subtype != "" {
+	//	p.SetSession("paraminfotype", subtype)
+	//} else {
+	//	p.SetSession("paraminfotype", toptype)
+	//}
+	////}
+	//p.T["selectType"] = selectType
+	//p.T["login"] = p.Session().Get("user")
+	//p.T["count"] = count
+	//p.T["totalPage"] = (count + 1) / int64(pageSize)
+	//p.T["keywords"] = keywords      //搜索关键词
+	//p.T["heightWords"] = heightKeys //主关键词和附加词合并后
+	//p.T["industry"] = industry
+	//p.T["industrylist"] = industrylist
+	//p.T["sortArray"] = sortArray
+	//p.T["showVipScreen"] = isPayedUser
+	//p.T["bidField"] = territorialization
+	//p.T["module"] = module
+	//p.T["interceptKeyWords"] = b_word   //超出限制关键词限制长度 截取后
+	//p.T["interceptOtherWords"] = a_word //超出限制关键词限制长度 截取后 提示关键词
+	//p.T["interceptLimit"] = keywordsLimit
+	////
+	//p.T["searchGroup"] = searchGroup
+	//p.T["searchMode"] = searchMode
+	//p.T["wordsMode"] = wordsMode
+	//p.T["additionalWords"] = additionalWords
+	//p.T["total"] = total
+	//
+	//p.T["isVip"] = userInfo.VipState > 0
+	//p.T["isMember"] = userInfo.BigMember > 0
+	//p.T["isEntniche"] = userInfo.EntMember > 0
+	//p.T["isEntnicheNew"] = userInfo.IsNewEnt
+	//p.T["isEntService"] = userInfo.EntService
+	//p.T["vipBefore202209"] = userInfo.VipState > 0 && userInfo.VipStartData < util.Int64All(config.Sysconfig["contextOldVipLimit"]) //超级订阅 超强项目
+	////
+	//cooperateCode := ""
+	//if userId != "" {
+	//	//企业画像 权限
+	//	p.T["portraitpower"] = jylabutil.IsAuthorized(userId, "i_portraitpower")
+	//} else {
+	//	if cc, err := p.GetCookie(jy.ChannelCookieName); err == nil {
+	//		cooperateCode = cc.Value
+	//	}
+	//}
+	//p.T["cooperateCode"] = cooperateCode
+	//p.T["isLimit"] = isLimit
+	//if module == "supsearch" {
+	//	p.T["simpleTemplateData"] = map[string]interface{}{
+	//		"isEntniche":      p.T["isEntniche"],
+	//		"isVip":           p.T["isVip"],
+	//		"isMember":        p.T["isMember"],
+	//		"vipBefore202209": p.T["vipBefore202209"],
+	//		"searchMode":      searchMode,
+	//		"searchvalue":     keywords,
+	//		"additionalWords": additionalWords,
+	//		"listLength":      util.If(list != nil, len(list), 0),
+	//	}
+	//}
+	////老版搜索页面
+	//return p.Render("/pc/supsearch.html", &p.T)
 }
 
 // Newbids  最新招标信息 --已失效

+ 25 - 21
src/jfw/front/swordfish.go

@@ -16,14 +16,13 @@ import (
 	"strings"
 	"time"
 
-	. "app.yhyue.com/moapp/jybase/date"
-	. "app.yhyue.com/moapp/jybase/mongodb"
-
 	util "app.yhyue.com/moapp/jybase/common"
+	. "app.yhyue.com/moapp/jybase/date"
 	"app.yhyue.com/moapp/jybase/encrypt"
 	elastic "app.yhyue.com/moapp/jybase/es"
 	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
 	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
+	. "app.yhyue.com/moapp/jybase/mongodb"
 	"app.yhyue.com/moapp/jybase/redis"
 	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/bidsearch"
 	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
@@ -769,16 +768,11 @@ func wxvisitD(sid, userId, openId, content string, isPayUser bool) (objdata map[
 
 // wx pc obj字段统一处理
 func ObjData(isPayUser bool, sid, content string, lent int) (t bool, obj map[string]interface{}) {
-	brobj, ok := mongodb.Find("bidding_rec", bson.M{"s_id": sid}, `{"l_recoverydate":-1}`, nil, false, 0, 1)
-	if ok && (*brobj) != nil && len(*brobj) == 1 && (*brobj)[0] != nil {
-		obj = (*brobj)[0]
-	} else {
-		aobj, ok := public.Mgo_Bidding.FindById(public.DbConf.Mongodb.Bidding.Collection, sid, nil)
-		if ok && (aobj == nil || *aobj == nil || len(*aobj) == 0) {
-			aobj, ok = public.Mgo_Bidding.FindById(public.DbConf.Mongodb.Bidding.Collection_back, sid, nil)
-		}
-		obj = *aobj
+	aobj, ok := public.Mgo_Bidding.FindById(public.DbConf.Mongodb.Bidding.Collection, sid, nil)
+	if ok && (aobj == nil || *aobj == nil || len(*aobj) == 0) {
+		aobj, ok = public.Mgo_Bidding.FindById(public.DbConf.Mongodb.Bidding.Collection_back, sid, nil)
 	}
+	obj = *aobj
 	if ok && obj != nil && len(obj) > lent {
 		t = true
 		if !isPayUser && (content != "indexcontent") && (util.ObjToString(obj["subtype"]) == "拟建" || util.ObjToString(obj["subtype"]) == "采购意向") {
@@ -1215,10 +1209,12 @@ func (m *Front) AjaxReq() error {
 			o_jy, _ := (*r)["o_jy"].(map[string]interface{})
 			a_key, _ := o_jy["a_key"].([]interface{})
 			keysArray := processKeyword(m.GetString("keys"))
-			if keysArray == nil {
+			if keysArray == nil || len(keysArray) > 10 {
 				break
 			}
-			var isExists bool
+			saveKey := []bson.M{}
+			//var isExists bool
+			existKeyMap := map[string]struct{}{}
 			for _, v := range a_key {
 				//count := 0
 				//for _, kay := range keysArray {
@@ -1228,26 +1224,34 @@ func (m *Front) AjaxReq() error {
 				for _, ky := range key {
 					kystr = kystr + " " + ky.(string)
 				}
-				if strings.TrimSpace(m.GetString("keys")) == strings.TrimSpace(kystr) {
-					isExists = true
-					flag = "y"
+				existKeyMap[strings.TrimSpace(kystr)] = struct{}{}
+				//if strings.TrimSpace(m.GetString("keys")) == strings.TrimSpace(kystr) {
+				//	isExists = true
+				//	flag = "y"
+				//	break
+				//}
+			}
+			for i := 0; i < len(keysArray); i++ {
+				if len(saveKey)+len(a_key) >= 10 {
 					break
 				}
+				if _, ok := existKeyMap[keysArray[i]]; !ok {
+					saveKey = append(saveKey, bson.M{"key": []string{keysArray[i]}, "notkey": []string{}, "from": 1})
+				}
 			}
 			//如果不存在
-			if !isExists {
+			if len(saveKey) > 0 {
 				if len(a_key) >= 10 {
 					flag = "o"
 				} else {
 					if jyutil.Compatible.Update(util.ObjToString(userid),
 						bson.M{
-							"$push": bson.M{"o_jy.a_key": bson.M{"key": keysArray, "notkey": []string{}, "from": 1}},
+							"$push": bson.M{"o_jy.a_key": bson.M{"$each": saveKey}},
 							"$set":  bson.M{"i_ts_guide": 1, "o_jy.l_modifydate": time.Now().Unix()},
 						}) {
 						flag = "y"
 					}
 				}
-
 			}
 		}
 		break
@@ -1948,7 +1952,7 @@ func (f *Front) HasPushHistory() {
 		"haskey":      hasKeyFlag,
 		"data":        list,
 		"hasNextPage": hasNextPage,
-		"isInTSguide": isInTSguide(userId),
+		"isInTSguide": isInTSguide(userId, f.Session()),
 		"isVipSub":    isVipFlag,
 		"isPassCount": isPassCount,
 		"isExpire":    isExpire,

+ 56 - 18
src/jfw/front/tags.go

@@ -3,6 +3,7 @@ package front
 import (
 	"context"
 	"fmt"
+	"github.com/gogf/gf/v2/container/gvar"
 	"jy/src/jfw/config"
 	"jy/src/jfw/jyutil"
 	"jy/src/jfw/paging"
@@ -45,7 +46,11 @@ type reqLimit struct {
 	waitPool chan struct{}
 }
 
-var reqLimitInit *reqLimit
+var (
+	reqLimitInit     *reqLimit
+	BlogQueryLock    = new(sync.RWMutex)
+	HotWordQueryLock = new(sync.RWMutex)
+)
 
 func init() {
 	xweb.AddAction(&Tags{})
@@ -458,14 +463,17 @@ func IsInArr(arr []string, s string) bool {
 	return false
 }
 
+var (
+	redisKey   = fmt.Sprintf("pcindex_newArticle")
+	redisKeySL = fmt.Sprintf("pcindex_newArticle_second_level") //二级缓存
+	redisLock  = &sync.Mutex{}
+	rn         = 3
+)
+
 // 获取最新招标信息
 func (this *Tags) GetNewBidInfo() (list []map[string]interface{}) {
 	var (
-		redisKey   = fmt.Sprintf("pcindex_newArticle")
-		redisKeySL = fmt.Sprintf("pcindex_newArticle_second_level") //二级缓存
-		redisLock  = &sync.Mutex{}
-		ri         int
-		rn         = 3
+		ri int
 	)
 	var newBidInfos = func() (list []map[string]interface{}) {
 		// p397 未登录详情页最新招投标信息去掉拟建
@@ -578,13 +586,41 @@ func (this *Tags) GetStype(href string) (list []map[string]interface{}) {
 	return list
 }
 
+// GetL2CacheData 二级缓存
+// 注意 lock定义为全局锁
+func GetL2CacheData(dbName string, lock *sync.RWMutex, key string, f func() interface{}, cacheSec int) *gvar.Var {
+	var (
+		data    = gvar.New(redis.Get(dbName, key))
+		newData *gvar.Var
+	)
+	if data.IsEmpty() {
+		data = gvar.New(redis.Get(dbName, fmt.Sprintf("%s_L2Cache", key)))
+		go func() {
+			if lock.TryLock() {
+				defer lock.Unlock()
+				if n := f(); n != nil {
+					newData = gvar.New(n)
+					go func() {
+						redis.Put(dbName, key, newData, cacheSec)
+						redis.Put(dbName, fmt.Sprintf("%s_L2Cache", key), newData, -1)
+					}()
+				}
+			}
+		}()
+		if data.IsEmpty() {
+			time.Sleep(100 * time.Millisecond)
+			if !newData.IsEmpty() {
+				data = newData
+			}
+		}
+	}
+	return data
+}
+
 // 剑鱼博客
-func (this *Tags) GetConsult() (list []map[string]interface{}) {
+func (this *Tags) GetConsult() []map[string]interface{} {
 	rediskey := fmt.Sprintf("pcseo_jybk")
-	if l, ok := redis.Get("seoCache", rediskey).([]interface{}); ok && l != nil && len(l) > 0 {
-		list = qu.ObjArrToMapArr(l)
-	} else {
-
+	res := GetL2CacheData("seoCache", BlogQueryLock, rediskey, func() interface{} {
 		rs, _, _ := jyutil.JyCmsSearch(map[string]string{
 			"perPage": "10",
 		}, "/jyblog/index_%s.html")
@@ -595,11 +631,13 @@ func (this *Tags) GetConsult() (list []map[string]interface{}) {
 				delete(v, "s_source")
 				v["url"] = fmt.Sprintf("/jyblog/%s.html", qu.ObjToString(v["_id"]))
 			}
-			list = *rs
-			redis.Put("seoCache", rediskey, list, cacheTime)
 		}
+		return rs
+	}, cacheTime)
+	if !res.IsEmpty() {
+		return res.Maps()
 	}
-	return list
+	return nil
 }
 
 func (this *Tags) GetLetterMap(pageSize, pageNum int64, letter string) ([]map[string]interface{}, int64) {
@@ -627,9 +665,7 @@ func (this *Tags) GetLetterMap(pageSize, pageNum int64, letter string) ([]map[st
 
 func (this *Tags) GetHotLabel(length int64) []map[string]interface{} {
 	rediskey := fmt.Sprintf("pcseo_getHotLabel_%v", length)
-	if l, ok := redis.Get("seoCache", rediskey).([]interface{}); ok && l != nil && len(l) > 0 {
-		return qu.ObjArrToMapArr(l)
-	} else {
+	res := GetL2CacheData("seoCache", HotWordQueryLock, rediskey, func() interface{} {
 		m := []map[string]interface{}{}
 		sql := `select id,name,letter from seo_words.seo_resource where state1=2`
 		cql := `select count(1) from seo_words.seo_resource where state1=2`
@@ -650,8 +686,10 @@ func (this *Tags) GetHotLabel(length int64) []map[string]interface{} {
 				})
 			}
 		}
-		redis.Put("seoCache", rediskey, m, cacheTime)
 		return m
+	}, cacheTime)
+	if !res.IsEmpty() {
+		return res.Maps()
 	}
 	return nil
 }

+ 34 - 2
src/jfw/front/vipsubscribe.go

@@ -63,12 +63,44 @@ type Subscribepay struct {
 	wxViewPage xweb.Mapper `xweb:"/vipsubscribe/wx/page/(.*)"` //超级订阅wx
 	//订阅付费消息提醒中转
 	msgremind xweb.Mapper `xweb:"/front/vipsubscribe/msgremind"`
+	//邮件推送-登录剑鱼标讯,查看更多招标信息 访问路由
+	mailToPage xweb.Mapper `xweb:"/front/subscribe/mailToPage"`
 }
 
 func init() {
 	xweb.AddAction(&Subscribepay{})
 }
 
+// (1)PC:未登录跳转至官网首页并弹窗提示登录,登录成功后进入【我的订阅】列表页;已登录直接进入【我的订阅】列表页(如有多套订阅,依据推送邮件是哪套订阅进行页面跳转);
+// (2)移动端:未登录跳转至登录页,登录成功后进入【我的订阅】列表页;已登录直接进入【我的订阅】列表页(如有多套订阅,依据推送邮件是哪套订阅进行页面跳转)。
+func (s *Subscribepay) MailToPage() error {
+	sess := s.Session().GetMultiple()
+	userid := util.ObjToString(sess["userId"])
+	//是否是移动端
+	bm := mobileReg.MatchString(s.Header("User-Agent"))
+	vSwitch := s.GetString("vSwitch")
+	if vSwitch == jy.SwitchService.Member || vSwitch == jy.SwitchService.Vip || vSwitch == jy.SwitchService.Entniche {
+		s.SetSession(jy.SwitchService.SessionKey, vSwitch)
+	}
+	page := "/"
+	if bm {
+		if userid == "" {
+			page = fmt.Sprintf("%s%s", config.Sysconfig["h5"].(string), "/jyapp/free/login?url=%2Fjy_mobile%2Ftabbar%2Fsubscribe")
+		} else {
+			page = fmt.Sprintf("%s%s", config.Sysconfig["h5"].(string), "/jy_mobile/tabbar/subscribe")
+		}
+	} else {
+		if userid == "" {
+			page = "/?nol=1"
+		} else {
+			if vSwitch == "" {
+				vSwitch = "f"
+			}
+			page = fmt.Sprintf("/page_workDesktop/work-bench/app/big/big_subscribe?vt=%s", vSwitch)
+		}
+	}
+	return s.Redirect(page, 302)
+}
 func (s *Subscribepay) EntSearch() {
 	s.Render("/weixin/vipsubscribe/vip_entSearch.html")
 }
@@ -154,8 +186,8 @@ func (s *Subscribepay) ToSetPage() error {
 	}
 
 	vipMsg := jy.GetBigVipUserBaseMsg(s.Session(), *config.Middleground)
-	if vipMsg.VipStatus <= 0 && vipMsg.Status <= 0 && isInTSguide(userid) { //仅免费用户跳转向导页面
-		return s.Redirect("/front/tenderSubscribe/guide?url=" + url.QueryEscape(s.Request.RequestURI))
+	if isInTSguide(userid, s.Session()) {
+		return s.Redirect("/jy_mobile/subscribe/guide?url=" + url.QueryEscape(s.Request.RequestURI))
 	} else if (vSwitch == "" || vSwitch == "v") && vipMsg.VipStatus <= 0 && !vipMsg.IsUpgrade {
 		if s.GetString("advertcode") != "" {
 			return s.Redirect("/wxkeyset/keyset/index?advertcode=" + s.GetString("advertcode"))

+ 15 - 0
src/jfw/front/websocket.go

@@ -150,6 +150,21 @@ func GetWsByCode(param []string) bool {
 				//jyutil.SetCookieValueForAutoLogin(wss.Conn.W, baseUserId)  不可用
 				//您可以将自己的webSocket消息发送回客户端,告知它设置cookie,然后在客户端中侦听该消息,当它收到该消息时,它可以在浏览器中设置cookie.
 			}
+			// 新用户注册 记录来源
+			sourceLabel := redis.GetStr("limitation", fmt.Sprintf("firstVisitTagByWX_%s", session.Id()))
+			if sourceLabel != "" && openid != "" {
+				//来源不为空,且 注册时间 在5分钟内
+				registeDate := qutil.Int64All(infoData["registedate"])
+				if time.Now().Unix()-registeDate < 300 {
+					if ok := public.MQFW.Update("user", map[string]interface{}{
+						"s_m_openid": openid,
+					}, &map[string]interface{}{"$set": &map[string]interface{}{"s_rsource": sourceLabel}}, false, false); !ok {
+						log.Println("用户更新来源异常:", openid, "-来源:", sourceLabel)
+					} else {
+						redis.Del("limitation", fmt.Sprintf("firstVisitTagByWX_%s", session.Id()))
+					}
+				}
+			}
 		}
 		if wss.Conn == nil {
 			return true

+ 3 - 0
src/jfw/front/ws_dataExport.go

@@ -210,14 +210,17 @@ func (w *WsDataExport) GetPreview() error {
 	//从500条数据中筛选字段最全五条
 	scd := dataexport.GetSqlObjFromId(public.MQFW, _id)
 	kws := scd.Keyword
+	tm := time.Now()
 	res, err := dataexport.GetDataExportSearchResult(public.Mgo_Bidding, public.DbConf.Mongodb.Bidding.DbName, public.DbConf.Elasticsearch.Main.Address, scd, dataType, -1)
 	if res == nil || err != nil {
 		return w.Render("/pc/dataExport_noDataErr.html", &w.T)
 	}
+	log.Println(fmt.Sprintf("id:%s 查询耗时:%s", _id, time.Now().Sub(tm)))
 	msgCount := dataexport.GetDataExportSearchCountByScdId(public.MQFW, public.Mgo_Bidding, public.DbConf.Mongodb.Bidding.DbName, public.DbConf.Elasticsearch.Main.Address, _id)
 	//格式化字段
 	res_screen := dataexport.ScreenData(res, dataType, 20, kws)
 	list := dataexport.FormatExportData(public.Mgo_Ent, &res_screen, config.Sysconfig["webdomain"].(string), dataType, true)
+	log.Println(fmt.Sprintf("id:%s 格式化耗时:%s", _id, time.Now().Sub(tm)))
 	//if msgCount > 20000 {
 	//	msgCount = 20000
 	//}

+ 2 - 2
src/jfw/front/wxkeyset.go

@@ -35,8 +35,8 @@ func (m *Front) WxKeyset(tpl string) error {
 		})
 	}
 	vipMsg := jy.GetBigVipUserBaseMsg(m.Session(), *config.Middleground)
-	if (tpl == "index" || tpl == "filterset") && vipMsg.VipStatus <= 0 && vipMsg.Status <= 0 && isInTSguide(userid) { //仅免费用户跳转向导页面
-		return m.Redirect("/front/tenderSubscribe/guide?url=" + url.QueryEscape(m.Request.RequestURI))
+	if (tpl == "index" || tpl == "filterset") && isInTSguide(userid, m.Session()) {
+		return m.Redirect("/jy_mobile/subscribe/guide?url=" + url.QueryEscape(m.Request.RequestURI))
 	}
 	//到新订阅设置
 	if vipMsg.VipStatus > 0 || vipMsg.IsUpgrade {

+ 4 - 3
src/jfw/modules/app/src/app/filter/cookie.go

@@ -9,14 +9,15 @@ import (
 
 // CookieInfo 信息
 type CookieInfo struct {
-	W http.ResponseWriter
-	R *http.Request
+	W       http.ResponseWriter
+	R       *http.Request
+	IsLogin bool
 }
 
 // Do 继承过滤器方法
 func (ci *CookieInfo) Do() {
 	log.Println(ci.R.Referer(), "----------------------", ci.R.RequestURI)
-	if crr := ci.R.Referer(); crr != "" {
+	if crr := ci.R.Referer(); !ci.IsLogin && crr != "" {
 		if strings.Contains(crr, "cooperate") {
 			match := strings.Split(crr, "cooperate/")
 			if len(match) > 1 {

+ 1 - 1
src/jfw/modules/app/src/app/filter/filter.go

@@ -45,7 +45,7 @@ func (f *Filter) Do(w http.ResponseWriter, r *http.Request) bool {
 	if getSession["base_user_id"] != nil && getSession["positionId"] == nil {
 		identity.SwitchToBest(util.Int64All(getSession["base_user_id"]), session, Middleground, &public.MQFW, false)
 	}
-	(&CookieInfo{w, r}).Do()
+	(&CookieInfo{w, r, getSession["userId"] != nil}).Do()
 	if !(&logFilter{w, r, getSession}).Do() {
 		return false
 	}

+ 1 - 0
src/jfw/modules/app/src/app/filter/loginfilter.go

@@ -42,6 +42,7 @@ var urls = []*regexp.Regexp{
 	regexp.MustCompile("^/jyapp/workbench/$"),
 	regexp.MustCompile("^/jyapp/freesubscribe/$"),
 	regexp.MustCompile("^/jyapp/notFind$"),
+	regexp.MustCompile("^/jyapp/miniprogram"),
 }
 
 type loginFilter struct {

+ 0 - 1
src/jfw/modules/app/src/app/front/activity.go

@@ -78,7 +78,6 @@ func (s *Activity) Mini(args string) {
 	}
 	s.Render(config.Active.ActivateInfo.Url, &s.T)
 	return
-
 }
 
 // CheckSubscribe 是否关注

+ 7 - 2
src/jfw/modules/app/src/app/front/commonPay.go

@@ -1,9 +1,11 @@
 package front
 
 import (
-	util "app.yhyue.com/moapp/jybase/common"
 	"errors"
 	"fmt"
+	"strings"
+
+	util "app.yhyue.com/moapp/jybase/common"
 
 	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
 )
@@ -25,7 +27,7 @@ var (
 		"areaPack":          {"省份订阅包"},
 		"filePack":          {"附件下载包"},
 		"buyerPortraitPack": {"采购单位画像包"},
-		"docMember":          {"剑鱼文库会员"},
+		"docMember":         {"剑鱼文库会员"},
 	}
 )
 
@@ -58,6 +60,9 @@ func (w *AppPayCommon) ToCreateOrderPage(doType string) error {
 	w.T["t"] = t
 	w.T["doType"] = doType
 	w.T["orderCode"] = orderCode
+	if strings.Contains(w.UserAgent(), "miniProgram") {
+		return w.Render("/me/pay-mini.html", &w.T)
+	}
 	return w.Render("/commonPay/checkout.html", &w.T)
 }
 

+ 4 - 2
src/jfw/modules/app/src/app/front/dataPackRouter.go

@@ -15,7 +15,8 @@ func init() {
 }
 
 func (this *DataPackRouter) PackIndex() {
-	this.Render("/dataPack/index.html")
+	//this.Render("/dataPack/index.html")
+	this.Redirect("/jy_mobile/packs/data-pack/index")
 }
 
 func (this *DataPackRouter) CreateOrder() {
@@ -23,5 +24,6 @@ func (this *DataPackRouter) CreateOrder() {
 }
 
 func (this *DataPackRouter) RecordList() {
-	this.Render("/dataPack/recordList.html")
+	//this.Render("/dataPack/recordList.html")
+	this.Redirect("/jy_mobile/packs/data-pack/record")
 }

+ 4 - 3
src/jfw/modules/app/src/app/front/errLogsReceive.go

@@ -52,9 +52,10 @@ func (this *ErrLogServer) Receive() {
 				"i_reqTime":    data.ReqTime,
 			})
 		}
-		if !public.Mgo_Log.SaveBulk("jyapp_errlogs", saveArr...) {
-			return false, "数据保存异常"
-		}
+		go public.Mgo_Log.SaveBulk("jyapp_errlogs", saveArr...)
+		//if !public.Mgo_Log.SaveBulk("jyapp_errlogs", saveArr...) {
+		//	return false, "数据保存异常"
+		//}
 		return true, ""
 	}()
 	this.ServeJson(map[string]interface{}{

+ 11 - 7
src/jfw/modules/app/src/app/front/front.go

@@ -243,20 +243,24 @@ func mesCaLog(mid, url, userId, recType string) {
 func (m *Front) Wxerr() error {
 	return m.Render("/_err.html")
 }
+
+const tsGuideFinished = 1 // 完成订阅向导设置
+
 func isInTSguide(userid string, session *httpsession.Session) bool {
 	if userid == "" {
 		return false
 	}
 	data := jy.GetBigVipUserBaseMsg(session, *config.Middleground)
-	//付费用户无免费订阅,不进入订阅向导页面
-	if data.Data.Vip.Status > 0 {
+	//p618发版之前注册的付费用户不进入订阅向导页面
+	userdata := Compatible.Select(userid, `{"i_ts_guide":1,"l_registedate":1}`)
+	if userdata == nil || len(*userdata) == 0 {
 		return false
 	}
-	i_ts_guide := data.Data.Free.TsGuide
-	if i_ts_guide == 2 || (i_ts_guide == 0 && !data.Data.Free.FreeHasKey) {
-		return true
+	registedate := util.Int64All((*userdata)["l_registedate"])
+	if (!data.Data.Free.IsFree && registedate < config.GuideRegistedate) || util.Int64All((*userdata)["i_ts_guide"]) == tsGuideFinished {
+		return false
 	}
-	return false
+	return true
 }
 func (m *Front) Feedback() error {
 	defer util.Catch()
@@ -290,7 +294,7 @@ func (m *Front) Feedback() error {
 	return m.Render("/weixin/feedback.html", &m.T)
 }
 
-// 招标订阅向导
+// 招标订阅向导   p618走新的订阅向导 该路由已弃用
 func (f *Front) TSGuide() error {
 	defer util.Catch()
 	sessVal := f.Session().GetMultiple()

+ 130 - 36
src/jfw/modules/app/src/app/front/login.go

@@ -1,13 +1,8 @@
 package front
 
 import (
-	"app.yhyue.com/moapp/jybase/date"
-	"app.yhyue.com/moapp/jybase/encrypt"
-	. "app.yhyue.com/moapp/jybase/mongodb"
-	. "app.yhyue.com/moapp/jypkg/identity"
 	"encoding/json"
 	"fmt"
-	"github.com/gogf/gf/v2/util/gconv"
 	"jy/src/jfw/modules/app/src/app/jyutil"
 	utils "jy/src/jfw/modules/app/src/app/jyutil"
 	"jy/src/jfw/modules/app/src/jfw/config"
@@ -19,6 +14,12 @@ import (
 	"sync"
 	"time"
 
+	"app.yhyue.com/moapp/jybase/date"
+	"app.yhyue.com/moapp/jybase/encrypt"
+	. "app.yhyue.com/moapp/jybase/mongodb"
+	. "app.yhyue.com/moapp/jypkg/identity"
+	"github.com/gogf/gf/v2/util/gconv"
+
 	qutil "app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/redis"
 	qrpc "app.yhyue.com/moapp/jybase/rpc"
@@ -27,7 +28,8 @@ import (
 
 	"app.yhyue.com/moapp/jypkg/public"
 
-	"app.yhyue.com/moapp/jybase/dchest/captcha"
+	//"app.yhyue.com/moapp/jybase/dchest/captcha"
+	"app.yhyue.com/moapp/jybase/captcha"
 	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
 	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
 	"go.mongodb.org/mongo-driver/bson"
@@ -121,6 +123,9 @@ func (l *Login) Login() error {
 		//普通登录,跳转到登录页面
 		if sign == "" {
 			l.T["kicked"] = kickedTip
+			if strings.Contains(l.UserAgent(), "miniProgram") {
+				return l.Render("/me/login-mini.html", &l.T)
+			}
 			return l.Render("/me/login.html", &l.T)
 		} else { //带有签名的登录
 			if url := l.GetString("url"); url != "" {
@@ -133,6 +138,9 @@ func (l *Login) Login() error {
 				} else if status == -3 {
 					return l.Redirect("/jyapp/free/login?flag=kicked&back=index")
 				} else {
+					if strings.Contains(l.UserAgent(), "miniProgram") {
+						return l.Render("/me/login-mini.html")
+					}
 					return l.Render("/me/login.html")
 				}
 			} else {
@@ -211,16 +219,31 @@ func (l *Login) Login() error {
 				return -2, -1
 			} else if !phoneReg.MatchString(phone) {
 				return -1, -1
-			} else if jy.SendPhoneIdentCode(qutil.ObjToString(config.Sysconfig["smsServiceRpc"]), phone, l.Session()) {
-				return 1, -1
+				//} else if jy.SendPhoneIdentCode(l.Request, qutil.ObjToString(config.Sysconfig["smsServiceRpc"]), phone, l.Session()) {
+				//	return 1, -1
 			}
 			return 0, -1
 		} else if reqType == "identCodeLogin" {
-			disWord := l.GetString("disWord")
-			phone, _ := l.GetSession("identCodeKey").(string)
-			if phone == "" || l.GetSession("identCodeValue") == nil || l.GetString("identCode") != l.GetSession("identCodeValue") { //验证码不正确
+			phone := l.GetString("phone")           //手机号参数
+			captchaKey := l.GetString("captchaKey") //图形验证码key
+			identCode := l.GetString("identCode")   //短信验证码
+			//首次不用图形验证码
+			mobileKey := fmt.Sprintf(captcha.MobileCacheKey, phone)
+			mobileFirst := redis.GetInt(captcha.RedisCode, mobileKey) <= 1
+			sendCodeKey := fmt.Sprintf(captcha.SendCodeKey, captchaKey, phone)
+			if mobileFirst {
+				sendCodeKey = "identCode"
+				if strings.TrimSpace(phone) == "" {
+					return -1, -1
+				}
+			} else if strings.TrimSpace(phone) == "" || strings.TrimSpace(captchaKey) == "" || strings.TrimSpace(identCode) == "" {
+				return -1, -1
+			}
+			captchaPhone := jy.CheckPhoneIdent(l.Session(), identCode, sendCodeKey)
+			if phone != captchaPhone { //验证码不正确
 				return -1, -1
 			} else {
+				disWord := l.GetString("disWord")
 				RegLock.Lock()
 				reg := RegMap[phone]
 				if reg == nil {
@@ -233,18 +256,56 @@ func (l *Login) Login() error {
 				RegLock.Unlock()
 				reg.Lock.Lock()
 				defer reg.Lock.Unlock()
-				ok, user := getPhoneUser(phone)
+				ok, users := getPhoneUser(phone)
 				//登录成功
 				if !ok {
 					return 0, -1
 				}
+				userPhone := qutil.InterfaceToStr(l.GetSession("phone"))
+				userId := qutil.InterfaceToStr(l.GetSession("userId"))
+				if userId != "" && userPhone == "" {
+					//绑定手机号用户
+					key := "s_phone"
+					for _, m := range users {
+						s_phone := gconv.String(m["s_phone"])
+						s_m_phone := gconv.String(m["s_m_phone"])
+						openid := gconv.String(m["s_m_openid"])
+						if (s_m_phone != "" || s_phone != "") && openid != "" {
+							//已经绑定过手机号
+							return -2, -1
+						}
+						if s_phone != "" {
+							key = "s_m_phone"
+							continue
+						}
+					}
+					if mongodb.UpdateById("user", BsonIdToSId(userId), map[string]interface{}{
+						"$set": map[string]interface{}{key: phone},
+					}) {
+						jy.JyAppCreateSession(mongodb, l.Session(), userId, 0, l.ResponseWriter, true, config.Middleground, qutil.ObjToString(config.Sysconfig["appPushServiceRpc"]), qutil.IntAll(config.Sysconfig["criticality"]))
+						if c := public.Mysql.CountBySql("SELECT count(1) FROM dataexport_order WHERE (user_id = ? OR user_phone = ?) AND distribution_channel = 'x054'", userId, phone); c > 0 {
+							return -3, 3
+						} else {
+							jy.Publish(public.Mgo_Log, nsqPath, nsq_topic, "task", userId, jy.Jyweb_node2, map[string]interface{}{
+								"code":       1007,
+								"types":      "bindPhone",
+								"num":        50,
+								"baseUserId": l.GetSession("base_user_id"),
+								"positionId": l.GetSession("positionId"),
+								"isOnlyBind": true,
+							})
+						}
+
+					}
+					return 3, 3
+				}
 				//用户不存在
 				rid := l.GetString("rid")
 				oid := l.GetString("oid")
 				phoneType := l.GetString("phoneType")
 				channel := l.GetString("channel")
 				deviceId := l.GetString("deviceId")
-				if user == nil || len(user) == 0 {
+				if users == nil || len(users) == 0 {
 					client := l.Header("User-Agent")
 					log.Println(client)
 					//clearRidByRid(rid)
@@ -265,6 +326,7 @@ func (l *Login) Login() error {
 						},
 						"s_platform": "app",
 						"s_sourceid": channelCode,
+						"s_rsource":  channelCode,
 					}
 					// 新用户注册 记录来源
 					sourceLabel := redis.GetStr("limitation", fmt.Sprintf("firstVisitTagByWX_%s", l.Session().Id()))
@@ -295,7 +357,7 @@ func (l *Login) Login() error {
 					_id := mongodb.Save("user", data)
 					if _id != "" {
 						log.Println(111, _id, phone, "phone", "app", isAndroidOrIOS(l.Header("User-Agent")), "", gconv.String(l.GetSession("RSource")), gconv.String(data["s_rsource"]), "", l.Header("User-Agent"), gconv.String(qutil.If(gconv.String(data["s_regsource"]) == "jyzbw", "jyzbw", "jybx")), "")
-						jy.SaveUserLog(public.Mgo_Log, _id, phone, "phone", "app", isAndroidOrIOS(l.Header("User-Agent")), "", gconv.String(l.GetSession("RSource")), gconv.String(data["s_rsource"]), "", l.Header("User-Agent"), gconv.String(qutil.If(gconv.String(data["s_regsource"]) == "jyzbw", "jyzbw", "jybx")), "")
+						go jy.SaveUserLog(public.Mgo_Log, _id, phone, "phone", "app", isAndroidOrIOS(l.Header("User-Agent")), "", gconv.String(l.GetSession("RSource")), gconv.String(data["s_rsource"]), "", l.Header("User-Agent"), gconv.String(qutil.If(gconv.String(data["s_regsource"]) == "jyzbw", "jyzbw", "jybx")), "")
 						if sourceLabel != "" {
 							go func() {
 								redis.Del("limitation", fmt.Sprintf("firstVisitTagByWX_%s", l.Session().Id()))
@@ -334,6 +396,7 @@ func (l *Login) Login() error {
 						return 1, 3
 					}
 				} else {
+					user := users[0]
 					//以s_m_phone登录的 需要把s_m_phone转化为s_phone
 					updataMap := map[string]interface{}{}
 					if user["s_m_phone"] != nil {
@@ -365,6 +428,10 @@ func (l *Login) Login() error {
 		}
 		return 0, -1
 	}()
+	//登录 注册后 清除合作商来源标识
+	if status > 0 && channelCode != "" {
+		jyutil.ClearCookie(l.ResponseWriter, jy.ChannelCookieName)
+	}
 	//登录source 更新 p414
 	mgoUserId := qutil.ObjToString(l.GetSession("mgoUserId"))
 	us := jy.UserSource{
@@ -577,23 +644,34 @@ func (l *Login) Register() error {
 			if !phoneReg.MatchString(phone) {
 				return "phoneError"
 			}
-			if tmp := l.GetSession("CheckCodeId"); tmp == nil || !captcha.VerifyString(tmp.(string), l.GetString("code")) {
-				return "codeError"
-			}
+			//if tmp := l.GetSession("CheckCodeId"); tmp == nil || !captcha.VerifyString(tmp.(string), l.GetString("code")) {
+			//	return "codeError"
+			//}
 			//手机号是否已被注册
 			if userIsExists(phone) {
 				return "phoneExists"
-			} else if jy.SendPhoneIdentCode(qutil.ObjToString(config.Sysconfig["smsServiceRpc"]), phone, l.Session()) {
-				return "y"
+				//} else if jy.SendPhoneIdentCode(l.Request, qutil.ObjToString(config.Sysconfig["smsServiceRpc"]), phone, l.Session()) {
+				//	return "y"
 			}
 		} else if reqType == "nextStep" {
-			if l.GetSession("identCodeValue") == nil || l.GetString("identCode") != l.GetSession("identCodeValue") { //验证码不正确
-				return "identCodeError"
+			phone := l.GetString("phone")           //手机号参数
+			captchaKey := l.GetString("captchaKey") //图形验证码key
+			identCode := l.GetString("identCode")   //短信验证码
+			sendCodeKey := fmt.Sprintf(captcha.SendCodeKey, captchaKey, phone)
+			if strings.TrimSpace(phone) == "" || strings.TrimSpace(captchaKey) == "" || strings.TrimSpace(identCode) == "" {
+				return "缺失参数"
+			}
+			captchaPhone := jy.CheckPhoneIdent(l.Session(), identCode, sendCodeKey)
+			if phone != captchaPhone { //验证码不正确
+				return "验证码错误"
 			}
-			l.SetSession("registerStep", "2")
+			//if l.GetSession("identCodeValue") == nil || l.GetString("identCode") != l.GetSession("identCodeValue") { //验证码不正确
+			//	return "identCodeError"
+			//}
+			l.SetSession("registerStep", phone)
 			return "y"
 		} else if reqType == "save" {
-			phone, _ := l.GetSession("identCodeKey").(string)
+			phone, _ := l.GetSession("registerStep").(string)
 			if phone == "" {
 				return "timeout"
 			}
@@ -831,6 +909,7 @@ func (l *Login) WxLogin() {
 				"s_platform": "app",                                                               //用户注册平台 app 微信 pc
 				"s_jyname":   jy.GetUserName("newother", config.Sysconfig["namePrefix"].(string)), //剑鱼昵称
 				"s_sourceid": channelCode,
+				"s_rsource":  channelCode,
 			}
 			sourceLabel := redis.GetStr("limitation", fmt.Sprintf("firstVisitTagByWX_%s", l.Session().Id()))
 			if sourceLabel != "" {
@@ -859,7 +938,7 @@ func (l *Login) WxLogin() {
 
 			if _id := mongodb.Save("user", newUser); _id != "" {
 				log.Println(222, _id, "", "wx", "app", isAndroidOrIOS(l.Header("User-Agent")), "", isAndroidOrIOS(l.Header("User-Agent")), sourceLabel, "", l.Header("User-Agent"), gconv.String(qutil.If(isAndroidOrIOS(l.Header("User-Agent")) == "jyzbw", "jyzbw", "jybx")), "")
-				jy.SaveUserLog(public.Mgo_Log, _id, "", "wx", "app", isAndroidOrIOS(l.Header("User-Agent")), "", isAndroidOrIOS(l.Header("User-Agent")), sourceLabel, "", l.Header("User-Agent"), gconv.String(qutil.If(isAndroidOrIOS(l.Header("User-Agent")) == "jyzbw", "jyzbw", "jybx")), "")
+				go jy.SaveUserLog(public.Mgo_Log, _id, "", "wx", "app", isAndroidOrIOS(l.Header("User-Agent")), "", isAndroidOrIOS(l.Header("User-Agent")), sourceLabel, "", l.Header("User-Agent"), gconv.String(qutil.If(isAndroidOrIOS(l.Header("User-Agent")) == "jyzbw", "jyzbw", "jybx")), "")
 				if sourceLabel != "" {
 					go func() {
 						redis.Del("limitation", fmt.Sprintf("firstVisitTagByWX_%s", l.Session().Id()))
@@ -934,9 +1013,11 @@ func (l *Login) WxLogin() {
 // ForgetPwd 修改登录密码
 func (l *Login) ForgetPwd() error {
 	defer qutil.Catch()
+	log.Println(l.Method(), "--手机号:", l.GetSession("forgetPwdPhone"), "----forgetPwdStep-----", l.GetSession("forgetPwdStep"), "---step--", l.GetString("step"))
 	if l.Method() == "GET" {
 		if l.GetString("step") == "2" {
 			if l.GetSession("forgetPwdStep") == "2" {
+				log.Println("===================================================")
 				return l.Render("/me/forgetPwdTwo.html")
 			}
 		}
@@ -950,9 +1031,9 @@ func (l *Login) ForgetPwd() error {
 			if !phoneReg.MatchString(phone) {
 				return "phoneError"
 			}
-			if tmp := l.GetSession("CheckCodeId"); tmp == nil || !captcha.VerifyString(tmp.(string), l.GetString("code")) {
-				return "codeError"
-			}
+			//if tmp := l.GetSession("CheckCodeId"); tmp == nil || !captcha.VerifyString(tmp.(string), l.GetString("code")) {
+			//	return "codeError"
+			//}
 			//手机号是否已被注册
 			if mongodb.Count("user", map[string]interface{}{
 				"i_appid": 2,
@@ -961,17 +1042,29 @@ func (l *Login) ForgetPwd() error {
 					{"s_m_phone": phone}},
 			}) == 0 {
 				return "phoneNotExists"
-			} else if jy.SendPhoneIdentCode(qutil.ObjToString(config.Sysconfig["smsServiceRpc"]), phone, l.Session()) {
-				return "y"
+				//} else if jy.SendPhoneIdentCode(l.Request, qutil.ObjToString(config.Sysconfig["smsServiceRpc"]), phone, l.Session()) {
+				//	return "y"
 			}
 		} else if reqType == "nextStep" {
-			if l.GetSession("identCodeValue") == nil || l.GetString("identCode") != l.GetSession("identCodeValue") { //验证码不正确
-				return "identCodeError"
+			phone := l.GetString("phone")           //手机号参数
+			captchaKey := l.GetString("captchaKey") //图形验证码key
+			identCode := l.GetString("identCode")   //短信验证码
+			sendCodeKey := fmt.Sprintf(captcha.SendCodeKey, captchaKey, phone)
+			if strings.TrimSpace(phone) == "" || strings.TrimSpace(captchaKey) == "" || strings.TrimSpace(identCode) == "" {
+				return "缺失参数"
+			}
+			captchaPhone := jy.CheckPhoneIdent(l.Session(), identCode, sendCodeKey)
+			if phone != captchaPhone { //验证码不正确
+				return "验证码错误"
 			}
+			//if l.GetSession("identCodeValue") == nil || l.GetString("identCode") != l.GetSession("identCodeValue") { //验证码不正确
+			//	return "identCodeError"
+			//}
 			l.SetSession("forgetPwdStep", "2")
+			l.SetSession("forgetPwdPhone", phone)
 			return "y"
 		} else if reqType == "save" {
-			phone, _ := l.GetSession("identCodeKey").(string)
+			phone, _ := l.GetSession("forgetPwdPhone").(string)
 			if phone == "" {
 				return "timeout"
 			}
@@ -983,7 +1076,7 @@ func (l *Login) ForgetPwd() error {
 			if !ok || user == nil || len(user) == 0 { //用户不存在
 				return "userNotExists"
 			}
-			if utils.Compatible.Update(qutil.InterfaceToStr(user["_id"]), map[string]interface{}{
+			if utils.Compatible.Update(qutil.InterfaceToStr(user[0]["_id"]), map[string]interface{}{
 				"$set": map[string]interface{}{
 					"s_phone":         phone,
 					"s_password":      qutil.GetMd5String(password),
@@ -992,6 +1085,7 @@ func (l *Login) ForgetPwd() error {
 				"$unset": map[string]interface{}{
 					"s_m_phone": "",
 				}}) {
+				l.DelSession("forgetPwdPhone")
 				l.DelSession("forgetPwdStep")
 				jy.ClearPhoneIdentSession(l.Session())
 				func(userid string) {
@@ -1000,7 +1094,7 @@ func (l *Login) ForgetPwd() error {
 					if uinfo := jy.GetInfoForBaseUser(mongodb, userid); uinfo != nil {
 						jy.UpdateUser(mongodb, userid, *uinfo, *config.Middleground)
 					}
-				}(BsonIdToSId(user["_id"]))
+				}(BsonIdToSId(user[0]["_id"]))
 				return "y"
 			}
 			return "saveError"
@@ -1159,7 +1253,7 @@ func (l *Login) SetPwd() {
 /**********************************************************************
 ***********************************************************************
 ***********************************************************************/
-func getPhoneUser(phone string) (bool, map[string]interface{}) {
+func getPhoneUser(phone string) (bool, []map[string]interface{}) {
 	users, ok := mongodb.Find("user", map[string]interface{}{
 		"i_appid": 2,
 		"$or": []map[string]interface{}{
@@ -1167,7 +1261,7 @@ func getPhoneUser(phone string) (bool, map[string]interface{}) {
 			{"s_m_phone": phone}},
 	}, `{"s_phone":-1}`, nil, false, 0, 1)
 	if users != nil && len(*users) > 0 {
-		return ok, (*users)[0]
+		return ok, *users
 	}
 	return ok, nil
 }

+ 18 - 19
src/jfw/modules/app/src/app/front/me.go

@@ -209,7 +209,6 @@ func (l *Me) Updatepwd() error {
 	return nil
 }
 
-//
 func (l *Me) CheckUpdate() error {
 	defer qutil.Catch()
 	channel := l.GetString("channel")
@@ -278,22 +277,25 @@ func (l *Me) CheckUpdate() error {
 
 /*
 触发下面这4种事件后,需要请求下服务端接口,保存日志:
-    1、弹出更新提示对话框(event:client_tip)
-    2、点击取消(event:client_cancel)
-    3、点击去更新(event:client_update)
-    4、内部更新失败后,浏览器更新(event:client_outside)
-    5、下载成功(event:client_download_success)
-    6、下载失败(event:client_download_fail)
+
+	1、弹出更新提示对话框(event:client_tip)
+	2、点击取消(event:client_cancel)
+	3、点击去更新(event:client_update)
+	4、内部更新失败后,浏览器更新(event:client_outside)
+	5、下载成功(event:client_download_success)
+	6、下载失败(event:client_download_fail)
+
 接口地址:/jyapp/free/newVersionUpdateLog
 参数:
-    token           //用户token
-    event            //事件类型
-    current_version //当前版本号
-    new_version     //新版本号
-    channel         //渠道
-    phonetype       //手机型号
-    system          //系统版本
-    error           //下载失败的异常信息
+
+	token           //用户token
+	event            //事件类型
+	current_version //当前版本号
+	new_version     //新版本号
+	channel         //渠道
+	phonetype       //手机型号
+	system          //系统版本
+	error           //下载失败的异常信息
 */
 func (l *Me) NewVersionUpdateLog() {
 	u, s := analySign("", l.GetString("token"))
@@ -304,7 +306,7 @@ func (l *Me) NewVersionUpdateLog() {
 	if l.GetString("event") == "server_tip" && userId != "" {
 		redis.Del(ClientUpdate.RedisCode, "app_clientupdate_"+userId)
 	}
-	public.Mgo_Log.Save("jyapp_newversion_updatelog", map[string]interface{}{
+	go public.Mgo_Log.Save("jyapp_newversion_updatelog", map[string]interface{}{
 		"createtime":      time.Now().Unix(),
 		"userid":          userId,
 		"event":           l.GetString("event"),
@@ -321,7 +323,6 @@ func (l *Me) NewVersionUpdateLog() {
 	l.ServeJson(map[string]interface{}{})
 }
 
-//
 func (l *Me) MyInfo() {
 	r := map[string]interface{}{
 		"userType": "free",
@@ -395,7 +396,6 @@ func (l *Me) MyInfo() {
 	l.ServeJson(r)
 }
 
-//
 func (l *Me) AccountSafe() error {
 	return l.Render("/me/account.html")
 }
@@ -422,7 +422,6 @@ func (l *Me) GetAccountInfo() {
 	return
 }
 
-//
 func (l *Me) ControlGrayUpdate(t string) {
 	if l.GetString("pwd") != "lHJ5agM3eiKczOPk3IVj" {
 		l.Write("密码错误!")

+ 7 - 0
src/jfw/modules/app/src/app/front/shorturl.go

@@ -924,6 +924,13 @@ func (s *Short) TransitRoute(key string) error {
 				redirectUrl = util.ObjToString(shortUrl["href"])
 			}
 		}
+
+		//未登录
+		if userId, _ := s.GetSession("userId").(string); userId == "" {
+			jy.SetCookieValue(s.ResponseWriter, jy.ChannelCookieName, key, cacheTimeOut)                      //三天
+			redis.Put("limitation", fmt.Sprintf("firstVisitTagByWX_%s", s.Session().Id()), key, cacheTimeOut) //登录注册 用户标识
+			return s.Redirect(redirectUrl)
+		}
 	}
 	return s.Redirect(redirectUrl)
 }

+ 27 - 19
src/jfw/modules/app/src/app/front/swordfish.go

@@ -1,6 +1,13 @@
 package front
 
 import (
+	util "app.yhyue.com/moapp/jybase/common"
+	. "app.yhyue.com/moapp/jybase/date"
+	"app.yhyue.com/moapp/jybase/encrypt"
+	. "app.yhyue.com/moapp/jybase/mongodb"
+	"app.yhyue.com/moapp/jybase/redis"
+	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
+	"app.yhyue.com/moapp/jypkg/public"
 	"fmt"
 	_ "jy/src/jfw/modules/app/src/app/filter"
 	. "jy/src/jfw/modules/app/src/app/jyutil"
@@ -11,15 +18,6 @@ import (
 	"strings"
 	"time"
 
-	. "app.yhyue.com/moapp/jybase/date"
-
-	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"
-	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
-	"app.yhyue.com/moapp/jypkg/public"
-
 	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/bidsearch"
 
 	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
@@ -133,10 +131,12 @@ func (m *Front) AjaxReq() error {
 			o_jy, _ := (*r)["o_jy"].(map[string]interface{})
 			a_key, _ := o_jy["a_key"].([]interface{})
 			keysArray := processKeyword(m.GetString("keys"))
-			if keysArray == nil {
+			if keysArray == nil || len(keysArray) > 10 {
 				break
 			}
-			var isExists bool
+			saveKey := []bson.M{}
+			//var isExists bool
+			existKeyMap := map[string]struct{}{}
 			for _, v := range a_key {
 				//count := 0
 				//for _, kay := range keysArray {
@@ -146,24 +146,32 @@ func (m *Front) AjaxReq() error {
 				for _, ky := range key {
 					kystr = kystr + " " + ky.(string)
 				}
-				if strings.TrimSpace(m.GetString("keys")) == strings.TrimSpace(kystr) {
-					isExists = true
-					flag = "y"
+				existKeyMap[strings.TrimSpace(kystr)] = struct{}{}
+				//if strings.TrimSpace(m.GetString("keys")) == strings.TrimSpace(kystr) {
+				//	isExists = true
+				//	flag = "y"
+				//	break
+				//}
+			}
+			for i := 0; i < len(keysArray); i++ {
+				if len(saveKey)+len(a_key) >= 10 {
 					break
 				}
+				if _, ok := existKeyMap[keysArray[i]]; !ok {
+					saveKey = append(saveKey, bson.M{"key": []string{keysArray[i]}, "notkey": []string{}, "from": 1})
+				}
 			}
 			positionType := util.Int64All(m.GetSession("positionType"))
 			//如果不存在
 			ok := false
-			if !isExists {
+			if len(saveKey) > 0 {
 				if len(a_key) >= 10 {
 					flag = "o"
 				} else {
-
 					if positionType == 0 {
 						ok = mongodb.UpdateById("user", userid,
 							bson.M{
-								"$push": bson.M{"o_jy.a_key": bson.M{"key": keysArray, "area": []string{}, "infotype": []string{}, "notkey": []string{}, "from": 1}},
+								"$push": bson.M{"o_jy.a_key": bson.M{"$each": saveKey}},
 								"$set":  bson.M{"i_ts_guide": 1, "o_jy.l_modifydate": time.Now().Unix()},
 							})
 					} else {
@@ -173,7 +181,7 @@ func (m *Front) AjaxReq() error {
 							"i_type":   2,
 						}
 						if mongodb.Update("entniche_rule", query, bson.M{
-							"$push": bson.M{"o_entniche.a_key": bson.M{"key": keysArray, "area": []string{}, "infotype": []string{}, "notkey": []string{}, "from": 1}},
+							"$push": bson.M{"o_entniche.a_key": bson.M{"$each": saveKey}},
 							"$set":  bson.M{"i_ts_guide": 1, "o_entniche.l_modifydate": time.Now().Unix()},
 						}, true, false) {
 							ok = true
@@ -196,7 +204,7 @@ func (m *Front) AjaxReq() error {
 					"i_type":   2,
 				}
 				if mongodb.Update("entniche_rule", query, bson.M{
-					"$push": bson.M{"o_entniche.a_key": bson.M{"key": keysArray, "area": []string{}, "infotype": []string{}, "notkey": []string{}, "from": 1}},
+					"$push": bson.M{"o_entniche.a_key": bson.M{"$each": saveKey}},
 					"$set":  bson.M{"i_ts_guide": 1, "o_entniche.l_modifydate": time.Now().Unix()},
 				}, true, false) {
 					flag = "y"

+ 2 - 3
src/jfw/modules/app/src/app/front/vipsubscribe.go

@@ -127,9 +127,8 @@ func (s *Subscribepay) ToSetPage() {
 	//	s.Redirect("/jyapp/big/page/init") //跳转至首次初始化页面
 	//	return
 	//}
-	//仅免费用户跳转向导页面
-	if bigBaseMsg.Status <= 0 && bigBaseMsg.VipStatus <= 0 && isInTSguide(userid, s.Session()) {
-		s.Redirect("/jyapp/tenderSubscribe/guide?url=" + url.QueryEscape(s.Request.RequestURI))
+	if isInTSguide(userid, s.Session()) {
+		s.Redirect("/jy_mobile/subscribe/guide?url=" + url.QueryEscape(s.Request.RequestURI))
 	}
 	s.Render("/vipsubscribe/vip_index_new.html")
 }

+ 3 - 0
src/jfw/modules/app/src/app/front/ws_dataExport.go

@@ -67,10 +67,12 @@ func (w *WsDataExport) GetPreview() error {
 	//从500条数据中筛选字段最全五条
 	scd := dataexport.GetSqlObjFromId(public.MQFW, _id)
 	kws := scd.Keyword
+	tm := time.Now()
 	res, err := dataexport.GetDataExportSearchResult(public.Mgo_Bidding, public.DbConf.Mongodb.Bidding.DbName, public.DbConf.Elasticsearch.Main.Address, scd, dataType, -1)
 	if res == nil || err != nil {
 		return w.Render("/pc/dataExport_noDataErr.html", &w.T)
 	}
+	log.Println(fmt.Sprintf("id:%s 查询耗时:%s", _id, time.Now().Sub(tm)))
 	msgCount := dataexport.GetDataExportSearchCountByScdId(public.MQFW, public.Mgo_Bidding, public.DbConf.Mongodb.Bidding.DbName, public.DbConf.Elasticsearch.Main.Address, _id)
 	//格式化字段
 	res_screen := dataexport.ScreenData(res, dataType, 20, kws)
@@ -84,6 +86,7 @@ func (w *WsDataExport) GetPreview() error {
 		}
 	}
 	list := dataexport.FormatExportData(public.Mgo_Ent, &res_screen, config.Sysconfig["webdomain"].(string), dataType, true)
+	log.Println(fmt.Sprintf("id:%s 格式划耗时:%s", _id, time.Now().Sub(tm)))
 	//if msgCount > 20000 {
 	//	msgCount = 20000
 	//}

+ 19 - 2
src/jfw/modules/app/src/app/front/wx.go

@@ -1,10 +1,12 @@
 package front
 
 import (
+	util "app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/encrypt"
 	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
 	"app.yhyue.com/moapp/jybase/redis"
 	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
+	"app.yhyue.com/moapp/jypkg/public"
 	"fmt"
 	"jy/src/jfw/modules/app/src/jfw/config"
 	. "jy/src/jfw/modules/app/src/public"
@@ -57,12 +59,27 @@ func (w *WX) Index(pageLabel string) error {
 	if bm := mobileReg.MatchString(w.Header("User-Agent")); !bm {
 		return w.Redirect(fmt.Sprintf("%s/partner/%s", config.Sysconfig["mainDomainName"].(string), pageLabel))
 	}
+	var (
+		shortInfos = public.Mysql.SelectBySql(`SELECT * FROM short_url WHERE mold = 1 AND code = ?`, pageLabel)
+		noLoginUrl = fmt.Sprintf("/jyapp/jylab/mainSearch?partner=%s", pageLabel)
+		loginUrl   = fmt.Sprintf("/jy_mobile/tabbar/home?partner=%s", pageLabel)
+	)
+	if shortInfos != nil && len(*shortInfos) > 0 {
+		shortInfo := (*shortInfos)[0]
+		loginUrl = util.ObjToString(shortInfo["url"])    //已登录用
+		noLoginUrl = util.ObjToString(shortInfo["href"]) //未登录
+		go func(pageLabel string) {
+			if ui := public.Mysql.UpdateOrDeleteBySql(`update short_url SET visits=visits+1 WHERE mold = 1 AND code = ?;`, pageLabel); ui <= 0 {
+				log.Println("update short_url visits false ,source:", pageLabel)
+			}
+		}(pageLabel)
+	}
 	//未登录
 	if userId, _ := w.GetSession("userId").(string); userId == "" {
 		jy.SetCookieValue(w.ResponseWriter, jy.ChannelCookieName, pageLabel, cacheTimeOut)
 		redis.Put("limitation", fmt.Sprintf("firstVisitTagByWX_%s", w.Session().Id()), pageLabel, cacheTimeOut) //app 登录注册 用户标识
-		return w.Redirect("/jyapp/jylab/mainSearch?partner=" + pageLabel)
+		return w.Redirect(noLoginUrl)
 	}
 	//已登录
-	return w.Redirect("/jy_mobile/tabbar/home?partner=" + pageLabel)
+	return w.Redirect(loginUrl)
 }

+ 305 - 305
src/jfw/modules/app/src/app/front/wxkeyset.go

@@ -2,333 +2,333 @@
 package front
 
 import (
-    "fmt"
-    . "jy/src/jfw/modules/app/src/app/jyutil"
-    utils "jy/src/jfw/modules/app/src/app/jyutil"
-    "jy/src/jfw/modules/app/src/jfw/config"
-    "net/url"
-    "regexp"
-    "strconv"
-    "strings"
+	"fmt"
+	. "jy/src/jfw/modules/app/src/app/jyutil"
+	utils "jy/src/jfw/modules/app/src/app/jyutil"
+	"jy/src/jfw/modules/app/src/jfw/config"
+	"net/url"
+	"regexp"
+	"strconv"
+	"strings"
 
-    util "app.yhyue.com/moapp/jybase/common"
-    . "app.yhyue.com/moapp/jybase/date"
-    "app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
-    //	"sync"
-    "time"
+	util "app.yhyue.com/moapp/jybase/common"
+	. "app.yhyue.com/moapp/jybase/date"
+	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
+	//	"sync"
+	"time"
 )
 
 // WxKeyset 进入订阅词设置
 func (m *Front) WxKeyset(tpl string) error {
-    defer util.Catch()
-    userid := util.ObjToString(m.GetSession("userId"))
-    surprise := m.GetSession("surprise")
-    if tpl == "index" && isInTSguide(userid, m.Session()) { //仅免费用户跳转向导页面
-        return m.Redirect("/jyapp/tenderSubscribe/guide?url=" + url.QueryEscape(m.Request.RequestURI))
-    }
-    //到新订阅设置
-    vipMsg := jy.GetBigVipUserBaseMsg(m.Session(), *config.Middleground)
-    if vipMsg.IsUpgrade {
-        return m.Redirect("/jyapp/vipsubscribe/toSubVipSetPage")
-    }
-    if tpl == "seniorset" {
-        data := utils.Compatible.Select(userid, `{"o_jy":1}`)
-        if data != nil && len(*data) > 0 {
-            o_jy, _ := (*data)["o_jy"].(map[string]interface{})
-            a_key, _ := o_jy["a_key"].([]interface{})
-            if len(a_key) > 0 {
-                m.T["haskeyword"] = true
-            }
-        }
+	defer util.Catch()
+	userid := util.ObjToString(m.GetSession("userId"))
+	surprise := m.GetSession("surprise")
+	if tpl == "index" && isInTSguide(userid, m.Session()) {
+		return m.Redirect("/jy_mobile/subscribe/guide?url=" + url.QueryEscape(m.Request.RequestURI))
+	}
+	//到新订阅设置
+	vipMsg := jy.GetBigVipUserBaseMsg(m.Session(), *config.Middleground)
+	if vipMsg.IsUpgrade {
+		return m.Redirect("/jyapp/vipsubscribe/toSubVipSetPage")
+	}
+	if tpl == "seniorset" {
+		data := utils.Compatible.Select(userid, `{"o_jy":1}`)
+		if data != nil && len(*data) > 0 {
+			o_jy, _ := (*data)["o_jy"].(map[string]interface{})
+			a_key, _ := o_jy["a_key"].([]interface{})
+			if len(a_key) > 0 {
+				m.T["haskeyword"] = true
+			}
+		}
 
-    }
-    userId, _ := m.GetSession("userId").(string)
-    s_surprise := ""
-    if tpl == "index" || tpl == "filterset" {
-        data := utils.Compatible.Select(userId, `{"o_jy":1}`)
-        var o_jy map[string]interface{}
-        if data != nil && len(*data) > 0 {
-            o_jy, _ = (*data)["o_jy"].(map[string]interface{})
-            s_surprise = util.ObjToString(o_jy["s_surprise"])
-        }
-    }
-    m.T["s_surprise"] = s_surprise
-    m.T["surprise"] = surprise
-    if tpl == "index" {
-        m.T["isIosExam"], m.T["isIosExamPhone"], _, _ = IosExamInfo(m.Action, false, false)
-    }
-    return m.Render("/weixin/wxkeyset/"+tpl+".html", &m.T)
+	}
+	userId, _ := m.GetSession("userId").(string)
+	s_surprise := ""
+	if tpl == "index" || tpl == "filterset" {
+		data := utils.Compatible.Select(userId, `{"o_jy":1}`)
+		var o_jy map[string]interface{}
+		if data != nil && len(*data) > 0 {
+			o_jy, _ = (*data)["o_jy"].(map[string]interface{})
+			s_surprise = util.ObjToString(o_jy["s_surprise"])
+		}
+	}
+	m.T["s_surprise"] = s_surprise
+	m.T["surprise"] = surprise
+	if tpl == "index" {
+		m.T["isIosExam"], m.T["isIosExamPhone"], _, _ = IosExamInfo(m.Action, false, false)
+	}
+	return m.Render("/weixin/wxkeyset/"+tpl+".html", &m.T)
 }
 
-//ajax各种请求
+// ajax各种请求
 func (m *Front) WxKeysetAjaxReq() {
-    defer util.Catch()
-    userId, _ := m.GetSession("userId").(string)
-    if userId == "" {
-        m.ServeJson(map[string]interface{}{
-            "flag": false,
-        })
-        return
-    }
-    //增加锁,防止map读写
-    //	lock, _ := m.Session().Get("Lock").(*sync.Mutex)
-    //	lock.Lock()
-    //	defer lock.Unlock()
-    reqType := m.GetString("reqType")
-    if reqType == "getKeyset" { //获取高级设置
-        data := utils.Compatible.Select(userId, `{"o_jy":1,"l_registedate":1}`)
-        var o_jy map[string]interface{}
-        if data != nil && len(*data) > 0 {
-            o_jy, _ = (*data)["o_jy"].(map[string]interface{})
-            o_jy["i_new"] = NewUserByVIP(data)
-            a_key, _ := o_jy["a_key"].([]interface{})
-            m.SetSession("o_jy_a_key", a_key)
-        }
-        m.ServeJson(o_jy)
-        return
-    }
-    /*******************以下是修改操作******************/
-    index := ""
-    saveData := make(map[string]interface{})
-    if reqType == "saveKeyWords" { //保存关键词
-        a_key, _ := m.GetSession("o_jy_a_key").([]interface{})
-        keyWords := m.GetSlice("keyWords")
-        indexs := m.GetSlice("indexs")
-        var keyMaps []map[string]interface{}
-        //给删除的关键词加上标识
-        a_keycopy := make([]map[string]interface{}, len(a_key))
-        //复制
-        for k, v := range a_key {
-            key := v.(map[string]interface{})
-            keycopy := map[string]interface{}{}
-            for k1, v1 := range key {
-                keycopy[k1] = v1
-            }
-            isExists := false
-            for _, i := range indexs {
-                if k == util.IntAll(i) {
-                    isExists = true
-                    break
-                }
-            }
-            //isExists =false已经被删除
-            keycopy["flag"] = !isExists
-            a_keycopy[k] = keycopy
-        }
-        for k, v := range keyWords {
-            if strings.Trim(v, " ") == "" {
-                continue
-            }
-            if k >= 10 {
-                break
-            }
-            index := util.IntAll(indexs[k])
-            key := map[string]interface{}{}
-            if index < len(a_keycopy) {
-                key = a_keycopy[index]
-                flag, _ := key["flag"].(bool)
-                if flag {
-                    key = map[string]interface{}{}
-                } else {
-                    delete(key, "flag")
-                }
-            }
-            keys := processKeyword(v)
-            if keys != nil {
-                key["key"] = keys
-                if len(key) > 0 {
-                    keyMaps = append(keyMaps, key)
-                }
-            }
-        }
-        saveData["o_jy.a_key"] = keyMaps
-    } else if reqType == "saveArea" { //保存信息范围
-        index = m.GetString("index")
-        saveData["o_jy.a_key."+index+".area"] = m.GetSlice("area")
-    } else if reqType == "saveInfotype" { //保存信息类型
-        index = m.GetString("index")
-        saveData["o_jy.a_key."+index+".infotype"] = m.GetSlice("infotype")
-    } else if reqType == "saveNotkey" { //保存排除关键词
-        index = m.GetString("index")
-        notkey := m.GetSlice("notkey")
-        if len(notkey) > 10 {
-            notkey = notkey[0:10]
-        }
-        for k, v := range notkey {
-            notkey[k] = strings.Replace(v, " ", "", -1)
-        }
-        saveData["o_jy.a_key."+index+".notkey"] = notkey
-    } else if reqType == "saveSeniorset" { //保存高级设置
-        //推送频率:1实时 2每日一推 3自定义时间
-        ratemode, _ := m.GetInteger("ratemode")
-        if ratemode != 2 && ratemode != 3 {
-            ratemode = 1
-        }
-        saveData["o_jy.i_ratemode"] = ratemode
-        apppush, _ := m.GetInteger("apppush")
-        mailpush, _ := m.GetInteger("mailpush")
-        if apppush == 0 && mailpush == 0 {
-            apppush = 1
-        }
-        if ratemode == 3 {
-            saveData["o_jy.i_rmstart"], _ = m.GetInteger("rmstart")
-            saveData["o_jy.i_rmend"], _ = m.GetInteger("rmend")
-        }
-        saveData["o_jy.s_email"] = strings.Trim(m.GetString("email"), " ")
-        saveData["o_jy.i_apppush"] = apppush
-        saveData["o_jy.i_mailpush"] = mailpush
-    } else if reqType == "delKeysWord" { //
-        index = m.GetString("index")
-        var keyMaps = []map[string]interface{}{}
-        a_key, _ := m.GetSession("o_jy_a_key").([]interface{})
-        for k, v := range a_key {
-            if k != util.IntAll(index) {
-                keyMaps = append(keyMaps, v.(map[string]interface{}))
-            }
-        }
-        saveData["o_jy.a_key"] = keyMaps
-    } else if reqType == "setSurp" {
-        saveData["o_jy.s_surprise"] = "A"
-        m.SetSession("surprise", "A")
-    } else if reqType == "saveKeyWordsNew" { //保存 or 修改 整个订阅词接口
-        index = m.GetString("index")
-        indexInt := util.IntAll(index)
-        area := m.GetSlice("area")
-        infotype := m.GetSlice("infotype")
-        notkey := m.GetSlice("notkey")
-        keyWords := m.GetString("keyWords")
-        a_key, a_key_ok := m.GetSession("o_jy_a_key").([]interface{})
-        if len(notkey) > 10 {
-            notkey = notkey[0:10]
-        }
-        for k, v := range notkey {
-            notkey[k] = strings.Replace(v, " ", "", -1)
-        }
-        keys := processKeyword(keyWords)
-        if keys == nil || indexInt >= 10 {
-            m.ServeJson(map[string]interface{}{
-                "flag": false,
-            })
-            return
-        }
-        saveKey := map[string]interface{}{
-            "key":      []string{keys[0]},
-            "area":     fliterEmptyArr(area),
-            "notkey":   fliterEmptyArr(notkey),
-            "infotype": fliterEmptyArr(infotype),
-        }
-        var optime time.Time
-        var regtime int64
-        if rd := utils.Compatible.Select(userId, `{"o_jy":1,"l_registedate":1}`); rd != nil && len(*rd) > 0 {
-            //获取活动上线时间
-            optimalTime, _ := config.Sysconfig["optimalTime"].(string)
-            optime, _ = time.ParseInLocation(Date_Full_Layout, optimalTime, time.Local)
-            regtime, _ = (*rd)["l_registedate"].(int64)
-            if ojy, _ := (*rd)["o_jy"].(map[string]interface{}); len(ojy) > 0 {
-                if ojy["i_new"] == nil {
-                    if time.Unix(regtime, 0).After(optime) {
-                        saveData["o_jy.i_new"] = 1
-                    } else {
-                        saveData["o_jy.i_new"] = 0
-                    }
-                }
-                if ojy["a_key"] != nil {
-                    ak, _ := ojy["a_key"].([]interface{})
-                    if len(ak) > indexInt {
-                        if akmap, _ := ak[indexInt].(map[string]interface{}); akmap["from"] != nil {
-                            saveKey["from"] = akmap["from"]
-                        }
-                    }
-                }
-            }
-        }
-        if !a_key_ok && indexInt == 0 { //第一次新增
-            index = ""
-            saveData["o_jy.a_key"] = []map[string]interface{}{saveKey}
-            if time.Unix(regtime, 0).Before(optime) {
-                saveData["o_jy.i_new"] = 1
-            }
-        } else { //修改新增
-            if indexInt > len(a_key) {
-                indexInt = len(a_key)
-            }
-            saveData[fmt.Sprintf("o_jy.a_key.%d", indexInt)] = saveKey
-        }
-    }
-    //修改操作
-    var flag bool
-    if len(saveData) > 0 {
-        saveData["o_jy.l_modifydate"] = time.Now().Unix()
-        if index == "" {
-            flag = utils.Compatible.Update(userId, map[string]interface{}{
-                "$set": saveData,
-            })
-        } else {
-            if intIndex, e := strconv.Atoi(index); e == nil && intIndex >= 0 && intIndex < 10 {
-                flag = utils.Compatible.Update(userId, map[string]interface{}{
-                    "$set": saveData,
-                })
-            }
-        }
-    }
-    m.ServeJson(map[string]interface{}{
-        "flag": flag,
-    })
-    return
+	defer util.Catch()
+	userId, _ := m.GetSession("userId").(string)
+	if userId == "" {
+		m.ServeJson(map[string]interface{}{
+			"flag": false,
+		})
+		return
+	}
+	//增加锁,防止map读写
+	//	lock, _ := m.Session().Get("Lock").(*sync.Mutex)
+	//	lock.Lock()
+	//	defer lock.Unlock()
+	reqType := m.GetString("reqType")
+	if reqType == "getKeyset" { //获取高级设置
+		data := utils.Compatible.Select(userId, `{"o_jy":1,"l_registedate":1}`)
+		var o_jy map[string]interface{}
+		if data != nil && len(*data) > 0 {
+			o_jy, _ = (*data)["o_jy"].(map[string]interface{})
+			o_jy["i_new"] = NewUserByVIP(data)
+			a_key, _ := o_jy["a_key"].([]interface{})
+			m.SetSession("o_jy_a_key", a_key)
+		}
+		m.ServeJson(o_jy)
+		return
+	}
+	/*******************以下是修改操作******************/
+	index := ""
+	saveData := make(map[string]interface{})
+	if reqType == "saveKeyWords" { //保存关键词
+		a_key, _ := m.GetSession("o_jy_a_key").([]interface{})
+		keyWords := m.GetSlice("keyWords")
+		indexs := m.GetSlice("indexs")
+		var keyMaps []map[string]interface{}
+		//给删除的关键词加上标识
+		a_keycopy := make([]map[string]interface{}, len(a_key))
+		//复制
+		for k, v := range a_key {
+			key := v.(map[string]interface{})
+			keycopy := map[string]interface{}{}
+			for k1, v1 := range key {
+				keycopy[k1] = v1
+			}
+			isExists := false
+			for _, i := range indexs {
+				if k == util.IntAll(i) {
+					isExists = true
+					break
+				}
+			}
+			//isExists =false已经被删除
+			keycopy["flag"] = !isExists
+			a_keycopy[k] = keycopy
+		}
+		for k, v := range keyWords {
+			if strings.Trim(v, " ") == "" {
+				continue
+			}
+			if k >= 10 {
+				break
+			}
+			index := util.IntAll(indexs[k])
+			key := map[string]interface{}{}
+			if index < len(a_keycopy) {
+				key = a_keycopy[index]
+				flag, _ := key["flag"].(bool)
+				if flag {
+					key = map[string]interface{}{}
+				} else {
+					delete(key, "flag")
+				}
+			}
+			keys := processKeyword(v)
+			if keys != nil {
+				key["key"] = keys
+				if len(key) > 0 {
+					keyMaps = append(keyMaps, key)
+				}
+			}
+		}
+		saveData["o_jy.a_key"] = keyMaps
+	} else if reqType == "saveArea" { //保存信息范围
+		index = m.GetString("index")
+		saveData["o_jy.a_key."+index+".area"] = m.GetSlice("area")
+	} else if reqType == "saveInfotype" { //保存信息类型
+		index = m.GetString("index")
+		saveData["o_jy.a_key."+index+".infotype"] = m.GetSlice("infotype")
+	} else if reqType == "saveNotkey" { //保存排除关键词
+		index = m.GetString("index")
+		notkey := m.GetSlice("notkey")
+		if len(notkey) > 10 {
+			notkey = notkey[0:10]
+		}
+		for k, v := range notkey {
+			notkey[k] = strings.Replace(v, " ", "", -1)
+		}
+		saveData["o_jy.a_key."+index+".notkey"] = notkey
+	} else if reqType == "saveSeniorset" { //保存高级设置
+		//推送频率:1实时 2每日一推 3自定义时间
+		ratemode, _ := m.GetInteger("ratemode")
+		if ratemode != 2 && ratemode != 3 {
+			ratemode = 1
+		}
+		saveData["o_jy.i_ratemode"] = ratemode
+		apppush, _ := m.GetInteger("apppush")
+		mailpush, _ := m.GetInteger("mailpush")
+		if apppush == 0 && mailpush == 0 {
+			apppush = 1
+		}
+		if ratemode == 3 {
+			saveData["o_jy.i_rmstart"], _ = m.GetInteger("rmstart")
+			saveData["o_jy.i_rmend"], _ = m.GetInteger("rmend")
+		}
+		saveData["o_jy.s_email"] = strings.Trim(m.GetString("email"), " ")
+		saveData["o_jy.i_apppush"] = apppush
+		saveData["o_jy.i_mailpush"] = mailpush
+	} else if reqType == "delKeysWord" { //
+		index = m.GetString("index")
+		var keyMaps = []map[string]interface{}{}
+		a_key, _ := m.GetSession("o_jy_a_key").([]interface{})
+		for k, v := range a_key {
+			if k != util.IntAll(index) {
+				keyMaps = append(keyMaps, v.(map[string]interface{}))
+			}
+		}
+		saveData["o_jy.a_key"] = keyMaps
+	} else if reqType == "setSurp" {
+		saveData["o_jy.s_surprise"] = "A"
+		m.SetSession("surprise", "A")
+	} else if reqType == "saveKeyWordsNew" { //保存 or 修改 整个订阅词接口
+		index = m.GetString("index")
+		indexInt := util.IntAll(index)
+		area := m.GetSlice("area")
+		infotype := m.GetSlice("infotype")
+		notkey := m.GetSlice("notkey")
+		keyWords := m.GetString("keyWords")
+		a_key, a_key_ok := m.GetSession("o_jy_a_key").([]interface{})
+		if len(notkey) > 10 {
+			notkey = notkey[0:10]
+		}
+		for k, v := range notkey {
+			notkey[k] = strings.Replace(v, " ", "", -1)
+		}
+		keys := processKeyword(keyWords)
+		if keys == nil || indexInt >= 10 {
+			m.ServeJson(map[string]interface{}{
+				"flag": false,
+			})
+			return
+		}
+		saveKey := map[string]interface{}{
+			"key":      []string{keys[0]},
+			"area":     fliterEmptyArr(area),
+			"notkey":   fliterEmptyArr(notkey),
+			"infotype": fliterEmptyArr(infotype),
+		}
+		var optime time.Time
+		var regtime int64
+		if rd := utils.Compatible.Select(userId, `{"o_jy":1,"l_registedate":1}`); rd != nil && len(*rd) > 0 {
+			//获取活动上线时间
+			optimalTime, _ := config.Sysconfig["optimalTime"].(string)
+			optime, _ = time.ParseInLocation(Date_Full_Layout, optimalTime, time.Local)
+			regtime, _ = (*rd)["l_registedate"].(int64)
+			if ojy, _ := (*rd)["o_jy"].(map[string]interface{}); len(ojy) > 0 {
+				if ojy["i_new"] == nil {
+					if time.Unix(regtime, 0).After(optime) {
+						saveData["o_jy.i_new"] = 1
+					} else {
+						saveData["o_jy.i_new"] = 0
+					}
+				}
+				if ojy["a_key"] != nil {
+					ak, _ := ojy["a_key"].([]interface{})
+					if len(ak) > indexInt {
+						if akmap, _ := ak[indexInt].(map[string]interface{}); akmap["from"] != nil {
+							saveKey["from"] = akmap["from"]
+						}
+					}
+				}
+			}
+		}
+		if !a_key_ok && indexInt == 0 { //第一次新增
+			index = ""
+			saveData["o_jy.a_key"] = []map[string]interface{}{saveKey}
+			if time.Unix(regtime, 0).Before(optime) {
+				saveData["o_jy.i_new"] = 1
+			}
+		} else { //修改新增
+			if indexInt > len(a_key) {
+				indexInt = len(a_key)
+			}
+			saveData[fmt.Sprintf("o_jy.a_key.%d", indexInt)] = saveKey
+		}
+	}
+	//修改操作
+	var flag bool
+	if len(saveData) > 0 {
+		saveData["o_jy.l_modifydate"] = time.Now().Unix()
+		if index == "" {
+			flag = utils.Compatible.Update(userId, map[string]interface{}{
+				"$set": saveData,
+			})
+		} else {
+			if intIndex, e := strconv.Atoi(index); e == nil && intIndex >= 0 && intIndex < 10 {
+				flag = utils.Compatible.Update(userId, map[string]interface{}{
+					"$set": saveData,
+				})
+			}
+		}
+	}
+	m.ServeJson(map[string]interface{}{
+		"flag": flag,
+	})
+	return
 }
 
-//过滤[""]数组
+// 过滤[""]数组
 func fliterEmptyArr(beforeArr []string) []string {
-    afterArr := []string{}
-    for _, v := range beforeArr {
-        if v == "" {
-            continue
-        }
-        afterArr = append(afterArr, v)
-    }
-    return afterArr
+	afterArr := []string{}
+	for _, v := range beforeArr {
+		if v == "" {
+			continue
+		}
+		afterArr = append(afterArr, v)
+	}
+	return afterArr
 }
 
-//高级设置
+// 高级设置
 func (m *Front) WxKeysetSeniorset() error {
-    return m.Render("/weixin/wxkeyset/seniorset.html")
+	return m.Render("/weixin/wxkeyset/seniorset.html")
 }
 
-//高级设置
+// 高级设置
 func (m *Front) WxKeysetFilterset() error {
-    return m.Render("/weixin/wxkeyset/filterset.html")
+	return m.Render("/weixin/wxkeyset/filterset.html")
 }
 
-//保存入库之前,处理订阅的关键词
+// 保存入库之前,处理订阅的关键词
 func processKeyword(keyword string) []string {
-    keywordReg := regexp.MustCompile("([\\s\u3000\u2003\u00a0+,,])+")
-    spaceReg := regexp.MustCompile("\\s+")
-    keyword = keywordReg.ReplaceAllString(keyword, " ")
-    keyword = spaceReg.ReplaceAllString(keyword, " ")
-    keyword = strings.Trim(keyword, " ")
-    if keyword == "" {
-        return nil
-    }
-    return strings.Split(keyword, " ")
+	keywordReg := regexp.MustCompile("([\\s\u3000\u2003\u00a0+,,])+")
+	spaceReg := regexp.MustCompile("\\s+")
+	keyword = keywordReg.ReplaceAllString(keyword, " ")
+	keyword = spaceReg.ReplaceAllString(keyword, " ")
+	keyword = strings.Trim(keyword, " ")
+	if keyword == "" {
+		return nil
+	}
+	return strings.Split(keyword, " ")
 }
 
-//超级订阅优化,免费订阅判断新老用户  1:新用户 0:老用户
+// 超级订阅优化,免费订阅判断新老用户  1:新用户 0:老用户
 func NewUserByVIP(mData *map[string]interface{}) int {
-    if len(*mData) == 0 || mData == nil {
-        return 1
-    }
-    ojy, _ := (*mData)["o_jy"].(map[string]interface{})
-    if len(ojy) > 0 {
-        if ojy["i_new"] != nil {
-            return util.IntAllDef(ojy["i_new"], 1)
-        }
-        optimalTime, _ := config.Sysconfig["optimalTime"].(string)
-        optime, _ := time.ParseInLocation(Date_Full_Layout, optimalTime, time.Local)
-        regtime, _ := (*mData)["l_registedate"].(int64)
-        //如果a_key 存在 即为老用户
-        if (ojy["a_key"] == nil && time.Unix(regtime, 0).Before(optime)) || (time.Unix(regtime, 0).After(optime)) {
-            return 1
-        }
-    }
-    return 0
+	if len(*mData) == 0 || mData == nil {
+		return 1
+	}
+	ojy, _ := (*mData)["o_jy"].(map[string]interface{})
+	if len(ojy) > 0 {
+		if ojy["i_new"] != nil {
+			return util.IntAllDef(ojy["i_new"], 1)
+		}
+		optimalTime, _ := config.Sysconfig["optimalTime"].(string)
+		optime, _ := time.ParseInLocation(Date_Full_Layout, optimalTime, time.Local)
+		regtime, _ := (*mData)["l_registedate"].(int64)
+		//如果a_key 存在 即为老用户
+		if (ojy["a_key"] == nil && time.Unix(regtime, 0).Before(optime)) || (time.Unix(regtime, 0).After(optime)) {
+			return 1
+		}
+	}
+	return 0
 }

+ 24 - 0
src/jfw/modules/app/src/app/jyutil/rpccall.go

@@ -1,10 +1,13 @@
 package jyutil
 
 import (
+	"context"
 	"jy/src/jfw/modules/app/src/jfw/config"
 	"log"
 	"net/rpc"
+
 	util "app.yhyue.com/moapp/jybase/common"
+	"github.com/gogf/gf/v2/frame/g"
 )
 
 var rpcserver string
@@ -30,3 +33,24 @@ func GetQrCodeFromWx(id string) string {
 	}, func(e interface{}) {})
 	return ret
 }
+
+func GetWxAccessToken(ctx context.Context, code string) string {
+	var repl string
+	client, err := rpc.DialHTTP("tcp", g.Config().MustGet(ctx, "wxTokenRpc").String())
+	if err != nil {
+		log.Println(code, err)
+		return repl
+	}
+	defer client.Close()
+	err = client.Call("WxTokenRpc.GetAccessToken", code, &repl)
+	if err != nil {
+		log.Println(code, err)
+		return repl
+	}
+	if repl == "" {
+		log.Println(code, "未获取到accessToken")
+	} else {
+		log.Println(code, "获取到accessToken", repl)
+	}
+	return repl
+}

+ 239 - 219
src/jfw/modules/app/src/app/jyutil/util.go

@@ -1,281 +1,301 @@
 package jyutil
 
 import (
-	util "app.yhyue.com/moapp/jybase/common"
-	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
-	"app.yhyue.com/moapp/jypkg/compatible"
-	"app.yhyue.com/moapp/jypkg/public"
-	"encoding/json"
-	. "jy/src/jfw/modules/app/src/jfw/config"
-	"net/http"
-	"reflect"
-	"regexp"
-	"sort"
-	"strconv"
-	"strings"
+    util "app.yhyue.com/moapp/jybase/common"
+    "app.yhyue.com/moapp/jybase/go-xweb/httpsession"
+    "app.yhyue.com/moapp/jypkg/compatible"
+    "app.yhyue.com/moapp/jypkg/public"
+    "encoding/json"
+    . "jy/src/jfw/modules/app/src/jfw/config"
+    "net/http"
+    "reflect"
+    "regexp"
+    "sort"
+    "strconv"
+    "strings"
 
-	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
-	"fmt"
-	"sync"
-	"time"
+    "app.yhyue.com/moapp/jybase/go-xweb/xweb"
+    "fmt"
+    "sync"
+    "time"
 )
 
 var Compatible = compatible.NewCompatible(&mongodb, public.BaseMysql, public.Mysql, Middleground)
 
 func init() {
-	VarOrderCode = &orderCode{
-		pool: make(chan string, 20),
-		all:  &sync.Map{},
-		lock: &sync.Mutex{},
-	}
-	VarOrderCode.gc()
-	for i := 0; i < 10; i++ {
-		go func() {
-			for {
-				o := fmt.Sprintf("%d%s", time.Now().Unix(), util.GetRandom(6))
-				VarOrderCode.lock.Lock()
-				if _, ok := VarOrderCode.all.Load(o); ok {
-					VarOrderCode.lock.Unlock()
-					continue
-				}
-				VarOrderCode.all.Store(o, time.Now().Day())
-				VarOrderCode.lock.Unlock()
-				VarOrderCode.pool <- o
-			}
-		}()
-	}
+    VarOrderCode = &orderCode{
+        pool: make(chan string, 20),
+        all:  &sync.Map{},
+        lock: &sync.Mutex{},
+    }
+    VarOrderCode.gc()
+    for i := 0; i < 10; i++ {
+        go func() {
+            for {
+                o := fmt.Sprintf("%d%s", time.Now().Unix(), util.GetRandom(6))
+                VarOrderCode.lock.Lock()
+                if _, ok := VarOrderCode.all.Load(o); ok {
+                    VarOrderCode.lock.Unlock()
+                    continue
+                }
+                VarOrderCode.all.Store(o, time.Now().Day())
+                VarOrderCode.lock.Unlock()
+                VarOrderCode.pool <- o
+            }
+        }()
+    }
 }
 
 // 生成订单号
 var VarOrderCode *orderCode
 
 type orderCode struct {
-	pool chan string
-	all  *sync.Map
-	lock *sync.Mutex
+    pool chan string
+    all  *sync.Map
+    lock *sync.Mutex
 }
 
 func (o *orderCode) gc() {
-	VarOrderCode.all.Range(func(key, value interface{}) bool {
-		if time.Now().Day() != value.(int) {
-			VarOrderCode.all.Delete(key)
-		}
-		return true
-	})
-	time.AfterFunc(24*time.Hour, o.gc)
+    VarOrderCode.all.Range(func(key, value interface{}) bool {
+        if time.Now().Day() != value.(int) {
+            VarOrderCode.all.Delete(key)
+        }
+        return true
+    })
+    time.AfterFunc(24*time.Hour, o.gc)
 }
 
 // 创建订单号
 func (o *orderCode) Get() string {
-	return <-VarOrderCode.pool
+    return <-VarOrderCode.pool
 }
 
 var IosReg = regexp.MustCompile(`\(i[^;]+;( U;)? CPU.+Mac OS X`)
 var IosIpadReg = regexp.MustCompile(`\(M[^;]+; Intel Mac OS X`)
 
 func IosExamInfo(a *xweb.Action, vip, ent bool) (bool, bool, bool, bool) {
-	if !IosReg.MatchString(a.Header("User-Agent")) && !IosIpadReg.MatchString(a.Header("User-Agent")) {
-		return false, false, false, false
-	}
-	iosExam, _ := Seoconfig["IosExam"].(map[string]interface{})
-	iosExam_flag, _ := iosExam["flag"].(bool)
-	//
-	iosExam_phone, _ := iosExam["phone"].(string)
-	isExamPhone := false
-	if phone, _ := a.GetSession("s_phone").(string); phone != "" && phone == iosExam_phone {
-		isExamPhone = true
-	}
-	//
-	isVip := false
-	isEnt := false
-	if iosExam_flag && (vip || ent) {
-		if userId, _ := a.GetSession("userId").(string); userId != "" {
-			user := Compatible.Select(userId, `{"i_vip_status":1,"s_phone":1,"s_m_phone":1}`)
-			if user != nil {
-				i_vip_status := util.IntAll((*user)["i_vip_status"])
-				isVip = i_vip_status == 1 || i_vip_status == 2
-			}
-			s_phone, _ := (*user)["s_phone"].(string)
-			if s_phone == "" {
-				s_phone, _ = (*user)["s_m_phone"].(string)
-			}
-			if ent && public.Mysql.CountBySql(`select count(1) as count from entniche_info where phone=? and status=1`, s_phone) > 0 {
-				isEnt = true
-			}
-		}
-	}
-	return iosExam_flag, isExamPhone, isVip, isEnt
+    if !IosReg.MatchString(a.Header("User-Agent")) && !IosIpadReg.MatchString(a.Header("User-Agent")) {
+        return false, false, false, false
+    }
+    iosExam, _ := Seoconfig["IosExam"].(map[string]interface{})
+    iosExam_flag, _ := iosExam["flag"].(bool)
+    //
+    iosExam_phone, _ := iosExam["phone"].(string)
+    isExamPhone := false
+    if phone, _ := a.GetSession("s_phone").(string); phone != "" && phone == iosExam_phone {
+        isExamPhone = true
+    }
+    //
+    isVip := false
+    isEnt := false
+    if iosExam_flag && (vip || ent) {
+        if userId, _ := a.GetSession("userId").(string); userId != "" {
+            user := Compatible.Select(userId, `{"i_vip_status":1,"s_phone":1,"s_m_phone":1}`)
+            if user != nil {
+                i_vip_status := util.IntAll((*user)["i_vip_status"])
+                isVip = i_vip_status == 1 || i_vip_status == 2
+            }
+            s_phone, _ := (*user)["s_phone"].(string)
+            if s_phone == "" {
+                s_phone, _ = (*user)["s_m_phone"].(string)
+            }
+            if ent && public.Mysql.CountBySql(`select count(1) as count from entniche_info where phone=? and status=1`, s_phone) > 0 {
+                isEnt = true
+            }
+        }
+    }
+    return iosExam_flag, isExamPhone, isVip, isEnt
 }
 
 // 排序 排序键必须为数字类型
 type SortBy struct {
-	Data    []map[string]interface{}
-	Sortkey string
+    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]
+    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)
-	}
+    //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)
-	}
+    //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
+    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
 }
 
 // AdInfo 广告信息
 type AdInfo struct {
-	S_link   string `json:"s_link"`   //广告位跳转链接
-	S_pic    string `json:"s_pic"`    //广告位弹窗
-	S_remark string `json:"s_remark"` //备注
-	S_picalt string `json:"s_picalt"` //图片ALT
-	S_id     string `json:"s_id"`     //广告标识id
-	O_extend struct {
-		Linktype  string `json:"linktype"`  //是否外部链接
-		Height    string `json:"height"`    //高度
-		Width     string `json:"width"`     //宽度
-		StartTime string `json:"startTime"` //开始时间
-		EndTime   string `json:"endTime"`   //结束时间
-		IosHref   string `json:"iosHref"`   //根据客户端不同 是否访问不同地址
-		Theme     string `json:"theme"`     // 主题样式
-		Title     string `json:"title"`     //标题
-		Power     string `json:"power"`     // 权限判断
-		Tab       string `json:"tab"`       // tab切换
-	} `json:"o_extend"` //拓展属性
-	S_script string `json:"s_script"` //脚本
+    S_link   string `json:"s_link"`   //广告位跳转链接
+    S_pic    string `json:"s_pic"`    //广告位弹窗
+    S_remark string `json:"s_remark"` //备注
+    S_picalt string `json:"s_picalt"` //图片ALT
+    S_id     string `json:"s_id"`     //广告标识id
+    O_extend struct {
+        Linktype  string `json:"linktype"`  //是否外部链接
+        Height    string `json:"height"`    //高度
+        Width     string `json:"width"`     //宽度
+        StartTime string `json:"startTime"` //开始时间
+        EndTime   string `json:"endTime"`   //结束时间
+        IosHref   string `json:"iosHref"`   //根据客户端不同 是否访问不同地址
+        Theme     string `json:"theme"`     // 主题样式
+        Title     string `json:"title"`     //标题
+        Power     string `json:"power"`     // 权限判断
+        Tab       string `json:"tab"`       // tab切换
+    } `json:"o_extend"`               //拓展属性
+    S_script string `json:"s_script"` //脚本
 }
 
 // Handle 广告位信息处理
 func Handle(data []interface{}, host string) []AdInfo {
-	var res []AdInfo
-	if len(data) > 0 {
-		var AdinfoArr []AdInfo
-		bytes, err := json.Marshal(data)
-		if err != nil {
-			return res
-		}
-		if err := json.Unmarshal(bytes, &AdinfoArr); err == nil {
-			if len(AdinfoArr) > 0 {
-				now := time.Now()
-				for _, v := range AdinfoArr {
-					if v.S_id != "" && host != "" {
-						//根据不同环境区分广告位信息 v.S_id 填充内容, 例:app-i2;app-a1
-						if !strings.Contains(host, v.S_id) {
-							continue
-						}
-					}
-					if v.O_extend.StartTime != "" && len(strings.Split(v.O_extend.StartTime, "-")) == 6 {
-						if thisTime, err := time.ParseInLocation("2006-01-02-15-04-05", v.O_extend.StartTime, time.Local); err == nil {
-							//广告还未开始
-							if thisTime.Unix() > now.Unix() {
-								continue
-							}
-						}
-					}
-					if v.O_extend.EndTime != "" && len(strings.Split(v.O_extend.EndTime, "-")) == 6 {
-						if thisTime, err := time.ParseInLocation("2006-01-02-15-04-05", v.O_extend.EndTime, time.Local); err == nil {
-							//广告已经结束
-							if thisTime.Unix() < now.Unix() {
-								continue
-							}
-						}
-					}
-					res = append(res, v)
-				}
-			}
-		}
-	}
-	return res
+    var res []AdInfo
+    if len(data) > 0 {
+        var AdinfoArr []AdInfo
+        bytes, err := json.Marshal(data)
+        if err != nil {
+            return res
+        }
+        if err := json.Unmarshal(bytes, &AdinfoArr); err == nil {
+            if len(AdinfoArr) > 0 {
+                now := time.Now()
+                for _, v := range AdinfoArr {
+                    if v.S_id != "" && host != "" {
+                        //根据不同环境区分广告位信息 v.S_id 填充内容, 例:app-i2;app-a1
+                        if !strings.Contains(host, v.S_id) {
+                            continue
+                        }
+                    }
+                    if v.O_extend.StartTime != "" && len(strings.Split(v.O_extend.StartTime, "-")) == 6 {
+                        if thisTime, err := time.ParseInLocation("2006-01-02-15-04-05", v.O_extend.StartTime, time.Local); err == nil {
+                            //广告还未开始
+                            if thisTime.Unix() > now.Unix() {
+                                continue
+                            }
+                        }
+                    }
+                    if v.O_extend.EndTime != "" && len(strings.Split(v.O_extend.EndTime, "-")) == 6 {
+                        if thisTime, err := time.ParseInLocation("2006-01-02-15-04-05", v.O_extend.EndTime, time.Local); err == nil {
+                            //广告已经结束
+                            if thisTime.Unix() < now.Unix() {
+                                continue
+                            }
+                        }
+                    }
+                    res = append(res, v)
+                }
+            }
+        }
+    }
+    return res
 }
 
 func ChangeLoginCookie(timeOut int, w http.ResponseWriter, r *http.Request, name string) (c int) {
-	v, err := r.Cookie(name)
-	if err == nil {
-		c, _ = strconv.Atoi(v.Value)
-	} else {
-		hCookie := r.Header.Get("Cookie")
-		if hCookie != "" && strings.Contains(hCookie, name) {
-			for _, hc := range strings.Split(hCookie, ";") {
-				if len(strings.Split(hc, "=")) > 1 {
-					c, _ = strconv.Atoi(strings.Split(hc, "=")[1])
-					break
-				}
-			}
-		}
-	}
-	c++
-	//log.Println(c, "-------------", err)
-	http.SetCookie(w, &http.Cookie{
-		Name:     name,
-		Value:    strconv.Itoa(c),
-		Path:     "/",
-		HttpOnly: false,
-		MaxAge:   timeOut,
-		Expires:  time.Now().Add(time.Duration(timeOut)),
-		Domain:   httpsession.Domain,
-	})
-	return
+    v, err := r.Cookie(name)
+    if err == nil {
+        c, _ = strconv.Atoi(v.Value)
+    } else {
+        hCookie := r.Header.Get("Cookie")
+        if hCookie != "" && strings.Contains(hCookie, name) {
+            for _, hc := range strings.Split(hCookie, ";") {
+                if len(strings.Split(hc, "=")) > 1 {
+                    c, _ = strconv.Atoi(strings.Split(hc, "=")[1])
+                    break
+                }
+            }
+        }
+    }
+    c++
+    //log.Println(c, "-------------", err)
+    http.SetCookie(w, &http.Cookie{
+        Name:     name,
+        Value:    strconv.Itoa(c),
+        Path:     "/",
+        HttpOnly: false,
+        MaxAge:   timeOut,
+        Expires:  time.Now().Add(time.Duration(timeOut)),
+        Domain:   httpsession.Domain,
+    })
+    return
+}
+
+// ClearCookie 清楚前端cookie 缓存
+func ClearCookie(w http.ResponseWriter, name string) {
+    if name == "" {
+        return
+    }
+    for _, nk := range strings.Split(name, ",") {
+        if nk != "" {
+            http.SetCookie(w, &http.Cookie{
+                Name:     nk,
+                Value:    "",
+                Path:     "/",
+                HttpOnly: false,
+                MaxAge:   -1,
+                Expires:  time.Now().Add(-1),
+                Domain:   httpsession.Domain,
+            })
+        }
+    }
 }

+ 352 - 0
src/jfw/modules/app/src/app/miniprogram/miniprogram.go

@@ -0,0 +1,352 @@
+package miniprogram
+
+import (
+	"encoding/json"
+	"jy/src/jfw/modules/app/src/app/jyutil"
+	"jy/src/jfw/modules/app/src/jfw/config"
+	"log"
+	"net/http"
+
+	. "app.yhyue.com/moapp/jybase/api"
+	"app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
+	. "app.yhyue.com/moapp/jybase/mongodb"
+	"app.yhyue.com/moapp/jybase/redis"
+	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
+	"app.yhyue.com/moapp/jypkg/public"
+	"bp.jydev.jianyu360.cn/BaseService/userCenter/rpc/pb"
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/os/gctx"
+	"github.com/gogf/gf/v2/os/gtime"
+	"github.com/gogf/gf/v2/util/gconv"
+)
+
+const (
+	HeaderMiniProgram = "MiniprogramCode"
+	MiniProgramKey    = "miniProgram"
+)
+
+type MiniProgramInfo struct {
+	Code      string //小程序code
+	Name      string //小程序名字
+	Appid     string //小程序appid
+	Appsecret string //小程序密钥
+}
+
+type JsonParam struct {
+	Token           string `json:"token"`
+	Phone           string `json:"phone"`
+	Openid          string `json:"openid"`
+	Unionid         string `json:"unionid"`
+	Source          string `json:"source"`
+	Code            string `json:"code"`
+	MiniProgramInfo *MiniProgramInfo
+}
+
+func init() {
+	xweb.AddAction(&MiniProgram{})
+}
+
+type MiniProgram struct {
+	*xweb.Action
+	autoLogin xweb.Mapper `xweb:"/jyapp/miniprogram/autoLogin"`
+	login     xweb.Mapper `xweb:"/jyapp/miniprogram/login"`
+	bindPhone xweb.Mapper `xweb:"/jyapp/miniprogram/bindphone"`
+	transfer  xweb.Mapper `xweb:"/jyapp/miniprogram/transfer"`
+}
+
+func (m *MiniProgram) getJsonParam() *JsonParam {
+	jsonPram := &JsonParam{}
+	if err := json.Unmarshal(m.Body(), &jsonPram); err != nil {
+		log.Println(err)
+	}
+	return jsonPram
+}
+func (m *MiniProgram) AutoLogin() {
+	m.reSetCookie()
+	jsonPram := m.getJsonParam()
+	if jsonPram.Token != "8817684142977367382" {
+		return
+	}
+	miniprogramCode := m.Header(HeaderMiniProgram)
+	if miniprogramCode == "" || jsonPram.Phone == "" || jsonPram.Openid == "" || jsonPram.Unionid == "" {
+		m.ServeJson(Result{
+			Error_code: Error_code_1001,
+			Error_msg:  Error_msg_1002,
+		})
+		return
+	}
+	m.Session().SetMultiple(map[string]interface{}{
+		"unionid": jsonPram.Unionid,
+		"openid":  jsonPram.Openid,
+		"source":  jsonPram.Source,
+	})
+	status := m.createSession(jsonPram.Unionid, jsonPram.Openid, miniprogramCode)
+	if status == -1 {
+		if m.createUser(jsonPram.Unionid, jsonPram.Openid, miniprogramCode, jsonPram.Phone, "") > 0 {
+			status = m.createSession(jsonPram.Unionid, jsonPram.Openid, miniprogramCode)
+		}
+	}
+	m.ServeJson(Result{Data: M{"status": 1}})
+	return
+}
+func (m *MiniProgram) Login() error {
+	m.reSetCookie()
+	jsonPram := m.getJsonParam()
+	if ok := m.check(jsonPram); !ok {
+		return nil
+	}
+	ctx := gctx.New()
+	status := func() int {
+		rb := g.Client().GetVar(ctx, "https://api.weixin.qq.com/sns/jscode2session", g.Map{
+			"appid":      jsonPram.MiniProgramInfo.Appid,
+			"secret":     jsonPram.MiniProgramInfo.Appsecret,
+			"js_code":    jsonPram.Code,
+			"grant_type": "authorization_code",
+		})
+		//rb := gvar.New(`{"openid":"wcj_openid","session_key":"wcj_session_key","unionid":"wcj_unionid","errcode":0,"errmsg":"xxxxx"}`)
+		log.Println("Code", jsonPram.Code, "Source", jsonPram.Source, "miniprogramCode", jsonPram.MiniProgramInfo.Code, "appid", jsonPram.MiniProgramInfo.Appid, "appsecret", jsonPram.MiniProgramInfo.Appsecret, "根据code获取用户信息返回结果", string(rb.Bytes()))
+		r := rb.MapStrVar()
+		if r["errcode"].Int() != 0 {
+			return 0
+		}
+		openid := r["openid"].String()
+		unionid := r["unionid"].String()
+		if openid == "" {
+			log.Println(jsonPram.Code, "未获取到openid")
+			return 0
+		} else if unionid == "" {
+			log.Println(jsonPram.Code, "未获取到unionid")
+			return 0
+		}
+		if sessErr := m.Session().SetMultiple(map[string]interface{}{
+			"unionid":    unionid,
+			"openid":     openid,
+			"sessionKey": r["session_key"].String(),
+			"source":     jsonPram.Source,
+		}); sessErr != nil {
+			log.Println(jsonPram.Code, "用户信息存入session出错", string(rb.Bytes()), sessErr)
+			return 0
+		}
+		return m.createSession(unionid, openid, jsonPram.MiniProgramInfo.Code)
+	}()
+	m.ServeJson(Result{
+		Data: M{"status": status, "sessionId": string(m.Session().Id())},
+	})
+	return nil
+}
+
+//
+func (m *MiniProgram) BindPhone() error {
+	jsonPram := m.getJsonParam()
+	if ok := m.check(jsonPram); !ok {
+		return nil
+	}
+	status := func() int {
+		ctx := gctx.New()
+		accessToken := jyutil.GetWxAccessToken(ctx, jsonPram.MiniProgramInfo.Appid)
+		if accessToken == "" {
+			return 0
+		}
+		rb := g.Client().ContentJson().PostVar(ctx, "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="+accessToken, g.Map{
+			"code": jsonPram.Code,
+		})
+		//rb := gvar.New(`{"errcode":0,"errmsg":"ok","phone_info": {"phoneNumber":"15037870765","purePhoneNumber":"15037870765","countryCode":86,"watermark":{"timestamp":1637744274,"appid":"xxxx"}}}`)
+		log.Println(jsonPram.Code, jsonPram.MiniProgramInfo.Code, "根据code获取手机号返回结果", string(rb.Bytes()))
+		r := rb.MapStrVar()
+		if r["errcode"].Int() != 0 {
+			return 0
+		}
+		phone := r["phone_info"].MapStrVar()["phoneNumber"].String()
+		sessVal := m.Session().GetMultiple()
+		unionid := common.ObjToString(sessVal["unionid"])
+		openid := common.ObjToString(sessVal["openid"])
+		source := common.ObjToString(sessVal["source"])
+		if createRes := m.createUser(unionid, openid, jsonPram.MiniProgramInfo.Code, phone, source); createRes > 0 {
+			status := m.createSession(unionid, openid, jsonPram.MiniProgramInfo.Code)
+			nsqPath, _ := config.Sysconfig["nsq"].(string)
+			nsq_topic, _ := config.Sysconfig["nsq_topic"].(string)
+			sessVal := m.Session().GetMultiple()
+			mgoUserId := common.ObjToString(sessVal["mgoUserId"])
+			if createRes == 1 {
+				if err := jy.Publish(public.Mgo_Log, nsqPath, nsq_topic, jy.Jyapp_phone_register, mgoUserId, jy.Jyapp_node1, nil); err != nil {
+					log.Println("nsq队列写入失败-->", err, jy.Jyapp_phone_register, mgoUserId)
+				}
+			} else if createRes == 2 {
+				if err := jy.Publish(public.Mgo_Log, nsqPath, nsq_topic, "task", mgoUserId, jy.Jyweb_node2, map[string]interface{}{
+					"code":       1007,
+					"types":      "bindPhone",
+					"num":        50,
+					"baseUserId": sessVal["base_user_id"],
+					"positionId": sessVal["positionId"],
+					"isOnlyBind": true,
+				}); err != nil {
+					log.Println("nsq队列写入失败-->", err, jy.Jyapp_phone_register, sessVal["mgoUserId"])
+				}
+			}
+			return status
+		}
+		return 0
+	}()
+	m.ServeJson(Result{Data: M{"status": status}})
+	return nil
+}
+
+func (m *MiniProgram) Transfer() error {
+	sid := m.GetString("sid")
+	b, err := redis.GetNewBytes("session", sid)
+	if err == nil && b != nil {
+		data := map[string]interface{}{}
+		json.Unmarshal(*b, &data)
+		data["needSyncSessionId"] = sid
+		m.Session().Clear()
+		m.Session().SetMultiple(data)
+	}
+	return m.Redirect(m.GetString("to"))
+}
+
+//
+func (m *MiniProgram) reSetCookie() {
+	m.SetCookie(&http.Cookie{
+		Name:  "SESSIONID",
+		Value: string(m.Session().Id()),
+		Path:  "/",
+	})
+}
+
+//
+func (m *MiniProgram) check(jsonParam *JsonParam) bool {
+	miniprogramCode := m.Header(HeaderMiniProgram)
+	var ctx = gctx.New()
+	appid := g.Cfg().MustGet(ctx, "miniprogram."+miniprogramCode+".appid").String()
+	appsecret := g.Cfg().MustGet(ctx, "miniprogram."+miniprogramCode+".appsecret").String()
+	if jsonParam.Code == "" {
+		m.ServeJson(Result{
+			Error_code: Error_code_1002,
+			Error_msg:  Error_msg_1002 + "code",
+		})
+		return false
+	} else if miniprogramCode == "" {
+		m.ServeJson(Result{
+			Error_code: Error_code_1002,
+			Error_msg:  "请求头中缺少参数" + HeaderMiniProgram,
+		})
+		return false
+	} else if appid == "" || appsecret == "" {
+		R.InvalidReqParam(m.ResponseWriter, m.Request, HeaderMiniProgram)
+		return false
+	}
+	jsonParam.MiniProgramInfo = &MiniProgramInfo{
+		Code:      miniprogramCode,
+		Appid:     appid,
+		Appsecret: appsecret,
+	}
+	return true
+}
+
+//
+func (m *MiniProgram) createUser(unionid, openid, miniprogramCode, phone, source string) int {
+	if phone == "" || unionid == "" || openid == "" {
+		log.Println("phone", phone, "unionid", unionid, "openid", openid, "创建用户失败,缺少phone、unionid、openid")
+		return 0
+	}
+	users, ok := public.MQFW.Find("user", map[string]interface{}{"i_appid": 2, "s_unionid": unionid}, `{"_id":-1}`, `{"_id":1,"s_phone":1,"s_m_phone":1,"s_unionid":1}`, false, 0, 1)
+	if ok && (users == nil || len(*users) == 0) {
+		users, ok = public.MQFW.Find("user", map[string]interface{}{
+			"i_appid": 2,
+			"$or": []map[string]interface{}{
+				map[string]interface{}{
+					"s_phone": phone,
+				}, map[string]interface{}{
+					"s_m_phone": phone,
+				},
+			},
+		}, `{"s_phone":-1}`, `{"_id":1,"s_phone":1,"s_m_phone":1,"s_unionid":1}`, false, 0, 1)
+	}
+	nowUnix := gtime.Timestamp()
+	if !ok {
+		log.Println(miniprogramCode, unionid, openid, phone, "查询mog库user表失败")
+	} else if users == nil || len(*users) == 0 {
+		if resp := config.Middleground.UserCenter.UserAdd(pb.UserAddReq{
+			Appid: "10000",
+			Phone: phone,
+		}); resp != nil && resp.Data.Id > 0 {
+			_id := public.MQFW.Save("user", map[string]interface{}{
+				"s_platform":                      "xcx",
+				"s_sourceid":                      miniprogramCode,
+				"l_registedate":                   nowUnix,
+				"base_user_id":                    resp.Data.Id,
+				"i_appid":                         2,
+				"s_phone":                         phone,
+				"s_unionid":                       unionid,
+				miniprogramCode + "_registerdate": nowUnix,
+				miniprogramCode + "_openid":       openid,
+				miniprogramCode + "_source":       source,
+			})
+			if _id != "" {
+				public.Mgo_Log.Save("register_log", map[string]interface{}{
+					"userid":      _id,
+					"phone":       phone,
+					"way":         "xcx",
+					"system":      common.GetSystem(m.UserAgent()),
+					"source":      gconv.String(m.GetSession("source")),
+					"ip":          common.GetIp(m.Request),
+					"user_agent":  m.UserAgent(),
+					"create_time": gtime.Timestamp(),
+					"code":        miniprogramCode,
+				})
+				return 1
+			} else {
+				log.Println(miniprogramCode, unionid, openid, phone, "mgo库user表用户创建失败")
+			}
+		} else {
+			log.Println(miniprogramCode, unionid, openid, phone, "调用usercenter失败")
+		}
+	} else {
+		set := map[string]interface{}{
+			miniprogramCode + "_source":       source,
+			miniprogramCode + "_openid":       openid,
+			miniprogramCode + "_registerdate": gtime.Timestamp(),
+		}
+		if gconv.String((*users)[0]["s_phone"]) == "" && gconv.String((*users)[0]["s_m_phone"]) == "" {
+			set["s_phone"] = phone
+			set["l_bindphonetime"] = nowUnix
+		}
+		if gconv.String((*users)[0]["s_unionid"]) == "" {
+			set["s_unionid"] = unionid
+		}
+		if public.MQFW.Update("user", map[string]interface{}{"_id": (*users)[0]["_id"]}, map[string]interface{}{"$set": set}, false, false) {
+			return 2
+		}
+	}
+	return 0
+}
+
+func (m *MiniProgram) createSession(unionid, openid, miniprogramCode string) int {
+	if unionid == "" || openid == "" || miniprogramCode == "" {
+		log.Println("缺少unionid、openid、miniprogramCode", miniprogramCode, unionid, openid)
+		return 0
+	}
+	userRes, userOk := public.MQFW.FindOneByField("user", map[string]interface{}{"i_appid": 2, "s_unionid": unionid}, `{"_id":1,"s_phone":1,"s_m_phone":1}`)
+	if !userOk {
+		log.Println(openid, miniprogramCode, "获取用户信息出错")
+		return 0
+	} else if userRes == nil || len(*userRes) == 0 || (gconv.String((*userRes)["s_phone"]) == "" && gconv.String((*userRes)["s_m_phone"]) == "") {
+		return -1
+	}
+	public.MQFW.Update("user", map[string]interface{}{"_id": (*userRes)["_id"]}, map[string]interface{}{"$set": map[string]interface{}{miniprogramCode + "_openid": openid}}, false, false)
+	m.Session().Del("source")
+	jy.JyAppCreateSession(public.MQFW, m.Session(), BsonIdToSId((*userRes)["_id"]), 0, m.ResponseWriter, true, config.Middleground, "", 0)
+	ctx := gctx.New()
+	m.Session().SetMultiple(map[string]interface{}{
+		"s_m_openid": openid,
+		MiniProgramKey: &MiniProgramInfo{
+			Code:      miniprogramCode,
+			Name:      g.Cfg().MustGet(ctx, "miniprogram."+miniprogramCode+".name").String(),
+			Appid:     g.Cfg().MustGet(ctx, "miniprogram."+miniprogramCode+".appid").String(),
+			Appsecret: g.Cfg().MustGet(ctx, "miniprogram."+miniprogramCode+".appsecret").String(),
+		},
+	})
+	log.Println(miniprogramCode, openid, "创建session成功", m.Session().Id())
+	return 1
+}

+ 1 - 0
src/jfw/modules/app/src/app/tag/ad.go

@@ -108,6 +108,7 @@ func Ad(sCode string, n int, host, sessionId string) []jy.AdInfo {
 		Ads:       nil,
 		OrderCode: "",
 		IsLogin:   isLogin,
+		SessionId: sessionId,
 	}
 	ads := adf.GetAdInfos()[sCode]
 	if n > 0 {

+ 12 - 1
src/jfw/modules/app/src/config.yaml

@@ -1,6 +1,17 @@
 etcd:
   hosts:
-  - 192.168.3.206:2379
+    - 172.31.31.203:2379
+  #- 192.168.3.165:2379
+  #- 192.168.3.204:2379
 userCenterKey: "usercenter.rpc" #用户中台rpc
 powerCheckCenterKey: "powercheck.rpc" #权益校验中台
 entManageApplication: "entmanageapplication.rpc" #企业管理中台
+
+GuideRegistedate: 1734451200  #该时间之前注册的付费用户不用进订阅向导
+
+miniprogram:
+  jyzbw:
+    name: "剑鱼招标网"
+    appid: "wx37f06c38292f7d82"
+    appsecret: "f7dba667a47b4b10c1f581e3de46d0d3"
+wxTokenRpc: "172.17.162.29:1166"

+ 64 - 64
src/jfw/modules/app/src/db.json

@@ -1,72 +1,72 @@
 {
-	"mongodb": {
-		"main": {
-			"address": "192.168.3.206:27080",
-	 		"size": 5,
-	 		"dbName": "qfw"
-		},
-		"log": {
-			"address": "192.168.3.206:27090",
-	 		"size": 5,
-	 		"dbName": "qfw",
-			"userName": "admin",
-			"password": "123456"
-		},
-		"ent": {
-			"address": "192.168.3.206:27001,192.168.3.206:27002",
-	 		"size": 5,
-	 		"dbName": "mixdata",
-			"userName": "jyDevGroup",
-			"password": "jy@DevGroup"
-		},
-		"bidding": {
-			"address": "192.168.3.206:27002",
-	 		"size": 5,
-	 		"dbName": "qfw_data",
-			"collection": "bidding",
-			"collection_back": "bidding_back",
-			"userName": "jyDevGroup",
-			"password": "jy@DevGroup"
-		}
-	},
-	"elasticsearch": {
-		"main": {
-			"address": "http://192.168.3.241:9205,http://192.168.3.149:9200",
+  "mongodb": {
+    "main": {
+      "address": "172.20.45.129:27002,172.20.45.130:27080",
       "size": 5,
-			"version": "v7",
-			"userName": "",
-			"password": ""
-		}
+      "dbName": "qfw"
     },
+    "log": {
+      "address": "172.20.45.129:27002,172.20.45.130:27080",
+      "size": 5,
+      "dbName": "qfw",
+      "userName": "",
+      "password": ""
+    },
+    "ent": {
+      "address": "172.20.45.129:27002,172.20.45.130:27080",
+      "size": 5,
+      "dbName": "mixdata",
+      "userName": "",
+      "password": ""
+    },
+    "bidding": {
+      "address": "172.20.45.129:27002,172.20.45.130:27080",
+      "size": 5,
+      "dbName": "qfw_data",
+      "collection": "bidding",
+      "collection_back": "bidding_back",
+      "userName": "",
+      "password": ""
+    }
+  },
+  "elasticsearch": {
+    "main": {
+      "address": "http://172.20.45.129:9206,http://172.20.45.130:9306",
+      "size": 2,
+      "version": "v7",
+      "userName": "",
+      "password": ""
+    }
+  },
   "redis": {
-    "main":{
-      "address": "other=192.168.3.149:1712,sso=192.168.3.149:1713,push=192.168.3.149:1711,session=192.168.3.149:1713,merge=192.168.3.149:1712,grayupdate=192.168.3.206:1712,newother=192.168.3.149:1712,seoCache=192.168.3.149:1712,limitation=192.168.3.149:1713,poly=192.168.3.149:1713"
+    "main": {
+      "address": "other=172.20.45.129:1712,sso=172.20.45.129:1713,push=172.20.45.129:1711,session=172.20.45.129:1713,merge=172.20.45.129:1712,grayupdate=172.20.45.129:1712,newother=172.20.45.129:1712,seoCache=172.20.45.129:1712,limitation=172.20.45.129:1713,poly=172.20.45.129:1713"
     }
+  },
+  "mysql": {
+    "main": {
+      "dbName": "jianyu",
+      "address": "172.20.45.129:4000",
+      "userName": "jianyu",
+      "passWord": "Topnet123",
+      "maxOpenConns": 2,
+      "maxIdleConns": 2
+    },
+    "base": {
+      "dBName": "base_service",
+      "address" : "172.20.45.129:4000",
+      "userName": "root",
+      "passWord": "=PDT49#80Z!RVv52_z",
+      "maxOpenConns": 5,
+      "maxIdleConns": 5
     },
-    "mysql": {
-	    "main": {
-	        "dbName": "jianyu",
-        "address": "192.168.3.217:4000",
-        "userName": "root",
-        "passWord": "=PDT49#80Z!RVv52_z",
-			"maxOpenConns": 2,
-			"maxIdleConns": 2
-	    },
-      	"base": {
-	        "dBName": "base_service",
-	        "address": "192.168.3.217:4000",
-	        "userName": "root",
-	        "passWord": "=PDT49#80Z!RVv52_z",
-	        "maxOpenConns": 5,
-	        "maxIdleConns": 5
-      	},
-      "globalCommon": {
-        "dBName": "global_common_data",
-        "address": "192.168.3.217:4000",
-        "userName": "root",
-        "passWord": "=PDT49#80Z!RVv52_z",
-        "maxOpenConns": 5,
-        "maxIdleConns": 5
-      }
+    "globalCommon": {
+      "dBName": "global_common_data",
+      "address": "172.20.45.129:4000",
+      "userName": "root",
+      "passWord": "=PDT49#80Z!RVv52_z",
+      "maxOpenConns": 5,
+      "maxIdleConns": 5
     }
+  }
 }

+ 12 - 6
src/jfw/modules/app/src/go.mod

@@ -3,17 +3,19 @@ module jy/src/jfw/modules/app/src
 go 1.20
 
 require (
-	app.yhyue.com/moapp/jybase v0.0.0-20240412015757-6d8429bb4dae
+	app.yhyue.com/moapp/jybase v0.0.0-20250225094323-2f6419d0d916
 	app.yhyue.com/moapp/jylog v0.0.0-20230522075550-05d7230ca545
-	app.yhyue.com/moapp/jypkg v1.22.3
+	app.yhyue.com/moapp/jypkg v1.31.8
 	bp.jydev.jianyu360.cn/BaseService/entManageApplication v0.0.0-20231226074509-942d80dc34eb
-	bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.18
+	bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.21
 	github.com/SKatiyar/qr v0.0.0-20151201054752-25b6bdf44e67
 	github.com/gogf/gf/v2 v2.7.0
 	github.com/pkg/errors v0.9.1
 	go.mongodb.org/mongo-driver v1.14.0
 )
 
+replace github.com/go-xorm/xorm v0.7.9 => gitea.com/xorm/xorm v0.7.9
+
 require (
 	app.yhyue.com/moapp/esv1 v0.0.0-20220414031211-3da4123e648d // indirect
 	app.yhyue.com/moapp/jyMarketing v0.0.2-0.20230304035551-21bb1eedf547 // indirect
@@ -21,7 +23,7 @@ require (
 	app.yhyue.com/moapp/jyResourcesCenter v0.0.0-20231024011103-8a2aacdbbd3e // indirect
 	app.yhyue.com/moapp/message v0.0.0-20231204024949-8c7145bfc161 // indirect
 	bp.jydev.jianyu360.cn/BaseService/jyMicroservices v0.0.2 // indirect
-	bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20240607062231-ae1d02891843 // indirect
+	bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20241213060113-ac41966a58ec // indirect
 	bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.1.3 // indirect
 	filippo.io/edwards25519 v1.1.0 // indirect
 	github.com/BurntSushi/toml v1.2.0 // indirect
@@ -47,6 +49,7 @@ require (
 	github.com/go-sql-driver/mysql v1.8.1 // indirect
 	github.com/gogo/protobuf v1.3.2 // indirect
 	github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
+	github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
 	github.com/golang/mock v1.6.0 // indirect
 	github.com/golang/protobuf v1.5.4 // indirect
 	github.com/golang/snappy v0.0.4 // indirect
@@ -99,6 +102,8 @@ require (
 	github.com/subosito/gotenv v1.4.2 // indirect
 	github.com/tealeg/xlsx v1.0.5 // indirect
 	github.com/thinxer/go-word2vec v0.0.0-20150917053916-5c19ec7379ed // indirect
+	github.com/wenlng/go-captcha-assets v1.0.1 // indirect
+	github.com/wenlng/go-captcha/v2 v2.0.3 // indirect
 	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
 	github.com/xdg-go/scram v1.1.2 // indirect
 	github.com/xdg-go/stringprep v1.0.4 // indirect
@@ -125,12 +130,13 @@ require (
 	go.uber.org/multierr v1.9.0 // indirect
 	go.uber.org/zap v1.24.0 // indirect
 	golang.org/x/crypto v0.22.0 // indirect
+	golang.org/x/image v0.24.0 // indirect
 	golang.org/x/net v0.24.0 // indirect
 	golang.org/x/oauth2 v0.17.0 // indirect
-	golang.org/x/sync v0.6.0 // indirect
+	golang.org/x/sync v0.11.0 // indirect
 	golang.org/x/sys v0.19.0 // indirect
 	golang.org/x/term v0.19.0 // indirect
-	golang.org/x/text v0.14.0 // indirect
+	golang.org/x/text v0.22.0 // indirect
 	golang.org/x/time v0.5.0 // indirect
 	google.golang.org/appengine v1.6.8 // indirect
 	google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect

+ 24 - 14
src/jfw/modules/app/src/go.sum

@@ -17,13 +17,13 @@ app.yhyue.com/moapp/jybase v0.0.0-20230117032034-ad7c00ffe11a/go.mod h1:zB47XTeJ
 app.yhyue.com/moapp/jybase v0.0.0-20230419121327-bedf77840ba6/go.mod h1:zB47XTeJvpcbtBRYgkQuxOICWNexiZfbUO+7aUf6mNs=
 app.yhyue.com/moapp/jybase v0.0.0-20230901064756-2fc66b18db40/go.mod h1:Hv9U/7oHRucqH315Tr1+d03NCvS9mOKPfk8pwwlOIwQ=
 app.yhyue.com/moapp/jybase v0.0.0-20231025021840-2f91c944ecdd/go.mod h1:Hv9U/7oHRucqH315Tr1+d03NCvS9mOKPfk8pwwlOIwQ=
-app.yhyue.com/moapp/jybase v0.0.0-20240412015757-6d8429bb4dae h1:zprLO87oURhdr/ccUORXvuZ7zp/LBGxMqUZUzQemISw=
-app.yhyue.com/moapp/jybase v0.0.0-20240412015757-6d8429bb4dae/go.mod h1:XHNATN6tsJKHdCB0DbUtFdPPHXexTUFyB3RlO+lUUoM=
+app.yhyue.com/moapp/jybase v0.0.0-20250225094323-2f6419d0d916 h1:uhzwulALpCu8gZN6O6V/jo9sbbgxQqLNX3dd4qN4Ick=
+app.yhyue.com/moapp/jybase v0.0.0-20250225094323-2f6419d0d916/go.mod h1:/HT/UZ4dKuUKAQqqKrzBBfIZ4vD56DPV4u2QyfH+kbU=
 app.yhyue.com/moapp/jyfs v0.0.0-20231024061508-480c270480d4/go.mod h1:61hzZ3dZHXL28BNl8BOgZsvM2S5UVY5YFzOkEUPrSu4=
 app.yhyue.com/moapp/jylog v0.0.0-20230522075550-05d7230ca545 h1:+Lak4m1zgsigQloOsvp8AJ+0XeX/+PGp9QP550xlbBQ=
 app.yhyue.com/moapp/jylog v0.0.0-20230522075550-05d7230ca545/go.mod h1:uFrsdUBFbETiJlEmr4PtJWPsZlUpPj2bHQRhryu6ggk=
-app.yhyue.com/moapp/jypkg v1.22.3 h1:iD5eC6JuF4eQV80lvTu3/D4qZeuogWpW4XkCG9TKO9Y=
-app.yhyue.com/moapp/jypkg v1.22.3/go.mod h1:FylaC4MJ4G36WndktgeZfc8jTq3uvBGWIwbk02xfdQI=
+app.yhyue.com/moapp/jypkg v1.31.8 h1:nbdjgRCvtVLA/27lM9WqoNqhU1sIb7qcOO5WnxX3MGg=
+app.yhyue.com/moapp/jypkg v1.31.8/go.mod h1:bdHYv0sag7HhH89ft9nbOXHk21cNKes4xu1Ocpc021Y=
 app.yhyue.com/moapp/message v0.0.0-20231204024949-8c7145bfc161 h1:WGi4OEIoqw6NpNFGioUEBZnjK9aBa+xJqf/5WY+QyhM=
 app.yhyue.com/moapp/message v0.0.0-20231204024949-8c7145bfc161/go.mod h1:0Oj8SB4pVjdCLD28sy2zyM3hS0WHGpNuVcakLW43GmI=
 bp.jydev.jianyu360.cn/BP/jynsq v0.0.0-20220222052708-ebc43af90698/go.mod h1:ojo/AUH9Yr1wzarEjOaNMkj1Cet/9r8IgLyba64Z52E=
@@ -33,8 +33,8 @@ bp.jydev.jianyu360.cn/BaseService/gateway v0.0.0-20220419090715-88ddb32961be/go.
 bp.jydev.jianyu360.cn/BaseService/gateway v1.3.4/go.mod h1:BMLd/5wb3BIEGhnEgF9y1sJN9P5/Dw9kYsoiE9V8I9g=
 bp.jydev.jianyu360.cn/BaseService/jyMicroservices v0.0.2 h1:Qi8C7gZeR7+kjOtSl9ilR5HwbjCe8GO1RuotFb4+kFA=
 bp.jydev.jianyu360.cn/BaseService/jyMicroservices v0.0.2/go.mod h1:v8y7FCbkKEIRP4Ie9ZM8NtoRP+Fk4O3C1hnexNusYIQ=
-bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20240607062231-ae1d02891843 h1:u+8k/T0D6EUjj9BhI5RJdRa+8v4FZbyZhaNcm66L6Vs=
-bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20240607062231-ae1d02891843/go.mod h1:rCCaOSWBYfQabf/yIvSVheSPtN2THnHeTl2J5/RrcuU=
+bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20241213060113-ac41966a58ec h1:oCO36pHkEHQa5+Z/DU83T5xT5NKptVbw5UVQSN6lJjw=
+bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20241213060113-ac41966a58ec/go.mod h1:rCCaOSWBYfQabf/yIvSVheSPtN2THnHeTl2J5/RrcuU=
 bp.jydev.jianyu360.cn/BaseService/pushpkg v0.0.0-20230911091604-2faa31032743/go.mod h1:1SQIPPL5Ya5BzQdByFKtTkXrXTWBv+PDqWIhNknLnZw=
 bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.0.0-20220418005748-8ba5d936dd53/go.mod h1:E5lcDI3k4FESLxiAetCfWQTq8qfpy9cv0yN1oKoEO34=
 bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.0.0-20220419023723-0b32d4a41751/go.mod h1:6KL5LMEku83uRbre0W/bj5kXG2I6pJGBFtktmtp51yM=
@@ -43,8 +43,8 @@ bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.1.3 h1:lk3he0hY+8VK1/Hm+ZSlc
 bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.1.3/go.mod h1:rRiGzKG4F/fmkNxXQCxrkxNWc8yf1SmW8qWCKfGIQSM=
 bp.jydev.jianyu360.cn/BaseService/userCenter v0.0.0-20220418072311-2062bed1e700/go.mod h1:KjcrxTzM96tBc6G4B8tlLBn1lrVy5UJYF8+eTdP4xAE=
 bp.jydev.jianyu360.cn/BaseService/userCenter v0.0.0-20220421015128-4a36f3eac5c5/go.mod h1:GT0QC4aaKDuXxAvaU4G02XjCc31TU1ctqBGqxQYOfC4=
-bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.18 h1:aJNS24p6SOAOsCMvdOF0togsiO6HxmLIExVyTjog8Io=
-bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.18/go.mod h1:03bxckJBVCjal3uQ1loJmupbYHWRnaRC3V5LG4bgg6Y=
+bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.21 h1:XWTYzWEOPedM0CNjtqya+VTpYQl5rL4MMmlqmuasIK0=
+bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.21/go.mod h1:UB56iVLBV0H06VbTdXychssHSaGoqZMThfOuXZyrUAs=
 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=
@@ -806,6 +806,7 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
 filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
 gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8=
 git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc=
+gitea.com/xorm/xorm v0.7.9/go.mod h1:XiVxrMMIhFkwSkh96BW7PACl7UhLtx2iJIHMdmjh5sQ=
 github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
 github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
 github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
@@ -1019,6 +1020,7 @@ github.com/gin-contrib/sessions v0.0.5/go.mod h1:vYAuaUPqie3WUSsft6HUlCjlwwoJQs9
 github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
 github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
 github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
+github.com/go-bindata/go-bindata v3.1.2+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo=
 github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=
 github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks=
 github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=
@@ -1091,7 +1093,6 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg78
 github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
 github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8=
 github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
-github.com/go-xorm/xorm v0.7.9/go.mod h1:XiVxrMMIhFkwSkh96BW7PACl7UhLtx2iJIHMdmjh5sQ=
 github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
 github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
 github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
@@ -1132,6 +1133,7 @@ github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw
 github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
 github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
 github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
@@ -1738,6 +1740,10 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY
 github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
 github.com/urfave/cli/v2 v2.11.0/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo=
 github.com/wader/gormstore/v2 v2.0.0/go.mod h1:3BgNKFxRdVo2E4pq3e/eiim8qRDZzaveaIcIvu2T8r0=
+github.com/wenlng/go-captcha-assets v1.0.1 h1:AdjRFMKmadPRWRTv0XEYfjDvcaayZ2yExITDvlK/7bk=
+github.com/wenlng/go-captcha-assets v1.0.1/go.mod h1:yQqc7rRbxgLCg+tWtVp+7Y317D1wIZDan/yIwt8wSac=
+github.com/wenlng/go-captcha/v2 v2.0.3 h1:QTZ39/gVDisPSgvL9O2X2HbTuj5P/z8QsdGB/aayg9c=
+github.com/wenlng/go-captcha/v2 v2.0.3/go.mod h1:5hac1em3uXoyC5ipZ0xFv9umNM/waQvYAQdr0cx/h34=
 github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
 github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
 github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
@@ -1964,6 +1970,9 @@ golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeap
 golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
 golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
 golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
+golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs=
+golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ=
+golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -2136,8 +2145,8 @@ golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
-golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
-golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
+golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -2304,8 +2313,9 @@ golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
+golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -2401,7 +2411,7 @@ golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
 golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
 golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
 golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
-golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA=
+golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
 golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

+ 2 - 0
src/jfw/modules/app/src/jfw/config/config.go

@@ -26,6 +26,7 @@ var (
 	Middleground          *middleground.Middleground
 	IpList                *ipmatch.WhiteIp
 	IpInitLock            sync.RWMutex //锁
+	GuideRegistedate      int64        //该时间之前注册的付费用户不用进订阅向导
 )
 
 func init() {
@@ -52,6 +53,7 @@ func init() {
 		RegPowerCheckCenter(g.Cfg().MustGet(ctx, "powerCheckCenterKey").String()).
 		RegEntManageApplication(g.Cfg().MustGet(ctx, "entManageApplication").String()).
 		RegPublicservice(g.Cfg().MustGet(ctx, "publicserviceKey").String())
+	GuideRegistedate = g.Cfg().MustGet(ctx, "GuideRegistedate").Int64()
 }
 
 func IpInit() {

+ 1 - 0
src/jfw/modules/app/src/main.go

@@ -7,6 +7,7 @@ import (
 	_ "jy/src/jfw/modules/app/src/app/filter"
 	_ "jy/src/jfw/modules/app/src/app/followent"
 	_ "jy/src/jfw/modules/app/src/app/front"
+	_ "jy/src/jfw/modules/app/src/app/miniprogram"
 	"jy/src/jfw/modules/app/src/app/tag"
 	. "jy/src/jfw/modules/app/src/jfw/config"
 	_ "jy/src/jfw/modules/app/src/public"

+ 53 - 1
src/jfw/modules/app/src/web/staticres/jyapp/big-member/css/ent_follow.css

@@ -5,6 +5,7 @@
     color: #171826;
 }
 
+
 .dot-red {
     width: .16rem;
     height: .16rem;
@@ -59,7 +60,9 @@
     width: .36rem;
     border-radius: 0;
 }
-
+.follow-list {
+  margin-top: .2rem;
+}
 .follow-list .follow-item {
     display: flex;
     flex-direction: column;
@@ -139,4 +142,53 @@
     margin-right: .08rem;
     width: .24rem;
     height: .24rem;
+}
+
+.ent-grouping .grouping-list {
+  display: flex;
+  flex-wrap: wrap;
+  max-height: 2.04rem;
+  overflow: hidden;
+  overflow-y: auto;
+}
+
+.ent-grouping .grouping-list .grouping-item {
+  margin: 0 .16rem .16rem 0;
+  padding: 0 .24rem;
+  border: 0.5px solid rgba(192, 196, 204, 1);
+  border-radius: .3rem;
+  line-height: .52rem;
+  color: #5F5E64;
+}
+
+.ent-grouping .grouping-list .grouping-item.active {
+  background: #2ABED1;
+  border-color: #2ABED1;
+  color: #fff;
+}
+
+.ent-grouping .grouping-list .grouping-item.disabled {
+  background: #F5F6F7;
+}
+
+.ent-grouping .grouping-footer {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin-top: .24rem;
+  font-size: .28rem;
+  line-height: .4rem;
+  color: #2ABED1;
+}
+
+.ent-grouping .grouping-footer .grouping-item-name {
+  margin-right: .08rem;
+}
+
+.ent-grouping-fixed{
+  position: fixed;
+  z-index: 9;
+}
+.ent-grouping-normal, .ent-grouping-fixed {
+  width: 100%;
 }

+ 69 - 3
src/jfw/modules/app/src/web/staticres/jyapp/big-member/css/ent_portrait.css

@@ -62,17 +62,17 @@
     z-index: 2;
 }
 .tabs-list {
-    padding: 0 8px;
+    padding: .08rem .32rem .08rem;
 }
 .tabs-container .tabs-item {
-    margin-bottom: .24rem;
+    margin-bottom: .16rem;
 }
 
 .tabs-list .tabs-item,
 .van-sticky .van-tab {
     flex: none;
     display: inline-block;
-    margin-right: .32rem;
+    margin-right: .16rem;
     height: .52rem;
     padding: 0 .24rem;
     color: #5F5E64;
@@ -656,3 +656,69 @@
   background: linear-gradient(rgba(234, 248, 250, 1), rgba(234, 248, 250, 0));
   border-radius: 8px;
 }
+.sesame-container{
+  padding: .24rem .32rem;
+  background: linear-gradient(#E3FCFF, #ffffff);
+}
+.sesame-container .sesame-header{
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+.sesame-container .sesame-header .sesame-title{
+  font-size: .28rem;
+  line-height: .4rem;
+  color: #171826;
+}
+.sesame-container .sesame-header > span{
+  display: flex;
+  align-items: center;
+  font-size: .22rem;
+  color: #5F5E64;
+}
+.sesame-container .sesame-header .sesame-logo{
+  width: 1.44rem;
+  margin: 0 .08rem;
+}
+.sesame-container .sesame-main{
+  padding: .24rem 0 .08rem;
+  height: .82rem;
+  transition: height 0.5s ease-out;
+  overflow: hidden;
+}
+.sesame-container .sesame-main .sesame-item{
+  display: inline-flex;
+  align-items: center;
+  margin-right: .16rem;
+  margin-bottom: .16rem;
+  padding: .04rem .08rem;
+  font-size: .22rem;
+  line-height: .32rem;
+  color: #5F5E64;
+  border-radius: .08rem;
+  background: #fff;
+  border: 1px solid rgba(0, 0, 0, 0.1);
+  box-sizing: border-box;
+}
+.sesame-container .sesame-main .sesame-item-icon{
+  width: .32rem;
+  height: .32rem;
+  margin-right: .04rem;
+}
+.sesame-container .sesame-more{
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  text-align: center;
+  color: #5F5E64;
+}
+.sesame-container .sesame-more .drop-down-img{
+  width: .32rem;
+  height: .32rem;
+}
+.sesame-container .sesame-more .drop-down-img.rotate180{
+  transform: rotate(180deg);
+}
+.sesame-container .sesame-main.expanded {
+  height: auto!important;
+}

+ 128 - 4
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/ent_follow.js

@@ -17,22 +17,46 @@ var vNode = {
             refreshing: false,
             pageNum: 0,
             pageSize: 50,
-            scrollTop: 0
+            scrollTop: 0,
+            count: 0
         },
         entFollowList: [],
-        loading: ''
+        loading: '',
+        activeNames: [],
+        groupingList: [],
+        selectGroupList: [],
+        domTopNum: {
+          top: 0,
+        }
     },
     created: function () {
         var recover = this.recover()
         if (!recover) {
             this.getPowerInfo()
         }
+        this.getEntGroupList()
     },
     mounted: function () {
         $(this.$refs.jList).scrollTop(this.listInfo.scrollTop)
         this.adjustAddButtonPadding()
+        this.domTopNum.top = $('.j-header').outerHeight(true)
+        // 监听$(this.$refs.jList)的滚动值,使用addEventListener监听
+        const jListElement = document.getElementById('jList')
+        if (jListElement) {
+          jListElement.addEventListener('scroll', this.handleScroll);
+        }
+    },
+    computed: {
+      getListScroll () {
+        return this.listInfo.scrollTop
+      }
     },
     methods: {
+        handleScroll(event) {
+          // 获取滚动值
+          const scrollTop = event.target.scrollTop;
+          this.listInfo.scrollTop = scrollTop
+        },
         recover: function () {
             var excludeKey = ['sessStorageKey']
             var $data = sessionStorage.getItem(this.sessStorageKey)
@@ -69,7 +93,21 @@ var vNode = {
                 }
             })
         },
-        getEntFollowList: function () {
+        // 获取企业分组数据
+        getEntGroupList: function () {
+            var _this = this
+            $.ajax({
+                type: 'POST',
+                url: '/bigmember/follow/ent/labelGroupList?t=' + new Date().getTime(),
+                success: function (res) {
+                    if (res.error_code == 0) {
+                        // 获取企业分组列表
+                        _this.setEntGroupData(res.data?.groupUserArr || [])
+                    }
+                }
+            })
+        },
+        getEntFollowList: function (params = {group: ''}) {
             var _this = this
             $.ajax({
                 type: 'POST',
@@ -77,6 +115,7 @@ var vNode = {
                 data: {
                     pageNum: _this.listInfo.pageNum,
                     pageSize: _this.listInfo.pageSize,
+                    ...params
                 },
                 success: function (res) {
                     if (_this.listInfo.pageNum === 0) {
@@ -85,6 +124,7 @@ var vNode = {
                     }
                     if (res.error_code == 0) {
                         if (res.data && res.data) {
+
                             // 判断是否为刷新
                             if (_this.listInfo.refreshing) {
                                 _this.entFollowList = []
@@ -96,6 +136,9 @@ var vNode = {
                             if (res.data.followMax) {
                                 _this.conf.maxLength = res.data.followMax
                             }
+                            if(res.data.count) {
+                              _this.listInfo.count = res.data.count
+                            }
 
                             // 列表赋值
                             if (res.data.list) {
@@ -109,7 +152,17 @@ var vNode = {
                                         )
                                     })
                                 } catch (error) {}
-                                _this.entFollowList = _this.entFollowList.concat(res.data.list)
+                                if(params.group) {
+                                  // 分组筛选
+                                  if(_this.listInfo.pageNum !== 0) {
+                                    _this.entFollowList = _this.entFollowList.concat(res.data.list)
+                                  } else {
+                                    _this.entFollowList = res.data.list
+                                  }
+                                } else {
+                                  _this.entFollowList = _this.entFollowList.concat(res.data.list)
+                                }
+
                             }
 
                             // 翻页
@@ -128,6 +181,72 @@ var vNode = {
                 }
             })
         },
+        // 设置企业分组数据
+        setEntGroupData (data) {
+          data.unshift({
+            count: this.listInfo.count,
+            id: "",
+            isPut: -1,
+            name: "全部"
+          })
+
+          data.forEach(item => {
+            item.active = item.name === '全部' ? true : false
+          })
+          this.groupingList = data
+        },
+        changeGrouping: function (item) {
+          const isAll = item.name === '全部'
+          if(isAll) {
+            item.count = this.listInfo.count
+          }
+          if (!item.count) return
+          if(item.active) {
+            if(isAll) {
+              this.selectGroupList = []
+            } else {
+              item.active = !item.active
+              this.selectGroupList = this.selectGroupList.filter(s => s.name !== item.name)
+            }
+          } else {
+            if(isAll) {
+              this.selectGroupList = []
+              item.active = !item.active
+              this.groupingList.forEach(s => {
+                if(s.name !== '全部') {
+                  s.active = false
+                }
+              })
+            } else {
+              this.groupingList.forEach(s => {
+                if(s.name === '全部') {
+                  s.active = false
+                }
+              })
+              item.active = !item.active
+              this.selectGroupList.push(item)
+            }
+          }
+          console.log(this.selectGroupList)
+          const lengthBool = this.selectGroupList.length > 0
+          if(!lengthBool) {
+            this.groupingList.forEach(s => {
+              s.active = false
+              if(s.name === '全部') {
+                s.active = true
+              }
+            })
+          }
+          this.listInfo.pageNum = 0
+          this.getEntFollowList({
+            pageNum: this.listInfo.pageNum,
+            group: lengthBool ? this.selectGroupList.map(s => s.id).join(',') : ''
+          })
+          $('.j-main').scrollTop(0)
+        },
+        groupManage: function () {
+            location.href = '/jy_mobile/entgroup/index'
+        },
         onRefresh: function () {
             // 重置数据
             this.listInfo.pageNum = 0
@@ -136,8 +255,13 @@ var vNode = {
             // 重新加载数据
             // 将 loading 设置为 true,表示处于加载状态
             this.listInfo.loading = true
+            // 将分组选择置为全部
+            this.groupingList.forEach(item => {
+              item.active = item.name === '全部' ? true : false
+            })
             // 请求数据
             this.getEntFollowList()
+            
         },
         connectEnt: function (phone) {
             try {

+ 323 - 19
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/ent_portrait.js

@@ -6,6 +6,7 @@ var vNode = {
     hisproComponent: hisproComponent,
     forwardshare: vmForward,
     mobilePortrayalFooter:mobilePortrayalFooter,
+    mobilePortrayalGroupingScript: mobilePortrayalGroupingScript,
     downloadpopup: downloadpopup,
 
   },
@@ -192,7 +193,23 @@ var vNode = {
       isLogin: false,
       // 是否是免费用户
       isFree: false,
-      balance:0
+      balance:0,
+      moreSesame: false,
+      isOneRow: false,
+      showGroupingDialog: false,
+      groupingList: [], // 监控分组列表
+      groupLimit: {}, // 监控达到上限返回值
+      sourceMap: {
+        app: 'app_ent_more',
+        wx: 'wx_ent_more',
+        h5: 'h5_ent_more'
+      },
+      sourceLimitMap: {
+        app: 'app_ent_limit',
+        wx: 'wx_ent_limit',
+        h5: 'h5_ent_limit'
+      },
+      setGroupState: '' // 如果为put说明是企业画像-已监控-更改
     }
   },
   created: function () {
@@ -349,6 +366,25 @@ var vNode = {
     }
   },
   methods: {
+    doMiniPostMessageShareFn (title) {
+      try {
+        wx.miniProgram.postMessage({ data: {
+            post: 'share',
+            type: 'common',
+            desc: '企业画像',
+            title: title + '画像分析'
+          }})
+      } catch (e) {
+        console.log(e)
+      }
+    },
+    doMiniPostMessageShare (title) {
+      this.doMiniPostMessageShareFn(title)
+      var _that = this
+       window.miniAppInitLoaded = function () {
+        _that.doMiniPostMessageShareFn(title)
+      }
+    },
     restoreTab: function() {
       var tab = utils.getParam('tab') || ''
       if (tab) {
@@ -365,6 +401,105 @@ var vNode = {
         referer: location.href
       }
     },
+    updateGroupList () {
+      this.getEntGroupList()
+    },
+    // 查看监控动态
+    lookDynamic () {
+      this.scrollToTab('4')
+    },
+    // 获取企业分组列表, 当关注达到上限时,这个接口照样返回列表,而labelGroup接口不会返回,所有更改企业分组时选择这个接口显示列表
+    getEntGroupListData () {
+      var _this = this
+      $.ajax({
+        url: '/bigmember/follow/ent/labelGroupList',
+        type: 'POST',
+        success: function (res) {
+          if (res.error_code === 0) {
+            res.data.groupUserArr.forEach(function (item) {
+              item.s_name = item.name
+            })
+            _this.groupingList = res.data.groupUserArr || []
+          }
+        }
+      })
+    },
+    // 获取企业分组列表
+    getEntGroupList () {
+      var _this = this
+      $.ajax({
+        url: '/bigmember/follow/ent/labelGroup',
+        type: 'POST',
+        data: {
+          type: 'get'
+        },
+        success: function (res) {
+          if (res.error_code === 0) {
+            _this.groupingList = res.data || []
+            _this.showGroupingDialog = true
+            // 回显上次选择的分组
+            const filterSelect = _this.groupingList.filter(item => !!item.isSelect)
+            const selectList = filterSelect.map(item => item.s_name) || ['默认分组']
+            _this.$refs.portrayalGrouping.setState(selectList)
+            
+          } else {
+            if(!res?.data?.status) {
+                // 监控达到上限
+              _this.$dialog({
+                width: 303,
+                className: 'monitor-dialog',
+                title: '监控企业个数已达上限',
+                message: '您最多可监控'+res?.data.limit_count+'个企业,可联系客服,申请监控更多企业',
+                messageAlign:'center',
+                confirmButtonText: '联系客服',
+                confirmButtonColor: '#2ABED1',
+                showConfirmButton: true,
+                showCancelButton: true,
+                cancelButtonText: '我再想想',
+                // cancelButtonColor: '#5F5E64'
+              }).then(() =>{
+                if(utils.$envs.inWX){
+                  window.location.href = '/big/wx/page/customer'
+                } else{
+                  window.location.href = '/jyapp/free/customer'
+                }
+              })
+            }
+          }
+        }
+      })
+    },
+    confirmGrouping (params) {
+      var _this = this;
+      // 确认分组事件
+      console.log(params, 'params')
+      this.showGroupingDialog = false
+      // 企业画像-已监控-更改分组
+      if(this.setGroupState === 'put') {
+        $.ajax({
+          url: '/bigmember/follow/ent/changeGroup',
+          type: 'POST',
+          data: params,
+          success: function (res) {
+            if (res.data === 'success') {
+              _this.$toast('修改分组成功')
+              // 更新分组内容
+              _this.getEntFollowState()
+            } else {
+              // 处理错误情况
+              _this.$toast(res.error_msg)
+            }
+          }
+        })
+        _this.setGroupState = ''
+      } else {
+        this.changeFollowStateRequest(params)
+      }
+    },
+    cancelGrouping () {
+      this.showGroupingDialog = false
+      this.setGroupState = ''
+    },
     // 监听画像页面滚动
     onEntScroll: utils.debounce(function (e) {
       this.pageScrollTop = e.target.scrollTop
@@ -761,15 +896,21 @@ var vNode = {
         data: {
           entId: _this.entInfo.id
         },
-        timeout: 6000,
+        // timeout: 6000,
         success: function (res) {
           if (res.error_code == 0) {
             if (res.data && Object.keys(res.data).length !== 0) {
               _this.entInfo.name = res.data.entName
+              _this.doMiniPostMessageShare(_this.entInfo.name)
               _this.entBaseInfo._empty = false
               for (var key in res.data) {
                 _this.entBaseInfo[key] = res.data[key]
               }
+              if(res.data.zhimaLabels) {
+                setTimeout(function() {
+                  _this.checkIsOneRow()
+                }, 500)
+              }
             }
           } else {
             // 不显示提示信息
@@ -787,8 +928,23 @@ var vNode = {
         },
       })
     },
+    changeGroupState: function (type) {
+      console.log(type);
+      this.getEntGroupListData() 
+      this.$nextTick(() => {
+        this.setGroupState = type
+        this.showGroupingDialog = true
+        const followedGroup = this.entInfo.followedGroup
+        let groupList = []
+        const isManyGroup = followedGroup.includes(',')
+        groupList = isManyGroup ? followedGroup.split(',') : [followedGroup]
+        if(!groupList.includes('默认分组')) {
+          this.$refs.portrayalGrouping.setState(groupList)
+        }
+      })
+    },
     // 查询企业是否存在和企业关注状态
-    getEntFollowState: function () {
+    getEntFollowState: function (callback) {
       var _this = this
       _this.entInfo.followSearchFinish = false
       $.ajax({
@@ -804,6 +960,9 @@ var vNode = {
             if (res.data) {
               _this.entInfo.follow = !!res.data.followed
               _this.entInfo.entExist = !!res.data.isShow
+              _this.entInfo.followedGroup = res.data.followedGroup
+              _this.entInfo.info = res.data.info
+              callback && callback(res.data)
             } else {
               _this.entInfo.entExist = false
             }
@@ -816,25 +975,73 @@ var vNode = {
         }
       })
     },
-    changeFollowState: function () {
+    changeFollowState: function (state) {
       var _this = this
-      if(!this.isLogin) {
+      if(!_this.isLogin) {
         window.location.href = "/jyapp/free/login?to=back";
         return
       }
-      if (this.entInfo.follow) {
-        this.$dialog.confirm({
-          title: '提示信息',
-          message: '取消对“' + _this.entInfo.name + '”的关注?',
-          confirmButtonColor: '#2cb7ca'
-        }).then(function () {
-          _this.changeFollowStateRequest()
-        })
+      if (_this.entInfo.follow) {
+        if(!state) {
+          _this.$dialog.confirm({
+            title: '提示信息',
+            message: '取消对“' + _this.entInfo.name + '”的关注?',
+            confirmButtonColor: '#2cb7ca'
+          }).then(function () {
+            _this.changeFollowStateRequest()
+          })
           .catch(function () {
             console.log('取消操作')
           })
+        } else {
+          _this.changeFollowStateRequest()
+        }
+        
       } else {
-        this.changeFollowStateRequest()
+        this.getEntFollowState((res) => {
+          const { surplus, used } = res.info
+          const monitorEntNum = surplus + used  // 可监控企业总数
+          let limit = this.powerInfo.memberStatus > 0 || this.powerInfo.entniche
+          // 1.超出可监控企业数量
+          if (surplus <= 0) {
+            // 大会员或商机管理用户
+            if (limit) {
+              this.$dialog({
+                width: 303,
+                className: 'monitor-dialog',
+                title: '监控企业个数已达上限',
+                message: '您最多可监控'+monitorEntNum+'个企业,可联系客服,申请监控更多企业',
+                messageAlign:'center',
+                confirmButtonText: '联系客服',
+                confirmButtonColor: '#2ABED1',
+                showConfirmButton: true,
+                showCancelButton: true,
+                cancelButtonText: '我再想想',
+                // cancelButtonColor: '#5F5E64'
+              }).then(() =>{
+                if(utils.$envs.inWX){
+                   window.location.href = '/big/wx/page/customer'
+                } else{
+                  window.location.href = '/jyapp/free/customer'
+                }
+              })
+            } else {
+              // 非大会员非商机管理用户,进入留资页面
+              let href_
+              if(utils.$envs.inWX){
+                href_ = '/weixin/frontPage/bigmember/free/perfect_info?source=' + this.sourceLimitMap.wx
+              }else if(utils.$envs.inApp){
+                href_ = '/jyapp/frontPage/bigmember/free/perfect_info?source=' + this.sourceLimitMap.app
+              }else if(utils.$envs.inH5){
+                href_ = '/jyapp/frontPage/bigmember/free/perfect_info?source=' + this.sourceLimitMap.h5
+              }
+              window.location.href = href_
+            }
+          } else {
+            this.getEntGroupList()
+          }
+        })
+        // this.changeFollowStateRequest()
       }
     },
     canReadConf13: function () {
@@ -977,7 +1184,7 @@ var vNode = {
       })
     },
     // 修改企业关注状态
-    changeFollowStateRequest: function () {
+    changeFollowStateRequest: function (params = {}) {
       var _this = this
       var loading = this.showLoading()
       var urls = {
@@ -989,7 +1196,8 @@ var vNode = {
         type: 'POST',
         url: url,
         data: {
-          entId: _this.entInfo.id
+          entId: _this.entInfo.id,
+          ...params
         },
         timeout: 5000,
         success: function (res) {
@@ -998,7 +1206,53 @@ var vNode = {
             sessionStorage.removeItem('$data-ent_follow')
             loading.clear()
             if (res.data === 'success' || res.data.status) {
+              const active = !_this.powerInfo.isFree ? 4 : 3
               _this.entInfo.follow = !_this.entInfo.follow
+              _this.getEntFollowState()
+              if(utils.$envs.inApp && JyObj.checkNoticePermission()!=1 && res.data.status){
+                _this.$dialog({
+                  width: 303,
+                  className: 'monitor-dialog',
+                  title: '监控成功',
+                  message: '您可前往“工作台-商机-企业情报监控”查看企业最新动态。为保证您能及时获取新增监控信息推送,请前往开启推送提醒。',
+                  messageAlign:'center',
+                  confirmButtonText: '去开启',
+                  confirmButtonColor: '#2ABED1',
+                  showConfirmButton: true,
+                  showCancelButton: true,
+                  cancelButtonText: '暂不开启',
+                  // cancelButtonColor: '#5F5E64'
+                }).then(() =>{
+                  //  展开监控菜单 active:4
+                  window.location.href = location.origin + '/jy_mobile/push/pushsetting?active=' + active
+                })
+                return
+              }
+              if(!res.data.msg_open && res.data.status){
+                _this.$dialog({
+                  width: 303,
+                  className: 'monitor-dialog',
+                  title: '监控成功',
+                  message: '您可前往“工作台-商机-企业情报监控”查看企业最新动态。为保证您能及时获取新增监控信息推送,请前往开启推送提醒。',
+                  messageAlign:'center',
+                  confirmButtonText: '去开启',
+                  confirmButtonColor: '#2ABED1',
+                  showConfirmButton: true,
+                  showCancelButton: true,
+                  cancelButtonText: '暂不开启',
+                  // cancelButtonColor: '#5F5E64'
+                }).then(() =>{
+                  //  展开监控菜单 active:3
+                  window.location.href = location.origin + '/jy_mobile/push/pushsetting?active=' + active
+                })
+        
+              } else if(res.data.msg_open && res.data.status){
+                _this.$toast({
+                  duration: 2000,
+                  message: '监控成功,您可前往“工作台-商机-企业情报监控”查看'
+                })
+        
+              }
             } else {
               return _this.showToast(res.error_msg || '监控失败')
             }
@@ -1006,9 +1260,9 @@ var vNode = {
               _this.pointsTaskSuccessTip()
             }
 
-            if (!_this.entInfo.follow) {
-              history.back()
-            }
+            // if (!_this.entInfo.follow) {
+            //   history.back()
+            // }
           } else {
             _this.showToast(res.error_msg)
           }
@@ -1019,6 +1273,39 @@ var vNode = {
         }
       })
     },
+    lookMore (){
+      if(this.powerInfo.memberStatus > 0 || this.powerInfo.entniche){
+        this.$dialog({
+          width: 303,
+          className: 'monitor-dialog',
+          title: `申请监控更多企业`,
+          message: `您可联系客服,申请升级产品套餐,监控更多企业`,
+          messageAlign:'center',
+          confirmButtonText: '联系客服',
+          confirmButtonColor: '#2ABED1',
+          showConfirmButton: true,
+          showCancelButton: true,
+          cancelButtonText: '我再想想',
+          // cancelButtonColor: '#2ABED1'
+        }).then(() =>{
+          if(utils.$envs.inWX){
+            window.location.href = '/big/wx/page/customer'
+         } else{
+           window.location.href = '/jyapp/free/customer'
+         }
+        })
+      }else{
+        let href_
+        if(utils.$envs.inWX){
+          href_ = '/weixin/frontPage/bigmember/free/perfect_info?source=' + this.sourceMap.wx
+        }else if(utils.$envs.inApp){
+          href_ = '/jyapp/frontPage/bigmember/free/perfect_info?source=' + this.sourceMap.app
+        }else if(utils.$envs.inH5){
+          href_ = '/jyapp/frontPage/bigmember/free/perfect_info?source=' + this.sourceMap.h5
+        }
+        window.location.href = href_
+      }
+    },
     // 赚剑鱼币任务完成提示
     pointsTaskSuccessTip: function() {
       // 获取剑鱼币任务信息
@@ -1633,6 +1920,23 @@ var vNode = {
       } else if (type === 'buy') {
         location.href = '/jy_mobile/common/order/create/svip?type=buy'
       }
+    },
+    checkIsOneRow: function() {
+      var container = document.querySelector('.sesame-main');
+      if(!container) return
+      var items = container.getElementsByClassName('sesame-item');
+
+      // 获取所有子元素的top值,如果所有子元素的top值相同,则说明只有一行
+      var firstItemTop = items[0].offsetTop;
+      var isOneRow = true;
+
+      for (var i = 1; i < items.length; i++) {
+        if (items[i].offsetTop !== firstItemTop) {
+          isOneRow = false;
+          break;
+        }
+      }
+      this.isOneRow = isOneRow
     }
   }
 }

+ 288 - 4
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/potential_cor_list.js

@@ -12,6 +12,9 @@ var titleMap = {
 var vConfig = {
     delimiters: ['${', '}'],
     el: '#potential-cor-list',
+    components: {
+      mobilePortrayalGroupingScript: mobilePortrayalGroupingScript,
+    },
     data: {
         surplusCount: 0, // 试用版剩余竞争对手数量(非试用)
         // 是否显示引导购买入口
@@ -63,6 +66,15 @@ var vConfig = {
             }
         },
         power: [],
+        showGroupingDialog: false,
+        isLogin: false,
+        groupingList: [],
+        selectedItem: {},
+        sourceLimitMap: {
+          app: 'app_ent_limit',
+          wx: 'wx_ent_limit',
+          h5: 'h5_ent_limit'
+        },
     },
     computed: {
         showTrialGuideBuy: function () {
@@ -85,6 +97,7 @@ var vConfig = {
     created: function () {
         this.type = utils.getParam('type') || '1'
         this.getVipStatus()
+        this.getUserSimpleInfo()
     },
     mounted: function () {
         // 恢复数据
@@ -176,6 +189,7 @@ var vConfig = {
                 url: '/bigmember/use/isAdd',
                 success: function (res) {
                     if (res.data) {
+                        _this.powerInfo = res.data
                         _this.bigVipStatus = res.data.memberStatus || 0
                         if ($.isArray(res.data.power)) {
                             _this.power = res.data.power
@@ -281,12 +295,282 @@ var vConfig = {
                 }
             })
         },
+        // 判断当前用户是登录
+        getUserSimpleInfo() {
+          const _this = this
+          $.ajax({
+            type: 'POST',
+            url: '/jypay/user/getSimpleData',
+            success: function (res) {
+              if(res && res.userId) {
+                _this.isLogin = true
+              }
+            },error:function (e) {
+              _this.isLogin = false
+            }
+          })
+        },
+        // changeFollowState: function (item) {
+        //     if (!this.pagePower){
+        //     	this.changeFS_normal(item)
+        //     } else {
+        //     	this.changeFS_bigvip(item)
+        //     }
+        // },
+
+        monitorCancellation (){ // 取消监控
+          this.$dialog({
+            width: 303,
+            className: 'monitor-dialog',
+            title: '确定不再监控?',
+            message: `取消监控,将错过企业最新动态推送`,
+            messageAlign:'center',
+            confirmButtonText: '确认取消',
+            confirmButtonColor: '#2ABED1',
+            showConfirmButton: true,
+            showCancelButton: true,
+            cancelButtonText: '我再想想',
+            cancelButtonColor: '#2ABED1'
+          }).then(() =>{
+            this.changeFollowStateRequest()
+          })
+        },
+        
         changeFollowState: function (item) {
-            if (!this.pagePower){
-            	this.changeFS_normal(item)
-            } else {
-            	this.changeFS_bigvip(item)
+          var _this = this
+          _this.selectedItem = item
+          if(!_this.isLogin) {
+            window.location.href = "/jyapp/free/login?to=back";
+            return
+          }
+          if (item.follow) {
+            _this.monitorCancellation()
+            
+          } else {
+            this.getEntFollowState(item, (res) => {
+              const { surplus, used } = res.info
+              const monitorEntNum = surplus + used  // 可监控企业总数
+              let limit = this.powerInfo.memberStatus > 0 || this.powerInfo.entniche
+              // 1.超出可监控企业数量
+              if (surplus <= 0) {
+                // 大会员或商机管理用户
+                if (limit) {
+                  this.$dialog({
+                    width: 303,
+                    className: 'monitor-dialog',
+                    title: '监控企业个数已达上限',
+                    message: '您最多可监控'+monitorEntNum+'个企业,可联系客服,申请监控更多企业',
+                    messageAlign:'center',
+                    confirmButtonText: '联系客服',
+                    confirmButtonColor: '#2ABED1',
+                    showConfirmButton: true,
+                    showCancelButton: true,
+                    cancelButtonText: '我再想想',
+                    // cancelButtonColor: '#5F5E64'
+                  }).then(() =>{
+                    if(utils.$envs.inWX){
+                       window.location.href = '/big/wx/page/customer'
+                    } else{
+                      window.location.href = '/jyapp/free/customer'
+                    }
+                  })
+                } else {
+                  // 非大会员非商机管理用户,进入留资页面
+                  let href_
+                  if(utils.$envs.inWX){
+                    href_ = '/weixin/frontPage/bigmember/free/perfect_info?source=' + this.sourceLimitMap.wx
+                  }else if(utils.$envs.inApp){
+                    href_ = '/jyapp/frontPage/bigmember/free/perfect_info?source=' + this.sourceLimitMap.app
+                  }else if(utils.$envs.inH5){
+                    href_ = '/jyapp/frontPage/bigmember/free/perfect_info?source=' + this.sourceLimitMap.h5
+                  }
+                  window.location.href = href_
+                }
+              } else {
+                this.getEntGroupList()
+              }
+            })
+          }
+        },
+        // 修改企业关注状态
+        changeFollowStateRequest: function (params = {}) {
+          var _this = this
+          var loading = this.showLoading()
+          var urls = {
+            addFollow: '/bigmember/follow/ent/addFollow',
+            delFollow: '/bigmember/follow/ent/delFollow'
+          }
+          var url = !!this.selectedItem.follow ? urls.delFollow : urls.addFollow
+          $.ajax({
+            type: 'POST',
+            url: url,
+            data: {
+              ...params,
+              entId: _this.selectedItem.entId,
+            },
+            timeout: 5000,
+            success: function (res) {
+              if (res.error_code == 0) {
+                loading.clear()
+                if (res.data === 'success' || res.data.status) {
+                  const active = !_this.powerInfo.isFree ? 4 : 3
+                  if(_this.selectedItem.follow) {
+                    _this.$toast({
+                      duration: 2000,
+                      message: '取消监控成功'
+                    })
+                  }
+                  _this.selectedItem.follow = !_this.selectedItem.follow
+                  // _this.getEntFollowState()
+                  if(utils.$envs.inApp && JyObj.checkNoticePermission()!=1 && res.data.status){
+                    _this.$dialog({
+                      width: 303,
+                      className: 'monitor-dialog',
+                      title: '监控成功',
+                      message: '您可前往“工作台-商机-企业情报监控”查看企业最新动态。为保证您能及时获取新增监控信息推送,请前往开启推送提醒。',
+                      messageAlign:'center',
+                      confirmButtonText: '去开启',
+                      confirmButtonColor: '#2ABED1',
+                      showConfirmButton: true,
+                      showCancelButton: true,
+                      cancelButtonText: '暂不开启',
+                      // cancelButtonColor: '#5F5E64'
+                    }).then(() =>{
+                      //  展开监控菜单 active:4
+                      window.location.href = location.origin + '/jy_mobile/push/pushsetting?active=' + active
+                    })
+                    return
+                  }
+                  if(!res.data.msg_open && res.data.status){
+                    _this.$dialog({
+                      width: 303,
+                      className: 'monitor-dialog',
+                      title: '监控成功',
+                      message: '您可前往“工作台-商机-企业情报监控”查看企业最新动态。为保证您能及时获取新增监控信息推送,请前往开启推送提醒。',
+                      messageAlign:'center',
+                      confirmButtonText: '去开启',
+                      confirmButtonColor: '#2ABED1',
+                      showConfirmButton: true,
+                      showCancelButton: true,
+                      cancelButtonText: '暂不开启',
+                      // cancelButtonColor: '#5F5E64'
+                    }).then(() =>{
+                      //  展开监控菜单 active:3
+                      window.location.href = location.origin + '/jy_mobile/push/pushsetting?active=' + active
+                    })
+            
+                  } else if(res.data.msg_open && res.data.status){
+                    _this.$toast({
+                      duration: 2000,
+                      message: '监控成功,您可前往“工作台-商机-企业情报监控”查看'
+                    })
+            
+                  }
+                } else {
+                  return _this.showToast(res.error_msg || '监控失败')
+                }
+                // if(_this.selectedItem.follow) {
+                //   _this.pointsTaskSuccessTip()
+                // }
+
+                // if (!_this.selectedItem.follow) {
+                //   history.back()
+                // }
+              } else {
+                _this.showToast(res.error_msg)
+              }
+            },
+            error: function (error) {
+              console.log(error)
+              loading.clear()
+            }
+          })
+        },
+        // 获取企业分组列表
+        getEntGroupList () {
+          var _this = this
+          $.ajax({
+            url: '/bigmember/follow/ent/labelGroup',
+            type: 'POST',
+            data: {
+              type: 'get'
+            },
+            success: function (res) {
+              if (res.error_code === 0) {
+                _this.groupingList = res.data || []
+                _this.showGroupingDialog = true
+                // 回显上次选择的分组
+                const filterSelect = _this.groupingList.filter(item => !!item.isSelect)
+                const selectList = filterSelect.map(item => item.s_name) || ['默认分组']
+                _this.$refs.portrayalGrouping.setState(selectList)
+                
+              } else {
+                if(!res?.data?.status) {
+                    // 监控达到上限
+                  _this.$dialog({
+                    width: 303,
+                    className: 'monitor-dialog',
+                    title: '监控企业个数已达上限',
+                    message: '您最多可监控'+res?.data.limit_count+'个企业,可联系客服,申请监控更多企业',
+                    messageAlign:'center',
+                    confirmButtonText: '联系客服',
+                    confirmButtonColor: '#2ABED1',
+                    showConfirmButton: true,
+                    showCancelButton: true,
+                    cancelButtonText: '我再想想',
+                    // cancelButtonColor: '#5F5E64'
+                  }).then(() =>{
+                    if(utils.$envs.inWX){
+                      window.location.href = '/big/wx/page/customer'
+                    } else{
+                      window.location.href = '/jyapp/free/customer'
+                    }
+                  })
+                }
+              }
             }
+          })
+        },
+        getEntFollowState: function (item, callback) {
+          var _this = this
+          // _this.selectedItem.followSearchFinish = false
+          $.ajax({
+            type: 'POST',
+            url: '/bigmember/follow/ent/followCheck',
+            data: {
+              entId: item.entId
+            },
+            timeout: 5000,
+            success: function (res) {
+              if (res.error_code == 0) {
+                // _this.selectedItem.followSearchFinish = true
+                if (res.data) {
+                  _this.selectedItem.follow = !!res.data.followed
+                  // _this.selectedItem.entExist = !!res.data.isShow
+                  // _this.selectedItem.followedGroup = res.data.followedGroup
+                  _this.selectedItem.info = res.data.info
+                  callback && callback(res.data)
+                } else {
+                  // _this.selectedItem.entExist = false
+                }
+              } else {
+                _this.$toast(res.error_msg)
+              }
+            },
+            error: function (error) {
+              console.log(error)
+            }
+          })
+        },
+        confirmGrouping: function(params) {
+          this.showGroupingDialog = false
+          this.changeFollowStateRequest(params)
+        },
+        cancelGrouping: function () {
+          this.showGroupingDialog = false
+        },
+        updateGroupList () {
+          this.getEntGroupList()
         },
         changeFS_normal:function(item){
         	var _this = this

+ 1 - 1
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/report_analysis.js

@@ -1819,7 +1819,7 @@ var vm = new Vue({
     toSubManage: function () {
       location.href = '/jyapp/vipsubscribe/toSetKeyWordPage?vSwitch=m'
     },
-    toArticleContent (item) {
+    clickTOP10ProjectName (item) {
       this.saveState()
       location.href = `/jyapp/article/content/${item._id}.html`
     },

+ 20 - 0
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/unit_portrayal.js

@@ -325,6 +325,7 @@ var vNode = {
   created () {
     this.buyer.name = decodeURIComponent(utils.getParam('entName'))
     this.portraitName = decodeURIComponent(utils.getParam('entName'))
+    this.doMiniPostMessageShare(this.buyer.name)
     this.getUserSimpleInfo()
     this.restore = this.reStoreState()
     setTimeout(() => {
@@ -358,6 +359,25 @@ var vNode = {
     window.removeEventListener("resize", this.init, 20);
   },
   methods: {
+    doMiniPostMessageShareFn (title) {
+      try {
+        wx.miniProgram.postMessage({ data: {
+            post: 'share',
+            type: 'common',
+            desc: '采购单位画像',
+            title: title + '画像分析'
+          }})
+      } catch (e) {
+        console.log(e)
+      }
+    },
+    doMiniPostMessageShare (title) {
+      this.doMiniPostMessageShareFn(title)
+      var _that = this
+      window.miniAppInitLoaded = function () {
+        _that.doMiniPostMessageShareFn(title)
+      }
+    },
     restoreTab: function() {
       var tab = utils.getParam('tab') || ''
       if (tab) {

+ 1 - 1
src/jfw/modules/app/src/web/staticres/jyapp/css/wxinfocontent.css

@@ -547,7 +547,7 @@ body .loading_ p span {
 }
 
 .jykeyword {
-    color: #2cb7ca;
+    color: #FA6F33;
 }
 
 .filename {

+ 49 - 1
src/jfw/modules/app/src/web/staticres/jyapp/followent/css/follow.css

@@ -257,9 +257,12 @@ a {
 	margin-left:5px;
 }
 .listpage .jytimest{
+  display: flex;
+  justify-content: flex-end;
+  align-items: center;
 	margin:15px 5px 5px;
 	text-align: right;
-    padding-right: 5%;    
+  padding-right: 5%;    
 	color: #a0a0a0;
 	margin-right: -3px;
 }
@@ -515,4 +518,49 @@ a {
   background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAIESURBVHgB5VfRccIwDFV6HYANmg3qEcIGbNBsUDYgTFA6Ad2g3SB0AmCCsAFsoEqNTFXXTmxDv3h3Ouew9SRZsmwAbh0FZAARJzSUJIbkJLIriuIE/wkyXJG0GAbP1XBtEGnpMbwlWZO8e+Y61oFrgIgMyVERzyUF7roJRy9rUHQMXALH+JvPcMCR1cVOCJGNpoFEKCe6GMd9BAtLAJlQtdFAKlT0VYKO0cWH/amxqYjfBaW4TdCx9XJ0fm+HArkL8NnFnxBpnIaWhKN8dab3DmeUA6WMO8fQM8uA8SV1w8bhshwP4ME9pKFhQ5xPMrSMMD6KMQfcwpmKwUaKqo4wnnUE51I4K8+cbk6jRwz7ds2YQ4ID5+MTmLdONBFcnXCldUR1fOI9/8tRZzczp4mUkAjsb1AbfQ05ULvQpTjhGF9DKiTH39euIuJxFqFbOTrszFN0DagCO8o3E2zxB63k1jgR1/j7YdLK70al0sQaR6U0k7lGRTaE8+lgXQ+fiTWu8SLR6Eg7Nc/f/DSzaZuITshB43Ngi8PosG8q5cAOcv4XGA7E4nzLFkqZWyZ7VpE8yui20QPJlNruIeCAvhs0+Lm+gf52Zd3N6BMeM1+66E/lR2j93QDXXn0fYCByDVrD1y9fWjrCHaQCVRvFvE6od6KCVGBfyS1e8AdDnGgx51V8M/gC6u7qiWrVshgAAAAASUVORK5CYII=) no-repeat center center;
   background-size: contain;
   margin-right: .04rem;
+}
+
+.ent-grouping .grouping-list {
+  display: flex;
+  flex-wrap: wrap;
+  max-height: 2.04rem;
+  overflow: hidden;
+  overflow-y: auto;
+}
+
+.ent-grouping .grouping-list .grouping-item {
+  margin: 0 .16rem .16rem 0;
+  padding: 0 .24rem;
+  border: 0.5px solid rgba(192, 196, 204, 1);
+  border-radius: .3rem;
+  line-height: .52rem;
+  color: #5F5E64;
+}
+
+.ent-grouping .grouping-list .grouping-item.active {
+  background: #2ABED1;
+  border-color: #2ABED1;
+  color: #fff;
+}
+
+.ent-grouping .grouping-list .grouping-item.disabled {
+  background: #F5F6F7;
+}
+
+.ent-grouping .grouping-footer {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin-top: .24rem;
+  font-size: .28rem;
+  line-height: .4rem;
+  color: #2ABED1;
+}
+
+.ent-grouping .grouping-footer .grouping-item-name {
+  margin-right: .08rem;
+}
+.grouping-bot-line {
+  height: .2rem;
+  background: #F5F6F7;
 }

+ 2 - 0
src/jfw/modules/app/src/web/staticres/jyapp/js/common.js

@@ -355,6 +355,7 @@ window.utilsEnv = {
   },
   getPlatformEnvs: function () {
     var inWX = navigator.userAgent.toLowerCase().indexOf('micromessenger') !== -1
+    var inWeiXinMiniApp = navigator.userAgent.toLowerCase().indexOf('miniprogram') !== -1
     var inApp = this.getIsInTheAppContainer()
     var platformOS = this.androidOrIOS()
     var getPlatform = function () {
@@ -374,6 +375,7 @@ window.utilsEnv = {
       platformOS: platformOS,
       platform: platform,
       inApp: inApp,
+      inWxMini: inWeiXinMiniApp, // 微信小程序
       inWX: inWX
     }
   }

+ 159 - 0
src/jfw/modules/app/src/web/staticres/jyapp/js/slide-verify.js

@@ -0,0 +1,159 @@
+function initDialogWrapper() {
+  return new Vue({
+		el: '#slide-verify-node',
+		delimiters: ['${', '}'],
+		data: {
+			popupShow: false
+		}
+	})
+}
+
+var SMSRequest = {
+  getCaptcha: function(phone, mold, callback) {
+    $.ajax({
+      type: 'POST',
+      url: '/publicapply/captcha/get',
+      data: {
+        phone: phone,
+        mold: mold
+      },
+      success: function (res) {
+        if (res.error_code === 0 && res.data) {
+          callback && callback(res.data)
+        } else {
+          if (res.error_msg) {
+            showToast(res.error_msg)
+          }
+        }
+      }
+    })
+  },
+  verifyCaptcha: function(data, callback) {
+    $.ajax({
+      type: 'POST',
+      url: '/publicapply/captcha/check',
+      data: data,
+      success: function (res) {
+        callback && callback(res)
+      }
+    })
+  }
+}
+var slideVerify = {
+  el: null,
+  capt: null,
+  phone: '',
+  captKey: '',
+  mold: '',
+  $dialog: null,
+  init: function() {
+    if (!this.capt) {
+      this.$dialog = initDialogWrapper()
+      this.initSlideVerify()
+    }
+    this.modalShow(true)
+  },
+  initSlideVerify: function() {
+    var el = document.getElementById('slide-wrap');
+    var capt = new GoCaptcha.Slide({
+      width: 300,
+      height: 220,
+    })
+    capt.mount(el)
+    
+    this.el = el
+    this.capt = capt
+    this.bindCaptEvents()
+  },
+  modalShow: function(f) {
+    if (!this.$dialog) {
+      this.$dialog = initDialogWrapper()
+    }
+    this.$dialog.popupShow = f
+  },
+  bindCaptEvents: function() {
+    if (!this.capt) return
+    var _this = this
+    this.capt.setEvents({
+      close: function() {
+        _this.modalShow(false)
+      },
+      confirm: function(point, reset) {
+        const payload = {
+          phone: _this.phone,
+          key: _this.captKey,
+          point: [point.x, point.y].join(',')
+        }
+        SMSRequest.verifyCaptcha(payload, function(res) {
+          if (res.error_code === 0 && res.data) {
+            const pass = res.data && res.data.code === 0
+            reset()
+            if (pass) {
+              try {
+                startSendSMSCodeTimer()
+              } catch (error) {
+                console.log(error)                
+              }
+              _this.modalShow(false)
+            } else {
+              _this.capt.refresh()
+            }
+          } else {
+            reset()
+            _this.capt.refresh()
+          }
+        })
+      },
+      refresh: function() {
+        SMSRequest.getCaptcha(_this.phone, _this.mold, function(data) {
+          if (data && data.code === 1) {
+            _this.refreshCaptData(data)
+          }
+        })
+      },
+    })
+  },
+  cachePhone: function(phone) {
+    this.phone = phone
+  },
+  cacheMold: function(mold) {
+    this.mold = mold
+  },
+  cacheCaptKey: function(k) {
+    this.captKey = k
+  },
+  refreshCaptData: function(x) {
+    if (!this.capt) return
+    const captKey = x.captcha_key || ''
+    this.cacheCaptKey(captKey)
+    this.capt.setData({
+      image: x.image_base64 || '',
+      thumb: x.tile_base64 || '',
+      captKey: captKey,
+      thumbX: x.tile_x || 0,
+      thumbY: x.tile_y || 0,
+      thumbWidth: x.tile_width || 0,
+      thumbHeight: x.tile_height || 0
+    })
+  }
+}
+
+function initGoCaptchaVerify(phone, mold) {
+  SMSRequest.getCaptcha(phone, mold, function(data) {
+    if (data && data.code === 1) {
+      slideVerify.init()
+      slideVerify.cachePhone(phone)
+      slideVerify.cacheMold(mold)
+      slideVerify.refreshCaptData(data)
+    } else {
+      startSendSMSCodeTimer(mold)
+    }
+  })
+}
+
+function getCaptchaInfo() {
+  return {
+    phone: slideVerify.phone,
+    captKey: slideVerify.captKey
+  }  
+}

+ 15 - 2
src/jfw/modules/app/src/web/staticres/jyapp/me/css/forgetPwd.css

@@ -38,7 +38,7 @@ body {
 	display: block;
 }
 .register .registerMain .code input{
-	width: 100%;
+	height: 100%;
     font-size: 16px;
 	padding-left: 15px;
 }
@@ -62,4 +62,17 @@ body {
 }
 center{
 	padding: 0px 15px;
-}
+}
+
+.flex-line {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+}
+.flex-line-content {
+	flex: 1;
+}
+.flex-line-block {
+	display: inline-block!important;
+	height: 100%;
+}

+ 36 - 8
src/jfw/modules/app/src/web/staticres/jyapp/me/css/login.css

@@ -6,7 +6,7 @@
   border-radius: 8px;
 }
 .login {
-  margin-top: 20px;
+  margin-top: 8px;
   padding: 0px 25px;
   /*微信登陆*/
 }
@@ -68,24 +68,46 @@
   text-align: center;
 }
 
-.forget:not(.flex) .fast-login-open-link {
+.fast-login-open-link {
+  position: relative;
   font-size: 16px;
+  line-height: 26px;
+  color: #2ABED1;
+  margin-right: .48rem;
+}
+.fast-login-open-link::after {
+  content: '';
+  position: absolute;
+  top: 0;
+  right: -.24rem;
+  width: 1px;
+  height: 100%;
+  background-color: #2ABED1;
 }
 
+.fast-login-open-link.no-right-line {
+  margin-right: 0;
+}
+.fast-login-open-link.no-right-line::after {
+  content: unset;
+}
 
 .login .forget a {
   color: #2ABED1;
   font-size: 14px;
 }
 
-.login .forget .forget-password{
-    display: none;
-}
 
 /*.login .forget a.register {*/
 /*  float: right;*/
 /*}*/
 
+.third-and-fast-login-container {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
 .login .wx {
   text-align: center;
   margin-top:20px;
@@ -145,10 +167,9 @@
   display: flex;
   justify-content: center;
   align-items: center;
-  margin-top: .32rem;
   padding: .16rem;
-  width: .96rem;
-  height: .96rem;
+  width: .8rem;
+  height: .8rem;
   border-radius: 50%;
   background: rgba(15, 184, 103, 0.05);
   border: 1px solid rgba(15, 184, 103, 0.1);
@@ -252,6 +273,13 @@
 .jyapp-icon-zuojiantou-x:after{
 	top:38px;
 }
+.footer-container {
+  padding-top: .16rem;
+}
+.login-placeholder {
+  height: 30px;
+  transition: height 0.3s ease;
+}
 /*重置input默认样式*/
 /*input:-webkit-autofill{*/
 /*    -webkit-box-shadow: 0 0 0px 1000px transparent inset;*/

+ 2 - 2
src/jfw/modules/app/src/web/staticres/jyapp/me/js/login.js

@@ -45,9 +45,9 @@ var loginEvents = {
   },
   fastButtonShow: function (f) {
     if (f) {
-      $('.forget').removeClass('center').find('.fast-login-open-link').show()
+      $('.fast-login-open-link').show()
     } else {
-      $('.forget').addClass('center').find('.fast-login-open-link').hide()
+      $('.fast-login-open-link').hide()
     }
   },
   checkAutoFastLogin: function (auto) {

+ 7 - 0
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/base.css

@@ -129,3 +129,10 @@ em,i{
   color: #5F5E64!important;
   text-align: justify!important;
 }
+.refund-success-tip {
+  margin-left: .4rem;
+  font-size: .28rem;
+  color: #FB483D;
+  line-height: .4rem;
+  font-weight: 400;
+}

+ 12 - 1
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/keyWord.css

@@ -23,8 +23,9 @@
   align-items: center;
   justify-content: space-between;
   margin: 0 .16rem;
-  padding: .08rem .24rem;
+  padding: 0 .16rem 0 .24rem;
   font-size: .24rem;
+  line-height: .48rem;
   color: #171826;
   background-color: #fff;
   border-radius: 50px;
@@ -36,6 +37,16 @@
   margin-left: .08rem;
   transform: rotate(90deg);
 }
+.filter-action{
+    display: flex;
+    align-items: center;
+}
+.add-classify{
+    margin: 0 0.08rem;
+    color: #2abed1;
+    font-size: .28rem;
+    white-space: nowrap;
+}
 
 .j-key-card {}
 .j-key-card-top {

+ 6 - 7
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/keyword-common.css

@@ -290,13 +290,12 @@
 }
 
 .key-tag {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  padding: .02rem .12rem;
-  font-size: .2rem;
-  border: 1px solid;
-  border-radius: .26rem;
+    display: inline-block;
+    width: 0.28rem;
+    height: 0.28rem;
+    background: url('/common-module/vipsubscribe/image/v_vip_icon.png') no-repeat center;
+    background-size: contain;
+    margin-top:-0.16rem;
 }
 .key-tag.red {
   color: #FA483C;

+ 19 - 2
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/vip_index_new.css

@@ -114,7 +114,7 @@
 }
 .sub-box{
   background: url(../image/vip-index-bg.png) no-repeat center top #fff;
-  background-size: 100% 3rem;
+  background-size: 100% 2.84rem;
   padding-top: 21.33333vw;
 }
 .sub-info{
@@ -122,11 +122,12 @@
   background: linear-gradient(270deg, #F1D090 0%, #FAE7CA 100%);
   box-shadow: 0px 12px 16px rgba(250, 231, 202, 0.32);
   padding: .16rem .32rem;
-  margin: 0.24rem .24rem;
+  margin: .24rem .24rem 0;
 }
 .sub-info .item-label{
   font-size: .3rem;
   color: #1B1A2A;
+  font-weight: bold;
 }
 .sub-info .icon-arrow{
   font-size: .28rem;
@@ -880,4 +881,20 @@
 .icon_vip{
   background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAANpSURBVHgB7VdNTttAFH5jxyZIXaS70iKRnKBhE1p1AZyg7QkwJ4CeoOQEwAmAEwAnwCwq1IBKbpC0lQjtBi8qQW3PTN9z7MgEz9jgdJcvijyen+dv5v0OwBRTTKEFgwngdnBWN8HcQ2lNkFDDLpcDX5+de9uHkihNMCLHzMuYWFqy54fB6rP5d10oAQNKwjTMzw/IEbDPNq1tKInSBJHIB+UYqbwkyhP8z5jECXY1Y0dQEqUJkrfio58x1MexNpREJf0S/DxfAQveSymbjLFuKMPdSYQKHWTvshZWww3BRJNJ5vk82E17/ijMhIOLNQFif2w9ncKqiuSf31+aNrcOsVmHbGjXx/HzZHy9kOJT9eWbnRFB2kUwG/QywwUGXXuutZruSHYtQW5BATBgWyGEB+NE/V+dPRDgZCzwrFurwRqLXkSQVCsr8kT1ASTIbntndcu0mtKWy0jMUWxGx9IjpzEC41gYom/Pt7r+dedGJUcK+XHm1dJRZIO4oMY0ScUfdGQ0D38g4WkYEnGEJZxYplYWcvLoGRG0fdtFFXuPPpUE8engrr+Pugy2gI8VUNunDv3qXbU7FB0DDdbBnLr9KJJITHK5TqrIGs6x7UIy7+mVvMoQhoO7X4bh7vXgsI62tD9aj3aatGcbQ4dAVfagyCliwJdMHlMkSTtTpuHF7t/Lk2ndWc/J06gdXJ9vY/zcvDdhqPpCpxeHI3e8PzOTRDsg4TlIyBEouD+YUFS1+K0sckqCkWwujyEH8urbQtKOUp6EXWy68EgIIU5VY2qCTOYWmqERjFRKp26/bG1SUKe4SSqD4mSV85TBr6gdAhUKHNrc5G5WSvOvOjv4lQ2dAMy/i6rKW1vyF/ZASJEd3kfaCdkCG+3jiTdUg/pyS0KuHY6hjn8Hq5KdpKNANeTqBrUEOeNPuvAYzLgpPJnDqW64ohvEdHMUVIM9tezIEQCDe43yedz2KHUmc6JCRJN0yXZBg9xrp84O04E6C6p6L/X1rv2itQgaaE8wAtmhwguDmeAk/HHRxpDk0Z8H3DMtk06yySrsdW5ZprvPFCWIGcLF8j87TOC1Esunw+TVNM30OsiVLfKTQe6lKW1Pk0YR2bkEycZQVQcwaWBa1Nnv6PtQEH8HX/ex6l6DCYA2PDO35MAUU0xRHv8Al8ebBRh7GtgAAAAASUVORK5CYII=);
   background-size: 24px;
+}
+
+.subscribe-manage-tips {
+  padding: .24rem .24rem 0;
+  background: #fff;
+}
+.subscribe-manage-tips > span {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  padding: .12rem 0;
+  font-size: .26rem;
+  color: #2ABED1;
+  border-radius: .32rem;
+  line-height: .4rem;
+  background: rgba(42, 190, 209, 0.08);
 }

+ 6 - 0
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/css/vip_pay_success.css

@@ -48,6 +48,12 @@
   background-color: #EDEFF2;
 }
 
+.bottom_button .left_btn > p {
+  line-height: .24rem;
+  font-size: .24rem;
+  color: #2ABED1;
+}
+
 .bottom_button .right_btn {
   /* color: #F1D090;
   background-color: #1B1A2A; */

BIN
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/image/v_vip_icon.png


+ 8 - 2
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/keyWord.js

@@ -29,7 +29,8 @@ var vm = new Vue({
       ordinarykc: 0
     },
     scrollTop: 0, // 记录滚动高度
-    isenterprise:false
+    isenterprise:false,
+    toWhere: ''
   },
   computed: {
     // 关键词是否达到上限
@@ -81,6 +82,7 @@ var vm = new Vue({
   },
   created: function () {
     let identification = getParam('pagesource')
+    this.toWhere = utils.getParam('to')
     this.isenterprise = identification=='enterprise' ? true:false
     this.restoreState()
     this.getSwitchType()
@@ -699,7 +701,11 @@ var vm = new Vue({
       })
     },
     completeToEdit: function () {
-      history.back()
+      if (this.toWhere) {
+        location.replace(this.toWhere)
+      } else {
+        history.back()
+      }
     },
     // 恢复数据
     restoreState: function () {

+ 26 - 1
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/vip_index_new.js

@@ -28,7 +28,13 @@ var subNode = new Vue({
       vSwitch: '', // 用户权限
       freeUserArea: {}, // 购买省份订阅包的用户所选择的地区
       isNewVip: 0,
-      entVipPower: false
+      entVipPower: false,
+      infoRoot: {}
+    }
+  },
+  computed: {
+    isFree () {
+      return this.infoRoot?.isFree
     }
   },
   created () {
@@ -49,6 +55,23 @@ var subNode = new Vue({
     })
   },
   methods: {
+    // 判断是否进入(新)订阅向导
+    // 需求:进入“我的订阅管理(免费、超级订阅、大会员、商机管理)”页:在该用户身份下,未完成过订阅向导,则默认进入“订阅向导”页,否则进入“我的订阅管理”页
+    linkToSubscribeGuide: function() {
+      var _this = this
+      var vType = _this.vSwitch ? _this.vSwitch + 'Type' : 'fType'
+      $.ajax({
+        url: '/jyapi/jybx/subscribe/' + vType + '/someInfo?t=' + Date.now(),
+        type: 'POST',
+        success: function (res) {
+          if (res) {
+            if (res.data.isInTSguide) {
+              location.href = '/jy_mobile/subscribe/guide'
+            }
+          }
+        }
+      })
+    },
     // 省份订阅包续费
     renewBtn: function () {
       location.href = '/jy_mobile/common/order/create/areapack?type=renew'
@@ -161,6 +184,7 @@ var subNode = new Vue({
         url: '/bigmember/use/isAdd',
         type: 'POST',
         success: function (res) {
+          _this.infoRoot = res.data || {}
           // 如果是商机管理、大会员、超级订阅会员有筛选权限
           if (res.data.vipStatus > 0 && res.data.memberStatus > 0 && !res.data.isSubCount) {
             $('.custom-header-right').show()
@@ -184,6 +208,7 @@ var subNode = new Vue({
         success: function (res) {
           if (res.data) {
             _this.vSwitch = res.data.vt || 'f'
+            _this.linkToSubscribeGuide()
             // f 免费 m 大会员 v 超级订阅
             if (res.data.vt == 'm') {
               _this.vipLink = 'javascript:;'

+ 13 - 4
src/jfw/modules/app/src/web/staticres/jyapp/vipsubscribe/js/vip_order_detail.js

@@ -48,7 +48,15 @@ $(function () {
             		$(".discountPrice").parent().hide();
             }
             //价格
-            $(".price").text("¥ " + formatMoney(parseFloat(r.data.order.pay_money  || r.data.order.order_money) / 100));
+            if(r.data.order.refund_status && r.data.order.refund_status > 0){
+              const domSpan = '<span class="refund-success-tip">退款成功</span>'
+              $(".price").html("¥ " + formatMoney(parseFloat(r.data.order.pay_money  || r.data.order.order_money) / 100) + domSpan);
+              $('.refund-success-tip').show()
+            } else {
+              $(".price").text("¥ " + formatMoney(parseFloat(r.data.order.pay_money  || r.data.order.order_money) / 100));
+              $('.refund-success-tip').hide()
+            }
+            
             $(".totalPrice").text("¥ " + formatMoney(parseFloat(r.data.order.order_money) / 100) + "元");
             if (!r.data.order.isLiveActive) {
                 $(".origin-price-container").hide();
@@ -504,7 +512,7 @@ $(function () {
                         
                     } 
                         //已支付已申请发票
-                        if(r.data.order.invoice_show){
+                        if(r.data.order.invoice_show ){
                         pay_again += "<button class=\"j-button-cancel\" onclick= 'checkinvoice(" + r.data.order.applybill_status + ")' style='width: 100%!important;'>查看发票</button >"
                         // $(".invoice").css("display", "none");
                         }
@@ -519,8 +527,9 @@ $(function () {
                                 $(".taxpayer_number").html(r.data.order.applybill_taxnum);
                                 break;
                         }
-                    
-                       $(".j-footer").show().html(pay_again)     
+                        if (!r.data.order.refund_status) {
+                          $(".j-footer").show().html(pay_again)     
+                        }
                 
             } else if (r.data.order.order_status == -2 || r.data.order.order_status == -3) {
                 if( r.data.order.pay_way === "transferAccounts" && r.data.order.course_status === 3){

+ 52 - 9
src/jfw/modules/app/src/web/templates/areaPack/page_set_area.html

@@ -158,7 +158,9 @@
                 popupTip: false,
                 noAreaFreeType: false, // 免费用户未设置地区时显示弹窗
                 backTipShowCount: 0, // 离开页面展示弹窗次数
-                successBack: false
+                successBack: false,
+                keywords: '',
+                wordsMode: ''
             },
             computed: {
                 moreThanSubCount: function () {
@@ -216,9 +218,14 @@
             mounted: function () {
                 var type = utils.getParam('type')
                 var url = utils.getParam('url')
+                var keywords = utils.getParam('keywords')
+                this.wordsMode = utils.getParam('wordsMode')
                 if (url) {
                   this.params.url = decodeURIComponent(url)
                 }
+                if(keywords) {
+                  this.keywords = decodeURIComponent(keywords)
+                }
                 var restore = this.restoreState()
 
                 if (restore) {
@@ -331,14 +338,21 @@
                         success: function (res) {
                             if (res && res.success) {
                                 sessionStorage.setItem('needPlayClick', 'true')
-                                if (history.state) {
-                                  _this.successBack = true
-                                }
-                                if (_this.params.url) {
-                                  location.replace(_this.params.url)
-                                } else {
-                                  history.back()
-                                }
+                                _this.freeSubscribeKeys(function() {
+                                  if (history.state) {
+                                    _this.successBack = true
+                                  }
+                                  if (_this.params.url) {
+                                    // 有关键词的情况-跳到关键词页面=>完成=>回到标讯搜索页面
+                                    if (_this.keywords) {
+                                      location.replace(_this.params.url + '?to=/jy_mobile/search/result/bidding')
+                                    } else {
+                                      location.replace(_this.params.url)
+                                    }
+                                  } else {
+                                    history.back()
+                                  }
+                                })
                             } else {
                                 if (res.errMsg) {
                                     _this.$toast(res.errMsg)
@@ -389,6 +403,35 @@
                     }
                     sessionStorage.setItem(this.sessKey, JSON.stringify(data))
                 },
+                // P611需求:用户点击一键订阅,没有设置地区跳到地区设置,地区订阅成功后 要将一键订阅的关键词同步设置上
+                freeSubscribeKeys: function(callback) {
+                  var _this = this
+                  if (_this.keywords) {
+                    try {
+                      $.ajax({
+                        url: '/jyapp/member/swordfish/ajaxReq',
+                        type: 'POST',
+                        data: {
+                          keys: _this.keywords,
+                          reqType: 'subscribe',
+                          match_way: _this.wordsMode
+                        },
+                        success: function (res) {
+                          // flag === 'o' '您已经超过订阅关键字上限'
+                          // flag === 'y' '订阅成功'
+                          callback && callback()
+                        },
+                        error: function (error) {
+                          callback && callback()
+                        }
+                      })
+                    } catch (error) {
+                      callback && callback()
+                    }
+                  } else {
+                    callback && callback()
+                  }
+                }
             }
         })
 

+ 6 - 3
src/jfw/modules/app/src/web/templates/big-member/page_bigvip_viewpage.html

@@ -358,7 +358,10 @@
 			htmlObj.on("click", function(event){
 				var h = $(this).find("a.bt").attr("s");
 				var eid = $(this).find("a.bt").attr("eid");
-				beforeJump(eid,h);
+        var smallKey = $(this).find('.keyword').map(function() {
+          return $(this).text();
+        }).get().join('_');
+        beforeJump(eid,h, smallKey);
 			});
 			$('#list').append(htmlObj);
 		}
@@ -377,7 +380,7 @@
 		function tablejump(eid,h){
 			beforeJump(eid,h);
 		}
-		function beforeJump(eid,h){
+		function beforeJump(eid,h, smallKey){
 			if(sessionStorage){
 				sessionStorage.resultpreviewScrollTop = scrollTop;
 				sessionStorage.resultpreviewPageNumCache = pageNum;
@@ -387,7 +390,7 @@
 				sessionStorage.resultpreviewSds = sds;
 				sessionStorage.resultpreviewKeys = keys;
 			}
-			newredirect(zbadd,h,eid,sds);
+      newredirect(zbadd,h,eid, smallKey || sds);
 		}
 </script>
 <style type="text/css">

+ 35 - 1
src/jfw/modules/app/src/web/templates/big-member/page_ent_follow.html

@@ -32,8 +32,42 @@
             </button>
         </div>
         <div class="j-container" v-else key="list">
-            <div class="j-main" ref="jList">
+            <div id="jList" class="j-main" ref="jList">
                 <div>
+                  <div class="ent-grouping-normal" v-if="!getListScroll">
+                    <van-collapse class="ent-grouping" v-model="activeNames">
+                      <van-collapse-item title="企业分组" name="1">
+                        <div class="grouping-list">
+                            <div class="grouping-item" :class="{'active': item.active, 'disabled': !item.count && item.isPut >= 0}" v-for="(item, index) in groupingList" :key="index" @click="changeGrouping(item)">
+                                <span class="grouping-item-name">${ item.name }</span>
+                                <span v-if="item.name === '全部'" class="grouping-item-count">${ listInfo.count }</span>
+                                <span v-else class="grouping-item-count">${ item.count }</span>
+                            </div>
+                        </div>
+                        <div class="grouping-footer" @click="groupManage()">
+                          <span class="grouping-item-name">分组管理</span>
+                          <van-icon color="#2ABED1" name="arrow" />
+                        </div>
+                      </van-collapse-item>
+                    </van-collapse>
+                  </div>
+                  <div class="ent-grouping-fixed" :style="domTopNum" v-else>
+                    <van-collapse class="ent-grouping" v-model="activeNames">
+                      <van-collapse-item title="企业分组" name="1">
+                        <div class="grouping-list">
+                            <div class="grouping-item" :class="{'active': item.active, 'disabled': !item.count && item.isPut >= 0}" v-for="(item, index) in groupingList" :key="index" @click="changeGrouping(item)">
+                                <span class="grouping-item-name">${ item.name }</span>
+                                <span v-if="item.name === '全部'" class="grouping-item-count">${ listInfo.count }</span>
+                                <span v-else class="grouping-item-count">${ item.count }</span>
+                            </div>
+                        </div>
+                        <div class="grouping-footer" @click="groupManage()">
+                          <span class="grouping-item-name">分组管理</span>
+                          <van-icon color="#2ABED1" name="arrow" />
+                        </div>
+                      </van-collapse-item>
+                    </van-collapse>
+                  </div>
                     <van-pull-refresh v-model="listInfo.refreshing" @refresh="onRefresh">
                         <van-list
                             v-model="listInfo.loading"

+ 59 - 5
src/jfw/modules/app/src/web/templates/big-member/page_ent_portrait.html

@@ -22,6 +22,7 @@
   <link rel="stylesheet" type="text/css" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/forward-share/css/forward.css?v={{Msg "seo" "version"}}'/>
   <link rel="stylesheet" type="text/css" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/dataExport/css/popup-data-export.css?v={{Msg "seo" "version"}}'/>
   <link rel="stylesheet" type="text/css" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/mobile-portrayal-footer/css/mobile-portrayal-footer.css?v={{Msg "seo" "version"}}'/>
+  <link rel="stylesheet" type="text/css" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/mobile-portrayal-footer/css/mobile-portrayal-grouping.css?v={{Msg "seo" "version"}}'/>
   <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/portrait/css/downloadpopup.css?v={{Msg "seo" "version"}}' />
   <!--E-当前页面的css资源-->
 </head>
@@ -154,7 +155,30 @@
         v-if="conf.powerLoaded && conf.showPortraitAll" :offset-top="stickyTop">
         <!-- 企业信息/工商信息 -->
         <van-tab :name="moduleList[0].name" :title="moduleList[0].title">
-          <div class="module-container pb-12 ent-info-detail">
+          <!-- 芝麻信用标 -->
+          <div class="sesame-container" v-if="entBaseInfo.zhimaLabels">
+            <div class="sesame-header">
+              <h3 class="sesame-title">芝麻实力标</h3>
+              <span>以下信息由<img class="sesame-logo" src="/common-module/big-member/image/zhima-logo.png">提供</span>
+            </div>
+            <div class="sesame-main" :class="{'expanded': moreSesame}">
+              <div class="sesame-item" v-for="item in entBaseInfo.zhimaLabels">
+                <img v-if="item.zhima_toptype === '社会价值'" src="/common-module/big-member/image/shehuijiazhi.png" class="sesame-item-icon">
+                <img v-else-if="item.zhima_toptype === '雇主诚信'" src="/common-module/big-member/image/guzhuchengxin.png" class="sesame-item-icon">
+                <img v-else-if="item.zhima_toptype === '企业实力'" src="/common-module/big-member/image/qiyeshili.png" class="sesame-item-icon">
+                <img v-else-if="item.zhima_toptype === '社会影响力'" src="/common-module/big-member/image/shehuiyingxiangli.png" class="sesame-item-icon">
+                <img v-else-if="item.zhima_toptype === '联合评价'" src="/common-module/big-member/image/lianhepingjia.png" class="sesame-item-icon">
+                <img v-else-if="item.zhima_toptype === '信用评价'" src="/common-module/big-member/image/xinyongpingjia.png" class="sesame-item-icon">
+                <span :data-toptyp="item.zhima_toptype">${item.zhima_value}</span>
+              </div>
+            </div>
+            <div v-show="!isOneRow" class="sesame-more" @click="moreSesame = !moreSesame" :style="{'padding-top': !moreSesame ? '.08rem' : 0}">
+              <span v-if="!moreSesame">查看全部</span>
+              <span v-else>收起</span>
+              <img class="drop-down-img" :class="{'rotate180': moreSesame}" src="/common-module/big-member/image/drop-down.png">
+            </div>
+          </div>
+          <div class="module-container pb-12 ent-info-detail" style="margin-top: .24rem;">
             <div class="module-title-container">
               <p class="module-title">工商信息</p>
             </div>
@@ -165,7 +189,7 @@
                   <div class="ent-registration-text">${entBaseInfo.creditNo ? entBaseInfo.creditNo : '-'}</div>
                 </div>
                 <div class="card-column organization-code">
-                  <div class="ent-info-label">联系方式</div>
+                  <div class="ent-info-label">企业通讯录</div>
                   <div class="ent-info-text">
                     <p>${entBaseInfo.phone ? entBaseInfo.phone : '-'}</p>
                     <p class="highlight-text" v-show="phoneUnlockTip" @click="goToUnlock">解锁查看</p>
@@ -175,7 +199,9 @@
               <div class="card-row">
                 <div class="card-column registered-capital">
                   <div class="ent-info-label">注册资本</div>
-                  <div class="ent-info-text">${entBaseInfo.capital ? entBaseInfo.capital : '-'}</div>
+                  <!-- <div class="ent-info-text">${entBaseInfo.capital ? entBaseInfo.capital : '-'}</div> -->
+                  <div class="ent-info-text">-</div>
+
                 </div>
                 <div class="card-column registered-capital">
                   <div class="ent-info-label">法人姓名</div>
@@ -630,7 +656,7 @@
         </van-tab>
       </van-tabs>
      <!--客服组件-->
-      <customer-corner-component v-show="isLogin" :scroll-status="pageScrollTop < 60"></customer-corner-component>
+      <customer-corner-component :scroll-status="pageScrollTop < 60"></customer-corner-component>
     </section>
 
     <div class="j-main project-tab-container" v-if="conf.powerLoaded && !conf.showPortraitAll">
@@ -671,8 +697,35 @@
                 'othertwo':entPortraitInfo.buyer_count ? entPortraitInfo.buyer_count + '个' : '--',balance}">
                  </downloadpopup>
                 <!-- 底部按钮组件 -->
-                <mobile-portrayal-footer ref="portrayalFooter":monitorshow="entInfo.followSearchFinish && entInfo.entExist" :monitor="!!entInfo.follow" @monitorclick="changeFollowState" :custom-monitor="true"  :downshow="true" :islogin="isLogin" :params="entParams" :shareshow="true">
+                <mobile-portrayal-footer
+                  ref="portrayalFooter"
+                  portrait-origin="ent"
+                  :custom-monitor="false"
+                  :source-limit-map="sourceLimitMap"
+                  :source-map="sourceMap"
+                  :monitorshow="entInfo.followSearchFinish && entInfo.entExist"
+                  :ent-info="entInfo"
+                  :allpower="powerInfo"
+                  :monitor="!!entInfo.follow"
+                  @lookmore="lookMore"
+                  @change="changeGroupState"
+                  @lookdynamic="lookDynamic"
+                  @monitorclick="changeFollowState"
+                  :downshow="true"
+                  :islogin="isLogin"
+                  :params="entParams"
+                  :shareshow="true">
                 </mobile-portrayal-footer>
+                <!-- 分组组件 -->
+                <mobile-portrayal-grouping-script
+                  ref="portrayalGrouping"
+                  @confirm="confirmGrouping"
+                  @cancel="cancelGrouping"
+                  @update="updateGroupList"
+                  :grouping-list="groupingList"
+                  :show-grouping-dialog="showGroupingDialog"
+                  :ent-id="entInfo.id"
+                ></mobile-portrayal-grouping-script>
     <popup-data-export ref="popup_dataExport" @next="next_export"></popup-data-export>
   </div>
   <div id="jyKeepComponent">
@@ -701,6 +754,7 @@
 </script>
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/portrait/js/downloadpopup.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module//mobile-portrayal-footer/js/mobile-portrayal-footer.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module//mobile-portrayal-footer/js/mobile-portrayal-grouping.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/forward-share/js/forward.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/ent_portrait.js?v={{Msg "seo" "version"}}'>
 </script>

+ 24 - 3
src/jfw/modules/app/src/web/templates/big-member/page_landingPage.html

@@ -71,10 +71,11 @@
       <div  style="padding-top: 0">
         <div class="action_out" style="font-size: 0;">
             <div>
-                <img src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/image/landpage_new/itemA_01.jpg'>
+                <img id="header-placeholder" src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/image/landpage_new/itemA_01.jpg'>
             </div >
             <div style="margin-top:-0.01rem">
-                <img src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/image/landpage_new/itemA_02.jpg'>
+                <!-- <img id="banner1" src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/image/landpage_new/itemA_02.jpg'> -->
+                <img id="banner1" src=''>
             </div>
             <div style="margin-top:-0.01rem">
                 <img src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/image/landpage_new/itemA_03.jpg'>
@@ -144,7 +145,8 @@
       <div class="insight" id="sj">
         <div class="action_out">
           <div style="font-size: 0;">
-            <img src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/image/landpage_new/itemB_06.jpg'>
+            <!-- <img id="banner2" src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/image/landpage_new/itemB_06.jpg'> -->
+            <img id="banner2" src=''>
           </div>
           <div style="font-size: 0;">
             <img src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/image/landpage_new/itemB_07.jpg' style="margin-top: -0.01rem">
@@ -182,6 +184,25 @@
   <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>
+    {{$ss1:=(Ad "app-banner-data-info" -1 .Host (cookie "SESSIONID"))}}
+    var headerImageList={{$ss1}}
+    function setHeaderBanner() {
+        if (!$.isArray(headerImageList)) return
+        var imageInfo1 = headerImageList[5]
+        var imageInfo2 = headerImageList[6]
+        if (imageInfo1) {
+            var imageUrl1 = imageInfo1.s_pic
+            $('#banner1').attr('src', imageUrl1)
+            $('#header-placeholder').hide()
+        }
+        if (imageInfo2) {
+            var imageUrl2 = imageInfo2.s_pic
+            $('#banner2').attr('src', imageUrl2)
+        }
+    }
+    setHeaderBanner()
+  </script>
   {{include "/big-member/commonjs.html"}}
   <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/selector/js/powerMap.js?v={{Msg "seo" "version"}}'></script>
   <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/js/common.js?v={{Msg "seo" "version"}}'></script>

+ 3 - 1
src/jfw/modules/app/src/web/templates/big-member/page_orderdetail_aiForecastPack.html

@@ -230,7 +230,9 @@
                       //已支付已申请发票
                       pay_again += "<button class=\"j-button-cancel\" style=\"width: 100%!important;height: 0.92rem!important;\" onclick='checkinvoice(" + r.data.applybill_status + ")'>查看发票</button>"
                   }
-                  $('.j-footer').show().html(pay_again);
+                  if (!r.data.refund_status) {
+                    $('.j-footer').show().html(pay_again);
+                  }
                 }
                 //支付方式
                 if(r.data.billingMode){

+ 11 - 5
src/jfw/modules/app/src/web/templates/big-member/page_orderdetail_member.html

@@ -419,9 +419,14 @@
                 var priceText = "¥ " + formatMoney((r.data.order_money / 100));
                 ;
                 if (r.data.order_status == 1) {
+                  if (r.data.refund_status && r.data.refund_status > 0) {
+                    const domSpan = '<span class="refund-success-tip">退款成功</span>'
+                    priceText = "¥ " + formatMoney((r.data.pay_money / 100)) + domSpan;
+                  } else {
                     priceText = "¥ " + formatMoney((r.data.pay_money / 100));
+                  }
                 }
-                $(".price").text(priceText);
+                $(".price").html(priceText);
                 // 优惠金额
                 if (r.data.discount_price) {
                   $('.discount').show()
@@ -443,8 +448,8 @@
                 cycle = filterObj.cycle + "天"
             }else {
                 cycle = filterObj.cycle + "年"
-                var createType = filterObj.createType
-                if (createType||filterObj.cycleType===0){
+                // var createType = filterObj.createType
+                if (filterObj.cycleType===0){
                   cycle = filterObj.cycle + "个月";
                 }
             }
@@ -476,8 +481,9 @@
                         //已支付已申请发票
                         pay_again += "<button class=\"j-button-cancel\" style=\"width: 100%!important;height: 0.92rem!important;\" onclick='checkinvoice(" + r.data.applybill_status + ")'>查看发票</button>"
                     }
-                  
+                    if (!r.data.refund_status) {
                       $('.j-footer').show().html(pay_again);
+                    }
                     
                 
                 //支付方式
@@ -511,7 +517,7 @@
 
 
                 $(".l-item.paymoney").css("display", "");
-                $(".price").text("¥ " + formatMoney(r.data.pay_money / 100));
+                // $(".price").text("¥ " + formatMoney(r.data.pay_money / 100));
                 //兑换码 不展示支付时间 p307
                 if (r.data.pay_time&&filterObj.badge!="exchange") {
                     $(".line_paytime").css("display", "");

+ 9 - 2
src/jfw/modules/app/src/web/templates/big-member/page_orderdetail_subAccount.html

@@ -197,9 +197,14 @@
                 //价格
                 var priceText = "¥ " + formatMoney((r.data.order_money / 100))
                 if (r.data.order_status == 1) {
+                  const domSpan = '<span class="refund-success-tip">退款成功</span>'
+                  if (r.data.refund_status && r.data.refund_status > 0) {
+                    priceText = "¥ " + formatMoney((r.data.pay_money / 100)) + domSpan
+                  } else {
                     priceText = "¥ " + formatMoney((r.data.pay_money / 100));
+                  }
                 }
-                $(".price").text(priceText);
+                $(".price").html(priceText);
             }
             //
             var level_value = filterObj.areaCount?r.data.combo:level_map.get(filterObj.level).get("level");
@@ -234,7 +239,9 @@
                       //已支付已申请发票
                       pay_again += "<button class=\"j-button-cancel\" style=\"width: 100%!important;height: 0.92rem!important;\" onclick='checkinvoice(" + r.data.applybill_status + ")'>查看发票</button>"
                   }
-                  $('.j-footer').show().html(pay_again);
+                  if (!r.data.refund_status) {
+                    $('.j-footer').show().html(pay_again);
+                  }
                 }
 
                 //支付方式

+ 22 - 1
src/jfw/modules/app/src/web/templates/big-member/page_potential_cor_list.html

@@ -16,6 +16,9 @@
     <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" type="text/css" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/mobile-portrayal-footer/css/mobile-portrayal-grouping.css?v={{Msg "seo" "version"}}'/>
+    <!-- <script type="text/javascript" src="//cdn.bootcdn.net/ajax/libs/vConsole/3.3.4/vconsole.min.js"></script>
+    <script>new VConsole()</script> -->
     <!--E-当前页面的css资源-->
     <style>
         /* 头部样式,兼容长字 */
@@ -78,6 +81,14 @@
             width: .4rem;
             height: .4rem;
         }
+        .cor-item-right .cor-yjk {
+          background-size: 100% 100%;
+          background-image: url('{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/big-member/image/yjk.png?v={{Msg "seo" "version"}}');
+        }
+        .cor-item-right .cor-jk {
+          background-size: 100% 100%;
+          background-image: url('{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/big-member/image/jk.png?v={{Msg "seo" "version"}}');
+        }
         .cor-item-l-r {
             margin: 0 .16rem;
             flex: 1;
@@ -233,7 +244,7 @@
                                 <span
                                     v-if="pageConf.followShow"
                                     class="j-icon"
-                                    :class="item.follow ? 'icon-favorite' : 'icon-no-favorite'"
+                                    :class="item.follow ? 'cor-yjk' : 'cor-jk'"
                                     @click.stop.prevent="changeFollowState(item)"
                                 ></span>
                                 <span class="more-action tooltip" @click.stop.prevent="showMoreActionPanel" v-if="pageConf.moreActionShow">
@@ -255,6 +266,14 @@
                 </div>
             </div>
         </div>
+        <mobile-portrayal-grouping-script 
+          ref="portrayalGrouping"
+          @confirm="confirmGrouping"
+          @cancel="cancelGrouping"
+          @update="updateGroupList"
+          :show-grouping-dialog="showGroupingDialog"
+          :grouping-list="groupingList"
+        ></mobile-portrayal-grouping-script>
     </div>
 </div>
 
@@ -269,6 +288,8 @@
 <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>
 {{include "/big-member/commonjs.html"}}
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/js/common.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/mobile-portrayal-footer/js/mobile-portrayal-grouping.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/potential_cor_list.js?v={{Msg "seo" "version"}}'></script>
 
 </body>

+ 3 - 0
src/jfw/modules/app/src/web/templates/big-member/page_pro_follow_detail.html

@@ -1508,6 +1508,9 @@
                 if (!this.isPayedUser) {
                     return this.openVip()
                 }
+                if (utils.$envs.inWxMini) {
+                    return utils.toDownloadApp()
+                }
                 if (this.isRequestIng) {
                     return
                 }

Some files were not shown because too many files changed in this diff