14
0

66 Commits a3a109c993 ... 0b93511b6c

Autor SHA1 Mensagem Data
  汤世哲 0b93511b6c Merge branch 'dev/v4.9.93_tsz' of qmx/jy into feature/v4.9.93 há 6 meses atrás
  tangshizhe 4b14aa0fb9 fix: 处理监控失败问题 há 6 meses atrás
  汤世哲 abae03098f Merge branch 'dev/v4.9.93_tsz' of qmx/jy into feature/v4.9.93 há 6 meses atrás
  tangshizhe c9964936fc fix: 出来监控失败问题 há 6 meses atrás
  汤世哲 2fa94f6a46 Merge branch 'dev/v4.9.93_tsz' of qmx/jy into feature/v4.9.93 há 6 meses atrás
  tangshizhe 5667b5f0b4 fix: 出来监控失败问题 há 6 meses atrás
  fuwencai 3320c48224 wip:调整 há 6 meses atrás
  fuwencai 9c30c2f6bc fix:bigmember 修复画像页-筛选时间条件导出数据后 导出记录时间展示异常的问题 há 6 meses atrás
  汤世哲 b93b7ee592 Merge branch 'dev/v4.9.93_tsz' of qmx/jy into feature/v4.9.93 há 6 meses atrás
  tangshizhe fc6015853b fix:回显问题调整 há 6 meses atrás
  汤世哲 821330fae0 Merge branch 'dev/v4.9.93_tsz' of qmx/jy into feature/v4.9.93 há 6 meses atrás
  tangshizhe e008a115dc fix: 企业画像逻辑调整 há 6 meses atrás
  tangshizhe 8b753e0eba fix: 企业画像企业情报逻辑调整 há 6 meses atrás
  汤世哲 e00dcc282d Merge branch 'dev/v4.9.93_tsz' of qmx/jy into feature/v4.9.93 há 6 meses atrás
  tangshizhe fd90ff81bc fix: 企业画像逻辑调整 há 6 meses atrás
  wangkaiyue e2be7b41a3 Merge remote-tracking branch 'origin/feature/v4.9.93' into feature/v4.9.93 há 6 meses atrás
  wangkaiyue 98892829b2 wip:tj há 6 meses atrás
  汤世哲 37c7c3b5e4 Merge branch 'dev/v4.9.93_tsz' of qmx/jy into feature/v4.9.93 há 6 meses atrás
  tangshizhe ea9cef0055 fix: 企业画像逻辑调整,企业情报监控逻辑调整 há 6 meses atrás
  汤世哲 be38995d36 Merge branch 'dev/v4.9.93_tsz' of qmx/jy into feature/v4.9.93 há 6 meses atrás
  tangshizhe 434486b3db Merge branch 'feature/v4.9.93' into dev/v4.9.93_tsz há 6 meses atrás
  tangshizhe 87c55a2210 fix: 企业画像监控逻辑调整 há 6 meses atrás
  汤世哲 bbcbece74b Merge branch 'dev/v4.9.93_tsz' of qmx/jy into feature/v4.9.93 há 6 meses atrás
  tangshizhe 6f2ebad835 fix:免费用户企业关注页面取消关注逻辑调整 há 6 meses atrás
  汤世哲 af6edb6b59 Merge branch 'dev/v4.9.93_tsz' of qmx/jy into feature/v4.9.93 há 6 meses atrás
  tangshizhe 352a074e69 fix: 企业画像无权限逻辑调整 há 6 meses atrás
  tangshizhe 05bce97537 fix: 企业情报监控调整 há 6 meses atrás
  wangkaiyue 339a61a154 Merge remote-tracking branch 'origin/feature/v4.9.93' into feature/v4.9.93 há 6 meses atrás
  wangkaiyue 68eee2dfd5 wip:tj há 6 meses atrás
  汤世哲 4e449469be Merge branch 'dev/v4.9.93_tsz' of qmx/jy into feature/v4.9.93 há 6 meses atrás
  tangshizhe bce82724bc fix: 文案调整 há 6 meses atrás
  tangshizhe 877126fb12 fix: 企业画像无权限逻辑调整 há 6 meses atrás
  yuelujie d04fc0037f Merge branch 'master' into feature/v4.9.93 há 6 meses atrás
  wangkaiyue 1662fc0e48 wip:tj há 6 meses atrás
  wangkaiyue 7bab7c2083 wip:tj há 6 meses atrás
  汤世哲 3abca5270d Merge branch 'dev/v4.9.93_tsz' of qmx/jy into feature/v4.9.93 há 6 meses atrás
  tangshizhe dc9661d3d5 fix: 企业画像逻辑调整 há 6 meses atrás
  汤世哲 4fe4b6af46 Merge branch 'dev/v4.9.93_tsz' of qmx/jy into feature/v4.9.93 há 6 meses atrás
  tangshizhe 7927e00920 fix: 企业画像逻辑调整 há 6 meses atrás
  duxin e3e346ac94 fix:默认分组初始化 há 6 meses atrás
  汤世哲 60e69ecd91 Merge branch 'dev/v4.9.93_tsz' of qmx/jy into feature/v4.9.93 há 6 meses atrás
  tangshizhe 5267edb874 feat: 企业画像监控逻辑调整 há 6 meses atrás
  汤世哲 30a4d129c1 Merge branch 'dev/v4.9.93_tsz' of qmx/jy into feature/v4.9.93 há 6 meses atrás
  tangshizhe fb1e262c67 Merge branch 'feature/v4.9.93' into dev/v4.9.93_tsz há 6 meses atrás
  tangshizhe a181318410 feat: 企业画像监控逻辑调整 há 6 meses atrás
  duxin 50c22e2dd1 fix:分组管理修改 há 6 meses atrás
  duxin 711cc5c6bc fix:分组管理修改 há 6 meses atrás
  duxin 9607657b05 Merge branch 'feature/v4.9.93' of https://jygit.jydev.jianyu360.cn/qmx/jy into feature/v4.9.93 há 6 meses atrás
  duxin 2776ee68e7 fix:分组管理提交 há 6 meses atrás
  yuelujie 16d0fcc099 Merge branch 'master' into feature/v4.9.93 há 6 meses atrás
  tangshizhe 3a7fd50b48 feat: 企业情报添加分组列表 há 6 meses atrás
  yuelujie ea3b37cb0a Merge branch 'master' into feature/v4.9.93 há 6 meses atrás
  tangshizhe 3917b7fbf7 feat: 添加分组弹窗需求开发 há 6 meses atrás
  duxin 4bffe110fb fix:企业关注展示关注信息 há 6 meses atrás
  duxin c80af4901a fix:企业关注展示关注信息 há 6 meses atrás
  duxin 9154247077 Merge remote-tracking branch 'origin/feature/v4.9.93' into feature/v4.9.93 há 6 meses atrás
  duxin 55ff84909e fix:企业关注展示关注信息 há 6 meses atrás
  yuelujie 36ce063ad1 Merge branch 'master' into feature/v4.9.93 há 6 meses atrás
  duxin f4e36f8958 fix:校验错误问题修改 há 6 meses atrás
  duxin 459a565a5f fix:分组操作修改 há 6 meses atrás
  wkyuer a1985988a1 Merge remote-tracking branch 'origin/feature/v4.9.93' into feature/v4.9.93 há 6 meses atrás
  wkyuer 996a5a2ce2 wip:企业关注分组自测提交 há 6 meses atrás
  yuelujie 42e6122fe6 Merge branch 'master' into feature/v4.9.93 há 6 meses atrás
  yuelujie 308d2a82d0 Merge branch 'master' into feature/v4.9.93 há 6 meses atrás
  wkyuer 29606793d9 wip:企业关注分组提交 há 6 meses atrás
  duxin de70eae401 fix:企业标签分组功能添加 há 6 meses atrás
24 ficheiros alterados com 1717 adições e 155 exclusões
  1. 0 1
      src/config.yaml
  2. 9 9
      src/db.json
  3. 46 1
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/css/ent_follow.css
  4. 97 3
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/ent_follow.js
  5. 279 19
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/ent_portrait.js
  6. 15 0
      src/jfw/modules/app/src/web/templates/big-member/page_ent_follow.html
  7. 30 1
      src/jfw/modules/app/src/web/templates/big-member/page_ent_portrait.html
  8. 9 0
      src/jfw/modules/app/src/web/templates/big-member/page_potential_cor_list.html
  9. 3 3
      src/jfw/modules/app/src/web/templates/followent/list.html
  10. 7 2
      src/jfw/modules/app/src/web/templates/followent/set.html
  11. 398 42
      src/jfw/modules/bigmember/src/entity/followEnterprise.go
  12. 9 1
      src/jfw/modules/bigmember/src/entity/portrait.go
  13. 73 8
      src/jfw/modules/bigmember/src/service/follow/enterprise.go
  14. 3 3
      src/jfw/modules/followent/src/web/templates/weixin/list.html
  15. 7 2
      src/jfw/modules/followent/src/web/templates/weixin/set.html
  16. BIN
      src/web/staticres/common-module/big-member/image/jk.png
  17. BIN
      src/web/staticres/common-module/big-member/image/yjk.png
  18. 281 18
      src/web/staticres/common-module/collection/js/ent_portrait.js
  19. 21 1
      src/web/staticres/common-module/mobile-portrayal-footer/css/mobile-portrayal-footer.css
  20. 89 0
      src/web/staticres/common-module/mobile-portrayal-footer/css/mobile-portrayal-grouping.css
  21. 110 40
      src/web/staticres/common-module/mobile-portrayal-footer/js/mobile-portrayal-footer.js
  22. 174 0
      src/web/staticres/common-module/mobile-portrayal-footer/js/mobile-portrayal-grouping.js
  23. 27 0
      src/web/staticres/common-module/perfect-info/js/perfect-info.js
  24. 30 1
      src/web/templates/frontRouter/wx/collection/sess/ent_portrait.html

+ 0 - 1
src/config.yaml

@@ -1,7 +1,6 @@
 etcd:
   hosts:
     - 192.168.3.207:2379
-    - 192.168.3.165:2379
     - 192.168.3.204:2379
 userCenterKey: "usercenter.rpc" #用户中台rpc
 powerCheckCenterKey: "powercheck.rpc" #权益校验中台

+ 9 - 9
src/db.json

