ソースを参照

Merge branch 'feature_20251107_质感销售专员首页'

sunny 3 週間 前
コミット
267095b70e
3 ファイル変更568 行追加15 行削除
  1. 535 0
      src/views/home/HomeTarget.vue
  2. 2 0
      src/views/home/hintTabPage/noVisit.vue
  3. 31 15
      src/views/home/index.vue

+ 535 - 0
src/views/home/HomeTarget.vue

@@ -0,0 +1,535 @@
+<template>
+  <div class="ABtarage">
+    <p class="updataTime">更新时间:{{ updataTime }}</p>
+    <template>
+      <div class="container linep">
+        <van-collapse v-model="activeNames">
+          <div v-for="(homePageItem, index) in homePageIndicatorList" :key="index">
+            <van-collapse-item v-if="homePageItem.labelStyle==1" :name="(index + 1).toString()" :title="homePageItem.name">
+              <van-row>
+                <!-- 动态渲染标题栏 -->
+                <div v-for="(periodItem, periodIndex) in homePageItem.children" :key="'title-' + periodIndex">
+                  <van-col span="12">
+                    <span :class="periodIndex % 2 === 0 ? 'leftTitle' : 'rightTitle'">{{ periodItem.name }}</span>
+                  </van-col>
+                </div>
+
+                <!-- 动态渲染指标项 -->
+                <div v-if="homePageItem.children.length >= 2">
+                  <!-- 遍历第一个周期的所有指标 -->
+                  <div v-for="(metric, metricIndex) in homePageItem.children[0].children" :key="'metric-' + metricIndex">
+                    <!-- 左侧指标 -->
+                    <van-col span="12">
+                      <p>
+                        {{ metric.name }}:
+                        <span class="colorblack">
+                          <template v-if="metric.indicatorUnit === '%'">{{ metric.indicatorValue }}%</template>
+                          <template v-else>
+                            {{ Micrometer(metric.indicatorValue) }}
+                            {{ metric.indicatorUnit }}
+                          </template>
+                        </span>
+                      </p>
+                    </van-col>
+                    <!-- 对应右侧指标 -->
+                    <van-col span="12">
+                      <p>
+                        {{ homePageItem.children[1]?.children[metricIndex]?.name || '-' }}:
+                        <span class="colorblack">
+                          <template v-if="homePageItem.children[1]?.children[metricIndex]?.indicatorUnit === '%'">
+                            {{ homePageItem.children[1]?.children[metricIndex]?.indicatorValue }}%
+                          </template>
+                          <template v-else>
+                            {{ Micrometer(homePageItem.children[1]?.children[metricIndex]?.indicatorValue) }}
+                            {{ homePageItem.children[1]?.children[metricIndex]?.indicatorUnit }}
+                          </template>
+                        </span>
+                      </p>
+                    </van-col>
+                  </div>
+                </div>
+              </van-row>
+            </van-collapse-item>
+            <van-collapse-item v-if="homePageItem.labelStyle==2" :name="(index + 1).toString()" :title="homePageItem.name">
+              <!-- 外层循环:遍历主要类别 -->
+              <van-row v-for="(category, index) in homePageItem.children" :key="index"
+                :style="{ marginTop: index > 0 ? '10px' : '0' }">
+                <van-col span="24">
+                  <span :class="index % 2 === 0 ? 'leftTitle' : 'rightTitle'">{{ category.name }}</span>
+                </van-col>
+
+                <!-- 内层循环:遍历各个统计项 -->
+                <div v-for="(item, idx) in category.children" :key="idx">
+                  <van-col :span="idx == 0 ? 24 : 12">
+                    <p>
+                      {{ item.name }}:<span :style="labelStyle(item.clickable)" @click="onClick(item.clickable)" class="colorbalck">{{ Micrometer(item.indicatorValue) }}{{
+                        item.indicatorUnit }}</span>
+                    </p>
+                  </van-col>
+                </div>
+              </van-row>
+            </van-collapse-item>
+            <van-collapse-item v-if="homePageItem.labelStyle==3" :name="(index + 1).toString()" :title="homePageItem.name">
+              <!-- 外层循环:遍历主要类别 -->
+              <van-row v-for="(category, index) in homePageItem.children" :key="index"
+                :style="{ marginTop: index == 0 ? '-10px' : '0' }">
+                <!-- 内层循环:遍历各个统计项 -->
+                <div v-for="(item, idx) in category.children" :key="idx">
+                  <van-col :span="idx == 0 ? 24 : 12">
+                    <p>
+                      {{ item.name }}:<span :style="labelStyle(item.clickable)" @click="onClick(item.clickable)" class="colorbalck">{{ Micrometer(item.indicatorValue) }}{{
+                        item.indicatorUnit }}</span>
+                    </p>
+                  </van-col>
+                </div>
+              </van-row>
+            </van-collapse-item>
+          </div>
+
+        </van-collapse>
+      </div>
+    </template>
+  </div>
+</template>
+
+<script>
+import store from '@/store';
+import {
+  userTodayPlanNum,
+  getReportInfo,
+} from '@/api/index';
+export default {
+  name: 'home',
+  props: {
+    tabVal: {
+      type: [String, Number],
+      default: '-1',
+    },
+  },
+  data() {
+    return {
+      shows: true,
+      show: true,
+      num: 0,
+      todayGoal: {},
+      progressWidth: 0,
+      updataTime: '',
+      activeNames: [
+        '1',
+        '2',
+        '3',
+        '4',
+        '5',
+        '6',
+        '7',
+        '8',
+        '10',
+        '11',
+        '12',
+        '16',
+        '17',
+        '20',
+        '21',
+        '22',
+        '23',
+        '24',
+        '25',
+        '26',
+        '27',
+        '28',
+        '29',
+        '30',
+        '31',
+        '32',
+        '33',
+        '34',
+        '35',
+        '36',
+        '37',
+        '38',
+        '39',
+        '40',
+        '41',
+        '42',
+        '43',
+      ],
+      activeNameType: [],
+      powerGradeShow: false,
+      showButton: false,
+      isCommit: null,
+      powerGrade: '2',
+      deptLevel: '',
+      // positionId:等级(1-销售员 2-销售部主管 3-大区主管 4-区域公司总经理 5-DIY公司)
+      reportTargetAll: {},
+      homePageIndicatorList: [],
+      approvalPendingNum: 0,
+      isDiy: false,
+      approvalButton: false,
+      times: 5,
+      timer: null,
+      type: '-1',
+      monthNoVisit: {},
+      flag: true,
+      reportInfoData: {},
+      applyNumber: '',
+      proccessPendingNum: 0,
+      JZQuota: false,
+      GZdata: false,
+    };
+  },
+  watch: {
+    tabVal: {
+      handler(val) {
+        if (val == 2) {
+          // keep-alive 模式watch执行了两次
+          this.initData();
+        }
+      },
+      immediate: true,
+    },
+  },
+  methods: {
+    labelStyle(val) {
+      return {
+        'text-decoration': val == 1 ? 'underline' : 'none',
+        color: val == 1 ? '#0057ba' : '#666666',
+      };
+    },
+    // 跳转详情
+    onClick(val) {
+      if(val==1){
+        store.dispatch('setActivaTypeStore', 'FuWuShang');
+        this.$router.push({ path: '/noVisit' });
+      }
+    },
+    initData() {
+      console.log(this.tabVal);
+      this.getReportInfo();
+      this.userTodayPlanNum();
+    },
+    getReportInfo() {
+      let loading1 = this.$toast.loading({
+        duration: 0,
+        message: '加载中...',
+        forbidClick: true,
+      });
+      getReportInfo({ isContent: false }).then((res) => {
+        if (res.code == 200) {
+          loading1.clear();
+          localStorage.setItem('powerGrade', res.data.positionId);
+          localStorage.setItem('userDeptLevel', res.data.userDeptLevel);
+          localStorage.setItem('isDiy', res.data.diy);
+          localStorage.setItem('uType', res.data.userType);
+          localStorage.setItem('jzType', res.data.jzType);
+          localStorage.setItem('customerVisits', res.data.customerManagerVisits);
+          localStorage.setItem('postType', res.data.postType);
+          if (res.data.homePageIndicatorList != null) {
+            this.homePageIndicatorList = res.data.homePageIndicatorList;
+            this.updataTime = res.data.homePageIndicatorUpdateTime;
+          }
+          this.type = res.data.userType;
+        } else {
+          this.$toast(res.msg);
+        }
+      });
+    },
+    userTodayPlanNum() {
+      localStorage.setItem('outvstoreName', '');
+      localStorage.setItem('outvchainName', '');
+      localStorage.removeItem('outvstoreLabelTypes');
+      localStorage.removeItem('outvstoreCategoryList');
+      localStorage.setItem('outvchainCode', '');
+      localStorage.setItem('outvstoreName', '');
+      localStorage.setItem('deviveStoreName', '');
+      localStorage.setItem('outvsortType', '');
+      localStorage.setItem('outsortParam', '');
+      localStorage.setItem('lat', '');
+      localStorage.setItem('lon', '');
+      userTodayPlanNum().then((res) => {
+        if (res.code == 200) {
+          this.todayGoal = res.data;
+          this.progressWidth = (this.todayGoal.finishNum / this.todayGoal.planNum) * 100 + '%';
+          localStorage.setItem('nickName', res.data.user.nickName);
+          localStorage.setItem('postName', res.data.user.postName);
+          localStorage.setItem('zipPhoto', res.data.zipPhoto);
+          localStorage.setItem('storeType', res.data.user.type);
+          localStorage.setItem('deptLevel', res.data.user.depts[0].deptLevel);
+          localStorage.setItem('userId', res.data.user.userId);
+          localStorage.setItem('deptIds', JSON.stringify(res.data.user.deptIds));
+          this.monthNoVisit = res.data.monthNoVisit;
+        } else {
+          this.$toast(res.msg);
+        }
+      });
+    },
+  },
+};
+</script>
+<style scoped>
+.homeTitle {
+  padding: 6px 16px;
+}
+
+.homeTitle .van-icon__image {
+  width: 1.4em;
+  height: auto;
+}
+
+.container {
+  margin: 10px;
+}
+
+.container .van-collapse-item {
+  margin-bottom: 10px;
+  border-radius: 6px;
+  overflow: hidden;
+}
+
+.progressContentlist {
+  font-size: 14px;
+  border-bottom: 1px dashed #f1f1f1;
+  padding: 10px 0;
+}
+
+.linep p {
+  margin: 10px 0 0 0;
+  font-size: 14px;
+  color: #666;
+}
+
+.leftTitle {
+  background-color: #74a4d9;
+  color: #fff;
+  display: inline-block;
+  padding: 0 4px;
+  border-radius: 2px;
+}
+
+.rightTitle {
+  background-color: #e7b4bb;
+  color: #fff;
+  display: inline-block;
+  padding: 0 4px;
+  border-radius: 2px;
+  white-space: nowrap;
+}
+</style>
+<style lang="scss">
+.myTab .van-tabs__nav--card {
+  margin: 0 !important;
+  border-left: 0;
+  border-right: 0;
+}
+
+.myTab .van-tabs__wrap,
+.van-tabs__nav--card {
+  height: 39px;
+}
+
+.myTab .van-tab {
+  line-height: 40px;
+}
+
+.linep .van-collapse-item__content {
+  color: #666;
+}
+
+.linep .van-collapse-item__content {
+  color: #666;
+}
+
+.linep .van-cell__title {
+  color: #1e5398;
+  font-weight: 500;
+  font-size: 16px;
+}
+
+.homeCellIcon {
+  line-height: 34px;
+}
+
+.homeTitle .van-cell__title {
+  color: #444;
+  font-size: 16px;
+  font-weight: bold;
+  padding-left: 4px;
+  line-height: 36px;
+  height: 36px;
+}
+
+.updataTime {
+  color: #999;
+  font-size: 12px;
+  text-align: center;
+}
+
+.homeTitle .van-tag--danger {
+  /* border-radius: 20px; */
+}
+
+.van-dialog__confirm,
+.van-dialog__confirm:active {
+  color: #0057ba;
+}
+
+.tipTitleBox p {
+  margin: 0;
+  line-height: 28px;
+  color: #555;
+}
+
+.tipTitleBox .p {
+  color: #555;
+  font-size: 16px;
+  border-bottom: 1px solid #f5f5f5;
+  margin: 0;
+  margin-bottom: 10px;
+  text-align: center;
+  padding: 14px 0px;
+}
+
+.storeTypeHome .van-collapse-item__content {
+  padding: 0;
+}
+
+.storeTypeHome .storeTypeHomeList .van-cell__title {
+  color: #4a4a4a;
+  font-size: 14px;
+}
+
+.storeTypeHome .monthNoVisit {
+  padding: 10px;
+  margin: 10px;
+  border-radius: 5px;
+  background-color: #ebf4ff;
+}
+
+.storeTypeHome .leftContent {
+  padding-right: 68px;
+  position: relative;
+}
+
+.storeTypeHome .monthNoVisitStatstext {
+  font-size: 12px;
+  background-color: #0057ba;
+  position: absolute;
+  right: 0;
+  top: 6px;
+  padding: 2px 6px 2px 12px;
+  border-bottom-left-radius: 60px;
+  border-top-left-radius: 60px;
+  color: #fff;
+}
+
+.ABtarage {
+  .table-headermd {
+    font-size: 12px;
+    text-align: center;
+    position: initial;
+    width: 98% !important;
+    margin: 0 auto;
+    border-right: 0;
+  }
+
+  .table-headermdhome {
+    font-size: 14px;
+  }
+
+  .table-headermdhome th.el-table__cell>.cell {
+    white-space: pre;
+  }
+
+  .table-headermd .el-table__header,
+  .table-headermd .el-table__body {
+    width: 100% !important;
+  }
+
+  .table-headermdhome.van-cell {
+    padding: 0 6px;
+    height: 100%;
+  }
+
+  .table-headermd th.el-table__cell>.cell {
+    padding: 0 4px;
+    text-align: center;
+  }
+
+  .table-headermdhometh.el-table__cell:first-child>.cell {
+    text-align: left;
+  }
+
+  .table-headermd th.el-table__cell {
+    background-color: #1989fa;
+    color: #fff;
+  }
+
+  .table-headermdhome th.el-table__cell {
+    background-color: #fff;
+    color: #444;
+  }
+
+  .table-headermd .el-table__cell {
+    padding: 4px 0;
+  }
+
+  .table-headermdhome.el-table .cell {
+    padding: 0 4px;
+    text-align: center;
+  }
+
+  .table-headermdhome .tipTitle {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    display: -webkit-box;
+    -webkit-box-orient: vertical;
+    -webkit-line-clamp: 2;
+    text-align: center;
+  }
+
+  .table-headermd::before {
+    height: 0;
+  }
+
+  .table-headermd .cell,
+  .el-table--border .el-table__cell:first-child .cell {
+    padding: 0 4px;
+  }
+}
+
+.colBack {
+  width: 100%;
+  height: 100%;
+  display: block;
+  /* overflow: unset; */
+  position: relative;
+  z-index: 2;
+  float: left;
+  z-index: 2;
+
+  .back {
+    position: absolute;
+    background: rgb(226, 240, 217);
+    height: 100%;
+    display: block;
+    overflow: hidden;
+    /* z-index: 1; */
+    border-radius: 12px;
+    bottom: -4px;
+  }
+
+  .backLeft {
+    width: 45%;
+    left: -12px;
+  }
+
+  .backRight {
+    width: 50%;
+    left: calc(50% - 12px);
+  }
+
+  .van-col {
+    position: relative;
+    z-index: 3;
+  }
+}
+</style>

