Procházet zdrojové kódy

会员端增加sponsor网络图

theo před 3 roky
rodič
revize
2c4a65bd3d

+ 1 - 0
frontendApi/config/menu.php

@@ -64,6 +64,7 @@ return [
         'show'=>1,
         'child'=>[
             ['name'=>'Placement network', 'class'=>'', 'icon'=>'', 'controller'=>'atlas', 'action'=>'network', 'routePath'=>'atlas/network', 'show'=>1,],
+            ['name'=>'Sponsor network', 'class'=>'', 'icon'=>'', 'controller'=>'atlas', 'action'=>'relation', 'routePath'=>'atlas/relation', 'show'=>1,],
         ]
     ],
     'bonus'=>[

+ 2 - 0
frontendApi/config/urlManagerRules.php

@@ -111,6 +111,8 @@ return [
             'GET main-user-info' => 'main-user-info',
             'GET network' => 'network',
             'GET network-list' => 'network-list',
+            'GET relation' => 'relation',
+            'GET relation-list' => 'relation-list',
             'GET get-period' => 'get-period',
         ],
     ],

+ 62 - 0
frontendApi/modules/v1/controllers/AtlasController.php

@@ -15,6 +15,7 @@ use common\models\EmployLevel;
 use common\models\Period;
 use common\models\StarCrownLevel;
 use common\models\UserNetwork;
+use common\models\UserRelation;
 use Yii;
 use common\models\User;
 
@@ -152,4 +153,65 @@ class AtlasController extends BaseController {
         ]);
     }
 
+    /**
+     * 推荐网络图
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionRelation() {
+        $userId = Yii::$app->request->get('id', \Yii::$app->user->id);
+        $periodNum = Yii::$app->request->get('periodNum', null);
+        $deep = Yii::$app->request->get('deep', 5);
+        if ($deep > 20) {
+            return static::notice('View the top 20 sub members of the member at most', 400); // 最多查看会员的前20层子会员
+        }
+        $allData = UserRelation::getChildrenWithDeepAndLayer($userId, $deep, 1, $periodNum);
+        return static::notice(['allData' => $allData, 'periodNum' => $periodNum]);
+    }
+
+    /**
+     * 推荐网络列表
+     * @return mixed
+     * @throws \yii\base\Exception
+     * @throws \yii\db\Exception
+     * @throws \yii\web\HttpException
+     */
+    public function actionRelationList() {
+        $userName = Yii::$app->request->get('userName');
+        $deep = Yii::$app->request->get('deep', 5);
+        $periodNum = Yii::$app->request->get('periodNum', null);
+        if (!$userName) {
+            $userId = \Yii::$app->user->id;
+        } else {
+            if (!$userId = Info::getUserIdByUserName($userName)) {
+                return static::notice('Member does not exist', 400); //  会员不存在
+            }
+            $topUid = \Yii::$app->user->id;
+            $userNetInfo = UserRelation::findOneAsArray('USER_ID=:USER_ID', [':USER_ID' => $userId], 'PARENT_UIDS');
+            $parentUidsArr = explode(',', $userNetInfo['PARENT_UIDS']);
+            if(!in_array($topUid,$parentUidsArr)){
+                return static::notice('会员与当前用户不再同一安置网络内', 400);
+            }
+        }
+        $period = Period::instance();
+        $mainUserInfo = Info::baseInfo($userId, $periodNum);
+        $decLevelConfig = Cache::getDecLevelConfig();
+        $empLevelConfig = Cache::getEmpLevelConfig();
+        $data = UserNetwork::getChildrenInDeepFromPeriodWithPage($userId, $deep, $periodNum, 1 ? ['pageSize' => 10] : []);
+        foreach($data['list'] as $key=>$value){
+            $userBaseInfo = Info::baseInfo($value['USER_ID'], $periodNum);
+            $data['list'][$key]['LIST_PERIOD_NUM'] = $periodNum?$periodNum:$period->getNowPeriodNum();
+            $data['list'][$key]['COUNT_DEEP'] = (int)($userBaseInfo['NETWORK_DEEP']);
+            $data['list'][$key]['USER_NAME'] = $userBaseInfo['USER_NAME'];
+            $data['list'][$key]['SEE_USER_NAME'] = $userBaseInfo['USER_NAME'];
+            $data['list'][$key]['REAL_NAME'] = $userBaseInfo['REAL_NAME'];
+            $data['list'][$key]['PERIOD_AT'] = $userBaseInfo['PERIOD_AT'];
+            $data['list'][$key]['DEC_LV_NAME'] = $decLevelConfig[$userBaseInfo['DEC_LV']]['LEVEL_NAME'];
+            $data['list'][$key]['EMP_LV_NAME'] = $empLevelConfig[$userBaseInfo['EMP_LV']]['LEVEL_NAME'];
+        }
+        $data['periodNum'] = $periodNum;
+        $data['listTopDeep'] = $mainUserInfo['NETWORK_DEEP'];
+
+        return static::notice($data);
+    }
 }

+ 31 - 19
frontendEle/src/router/index.js