@@ -1,26 +1,26 @@
 {
   "mongodb": {
     "main": {
-      "address": "192.168.3.206:27080",
+      "address": "192.168.3.149:27180",
       "size": 10,
       "dbName": "qfw"
     },
     "log": {
-      "address": "192.168.3.206:27090",
+      "address": "192.168.3.149:27190",
       "size": 5,
       "dbName": "qfw",
       "userName": "admin",
       "password": "123456"
     },
     "ent": {
-      "address": "192.168.3.206:27002",
+      "address": "192.168.3.149:27102",
       "size": 5,
       "dbName": "mixdata",
       "userName": "jyDevGroup",
       "password": "jy@DevGroup"
     },
     "bidding": {
-      "address": "192.168.3.206:27002",
+      "address": "192.168.3.149:27102",
       "size": 5,
       "dbName": "qfw_data",
       "replSet": "",
@@ -32,7 +32,7 @@
   },
   "elasticsearch": {
     "main": {
-      "address": "http://192.168.3.149:9200",
+      "address": "http://192.168.3.149:9201,http://192.168.3.241:9206",
       "size": 30,
       "version": "v7",
       "userName": "",
@@ -41,7 +41,7 @@
       "esType": "bidding"
     },
     "other": {
-      "address": "http://192.168.3.149:9200",
+      "address": "http://192.168.3.149:9201,http://192.168.3.241:9206",
       "size": 30,
       "version": "v7",
       "userName": "",
@@ -50,7 +50,7 @@
       "esType": "bidding_year"
     },
     "free": {
-      "address": "http://192.168.3.149:9200",
+      "address": "http://192.168.3.149:9201,http://192.168.3.241:9206",
       "size": 30,
       "version": "v7",
       "userName": "",
@@ -59,7 +59,7 @@
       "esType": "bidding"
     },
     "doc": {
-      "address": "http://192.168.3.242:9200",
+      "address": "http://192.168.3.149:9201,http://192.168.3.241:9206",
       "size": 30,
       "version": "v7",
       "userName": "elastic",
@@ -87,7 +87,7 @@
     },
     "base": {
       "dBName": "base_service",
-      "address" : "192.168.3.14:4000",
+      "address" : "192.168.3.217:4000",
       "userName": "root",
       "passWord": "=PDT49#80Z!RVv52_z",
       "maxOpenConns": 5,

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

@@ -5,6 +5,10 @@
     color: #171826;
 }
 
+.ent-grouping {
+  margin-bottom: .2rem;
+}
+
 .dot-red {
     width: .16rem;
     height: .16rem;
@@ -139,4 +143,45 @@
     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;
+}

+ 97 - 3
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/ent_follow.js

@@ -17,16 +17,21 @@ var vNode = {
             refreshing: false,
             pageNum: 0,
             pageSize: 50,
-            scrollTop: 0
+            scrollTop: 0,
+            count: 0
         },
         entFollowList: [],
-        loading: ''
+        loading: '',
+        activeNames: [],
+        groupingList: [],
+        selectGroupList: []
     },
     created: function () {
         var recover = this.recover()
         if (!recover) {
             this.getPowerInfo()
         }
+        this.getEntGroupList()
     },
     mounted: function () {
         $(this.$refs.jList).scrollTop(this.listInfo.scrollTop)
@@ -69,7 +74,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 +96,7 @@ var vNode = {
                 data: {
                     pageNum: _this.listInfo.pageNum,
                     pageSize: _this.listInfo.pageSize,
+                    ...params
                 },
                 success: function (res) {
                     if (_this.listInfo.pageNum === 0) {
@@ -85,6 +105,7 @@ var vNode = {
                     }
                     if (res.error_code == 0) {
                         if (res.data && res.data) {
+
                             // 判断是否为刷新
                             if (_this.listInfo.refreshing) {
                                 _this.entFollowList = []
@@ -96,6 +117,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) {
@@ -128,6 +152,71 @@ var vNode = {
                 }
             })
         },
+        // 设置企业分组数据
+        setEntGroupData (data) {
+          data.unshift({
+            count: this.listInfo.count,
+            id: "",
+            isPut: 0,
+            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.getEntFollowList({
+            group: lengthBool ? this.selectGroupList.map(s => s.id).join(',') : ''
+          })
+          this.activeNames = []
+        },
+        groupManage: function () {
+            location.href = '/jy_mobile/entgroup/index'
+        },
         onRefresh: function () {
             // 重置数据
             this.listInfo.pageNum = 0
@@ -136,8 +225,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 {

+ 279 - 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,
 
   },
@@ -194,7 +195,21 @@ var vNode = {
       isFree: false,
       balance:0,
       moreSesame: false,
-      isOneRow: 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 () {
@@ -386,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
@@ -782,7 +896,7 @@ 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) {
@@ -814,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({
@@ -831,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
             }
@@ -843,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 () {
@@ -1004,7 +1184,7 @@ var vNode = {
       })
     },
     // 修改企业关注状态
-    changeFollowStateRequest: function () {
+    changeFollowStateRequest: function (params = {}) {
       var _this = this
       var loading = this.showLoading()
       var urls = {
@@ -1016,7 +1196,8 @@ var vNode = {
         type: 'POST',
         url: url,
         data: {
-          entId: _this.entInfo.id
+          entId: _this.entInfo.id,
+          ...params
         },
         timeout: 5000,
         success: function (res) {
@@ -1025,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 || '监控失败')
             }
@@ -1033,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)
           }
@@ -1046,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() {
       // 获取剑鱼币任务信息

+ 15 - 0
src/jfw/modules/app/src/web/templates/big-member/page_ent_follow.html

@@ -34,6 +34,21 @@
         <div class="j-container" v-else key="list">
             <div class="j-main" ref="jList">
                 <div>
+                    <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}" 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>
                     <van-pull-refresh v-model="listInfo.refreshing" @refresh="onRefresh">
                         <van-list
                             v-model="listInfo.loading"

+ 30 - 1
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>
@@ -696,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">
@@ -726,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>

+ 9 - 0
src/jfw/modules/app/src/web/templates/big-member/page_potential_cor_list.html

@@ -78,6 +78,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;
@@ -230,6 +238,7 @@
                                 </span>
                             </span>
                             <span class="cor-item-right" v-if="pagePower">
+                              <!-- 关注图标改为监控图标可以直接使用 :class="item.follow ? 'cor-yjk' : 'cor-jk'" -->
                                 <span
                                     v-if="pageConf.followShow"
                                     class="j-icon"

+ 3 - 3
src/jfw/modules/app/src/web/templates/followent/list.html

@@ -85,7 +85,7 @@
 				if(frontarr[f]["i_apppushunread"]==1){
 					redSpot = '<i class="redspot"></i>';
 				}
-				fronthtml +="<li data-id='"+frontarr[f]["fid"]+"' Sort='"+lastpushtime+"'>"
+				fronthtml +="<li data-id='"+frontarr[f]["fid"]+"' ent-id='"+frontarr[f]["s_entId"]+"' Sort='"+lastpushtime+"'>"
 	                +"<div class='jyfwlistno'>"+listno+".</div>"
 	                +"<div class='jyfwlisttitle'>"+entname+"</div>"
 	                +"<div style='clear:both;'></div>"+rem
@@ -118,7 +118,7 @@
 				if(lastarr[l]["i_apppushunread"]==1){
 					redSpot = '<i class="redspot"></i>';
 				}
-				lasthtml +="<li class='jyovertime' data-id='"+lastarr[l]["fid"]+"'>"
+				lasthtml +="<li class='jyovertime' data-id='"+lastarr[l]["fid"]+"' ent-id='"+lastarr[l]["s_entId"]+"'>"
 				+"<div class='jyfwlistno'>"+listno+".</div>"
 				+"<div class='jyfwlisttitle'>"+lastarr[l]["s_entname"]+"</div>"
 				+"<div style='clear:both;'></div>"+rem
@@ -135,7 +135,7 @@
 	            if(sessionStorage){
 	                sessionStorage.version="0";
 	            }
-	            window.location.href = "/jyapp/followent/detail/"+$(this).attr("data-id");
+	            window.location.href = "/jyapp/followent/detail/"+$(this).attr("data-id") + '?entId=' + $(this).attr("ent-id");
 	        });
 		});
 

+ 7 - 2
src/jfw/modules/app/src/web/templates/followent/set.html

@@ -129,10 +129,15 @@ if(sessionStorage){
 		$("#sure").click(function(){
 			easyPopup.hide();
 			//发送Ajax请求,取消关注
-      const eid = window.location.href.split("/")[6]
+      const fid = window.location.href.split("/")[6]
+      const url = new URL(window.location.href); // 获取当前页面的URL
+      const params = new URLSearchParams(url.search); // 获取查询字符串部分
+
+      // 获取单个参数
+      const eId = params.get('entId');
 			$.post(
 				"/bigmember/follow/ent/delFollow",
-				{"fid":eid},
+				{"entId":eId},
 				function(r){
 					if(r.data == "success"){
 						if(sessionStorage){

+ 398 - 42
src/jfw/modules/bigmember/src/entity/followEnterprise.go

@@ -2,8 +2,10 @@ package entity
 
 import (
 	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
+	"database/sql"
 	"errors"
 	"fmt"
+	"github.com/gogf/gf/v2/util/gconv"
 	"jy/src/jfw/modules/bigmember/src/config"
 	"jy/src/jfw/modules/bigmember/src/db"
 	"jy/src/jfw/modules/bigmember/src/util"
@@ -15,7 +17,6 @@ import (
 	qutil "app.yhyue.com/moapp/jybase/common"
 	. "app.yhyue.com/moapp/jybase/date"
 	elastic "app.yhyue.com/moapp/jybase/es"
-	"app.yhyue.com/moapp/jybase/mongodb"
 	"app.yhyue.com/moapp/jybase/redis"
 	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
 )
@@ -87,19 +88,28 @@ func (this *EntFollow) GetAssociationEnt(entName string) ([]map[string]interface
 // EntFollowedShow 详情页查询是否关注企业
 // followed 是否已关注
 // showFollow 是否展示关注(检索库存在相关企业信息时展示)
-func (this *EntFollow) EntFollowedShow(entId string) (followed, showFollow bool, err error) {
+func (this *EntFollow) EntFollowedShow(entId string) (followed, showFollow bool, followedGroup string, err error) {
 	if entId == "" {
 		err = errors.New("未查询到企业")
 		return
 	}
-	query := map[string]interface{}{"s_entId": entId, "s_userid": this.UserId}
-	fRes := db.Base.FindOne(this.SaveTable, query, "i_apppushunread", "")
+	//query := map[string]interface{}{"s_entId": entId, "s_userid": this.UserId}
+	//fRes := db.Base.FindOne(this.SaveTable, query, "i_apppushunread", "")
+	fRes := db.Base.SelectBySql(fmt.Sprintf(`SELECT a.i_apppushunread,c.s_name FROM %s a
+INNER  JOIN  follow_ent_monitor_relationship b on (a.s_entId = b.s_entId)
+INNER JOIN  follow_ent_monitor_group c on (b.s_groupId = c.id and a.s_userid = c.s_userid)
+WHERE a.s_entId = '%s' and a.s_userid = '%s'`, this.SaveTable, entId, this.UserId))
 	followed = false
-	if fRes != nil {
+	if fRes != nil && len(*fRes) > 0 {
 		followed = true
+		var names []string
+		for _, m := range *fRes {
+			names = append(names, qutil.ObjToString(m["s_name"]))
+		}
+		followedGroup = strings.Join(names, ",")
 		//已关注,并且有未读标示
-		if qutil.IntAll((*fRes)["i_apppushunread"]) > 0 {
-			go db.Base.Update(this.SaveTable, query, map[string]interface{}{
+		if qutil.IntAll((*fRes)[0]["i_apppushunread"]) > 0 {
+			go db.Base.Update(this.SaveTable, map[string]interface{}{"s_entId": entId, "s_userid": this.UserId}, map[string]interface{}{
 				"i_apppushunread": 0,
 			})
 		}
@@ -117,11 +127,22 @@ func (this *EntFollow) EntFollowedShow(entId string) (followed, showFollow bool,
 	return
 }
 
+type EntFollowGroup struct {
+	Id    string `json:"id"`
+	Name  string `json:"name"`
+	IsPut int    `json:"isPut"`
+	Count int    `json:"count"`
+}
+
 // GetEntFollowList 我关注的企业列表
 // param A默认分组 B竞争对手 C合作伙伴 逗号分隔
 // db  0||nil 默认分组、1 竞争对手、2 合作伙伴、3 竞争对手和合作伙伴
-func (this *EntFollow) GetEntFollowList(pNum, pSize int, match, group string) (followData []map[string]interface{}, hasNext bool, count, total int, err error) {
-	flistSql := fmt.Sprintf(`SELECT id,f_capital,i_apppushunread,l_establishdate,l_lastpushtime,s_area,s_city,s_employeeno,s_entId,s_entname,i_group,s_phone FROM follow_ent_monitor WHERE  s_userid="%s" ORDER BY l_lastpushtime DESC,l_createtime DESC LIMIT %d,%d`, this.UserId, 0, this.MaxNum)
+func (this *EntFollow) GetEntFollowList(pNum, pSize int, match, groups string) (followData []map[string]interface{}, hasNext bool, count, total int, err error) {
+	groupIds, groupErr := checkGroup(this.UserId, groups, true)
+	if groupErr != nil {
+		return nil, false, -1, -1, fmt.Errorf("分组不存在")
+	}
+	flistSql := fmt.Sprintf(`SELECT  m.*,GROUP_CONCAT(g.id SEPARATOR ',') as gs  from follow_ent_monitor m inner join follow_ent_monitor_group g on(m.s_userid =g.s_userid and g.s_userid ='%s') INNER JOIN follow_ent_monitor_relationship r  on ( g.id=r.s_groupId and m.s_entId=r.s_entId ) GROUP BY s_entId  ORDER BY m.l_lastpushtime DESC,m.l_createtime DESC LIMIT %d,%d`, this.UserId, 0, this.MaxNum)
 	log.Print("我关注的企业列表开始查询:", flistSql)
 	res := db.Base.SelectBySql(flistSql)
 	if res == nil || len(*res) == 0 {
@@ -130,8 +151,11 @@ func (this *EntFollow) GetEntFollowList(pNum, pSize int, match, group string) (f
 	}
 	log.Print("我关注的企业列表查询结束")
 	count = len(*res)
+	//获取用户分组列表
+	var (
+		followDataAll []map[string]interface{}
+	)
 
-	var followDataAll []map[string]interface{}
 	for _, item := range *res {
 		//兼容从大会员变成免费用户时筛选条件数据错乱问题 取数据全部取出后在进行筛选过滤
 		if match != "" {
@@ -139,21 +163,28 @@ func (this *EntFollow) GetEntFollowList(pNum, pSize int, match, group string) (f
 				continue
 			}
 		}
-		if group != "" {
-			var iGroup bool
-			if strings.Contains(group, "A") && (qutil.IntAll(item["i_group"]) == 0) {
-				iGroup = true
-			}
-			if !iGroup && strings.Contains(group, "B") && (qutil.IntAll(item["i_group"]) == 1 || qutil.IntAll(item["i_group"]) == 3) {
-				iGroup = true
-			}
-			if !iGroup && strings.Contains(group, "C") && (qutil.IntAll(item["i_group"]) == 2 || qutil.IntAll(item["i_group"]) == 3) {
-				iGroup = true
-			}
-			if !iGroup {
-				continue
+
+		var (
+			enCodeGroups []string
+			has          = true
+		)
+		if len(groupIds) > 0 {
+			has = false
+			var (
+				groups = strings.Split(gconv.String(item["gs"]), ",")
+			)
+			for _, group := range groups {
+				if group != "" {
+					enCodeGroups = append(enCodeGroups, util.EncodeId(group))
+					if !has && groupIds[gconv.Int(group)] {
+						has = true
+					}
+				}
 			}
 		}
+		if !has {
+			continue
+		}
 		entId := qutil.ObjToString(item["s_entId"])
 		if entId == "" { //dev3.6.2 前关注企业未存入企业id
 			//查询企业entid
@@ -172,10 +203,11 @@ func (this *EntFollow) GetEntFollowList(pNum, pSize int, match, group string) (f
 			"s_phone":         item["s_phone"],
 			"i_apppushunread": item["i_apppushunread"],
 			"l_lastpushtime":  item["l_lastpushtime"],
-			"s_group":         parseGroupStr(qutil.IntAll(item["i_group"])),
+			"s_grousp":        strings.Join(enCodeGroups, ","),
 		}
 		followDataAll = append(followDataAll, rowMap)
 	}
+
 	total = len(followDataAll)
 	//分页
 	if total > 0 {
@@ -272,8 +304,11 @@ func (this *EntFollow) updateFollowed(follow map[string]interface{}) string {
 }
 
 // AddFollowEnt 添加关注企业
-func (this *EntFollow) AddFollowEnt(entId, group string, getOldData ...bool) error {
-	groupFlag := getGroup(group)
+func (this *EntFollow) AddFollowEnt(entId, groups string, getOldData ...bool) error {
+	groupIds, groupErr := checkGroup(this.UserId, groups)
+	if groupErr != nil {
+		return fmt.Errorf("分组不存在")
+	}
 	//if this.HasPower {
 	if db.Base.Count(this.SaveTable, map[string]interface{}{"s_userid": this.UserId, "s_entId": entId}) > 0 {
 		return errors.New("已关注此企业")
@@ -286,7 +321,7 @@ func (this *EntFollow) AddFollowEnt(entId, group string, getOldData ...bool) err
 		return errors.New("查找企业异常")
 	}
 	followData := map[string]interface{}{
-		"s_entId":        mongodb.BsonIdToSId((*res)["_id"]), //dev3.6.2 企业画像根据entId查询
+		"s_entId":        entId, //dev3.6.2 企业画像根据entId查询
 		"s_entname":      (*res)["company_name"],
 		"s_area":         qutil.If((*res)["company_area"] == nil, "", (*res)["company_area"]),
 		"s_city":         qutil.If((*res)["company_city"] == nil, "", (*res)["company_city"]),
@@ -313,14 +348,25 @@ func (this *EntFollow) AddFollowEnt(entId, group string, getOldData ...bool) err
 			followData["l_establishdate"] = t.Unix()
 		}
 	}
-
-	//设置分组
-	if groupFlag > -1 {
-		followData["i_group"] = groupFlag
-	}
-	followId := db.Base.Insert(this.SaveTable, followData)
-	if followId == -1 {
-		return errors.New("保存关注企业异常")
+	if !db.Base.ExecTx("企业关注", func(tx *sql.Tx) bool {
+		if len(groupIds) == 0 {
+			return false
+		}
+		followId := db.Base.InsertByTx(tx, this.SaveTable, followData)
+		if followId == -1 {
+			return false
+		}
+		for groupId, _ := range groupIds {
+			if db.Base.InsertByTx(tx, "follow_ent_monitor_relationship", map[string]interface{}{
+				"s_entId":   entId,
+				"s_groupId": groupId,
+			}) <= 0 {
+				return false
+			}
+		}
+		return true
+	}) {
+		return fmt.Errorf("企业关注存储异常")
 	}
 	go func(userId string) {
 		//首页潜在竞争对手缓存
@@ -357,6 +403,58 @@ func getGroup(groupStr string) (s int) {
 	return
 }
 
+// checkGroup 校验分组是否存在
+func checkGroup(userId, groupStr string, defaultGetAll ...bool) (map[int]bool, error) {
+	rData := db.Base.Query("SELECT id,s_name FROM follow_ent_monitor_group WHERE s_userid=?", userId)
+	if rData == nil || len(*rData) == 0 {
+		//新用户插入分组
+		if _, err := db.Base.ExecBySql(fmt.Sprintf(`INSERT INTO follow_ent_monitor_group (s_name, s_userid, create_time, update_time, isPut, isdefGoup) VALUES
+        ('默认分组', '%s',  '2025-01-03 12:00:00', '2025-01-13 12:00:00', 0, 1),
+        ('竞争对手', '%s',  '2024-01-02 12:00:00', '2025-01-13 12:00:00', 1, 0),
+        ('合作伙伴', '%s',  '2024-01-01 12:00:00', '2025-01-13 12:00:00', 1, 0);`, userId, userId, userId)); err != nil {
+			log.Printf("新用户 %s创建分组异常", userId)
+		}
+		return nil, nil
+	}
+	var (
+		hasGroupId = map[int]bool{}
+		rMap       = map[int]bool{}
+		deafultMap = map[int]bool{}
+	)
+	for _, m := range *rData {
+		var (
+			name = gconv.String(m["s_name"])
+			gId  = gconv.Int(m["id"])
+		)
+		hasGroupId[gId] = true
+		if name == "默认分组" {
+			deafultMap[gId] = true
+		}
+	}
+
+	if strings.TrimSpace(groupStr) == "" {
+		if len(defaultGetAll) > 0 && defaultGetAll[0] {
+			//仅仅返回全部分组
+			return hasGroupId, nil
+		} else {
+			//仅仅返回默认分组
+			return deafultMap, nil
+		}
+	}
+	for _, gId := range strings.Split(groupStr, ",") {
+		tId := gconv.Int(util.DecodeId(gId))
+		if tId <= 0 {
+			continue
+		}
+		if hasGroupId[tId] {
+			rMap[tId] = true
+		} else {
+			return nil, fmt.Errorf("未知标签")
+		}
+	}
+	return rMap, nil
+}
+
 // 格式化分组字段
 func parseGroupStr(gFlag int) string {
 	switch gFlag {
@@ -372,12 +470,59 @@ func parseGroupStr(gFlag int) string {
 }
 
 // ChangeFollowGroup 更换关注企业分组
-func (this *EntFollow) ChangeFollowGroup(fid, group string) error {
-	groupValue := getGroup(group)
-	if groupValue == -1 {
-		groupValue = 0
-	}
-	if !db.Base.Update(this.SaveTable, map[string]interface{}{"id": fid}, map[string]interface{}{"i_group": groupValue}) {
+func (this *EntFollow) ChangeFollowGroup(entId, groupStr string) error {
+	groupMap, groupErr := checkGroup(this.UserId, groupStr)
+	if groupErr != nil {
+		return fmt.Errorf("分组不存在")
+	}
+	if !db.Base.ExecTx("更换关注分组", func(tx *sql.Tx) bool {
+		//查询关联的标签
+		rData := db.Base.Query("SELECT r.id,r.s_groupId FROM follow_ent_monitor_group g inner join follow_ent_monitor_relationship r on (g.id = r.s_groupId ) WHERE g.s_userid=? AND r.s_entId=?", this.UserId, entId)
+		if rData == nil || len(*rData) == 0 {
+			return false
+		}
+		var (
+			remove []int
+		)
+		for _, m := range *rData {
+			var (
+				releaseId = gconv.Int(m["id"])
+				groupId   = gconv.Int(m["s_groupId"])
+				has       = false
+			)
+
+			for newGroupId, _ := range groupMap {
+				if groupId == newGroupId {
+					has = true
+					groupMap[groupId] = false
+					break
+				}
+			}
+
+			if !has {
+				remove = append(remove, releaseId)
+			}
+		}
+		for _, id := range remove {
+			if !db.Base.DeleteByTx(tx, "follow_ent_monitor_relationship", map[string]interface{}{
+				"id": id,
+			}) {
+				return false
+			}
+		}
+
+		for groupId, ok := range groupMap {
+			if ok {
+				if db.Base.Insert("follow_ent_monitor_relationship", map[string]interface{}{
+					"s_entId":   entId,
+					"s_groupId": groupId,
+				}) <= 0 {
+					return false
+				}
+			}
+		}
+		return true
+	}) {
 		return fmt.Errorf("设置分组失败")
 	}
 	return nil
@@ -398,7 +543,23 @@ func (this *EntFollow) DelFollowEnt(entId, fid string) error {
 		query["id"] = fid
 	}
 	data := db.Base.FindOne(this.SaveTable, query, "id,s_entId,s_entname,s_area,s_city,s_phone,f_capital,s_employeeno,l_createtime,s_userid,l_lastpushtime", "")
-	if data != nil && db.Base.Delete(this.SaveTable, query) {
+	if data != nil {
+		db.Base.ExecTx("取消关注", func(tx *sql.Tx) bool {
+			if !db.Base.DeleteByTx(tx, this.SaveTable, query) {
+				return false
+			}
+			//查询关联的标签
+			rData := db.Base.Query("SELECT r.id FROM follow_ent_monitor_group g inner join follow_ent_monitor_relationship r on (g.id = r.s_groupId ) WHERE g.s_userid=? AND r.s_entId=?", this.UserId, entId)
+			if rData == nil || len(*rData) == 0 {
+				return false
+			}
+			for _, m := range *rData {
+				if !db.Base.DeleteByTx(tx, "follow_ent_monitor_relationship", map[string]interface{}{"id": gconv.String(m["id"])}) {
+					return false
+				}
+			}
+			return true
+		})
 		(*data)["s_followid"] = (*data)["id"]
 		delete(*data, "id")
 		db.Mgo.Save("jylab_followent_back", data)
@@ -544,3 +705,198 @@ func (this *EntFollow) GetFollowEntInfo() (used int64, surplus int64) {
 	}
 	return
 }
+
+func (this *EntFollow) GetLabelGroup() *[]map[string]interface{} {
+	defIdMap := make(map[int]bool)
+	//检测默认分组 初始化
+	count := db.Base.Count("follow_ent_monitor_group", map[string]interface{}{
+		"s_userid":  this.UserId,
+		"isdefGoup": 1,
+	})
+	if count == 0 { //初始化默认分组
+		db.Base.SelectBySql(fmt.Sprintf(`INSERT INTO follow_ent_monitor_group (s_name, s_userid, create_time, update_time, isPut, isdefGoup) VALUES
+('默认分组', '%s',  '2025-01-03 12:00:00', '2025-01-13 12:00:00', 0, 1),
+('竞争对手', '%s',  '2024-01-02 12:00:00', '2025-01-13 12:00:00', 1, 0),
+('合作伙伴', '%s',  '2024-01-01 12:00:00', '2025-01-13 12:00:00', 1, 0);`, this.UserId, this.UserId, this.UserId))
+	} else {
+		//获取最近一次关注的分组
+		groupIdData := db.Base.SelectBySql(fmt.Sprintf(fmt.Sprintf(`SELECT b.s_groupId FROM follow_ent_monitor_relationship b
+INNER JOIN (
+SELECT s_entId FROM follow_ent_monitor  WHERE s_userid = '%s' ORDER BY l_createtime desc limit 1
+) a on a.s_entId = b.s_entId
+INNER  JOIN  follow_ent_monitor_group c on c.s_userid = '%s' and c.id = b.s_groupId`, this.UserId, this.UserId)))
+		if groupIdData != nil && len(*groupIdData) > 0 {
+			for _, m := range *groupIdData {
+				defIdMap[qutil.IntAll(m["s_groupId"])] = true
+			}
+		}
+	}
+
+	data := db.Base.SelectBySql(fmt.Sprintf(`SELECT id,s_name,isPut from follow_ent_monitor_group  WHERE s_userid = '%s'  ORDER BY isdefGoup desc , create_time desc`, this.UserId))
+	if data != nil && len(*data) > 0 {
+		for _, m := range *data {
+			switch { //最近一次分组
+			case len(defIdMap) == 0 && m["s_name"] == "默认分组": //最近没有关注 分配到默认分组
+				m["isSelect"] = true
+			case defIdMap[qutil.IntAll(m["id"])]:
+				m["isSelect"] = true
+			default:
+				m["isSelect"] = false
+			}
+			m["id"] = util.EncodeId(qutil.InterfaceToStr(m["id"]))
+		}
+	}
+
+	return data
+}
+
+func (this *EntFollow) AddLabelGroup(name string) error {
+	//检测默认分组 初始花
+	DefaultGroupInit(this.UserId)
+	if db.Base.Count("follow_ent_monitor_group", map[string]interface{}{
+		"user_id": this.UserId,
+		"s_name":  name,
+	}) > 0 { //是否重名
+		return errors.New("分组名称已存在")
+	}
+	db.Base.Insert("follow_ent_monitor_group", map[string]interface{}{
+		"s_name":      name,
+		"s_userid":    this.UserId,
+		"create_time": time.Now(),
+		"update_time": time.Now(),
+		"isPut":       1,
+		"isdefGoup":   0,
+	})
+	return nil
+}
+
+func (this *EntFollow) PutLabelGroup(name string, groupId string) error {
+	if db.Base.Count("follow_ent_monitor_group", map[string]interface{}{
+		"s_userid": this.UserId,
+		"s_name":   name,
+	}) > 0 { //是否重名
+		return errors.New("分组名称已存在")
+	}
+	db.Base.Update("follow_ent_monitor_group", map[string]interface{}{
+		"s_userid": this.UserId,
+		"id":       groupId,
+	}, map[string]interface{}{"s_name": name})
+	return nil
+}
+
+// DelLabelGroup删除分组 -删除分组:如果删除完分组对应企业没分组了,放到默认分组里,如果企业还有其他分组,就还在其他分组里
+func (this *EntFollow) DelLabelGroup(groupId string) error {
+	var err error
+	if !db.Base.ExecTx("删除分组", func(tx *sql.Tx) bool {
+		var (
+			needMoveDefault []string
+		)
+		//查询当前分组内所有数据
+		rData := db.Base.Query("SELECT r.s_entId,GROUP_CONCAT(g.id SEPARATOR ',') as gs  FROM  follow_ent_monitor_relationship r inner join  follow_ent_monitor_group g  on ( r.s_groupId = g.id ) WHERE g.s_userid =? GROUP BY r.s_entId  HAVING FIND_IN_SET(?, gs) > 0;", this.UserId, groupId)
+		if rData != nil && len(*rData) > 0 {
+			for _, m := range *rData {
+				var (
+					s_entId       = gconv.String(m["s_entId"])
+					groups        = gconv.String(m["gs"])
+					hasOtherGroup = false //是否存在其他标签
+				)
+				for _, s := range strings.Split(groups, ",") {
+					if s == "" {
+						continue
+					}
+					if s != groupId {
+						hasOtherGroup = true
+						break
+					}
+				}
+				if !hasOtherGroup {
+					needMoveDefault = append(needMoveDefault, s_entId)
+				}
+			}
+		}
+		if len(needMoveDefault) > 0 {
+			//查询默认分组id
+			rMap := db.Base.FindOne("follow_ent_monitor_group", map[string]interface{}{
+				"s_name":   "默认分组",
+				"s_userid": this.UserId,
+			}, "", "")
+			if rMap == nil || len(*rMap) == 0 {
+				err = fmt.Errorf("未知默认分组")
+				return false
+			}
+			var defaultGroupId = gconv.Int((*rMap)["id"])
+			for _, entId := range needMoveDefault {
+				if db.Base.InsertByTx(tx, "follow_ent_monitor_relationship", map[string]interface{}{
+					"s_groupId": defaultGroupId,
+					"s_entId":   entId,
+				}) <= 0 {
+					err = fmt.Errorf("企业数据迁移异常")
+					return false
+				}
+			}
+		}
+		//删除当前标签
+		if !db.Base.DeleteByTx(tx, "follow_ent_monitor_group", map[string]interface{}{
+			"s_userid": this.UserId,
+			"id":       groupId,
+		}) {
+			err = fmt.Errorf("未知分组")
+			return false
+		}
+		return true
+	}) && err == nil {
+		err = fmt.Errorf("删除分组异常")
+	}
+	return err
+}
+
+func (this *EntFollow) GetFollowGroupList() (groupUserArr []EntFollowGroup, err error) {
+	groupMap := make(map[int]int)
+	DefaultGroupInit(this.UserId)
+	flistSql := fmt.Sprintf(`SELECT  m.s_entId,GROUP_CONCAT(g.id SEPARATOR ',') as gs from follow_ent_monitor m inner join follow_ent_monitor_group g on(m.s_userid =g.s_userid and g.s_userid ='%s') INNER JOIN follow_ent_monitor_relationship r  on ( g.id=r.s_groupId and m.s_entId=r.s_entId ) GROUP BY s_entId  ORDER BY m.l_lastpushtime DESC,m.l_createtime DESC LIMIT %d,%d`, this.UserId, 0, this.MaxNum)
+	log.Print("我关注的企业列表开始查询:", flistSql)
+	res := db.Base.SelectBySql(flistSql)
+	if res != nil && len(*res) > 0 {
+		for _, m := range *res {
+			for _, gId := range strings.Split(gconv.String(m["gs"]), ",") {
+				if groupId := gconv.Int(gId); groupId > 0 {
+					groupMap[groupId]++
+				}
+			}
+		}
+	}
+	data := db.Base.SelectBySql(fmt.Sprintf(`SELECT
+	a.id,
+	a.isPut,
+	a.s_name
+FROM
+	follow_ent_monitor_group a
+WHERE
+	a.s_userid = '%s'
+ORDER BY
+	a.isdefGoup DESC,
+	a.create_time DESC`, this.UserId))
+	if data != nil && len(*data) > 0 {
+		for _, m := range *data {
+			groupUserArr = append(groupUserArr, EntFollowGroup{
+				util.EncodeId(qutil.InterfaceToStr(m["id"])),
+				qutil.InterfaceToStr(m["s_name"]),
+				qutil.IntAll(m["isPut"]),
+				groupMap[qutil.IntAll(m["id"])],
+			})
+		}
+	}
+	return
+}
+
+func DefaultGroupInit(userId string) {
+	if db.Base.Count("follow_ent_monitor_group", map[string]interface{}{
+		"user_id":   userId,
+		"isdefGoup": 1,
+	}) == 0 { //初始化默认分组
+		db.Base.SelectBySql(fmt.Sprintf(`INSERT INTO follow_ent_monitor_group (s_name, s_userid, create_time, update_time, isPut, isdefGoup) VALUES
+('默认分组', '%s',  '2025-01-03 12:00:00', '2025-01-13 12:00:00', 0, 1),
+('竞争对手', '%s',  '2024-01-02 12:00:00', '2025-01-13 12:00:00', 1, 0),
+('合作伙伴', '%s',  '2024-01-01 12:00:00', '2025-01-13 12:00:00', 1, 0);`, userId, userId, userId))
+	}
+}

+ 9 - 1
src/jfw/modules/bigmember/src/entity/portrait.go

@@ -355,13 +355,21 @@ func (this *Portrait) SaveExportRecord(pwp *PortraitProjectScreen, ids []string,
 	for _, k := range pwp.Screen.KeyWordArr {
 		keyWords = append(keyWords, dataExportKeywords{Keyword: k})
 	}
+	if (pwp.Screen.PareStartTime == 0 || pwp.Screen.PareEndTime == 0) && pwp.Screen.TimeRange != "" {
+		// 前端传的有timerange 但是PareStartTime 或者PareEndTime没有被赋值过  需要赋值  --筛选条件有时间  然后勾选导出的时候会有这种情况
+		pwp.Screen.PareTimeSelect(true)
+	}
+	publishtime := fmt.Sprintf("%d_%d", pwp.Screen.PareStartTime, pwp.Screen.PareEndTime)
+	if publishtime == "0_0" {
+		publishtime = ""
+	}
 	saveMap := map[string]interface{}{
 		"s_userid":    this.UserId,
 		"comeinfrom":  flag,
 		"comeintime":  time.Now().Unix(),
 		"selectIds":   ids,
 		"area":        qutil.If(pwp.Screen.Area != "", strings.Split(pwp.Screen.Area, ","), nil),
-		"publishtime": fmt.Sprintf("%d_%d", pwp.Screen.PareStartTime, pwp.Screen.PareEndTime),
+		"publishtime": publishtime,
 		"industry":    qutil.If(pwp.Screen.ScopeClass != "", strings.Split(pwp.Screen.ScopeClass, ","), nil),
 		"keywords":    keyWords,
 		"selectType":  pwp.Screen.ShowMatch,

+ 73 - 8
src/jfw/modules/bigmember/src/service/follow/enterprise.go

@@ -23,9 +23,11 @@ type FollowEnt struct {
 	list               xweb.Mapper `xweb:"/follow/ent/list"`               //关注企业列表
 	addFollow          xweb.Mapper `xweb:"/follow/ent/addFollow"`          //添加关注标企业
 	delFollow          xweb.Mapper `xweb:"/follow/ent/delFollow"`          //取消关注标企业
+	changeGroup        xweb.Mapper `xweb:"/follow/ent/changeGroup"`        //关注企业分组改变
 	entChangeList      xweb.Mapper `xweb:"/follow/ent/entChangeList"`      //企业变更记录
 	pcSimpleFollowList xweb.Mapper `xweb:"/follow/ent/pcSimpleFollowList"` //pc关注企业列表(带变更)
-	changeGroup        xweb.Mapper `xweb:"/follow/ent/changeGroup"`        //关注企业分组改变
+	labelGroup         xweb.Mapper `xweb:"/follow/ent/labelGroup"`         //关注标签分组
+	labelGroupList     xweb.Mapper `xweb:"/follow/ent/labelGroupList"`     //标签分组列表
 }
 
 // Association 中标企业联想
@@ -61,14 +63,15 @@ func (this *FollowEnt) FollowCheck() {
 		if err != nil {
 			return nil, err
 		}
-		followed, showFollow, err := followEntManager.EntFollowedShow(util.DecodeId(this.GetString("entId")))
+		followed, showFollow, followedGroup, err := followEntManager.EntFollowedShow(util.DecodeId(this.GetString("entId")))
 		if err != nil {
 			return nil, err
 		}
 		used, surplus := followEntManager.GetFollowEntInfo()
 		return map[string]interface{}{
-			"followed": followed,
-			"isShow":   showFollow,
+			"followed":      followed,
+			"isShow":        showFollow,
+			"followedGroup": followedGroup,
 			"info": map[string]interface{}{
 				"surplus": surplus,
 				"used":    used,
@@ -159,7 +162,7 @@ func (this *FollowEnt) AddFollow() {
 				"limit_count": followEntManager.MaxNum,
 			}, errors.New(fmt.Sprintf("您关注的企业已达%d个,无法关注更多", followEntManager.MaxNum))
 		}
-		err = followEntManager.AddFollowEnt(util.DecodeId(entId), this.GetString("group"))
+		err = followEntManager.AddFollowEnt(util.DecodeId(entId), this.GetString("groups"))
 		if err != nil {
 			return nil, err
 		}
@@ -247,9 +250,8 @@ func (this *FollowEnt) ChangeGroup() {
 		if err != nil {
 			return nil, err
 		}
-		group := this.GetString("group")
-		followId := util.DecodeId(this.GetString("fid"))
-		err = cepm.ChangeFollowGroup(followId, group)
+		groups := this.GetString("groups")
+		err = cepm.ChangeFollowGroup(util.DecodeId(this.GetString("entId")), groups)
 		if err != nil {
 			return nil, err
 		}
@@ -260,3 +262,66 @@ func (this *FollowEnt) ChangeGroup() {
 	}
 	this.ServeJson(NewResult(rData, errMsg))
 }
+
+// LabelGroup 关注企业标签分组
+func (this *FollowEnt) LabelGroup() {
+	userId := qutil.ObjToString(this.GetSession("userId"))
+	request := this.GetString("type")
+	rData, errMsg := func() (interface{}, error) {
+		followEntManager, err := entity.CreateEntFollowManager(this.Session())
+		if err != nil {
+			return nil, err
+		}
+		switch request {
+		case "get":
+			//获取列表
+			// 获取剩余数量信息
+			_, surplus := followEntManager.GetFollowEntInfo()
+			if surplus == 0 {
+				return map[string]interface{}{
+					"status":      false,
+					"limit_count": followEntManager.MaxNum,
+				}, errors.New(fmt.Sprintf("您关注的企业已达%d个,无法关注更多", followEntManager.MaxNum))
+			}
+			data := followEntManager.GetLabelGroup()
+			return data, nil
+		case "add": //增加列表
+			err = followEntManager.AddLabelGroup(this.GetString("name"))
+			return nil, err
+		case "put": //
+			err = followEntManager.PutLabelGroup(this.GetString("name"), util.DecodeId(this.GetString("groupId")))
+			return nil, err
+		case "del":
+			err = followEntManager.DelLabelGroup(util.DecodeId(this.GetString("groupId")))
+			return nil, err
+		default:
+			return nil, errors.New("错误参数")
+		}
+	}()
+	if errMsg != nil {
+		log.Printf("%s 关注企业-关注企业标签分组:%s\n", userId, errMsg.Error())
+	}
+	this.ServeJson(NewResult(rData, errMsg))
+}
+
+// LabelGroupList 关注中标企业标签列表
+func (this *FollowEnt) LabelGroupList() {
+	userId := qutil.ObjToString(this.GetSession("userId"))
+	rData, errMsg := func() (interface{}, error) {
+		followEntManager, err := entity.CreateEntFollowManager(this.Session())
+		if err != nil {
+			return nil, err
+		}
+		groupUserArr, err := followEntManager.GetFollowGroupList()
+		if err != nil {
+			return nil, err
+		}
+		return map[string]interface{}{
+			"groupUserArr": groupUserArr, //关注分组列表
+		}, nil
+	}()
+	if errMsg != nil {
+		log.Printf("%s 企业关注列表查询出错:%s\n", userId, errMsg.Error())
+	}
+	this.ServeJson(NewResult(rData, errMsg))
+}

+ 3 - 3
src/jfw/modules/followent/src/web/templates/weixin/list.html

@@ -149,7 +149,7 @@ initShare({{.T.signature}},{{.T.openid}},2,"jy_extend",{{.T.nickname}},{{.T.avat
     				if(frontarr[f]["i_apppushunread"]==1){
     					redSpot = '<i class="redspot"></i>';
     				}
-            fronthtml +="<li data-id='"+frontarr[f]["fid"]+"' Sort='"+lastpushtime+"'>"
+            fronthtml +="<li data-id='"+frontarr[f]["fid"]+"' ent-id='"+frontarr[f]["s_entId"]+"' Sort='"+lastpushtime+"'>"
                 +"<div class='jyfwlistno'>"+listno+".</div>"
                 +"<div class='jyfwlisttitle'>"+entname+"</div>"
                 +"<div style='clear:both;'></div>"+rem
@@ -182,7 +182,7 @@ initShare({{.T.signature}},{{.T.openid}},2,"jy_extend",{{.T.nickname}},{{.T.avat
     					redSpot = '<i class="redspot"></i>';
     				}
             var listno = parseInt(l)+parseInt(1)+jyno;
-            lasthtml +="<li class='jyovertime' data-id='"+lastarr[l]["fid"]+"'>"
+            lasthtml +="<li class='jyovertime' data-id='"+lastarr[l]["fid"]+"' ent-id='"+lastarr[l]["s_entId"]+"'>"
             +"<div class='jyfwlistno'>"+listno+".</div>"
             +"<div class='jyfwlisttitle'>"+lastarr[l]["s_entname"]+"</div>"
             +"<div style='clear:both;'></div>"+rem
@@ -201,7 +201,7 @@ initShare({{.T.signature}},{{.T.openid}},2,"jy_extend",{{.T.nickname}},{{.T.avat
                 sessionStorage.version="0";
             }
             $(this).find(".redspot").remove();
-            window.location.href = "/jylab/followent/detail/"+$(this).attr("data-id");
+            window.location.href = "/jylab/followent/detail/"+$(this).attr("data-id") + '?entId=' + $(this).attr("ent-id");
         });
 
         var flag = {{.T.flag}};

+ 7 - 2
src/jfw/modules/followent/src/web/templates/weixin/set.html

@@ -149,10 +149,15 @@ if(sessionStorage){
 		$("#sure").click(function(){
 			easyPopup.hide();
 			//发送Ajax请求,取消关注
-      const eid = window.location.href.split("/")[6]
+      const fid = window.location.href.split("/")[6]
+      const url = new URL(window.location.href); // 获取当前页面的URL
+      const params = new URLSearchParams(url.search); // 获取查询字符串部分
+
+      // 获取单个参数
+      const eId = params.get('entId');
 			$.post(
 				"/bigmember/follow/ent/delFollow",
-        {"fid":eid},
+        {"entId":eId},
 				function(r){
 					if(r.data == "success"){
 						if(sessionStorage){

BIN
src/web/staticres/common-module/big-member/image/jk.png


BIN
src/web/staticres/common-module/big-member/image/yjk.png


+ 281 - 18
src/web/staticres/common-module/collection/js/ent_portrait.js

@@ -6,6 +6,7 @@ var vNode = {
     hisproComponent: hisproComponent,
     forwardshare: vmForward,
     mobilePortrayalFooter:mobilePortrayalFooter,
+    mobilePortrayalGroupingScript: mobilePortrayalGroupingScript,
     downloadpopup: downloadpopup,
   },
   data () {
@@ -193,7 +194,21 @@ var vNode = {
       isFree: false,
       balance:0,
       moreSesame: false,
-      isOneRow: 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 () {
@@ -365,6 +380,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.showGroupingDialog = false
+        _this.setGroupState = ''
+      } else {
+        this.changeFollowStateRequest(params)
+      }
+    },
+    cancelGrouping () {
+      this.showGroupingDialog = false
+      this.setGroupState = ''
+    },
     // 监听画像页面滚动
     onEntScroll: utils.debounce(function(e){
       this.pageScrollTop = e.target.scrollTop
@@ -773,8 +887,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({
@@ -789,6 +918,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
             }
@@ -801,21 +933,71 @@ var vNode = {
         }
       })
     },
-    changeFollowState: function () {
+    changeFollowState: function (state) {
       var _this = this
-      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.setGroupState = ''
+          _this.showGroupingDialog = false
+          _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()
       }
     },
     goToUnlock: function () {
@@ -956,7 +1138,7 @@ var vNode = {
       })
     },
     // 修改企业关注状态
-    changeFollowStateRequest: function () {
+    changeFollowStateRequest: function (params = {}) {
       var _this = this
       var loading = this.showLoading()
       var urls = {
@@ -968,7 +1150,8 @@ var vNode = {
         type: 'POST',
         url: url,
         data: {
-          entId: _this.entInfo.id
+          entId: _this.entInfo.id,
+          ...params
         },
         success: function (res) {
           if (res.error_code == 0) {
@@ -976,16 +1159,62 @@ 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 || '监控失败')
             }
             if(_this.entInfo.follow) {
               _this.pointsTaskSuccessTip()
             }
-            if (!_this.entInfo.follow) {
-              history.back()
-            }
+            // if (!_this.entInfo.follow) {
+            //   history.back()
+            // }
           } else {
             _this.showToast(res.error_msg)
           }
@@ -994,7 +1223,41 @@ var vNode = {
           console.log(error)
         }
       })
-    }, // 赚剑鱼币任务完成提示
+    },
+    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() {
       // 获取剑鱼币任务信息
       const from =  utils.getParam('from')

+ 21 - 1
src/web/staticres/common-module/mobile-portrayal-footer/css/mobile-portrayal-footer.css

@@ -25,13 +25,14 @@
   border-top: 0.01rem solid #0000001A;
 }
 .m-footer-box .footer-item{
+  display: flex;
+  flex-direction: column;
   flex: 1;
   padding-top: 0.1rem;
   justify-content: center;
 }
 .monitor-box{
   width: 3.22rem;
-  height: 3.84rem;
   background-color: #fff;
   box-sizing: border-box;
   border: 0.01rem solid #0000000D;
@@ -41,10 +42,29 @@
   left: 0.32rem;
   top: -4rem;
 }
+.monitor-box.action {
+  top: -4.8rem;
+}
 .monitor-box .monitor-box-item{
   padding: 0.24rem 0;
   border-bottom: 0.01rem solid #0000000D;
 }
+.monitor-box .monitor-box-item.monitor-group {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: .24rem .16rem;
+}
+.monitor-box-item.monitor-group .look-text{
+  width: 2rem;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.monitor-box .monitor-box-item.monitor-group .editor-group {
+  color: #2ABED1;
+  font-size: .28rem;
+}
 .monitor-box .monitor-box-item:last-child{
   border-bottom: none;
 }

+ 89 - 0
src/web/staticres/common-module/mobile-portrayal-footer/css/mobile-portrayal-grouping.css

@@ -0,0 +1,89 @@
+.mobile-portrayal-grouping .grouping-dialog.van-dialog {
+  padding: 0 .32rem;
+  top: 50%;
+}
+.mobile-portrayal-grouping .van-dialog .van-dialog__header {
+  padding-top: 24px;
+  font-weight: 400;
+}
+.mobile-portrayal-grouping .van-dialog.grouping-dialog .van-dialog__content {
+  padding: 0;
+  margin-bottom: .44rem;
+}
+.mobile-portrayal-grouping .van-dialog__content .add-grouping {
+  display: flex;
+  justify-content: flex-end;
+  align-items: center;
+  margin: .16rem 0;
+  height: .4rem;
+}
+.add-grouping .van-icon-plus {
+  margin-bottom: .04rem;
+}
+.mobile-portrayal-grouping .van-dialog__content .add-grouping .add-grouping-text {
+  margin-left: .08rem;
+  font-size: .28rem;
+  color: #2ABED1;
+}
+.mobile-portrayal-grouping .grouping-list {
+  min-height: 2.4rem;
+  max-height: 8rem;
+  overflow: hidden;
+  overflow-y: auto;
+}
+.mobile-portrayal-grouping .grouping-list .van-checkbox {
+  padding: .2rem 0;
+  border-bottom: 0.5px solid rgba(0, 0, 0, 0.05);
+}
+.mobile-portrayal-grouping .grouping-list .van-checkbox .van-checkbox__label {
+  width: 5.94rem;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.mobile-portrayal-grouping .add-grouping-dialog .dialog-footer {
+  display: flex;
+  justify-content: space-between;
+  
+}
+.add-grouping-dialog .dialog-footer .van-button {
+  flex: 1;
+  font-size: 18px;
+  border: none;
+  border-top: 0.5px solid rgba(0, 0, 0, 0.1);
+}
+
+.add-grouping-dialog .dialog-footer .van-button.confirm-button {
+  color: #2abed1;
+  border-left: 0.5px solid rgba(0, 0, 0, 0.1);
+}
+
+.mobile-portrayal-grouping .add-grouping-dialog .van-dialog__content {
+  padding: 0;
+  margin: .32rem 0 0 0;
+}
+.mobile-portrayal-grouping .add-grouping-dialog .van-cell {
+  padding: 0 .32rem .44rem .32rem;
+}
+.mobile-portrayal-grouping .add-grouping-dialog .van-cell .van-field__body {
+  padding-bottom: .22rem;
+  border-bottom: 0.5px solid rgba(0, 0, 0, 0.05);
+}
+.mobile-portrayal-grouping .add-grouping-dialog .van-field__control::placeholder {
+  color: #9B9CA3;
+}
+.mobile-portrayal-grouping .add-grouping-dialog .van-field__word-limit {
+  position: absolute;
+  right: 0;
+  top: 0;
+}
+.mobile-portrayal-grouping .add-grouping-dialog .van-field__word-limit .van-field__word-num {
+  color: #2ABED1;
+}
+.mobile-portrayal-grouping .add-grouping-dialog .van-field__error-message {
+  margin-top: .16rem;
+  font-size: .28rem;
+  color: #FB483D;
+  line-height: .4rem;
+}

+ 110 - 40
src/web/staticres/common-module/mobile-portrayal-footer/js/mobile-portrayal-footer.js

@@ -26,14 +26,18 @@ var mobileportrayalfootertemp = `
         </div>
         <p class="footer-text">下载报告</p>
       </div>
-      <div class="monitor-box" v-show="monitorboxShow">
+      <div class="monitor-box" :class="{'action': monitorGroupShow }" v-show="monitorboxShow">
+        <div class="monitor-box-item monitor-group" v-if="monitorGroupShow">
+          <p class="look-text">{{ entInfo.followedGroup }}</p>
+          <span @click.stop="editorGroupEvent" class="editor-group">更改></span>
+        </div>
         <div class="monitor-box-item">
           <p class="look-text" @click="lookDynamic">查看监控动态</p>
         </div>
         <div class="monitor-box-item">
           <p class="look-text look-text--monitor" @click="lookList">查看监控列表</p>
           <p class="look-desc">已监控 <span class="look-num" v-text="use"></span> 个,剩余 <span class="look-num" v-text="surplus"></span> 个</p>
-          <div class="look-btn" @click="lookMore">申请监控更多业主</div>
+          <div class="look-btn" @click="lookMore">申请监控更多{{ setMonitorObj }}</div>
         </div>
         <div class="monitor-box-item">
           <p class="look-cancellation"  @click="monitorCancellation">取消监控</p>
@@ -73,6 +77,10 @@ var mobilePortrayalFooter = {
       type: Boolean,
       default: false
     },
+    entInfo: { // 监控分组
+      type: Object,
+      default: {}
+    },
     customMonitor:{ // 是否自定义监控点击
       type: Boolean,
       default: false
@@ -89,10 +97,31 @@ var mobilePortrayalFooter = {
       type: Boolean,
       default: false
     },
-    allpower:{ // 权限状态
-
-    }
-
+    allpower:{}, // 权限状态
+    portraitOrigin: { // 页面来源
+      type: String,
+      default: ''
+    },
+    sourceMap: {
+      type: Object,
+      default: function (){
+        return {
+          app: 'app_buyer_monitor_more',
+          wx: 'wx_buyer_monitor_more',
+          h5: 'h5_buyer_monitor_more'
+        }
+      }
+    },
+    sourceLimitMap: {
+      type: Object,
+      default: function (){
+        return {
+          app: 'app_buyer_monitor_limit',
+          wx: 'wx_buyer_monitor_limit',
+          h5: 'h5_buyer_monitor_limit'
+        }
+      }
+    },
   },
   data: function () {
     return {
@@ -101,7 +130,8 @@ var mobilePortrayalFooter = {
       showIframe: false,
       monitorboxShow: false,
       use:'',
-      surplus:''
+      surplus:'',
+      monitorGroupShow: false // 监控分组是否展示, 也用来设置弹窗的定位高度
     }
   },
   created () {
@@ -110,6 +140,11 @@ var mobilePortrayalFooter = {
   mounted () {
 
   },
+  computed: {
+    setMonitorObj () {
+      return this.portraitOrigin === 'ent' ? '企业' : '业主'
+    }
+  },
  watch: {
   islogin (val){
     if(val){
@@ -135,27 +170,34 @@ var mobilePortrayalFooter = {
       // }
       this.$parent.$refs.downloadpopup.show() //触发引用此组件父级组件的下载弹框
     },
+    editorGroupEvent () { // 更改监控分组事件
+      this.$emit('change', 'put')
+    },
     monitorClick: utils.debounce(function(){
       let this_ = this
       let params = {
         name_list:[decodeURIComponent(utils.getParam('entName'))]
       }
       if(this_.monitor){ // 已监控
-        if (this.customMonitor) {
-          this.$emit('monitorclick', true)
+        if (this_.customMonitor) {
+          this_.$emit('monitorclick', true)
         } else {
-          $.ajax({
-            type: 'POST',
-            url: '/publicapply/customer/check',
-            contentType: 'application/json',
-            data: JSON.stringify(params),
-            success: function(res) {
-              this_.yes_monitor(res.data) // 弹出取消监控弹窗
-            }
-          })
+          if(this_.portraitOrigin === 'ent'){
+            this_.yes_monitor(this_.entInfo)
+          } else {
+            $.ajax({
+              type: 'POST',
+              url: '/publicapply/customer/check',
+              contentType: 'application/json',
+              data: JSON.stringify(params),
+              success: function(res) {
+                this_.yes_monitor(res.data) // 弹出取消监控弹窗
+              }
+            })
+          }
         }
       } else{ //未监控 去监控
-        this.$emit('monitorclick')
+        this_.$emit('monitorclick')
       }
     },300),
     monitorCancellation (){ // 取消监控
@@ -163,7 +205,7 @@ var mobilePortrayalFooter = {
         width: 303,
         className: 'monitor-dialog',
         title: '确定不再监控?',
-        message: '取消监控,将错过业主最新动态推送',
+        message: `取消监控,将错过${this.setMonitorObj}最新动态推送`,
         messageAlign:'center',
         confirmButtonText: '确认取消',
         // confirmButtonColor: '#2ABED1',
@@ -180,29 +222,51 @@ var mobilePortrayalFooter = {
       this.$emit('claimclick')
     },
     lookDynamic (){
-      try{
-        this.$parent.$refs.scrollspyTabs.scrollTo('2'); //触发引用此组件父级tab 滚动至招标动态
-      }catch(e){
+      this.$emit('lookdynamic')
+      if(!this.portraitOrigin){
+        try{
+          this.$parent.$refs.scrollspyTabs.scrollTo('2'); //触发引用此组件父级tab 滚动至招标动态
+        }catch(e){
+        }
       }
     },
     //  采购单位监控点击相关
     lookList (){
-      // 跳转至监控列表页
-      if(utils.$envs.inWX){
-        window.location.href = '/big/wx/page/client_list'
-     } else {
-       window.location.href = '/jyapp/big/page/client_list'
-     }
+      // 大会员企业画像点击查看监控列表跳转到大会员企业情报监控列表页
+      if (this.portraitOrigin === 'ent'){
+        if(utils.$envs.inWX){
+          window.location.href = '/jylab/followent/entList'
+        } else {
+          if(this.allpower.memberStatus > 0) {
+            window.location.href = '/jyapp/big/page/ent_follow'
+          } else {
+            window.location.href = '/jyapp/followent/entList'
+          }
+        }
+      } else {
+        // 非企业画像跳转至对应的监控列表页
+        if(utils.$envs.inWX){
+          window.location.href = '/big/wx/page/client_list'
+        } else {
+          window.location.href = '/jyapp/big/page/client_list'
+        }
+      }
+      
     },
     lookMore (){
+      if(this.portraitOrigin === 'ent'){
+        this.$emit('lookmore')
+        return
+      }
+
       if(this.allpower.vipStatus > 0){
         let href_
         if(utils.$envs.inWX){
-          href_ = '/weixin/frontPage/bigmember/free/perfect_info?source=wx_buyer_monitor_more'
+          href_ = '/weixin/frontPage/bigmember/free/perfect_info?source=' + this.sourceMap.wx
         }else if(utils.$envs.inApp){
-          href_ = '/jyapp/frontPage/bigmember/free/perfect_info?source=app_buyer_monitor_more'
+          href_ = '/jyapp/frontPage/bigmember/free/perfect_info?source=' + this.sourceMap.app
         }else if(utils.$envs.inH5){
-          href_ = '/jyapp/frontPage/bigmember/free/perfect_info?source=h5_buyer_monitor_more'
+          href_ = '/jyapp/frontPage/bigmember/free/perfect_info?source=' + this.sourceMap.h5
         }
         window.location.href = href_
 
@@ -210,8 +274,8 @@ var mobilePortrayalFooter = {
         this.$dialog({
           width: 303,
           className: 'monitor-dialog',
-          title: '申请监控更多业主',
-          message: '您可联系客服,申请升级产品套餐,监控更多业主',
+          title: `申请监控更多${this.setMonitorObj}`,
+          message: `您可联系客服,申请升级产品套餐,监控更多${this.setMonitorObj}`,
           messageAlign:'center',
           confirmButtonText: '联系客服',
           confirmButtonColor: '#2ABED1',
@@ -229,10 +293,16 @@ var mobilePortrayalFooter = {
       }
     },
     yes_monitor (data, isInit){
-      this.surplus = data.count.surplus
-      this.use = data.count.use
+      if(this.portraitOrigin === 'ent'){
+        this.surplus = data.info.surplus
+        this.use = data.info.used
+      } else {
+        this.surplus = data.count.surplus
+        this.use = data.count.use
+      }
       if (isInit !== true) {
         this.monitorboxShow = !this.monitorboxShow
+        this.monitorGroupShow = this.portraitOrigin === 'ent' ? true : false
       }
     },
     no_monitor (data){
@@ -277,16 +347,16 @@ var mobilePortrayalFooter = {
         this.$toast({
           duration: 2000,
           message: '监控成功,您可前往“工作台-商机-业主监控”查看'
-      })
+        })
 
       }else if(!this.allpower.isFree && data.limit_status === 1){
         let href_
         if(utils.$envs.inWX){
-          href_ = '/weixin/frontPage/bigmember/free/perfect_info?source=wx_buyer_monitor_limit'
+          href_ = '/weixin/frontPage/bigmember/free/perfect_info?source=' + this.sourceLimitMap.wx
         }else if(utils.$envs.inApp){
-          href_ = '/jyapp/frontPage/bigmember/free/perfect_info?source=app_buyer_monitor_limit'
+          href_ = '/jyapp/frontPage/bigmember/free/perfect_info?source=' + this.sourceLimitMap.app
         }else if(utils.$envs.inH5){
-          href_ = '/jyapp/frontPage/bigmember/free/perfect_info?source=h5_buyer_monitor_limit'
+          href_ = '/jyapp/frontPage/bigmember/free/perfect_info?source=' +  + this.sourceLimitMap.h5
         }
         window.location.href = href_
       } else if(!this.allpower.isFree && data.limit_status === 2){

+ 174 - 0
src/web/staticres/common-module/mobile-portrayal-footer/js/mobile-portrayal-grouping.js

@@ -0,0 +1,174 @@
+var mobilePortrayalGrouping = `
+  <div class="mobile-portrayal-grouping">
+    <van-dialog
+      v-model="showGroupingDialog"
+      :title="title"
+      show-cancel-button
+      confirmButtonText="确定"
+      class="grouping-dialog"
+      @confirm="confirmGrouping"
+      @cancel="cancelGrouping"
+      >
+      <div class="add-grouping" @click="addMonitor">
+        <van-icon color="#2ABED1" name="plus" />
+        <span class="add-grouping-text">新增分组</span>
+      </div>
+      <div class="grouping-list">
+
+        <van-checkbox-group v-model="groupingResult" @change="handleGroupChange">
+          <van-checkbox checked-color="#2ABED1" :name="item.s_name" v-for="(item, index) in groupingList" :key="index">{{item.s_name}}</van-checkbox>
+        </van-checkbox-group>
+      </div>
+    </van-dialog>
+    <van-dialog
+      class="add-grouping-dialog"
+      v-model="showAddGroupingDialog"
+      :show-confirm-button="false"
+      title="新增分组"
+      >
+      <van-field 
+        v-model="groupingName"
+        show-word-limit 
+        maxlength="15"
+        :error-message="errorMessageText"
+        placeholder="请输入分组名称"
+        @input="setGroupingName"
+      >
+      </van-field>
+      <div class="dialog-footer">
+        <van-button type="default" @click="showAddGroupingDialog = false">
+          取消
+        </van-button>
+        <van-button
+          type="default"
+          class="confirm-button"
+          :disabled="isConfirmButtonDisabled"
+          @click="addGrouping"
+        >
+          确定
+        </van-button>
+      </div>
+    </van-dialog>
+  </div>
+`
+
+var mobilePortrayalGroupingScript = {
+  name: 'mobile-portrayal-grouping',
+  template: mobilePortrayalGrouping,
+  props: {
+    title: {
+      type: String,
+      default: '选择分组'
+    },
+    showGroupingDialog: {
+      type: Boolean,
+      default: false
+    },
+    groupingList: {
+      type: Array,
+      default: () => []
+    },
+    entId: {
+      type: String,
+      default: ''
+    }
+  },
+  data () {
+    return {
+      groupingResult: ['默认分组'],
+      groupingName: '',
+      showAddGroupingDialog: false,
+      errorMessageText: '',
+      isUpdating: false, // 标志位,避免死循环
+      isConfirmButtonDisabled: true, // 控制确定按钮是否禁用
+    }
+  },
+  methods: {
+    setState (data) {
+      this.groupingResult = data
+    },
+    addMonitor () {
+      this.showAddGroupingDialog = true
+      this.isConfirmButtonDisabled = true
+    },
+    addGrouping () {
+      // 添加分组确定事件
+      $.ajax({
+        url: '/bigmember/follow/ent/labelGroup',
+        type: 'post',
+        data: {
+          type: 'add',
+          name: this.groupingName
+        },
+        success: (res) => {
+          if (res.error_code === 0) {
+            this.$toast('新增分组成功')
+            this.groupingName = ''
+            this.$emit('update')
+          } else {
+            this.$toast(res.error_msg || '新增分组失败')
+          }
+        }
+      })
+      this.showAddGroupingDialog = false
+    },
+    setGroupingName (val) {
+      this.groupingName = val.trim().replace(/\s+/g, '')
+      this.errorMessageText = ''
+      this.isConfirmButtonDisabled = false
+
+      if (this.groupingName === '') {
+        this.errorMessageText = '分组名称不能为空'
+        this.isConfirmButtonDisabled = true
+      } else {
+        const exists = this.groupingList.some(
+          (item) => item.s_name === this.groupingName
+        )
+        if (exists) {
+          this.errorMessageText = '分组名称已存在'
+          this.isConfirmButtonDisabled = true
+        }
+      }
+    },
+    handleGroupChange (checked) {
+      if(checked.length === 0) {
+        this.groupingResult = ['默认分组']; // 如果没有选择任何其他分组,则只保留'默认分组'
+        return;
+      }
+      if (this.isUpdating) {
+        // 如果正在更新,直接返回,避免递归调用
+        return;
+      }
+      this.isUpdating = true; // 设置标志位
+
+      if (checked.indexOf('默认分组') > 0) {
+        // 如果选择了默认分组,清空其他分组的选择
+        this.groupingResult = ['默认分组'];
+      } else {
+        // 如果选择了其他分组,移除默认分组的选择
+        this.groupingResult = this.groupingResult.filter(item => item !== '默认分组');
+      }
+      this.$nextTick(() => {
+        this.isUpdating = false; // 更新完成后重置标志位
+      });
+    },
+    confirmGrouping () {
+      const idArr = []
+      this.groupingList.forEach(item => {
+        this.groupingResult.forEach(group => {
+          if (item.s_name === group) {
+            idArr.push(item.id)
+          }
+        })
+      })
+      const params = {
+        groups: idArr.length ? idArr.join(',') : '',
+        entId: this.entId
+      }
+      this.$emit('confirm', params)
+    },
+    cancelGrouping () {
+      this.$emit('cancel')
+    }
+  }
+}

+ 27 - 0
src/web/staticres/common-module/perfect-info/js/perfect-info.js

@@ -133,6 +133,13 @@ var titleMap = {
   h5_list_monitor_more:'申请监控更多业主',
   app_list_monitor_more:'申请监控更多业主',
   wx_list_monitor_more:'申请监控更多业主',
+  app_ent_limit: '申请监控更多企业',
+  wx_ent_limit: '申请监控更多企业',
+  h5_ent_limit: '申请监控更多企业',
+  app_ent_more: '申请监控更多企业',
+  wx_ent_more: '申请监控更多企业',
+  h5_ent_more: '申请监控更多企业',
+
   // 商机情报详情页
   app_project_businessDetails: '欢迎体验剑鱼大会员',
   wx_project_businessDetails: '欢迎体验剑鱼大会员',
@@ -385,6 +392,14 @@ var tipMap = {
   h5_list_monitor_more:'请升级大会员,可实时监控最多500个业主采购动态,洞察潜在商机。',
   app_list_monitor_more:'请升级大会员,可实时监控最多500个业主采购动态,洞察潜在商机。',
   wx_list_monitor_more:'请升级大会员,可实时监控最多500个业主采购动态,洞察潜在商机。',
+  app_ent_more: '请升级大会员,可实时监控最多500个企业中标动态,帮助你了解竞争对手和合作伙伴的动向。',
+  wx_ent_more: '请升级大会员,可实时监控最多500个企业中标动态,帮助你了解竞争对手和合作伙伴的动向。',
+  h5_ent_more: '请升级大会员,可实时监控最多500个企业中标动态,帮助你了解竞争对手和合作伙伴的动向。',
+  app_ent_limit: '您当前权限不足,请升级大会员,可实时监控最多500个企业中标动态,帮助你了解竞争对手和合作伙伴的动向。',
+  wx_ent_limit: '您当前权限不足,请升级大会员,可实时监控最多500个企业中标动态,帮助你了解竞争对手和合作伙伴的动向。',
+  h5_ent_limit: '您当前权限不足,请升级大会员,可实时监控最多500个企业中标动态,帮助你了解竞争对手和合作伙伴的动向。',
+
+  
   // 商机情报详情页
   app_project_businessDetails: '请留下联系方式,我们会尽快联系您体验大会员全部功能!',
   wx_project_businessDetails: '请留下联系方式,我们会尽快联系您体验大会员全部功能!',
@@ -512,6 +527,12 @@ var sourceDescMap = {
   h5_list_monitor_more:'业主监控页-超级订阅用户申请监控更多业主',
   app_list_monitor_more:'业主监控页-超级订阅用户申请监控更多业主',
   wx_list_monitor_more:'业主监控页-超级订阅用户申请监控更多业主',
+  app_ent_limit: '企业画像页-申请监控更多企业(已达上限)',
+  wx_ent_limit: '企业画像页-申请监控更多企业(已达上限)',
+  h5_ent_limit: '企业画像页-申请监控更多企业(已达上限)',
+  app_ent_more: '企业画像页-申请监控更多企业',
+  wx_ent_more: '企业画像页-申请监控更多企业',
+  h5_ent_more: '企业画像页-申请监控更多企业',
   // 商机情报详情页
   app_project_businessDetails: '商机情报详情页-查看潜在项目预测',
   wx_project_businessDetails: '商机情报详情页-查看潜在项目预测',
@@ -1858,6 +1879,12 @@ var vNode = {
                 case  'h5_list_monitor_more':
                 case  'app_list_monitor_more':
                 case  'wx_list_monitor_more':
+                case 'app_ent_more':
+                case 'wx_ent_more':
+                case 'h5_ent_more':
+                case 'app_ent_limit':
+                case 'wx_ent_limit':
+                case 'h5_ent_limit':
                 {
                  _this.showMessage('已收到您提交的升级大会员申请,我们会尽快联系您并预约演示时间。', '我知道了', function () {
                     history.back()

+ 30 - 1
src/web/templates/frontRouter/wx/collection/sess/ent_portrait.html

@@ -29,6 +29,7 @@
         <link rel="stylesheet" href='{{Msg "seo" "cdn"}}/common-module/mainSearch/css/j-icons.css?v={{Msg "seo" "version"}}' />
         <link rel="stylesheet" type="text/css" href='{{Msg "seo" "cdn"}}/common-module/dataExport/css/popup-data-export.css?v={{Msg "seo" "version"}}'/>
         <link rel="stylesheet" type="text/css" href='{{Msg "seo" "cdn"}}/common-module/mobile-portrayal-footer/css/mobile-portrayal-footer.css?v={{Msg "seo" "version"}}'/>
+        <link rel="stylesheet" type="text/css" href='{{Msg "seo" "cdn"}}/common-module/mobile-portrayal-footer/css/mobile-portrayal-grouping.css?v={{Msg "seo" "version"}}'/>
         <link rel="stylesheet" href='{{Msg "seo" "cdn"}}/common-module/portrait/css/downloadpopup.css?v={{Msg "seo" "version"}}' />
 </head>
 <style>
@@ -694,7 +695,34 @@
     '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>
+    <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"
+      @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">
@@ -721,6 +749,7 @@
 <script src='{{Msg "seo" "cdn"}}/common-module/forward-share/js/forward.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Msg "seo" "cdn"}}/common-module/portrait/js/downloadpopup.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Msg "seo" "cdn"}}/common-module//mobile-portrayal-footer/js/mobile-portrayal-footer.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module//mobile-portrayal-footer/js/mobile-portrayal-grouping.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Msg "seo" "cdn"}}/common-module/collection/js/ent_portrait.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Msg "seo" "cdn"}}/common-module/keep-tags/keep-tags-template.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Msg "seo" "cdn"}}/common-module/keep-tags/keep-ent-tags-template.js?v={{Msg "seo" "version"}}'></script>