+ 2 - 0
src/views/home/hintTabPage/noVisit.vue

@@ -100,6 +100,8 @@ export default {
         type = '同城分销-涂料店';
       } else if (value == 'QiTa') {
         type = '同城分销-其他店';
+      }else if (value == 'FuWuShang') {
+        type = '服务商';
       }
       return type;
     },

+ 31 - 15
src/views/home/index.vue

@@ -8,19 +8,22 @@
         type="card"
         v-model="tabVal"
         color="#0057ba"
-        @click="onClickTabs"
-        v-if="isGZorJZ">
-        <van-tab title="提示类" name="-1" v-if="isGZorJZ == 'false'">
+        @click="onClickTabs">
+
+        <van-tab title="提示类" name="-1" v-if="isGZorJZ == 'false' && onlyShowHomeTarget == false">
           <van-pull-refresh v-model="isLoading" @refresh="onRefresh">
             <hintTabPage :tabVal="tabVal" ref="hintTabPage"></hintTabPage>
           </van-pull-refresh>
         </van-tab>
-        <van-tab title="A类指标" name="0">
+        <van-tab title="A类指标" name="0" v-if="onlyShowHomeTarget == false">
           <ABtarget :tabVal="tabVal" ref="Atarget"></ABtarget>
         </van-tab>