@@ -246,25 +246,37 @@ export const constantRouterMap = [
       },
     ]
   },
-    {
-        path: '/atlas',
-        component: layout,
-        redirect: '/atlas/network',
-        children: [
-            {
-                path: '/atlas/network',
-                component: _import('atlas/network'),
-                name: 'atlas_network',
-                meta: {
-                    title: 'Placement network',
-                    breadcrumb: [
-                        {title: 'Dashboard', path: '/dashboard/index'},
-                        {title: 'Network Chart', path: '/atlas/network'},
-                    ],
-                },
-            },
-        ]
-    },
+  {
+    path: '/atlas',
+    component: layout,
+    redirect: '/atlas/network',
+    children: [
+      {
+        path: '/atlas/network',
+        component: _import('atlas/network'),
+        name: 'atlas_network',
+        meta: {
+          title: 'Placement network',
+          breadcrumb: [
+            {title: 'Dashboard', path: '/dashboard/index'},
+            {title: 'Network Chart', path: '/atlas/network'},
+          ]
+        }
+      },
+      {
+        path: '/atlas/relation',
+        component: _import('atlas/relation'),
+        name: 'atlas_relation',
+        meta: {
+          title: 'Sponsor network',
+          breadcrumb: [
+            {title: 'Dashboard', path: '/dashboard/index'},
+            {title: 'Sponsor Chart', path: '/atlas/relation'}
+          ]
+        }
+      }
+    ]
+  },
   {
     path: '/bonus',
     component: layout,

+ 251 - 0
frontendEle/src/views/atlas/relation.vue

@@ -0,0 +1,251 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <div class="filter-user" @keyup.enter="enterToGetData()" >
+        <el-input v-model="mainUserName" size="small" style="width:300px;" class="top-member">
+          <template slot="prepend">Top Member</template>
+        </el-input>
+        <el-input v-model="expandDeep" size="small" style="width:200px;" class="spread-depth">
+          <template slot="prepend">Spread depth</template>
+        </el-input>
+        <el-input v-model="periodNum" size="small" style="width:150px;" v-show="false">
+          <template slot="prepend">Period number</template>
+        </el-input>
+        <el-button type="primary" size="small" @click="getMainData()">Confirm</el-button>
+      </div>
+      <el-tree :props="props" :data="treeData" node-key="USER_ID" @node-click="getChildData" ref="tree" :indent="0"
+                default-expand-all :height="tool.getTableHeight(true)">
+        <span :id="'node_'+data.USER_ID" :class="'custom-tree-node '+data.className" slot-scope="{ node, data }">
+          <span :class="'el-icon-loading '+ data.displayNone"></span>
+          <span :class="data.icon"></span>
+          <span>
+            <el-tag type="danger">Number of Layers: {{countTopDeep(data.TOP_NETWORK_DEEP,topDeep)}}</el-tag>
+            <el-tag>Member Code: {{ node.label }}</el-tag>
+            <el-tag>Name: {{data.REAL_NAME}}</el-tag>
+            <el-tag type="danger">Location: {{data.RELATIVE_LOCATION}}</el-tag>
+            <el-tag type="success">Level: {{data.DEC_LV_NAME}}</el-tag>
+            <el-tag type="warning">Rank: {{data.EMP_LV_NAME}}, {{data.CROWN_LV_NAME}}</el-tag>
+<!--            <el-tag type="warning">Star: {{data.CROWN_LV_NAME}}</el-tag>-->
+            <el-tag>Joining Period: {{data.PERIOD_AT}}</el-tag>
+          </span>
+        </span>
+      </el-tree>
+    </div>
+  </div>
+</template>
+
+<script>
+import network from '@/utils/network'
+import tool from '@/utils/tool'
+import store from '@/utils/vuexStore'
+import Pagination from '@/components/Pagination'
+import baseInfo from '@/utils/baseInfo'
+
+export default {
+  name: 'atlas_relation',
+  components: {Pagination},
+  mounted () {
+    this.getData()
+    store.state.socket.onMessageCallback = this.onMessageCallback
+  },
+  data () {
+    return {
+      loading: true,
+      tabActiveName: 'first',
+      // relation
+      props: {
+        label: 'USER_NAME',
+        children: 'children',
+        // isLeaf: 'leaf',
+        icon: 'icon'
+      },
+      treeData: null,
+      expandDeep: 5,
+      topDeep: 0,
+      mainUserName: '',
+      periodNum: null,
+      listPeriodNum: null,
+      allData: null,
+      tableHeaders: null,
+      tableData: null,
+      currentPage: 1,
+      totalPages: 1,
+      totalCount: 1,
+      pageSize: 20,
+      tool: tool,
+      filterForm: {
+        userName: null,
+        deep: 5,
+        periodNum: null
+      },
+      listTopDeep: 0
+    }
+  },
+  methods: {
+    getData () {
+      this.$message({
+        message: 'Retrieving data, please wait.' // 正在获取数据,请稍后
+      })
+      // this.periodNum = baseInfo.nowPeriodNum()
+      // this.filterForm.periodNum = baseInfo.nowPeriodNum()
+      this.getMainData(null, true)
+    },
+    getMainData (userName = null, getList = false) {
+      this.$message.closeAll()
+      this.$message({
+        message: 'Retrieving data, please wait.' // 正在获取数据,请稍后
+      })
+      let thisObj = this
+      let requestData = {
+        periodNum: this.periodNum
+      }
+      if (this.mainUserName !== null) {
+        requestData = {userName: this.mainUserName, periodNum: this.periodNum}
+      }
+      network.getData('atlas/main-user-info', requestData).then(response => {
+        thisObj.treeData = response
+        thisObj.topDeep = Number(response[0].TOP_NETWORK_DEEP)
+        thisObj.listPeriodNum = response[0].listPeriodNum
+        if (getList) thisObj.getListData()
+        thisObj.loading = false
+      }).catch(response => {
+        thisObj.loading = false
+      })
+    },
+    getChildData (data, node) {
+      let thisObj = this
+      let userId = data.USER_ID
+      let thisData = data
+      if (thisData.leaf) {
+        return ''
+      }
+      if (thisData.isExpanded) {
+        return ''
+      }
+      if (thisData.children !== null && thisData.children.length > 0) {
+        return ''
+      }
+      thisData.displayNone = ''
+      network.getData('atlas/relation', {
+        id: userId,
+        deep: thisObj.expandDeep,
+        periodNum: this.periodNum
+      }).then(response => {
+        thisObj.$refs.tree.updateKeyChildren(userId, response.allData)
+        thisObj.listPeriodNum = response.periodNum
+        thisData.displayNone = 'display-none'
+        thisData.isExpanded = true
+      })
+    },
+    countTopDeep (deep, topDeep) {
+      return Number(deep) - Number(topDeep)
+    },
+    handleCurrentChange (page) {
+      this.getListData(page, this.pageSize)
+    },
+    handleSizeChange (pageSize) {
+      this.getListData(this.currentPage, pageSize)
+    },
+    handleFilter () {
+      this.getListData(1, this.pageSize)
+      this.tabActiveName = 'two'
+    },
+    handleShow (row) {
+      this.loading = true
+      this.filterForm.userName = row.SEE_USER_NAME
+      this.getListData(1, this.pageSize)
+      this.tabActiveName = 'two'
+    },
+    getListData (page, pageSize) {
+      let obj = this
+      network.getPageData(this, 'atlas/relation-list', page, pageSize, this.filterForm, function (response) {
+        obj.allData = response
+        obj.listTopDeep = response.listTopDeep
+      })
+    },
+    onMessageCallback (data) {
+      // this.getData(this.currentPage, this.pageSize, false)
+    },
+    handleExport () {
+      this.$confirm(`Are you sure you want to export the current data?`, 'Hint', { // 确定要导出当前数据吗?
+        confirmButtonText: 'confirm', // 确定
+        cancelButtonText: 'cancel', // 取消
+        type: 'warning'
+      }).then(() => {
+        return network.getData(`atlas/relation-list-export`, this.filterForm)
+      }).then(response => {
+        this.$message({
+          message: response,
+          type: 'success'
+        })
+      }).catch(response => {
+      })
+    },
+    enterToGetData (ev) {
+      this.getMainData()
+    }
+  }
+}
+</script>
+
+<style scoped>
+  .filter-user{font-size: 14px;margin-bottom: 20px;}
+  .filter-user:after{content: '';display: table;
+      clear: both;}
+  .filter-user .el-input-group{float: left;margin-right: 15px;}
+  .filter-user >>> .el-input__inner{border: 1px solid #DCDFE6;width: 100%;background: none;border-radius: 0;float: right;display: block; }
+  .filter-user >>> .el-input-group__prepend{border-top: 1px solid #DCDFE6;border-left: 1px solid #DCDFE6;border-bottom: 1px solid #DCDFE6;border-right:none;}
+  .el-tree {
+      padding-bottom: 20px;
+      font-size: 14px;
+      overflow-x: auto;
+  }
+
+  .el-tree .el-tag {
+      height: 20px;
+      line-height: 18px;vertical-align: middle;
+  }
+  .el-tree-node{position: relative;}
+
+  .el-tree-node__content {
+      height: 30px;
+      line-height: 30px;
+  }
+
+  .el-tree-node__children {
+      position: relative;
+      padding: 0 0 0 16px;
+  }
+
+  .el-tree-node:before {
+      position: absolute;
+      content: '';
+      top: 0px;
+      left: -4px;
+      height: 100%;
+      border-left: 1px solid #ccc;
+  }
+  .el-tree-node:last-child:before{height: 15px;}
+
+  .custom-tree-node {
+      position: relative;
+      padding-left: 5px;
+  }
+
+  .first-node:before {
+      display: none;
+  }
+
+  .custom-tree-node:before {
+      position: absolute;
+      width: 8px;
+      content: '';
+      top: 15px;
+      left: -4px;
+      border-bottom: 1px solid #ccc;
+  }
+
+  .el-tree-node__expand-icon {
+      display: none !important;
+  }
+</style>