-        <van-tab title="B类指标" name="1">
+        <van-tab title="B类指标" name="1" v-if="onlyShowHomeTarget == false">
           <ABtarget :tabVal="tabVal" ref="Btarget"></ABtarget>
         </van-tab>
+        <van-tab title="首页指标" name="2" v-if="onlyShowHomeTarget == true">
+          <HomeTarget :tabVal="tabVal" ref="HomeTarget"></HomeTarget>
+        </van-tab>
       </van-tabs>
       <div class="bottomBtn">
         <bottomBtn :tabVal="tabVal" ref="bottomBtn"></bottomBtn>
@@ -46,12 +49,13 @@ import { getReportInfo, getDictOption, buryingPoint } from '@/api/index';
 import hintTabPage from './hintTabPage/index.vue';
 import tabBar from '@/components/tabBar';
 import ABtarget from './ABtarget.vue';
+import HomeTarget from './HomeTarget.vue';
 import { mapState } from 'vuex';
 import bottomBtn from './bottomBtn.vue';
 import { WXdigest } from '@/utils/digest';
 export default {
   name: 'home',
-  components: { tabBar, hintTabPage, ABtarget, bottomBtn },
+  components: { tabBar, hintTabPage, ABtarget, HomeTarget, bottomBtn },
   computed: {
     ...mapState({
       userInfo: (state) => state.user.userInfo,
@@ -62,6 +66,7 @@ export default {
       tabVal: '-1',
       hintTabPageIndex: 0,
       isGZorJZ: null,
+      onlyShowHomeTarget: false,
       isLoading: false,
       setSIcontyle: {
         bottom: '85px',
@@ -109,15 +114,21 @@ export default {
       this.isLoading = false;
     },
     async getDict(isRefresh) {
-      let postType = this.userInfo.postType;
-      // postType:人员类型,JZ(家装)、GZ(公装)、YF(应服)、DIY(DIY)
-      if (postType == 'JZ' || postType == 'GZ') {
-        localStorage.setItem('isGZorJZ', 'true');
-        this.isGZorJZ = 'true';
-      } else {
-        localStorage.setItem('isGZorJZ', 'false');
-        this.isGZorJZ = 'false';
-      }
+      let postName = this.userInfo.postName;
+      if (postName == '质感销售负责人' || postName == '质感销售专员') {
+        this.onlyShowHomeTarget = true;
+      }else {
+        this.onlyShowHomeTarget = false;
+        let postType = this.userInfo.postType;
+        // postType:人员类型,JZ(家装)、GZ(公装)、YF(应服)、DIY(DIY)
+        if (postType == 'JZ' || postType == 'GZ') {
+          localStorage.setItem('isGZorJZ', 'true');
+          this.isGZorJZ = 'true';
+        } else {
+          localStorage.setItem('isGZorJZ', 'false');
+          this.isGZorJZ = 'false';
+        }
+      } 
       // 家装或工装不显示提示类tab
       this.$nextTick(() => {
         // 刷新状态
@@ -135,6 +146,8 @@ export default {
           if (this.$refs.Atarget) this.$refs.Atarget.initData();
         } else if (this.tabVal == '1') {
           if (this.$refs.Btarget) this.$refs.Btarget.initData();
+        }else if (this.tabVal == '2') {
+          if (this.$refs.HomeTarget) this.$refs.HomeTarget.initData();
         }
       });
     },
@@ -147,6 +160,9 @@ export default {
         if (this.tabVal == '1') {
           if (this.$refs.Btarget) this.$refs.Btarget.initData();
         }
+        if (this.tabVal == '2') {
+          if (this.$refs.HomeTarget) this.$refs.HomeTarget.initData();
+        }
       });
     },
     onClickLeft() {