Browse Source

客户档案、公海、私海页面优化

lxf 1 year ago
parent
commit
8ac2a15152

+ 272 - 90
src/views/customer/file/index.vue

@@ -1,105 +1,164 @@
 <template>
   <div class="tenant">
-    <div class="content">
-      <byTable
-        :source="sourceList.data"
-        :pagination="sourceList.pagination"
-        :config="config"
-        :loading="loading"
-        :selectConfig="selectConfig"
-        highlight-current-row
-        :action-list="[
-          {
-            text: '添加客户',
-            action: () => openModal(),
-          },
-        ]"
-        @get-list="getList">
-        <template #isTop="{ item }">
-          <div>
-            <img style="cursor: pointer; width: 20px; transform: translateY(5px)" :src="'/img/isTop.png'" @click="deleteTop(item)" v-if="item.isTop === 1" />
-            <img style="cursor: pointer; width: 20px; transform: translateY(5px)" :src="'/img/noTop.png'" @click="addTop(item)" v-else />
+    <div style="padding: 20px; background: #fff; margin-bottom: 20px">
+      <el-button type="primary" style="margin-left: 10px" @click="openModal()">添加客户</el-button>
+    </div>
+    <div style="padding: 20px 20px 0 20px; background: #fff; margin-bottom: 20px">
+      <div style="display: flex">
+        <div style="font-size: 14px; cursor: pointer" class="by-dropdown">
+          <div class="by-dropdown-title">
+            <span>{{ dictValueLabel(sourceList.paginationTwo.statisticsType, statisticsType) }}</span>
+            <el-icon style="margin-left: 5px; font-size: 16px"><CaretBottom /></el-icon>
+          </div>
+          <ul class="by-dropdown-lists">
+            <li
+              v-for="item in statisticsType"
+              :key="item.value"
+              @click="searchItemSelect(item.value)"
+              style="display: flex; align-items: center; justify-content: center">
+              {{ item.label }}
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div style="display: flex; width: 100%; margin: 10px 0 0 10px; flex-wrap: wrap">
+        <div style="padding: 20px; border-radius: 10px; width: 200px; background-color: #d1caff59; margin: 0 20px 20px 0">
+          <div style="margin-bottom: 10px; display: flex">
+            <div style="width: 8px; height: 8px; background-color: #5bacff; border-radius: 50px; margin-top: 6px"></div>
+            <span style="padding-left: 8px">合计</span>
+          </div>
+          <div style="color: black; font-size: 20px; font-weight: 700">{{ statisticalData.countAmount }}</div>
+        </div>
+        <template v-if="sourceList.paginationTwo.statisticsType === 1">
+          <div
+            style="padding: 20px; border-radius: 10px; width: 200px; background-color: #a2d8ff70; margin: 0 20px 20px 0"
+            v-for="(item, index) in customerSource"
+            :key="index">
+            <div style="margin-bottom: 10px; display: flex">
+              <div style="width: 8px; height: 8px; background-color: #5bacff; border-radius: 50px; margin-top: 6px"></div>
+              <span style="padding-left: 8px">{{ item.label }}</span>
+            </div>
+            <div style="color: black; font-size: 20px; font-weight: 700">{{ getNum(item.value) }}</div>
           </div>
         </template>
-        <template #address="{ item }">
-          <span>{{ item.countryName }}</span>
-          <span v-if="item.provinceName"> ,{{ item.provinceName }}</span>
-          <span v-if="item.cityName"> ,{{ item.cityName }}</span>
-        </template>
-        <template #name="{ item }">
-          <div style="cursor: pointer; color: #409eff" @click="handleClickName(item)">
-            {{ item.name }}
+        <template v-else-if="sourceList.paginationTwo.statisticsType === 2">
+          <div
+            style="padding: 20px; border-radius: 10px; width: 200px; background-color: #a2d8ff70; margin: 0 20px 20px 0"
+            v-for="(item, index) in customerStatus"
+            :key="index">
+            <div style="margin-bottom: 10px; display: flex">
+              <div style="width: 8px; height: 8px; background-color: #5bacff; border-radius: 50px; margin-top: 6px"></div>
+              <span style="padding-left: 8px">{{ item.label }}</span>
+            </div>
+            <div style="color: black; font-size: 20px; font-weight: 700">{{ getNum(item.value) }}</div>
           </div>
         </template>
-        <template #tags="{ item }">
-          <div style="width: 100%">
-            <el-tag style="margin-right: 8px" type="success" v-for="(tag, index) in item.tag" closable :key="index" @close="tagClose(tag, item)">
-              {{ dictValueLabel(tag, customerTag) }}
-            </el-tag>
-            <template v-if="item.tag.length !== customerTag.length">
-              <el-select
-                v-if="item.addTagShow"
-                v-model="addTag"
-                style="width: 100%"
-                @change="
-                  (val) => {
-                    return changeTag(val, item);
-                  }
-                ">
-                <el-option v-for="tag in customerTag" :key="tag.value" :label="tag.label" :value="tag.value" :disabled="judgeTagSelect(item.tag, tag.value)" />
-              </el-select>
-              <el-tag style="cursor: pointer" type="success" @click="showSelect(item)" v-else> + </el-tag>
-            </template>
+        <template v-else-if="sourceList.paginationTwo.statisticsType === 3">
+          <div
+            style="padding: 20px; border-radius: 10px; width: 200px; background-color: #a2d8ff70; margin: 0 20px 20px 0"
+            v-for="(item, index) in userList"
+            :key="index">
+            <div style="margin-bottom: 10px; display: flex">
+              <div style="width: 8px; height: 8px; background-color: #5bacff; border-radius: 50px; margin-top: 6px"></div>
+              <span style="padding-left: 8px">{{ item.label }}</span>
+            </div>
+            <div style="color: black; font-size: 20px; font-weight: 700">{{ getNum(item.value) }}</div>
           </div>
         </template>
-        <template #follow="{ item }">
-          <div :class="'getWidth' + item.id" style="width: 100%">
-            <div style="width: 100%; display: flex">
-              <template v-if="item.customerFollowRecordsList && item.customerFollowRecordsList.length > 0">
-                <div
-                  :style="
-                    index > 2
-                      ? 'line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer; display: none'
-                      : 'line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer'
-                  "
-                  v-for="(record, index) in item.customerFollowRecordsList"
-                  :key="record.id">
-                  <el-popover placement="bottom" :width="300" trigger="hover" @show="recordShow(record)">
-                    <template #reference>
-                      <div>
-                        <span v-if="record.date">{{ record.date.substr(0, 10) }}</span>
-                        <el-icon style="margin-left: 8px; transform: translateY(2px)" @click="deleteFollow(record)"><DeleteFilled /></el-icon>
-                      </div>
-                    </template>
-                    <template #default>
-                      <div style="width: 100%">
-                        <div style="color: #909399; margin: 8px 0">跟进时间: {{ record.date }}</div>
-                        <div style="word-wrap: break-word; margin: 8px 0" v-html="getStyle(record.content)" v-if="record.content"></div>
-                        <div v-else>跟进记录:</div>
-                        <div style="margin: 8px 0; display: flex" v-if="record.fileList && record.fileList.length > 0">
-                          <div style="width: 36px">附件:</div>
-                          <div style="width: calc(100% - 36px)">
-                            <div v-for="(file, index) in record.fileList" :key="index">
-                              <a style="color: #409eff; cursor: pointer" @click="openFile(file.fileUrl)">{{ file.fileName }}</a>
-                            </div>
+      </div>
+    </div>
+    <byTable
+      :source="sourceList.data"
+      :pagination="sourceList.pagination"
+      :config="config"
+      :loading="loading"
+      :selectConfig="selectConfig"
+      highlight-current-row
+      @get-list="getList">
+      <template #isTop="{ item }">
+        <div>
+          <img style="cursor: pointer; width: 20px; transform: translateY(5px)" :src="'/img/isTop.png'" @click="deleteTop(item)" v-if="item.isTop === 1" />
+          <img style="cursor: pointer; width: 20px; transform: translateY(5px)" :src="'/img/noTop.png'" @click="addTop(item)" v-else />
+        </div>
+      </template>
+      <template #address="{ item }">
+        <span>{{ item.countryName }}</span>
+        <span v-if="item.provinceName"> ,{{ item.provinceName }}</span>
+        <span v-if="item.cityName"> ,{{ item.cityName }}</span>
+      </template>
+      <template #name="{ item }">
+        <div style="cursor: pointer; color: #409eff" @click="handleClickName(item)">
+          {{ item.name }}
+        </div>
+      </template>
+      <template #tags="{ item }">
+        <div style="width: 100%">
+          <el-tag style="margin-right: 8px" type="success" v-for="(tag, index) in item.tag" closable :key="index" @close="tagClose(tag, item)">
+            {{ dictValueLabel(tag, customerTag) }}
+          </el-tag>
+          <template v-if="item.tag.length !== customerTag.length">
+            <el-select
+              v-if="item.addTagShow"
+              v-model="addTag"
+              style="width: 100%"
+              @change="
+                (val) => {
+                  return changeTag(val, item);
+                }
+              ">
+              <el-option v-for="tag in customerTag" :key="tag.value" :label="tag.label" :value="tag.value" :disabled="judgeTagSelect(item.tag, tag.value)" />
+            </el-select>
+            <el-tag style="cursor: pointer" type="success" @click="showSelect(item)" v-else> + </el-tag>
+          </template>
+        </div>
+      </template>
+      <template #follow="{ item }">
+        <div :class="'getWidth' + item.id" style="width: 100%">
+          <div style="width: 100%; display: flex">
+            <template v-if="item.customerFollowRecordsList && item.customerFollowRecordsList.length > 0">
+              <div
+                :style="
+                  index > 2
+                    ? 'line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer; display: none'
+                    : 'line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer'
+                "
+                v-for="(record, index) in item.customerFollowRecordsList"
+                :key="record.id">
+                <el-popover placement="bottom" :width="300" trigger="hover" @show="recordShow(record)">
+                  <template #reference>
+                    <div>
+                      <span v-if="record.date">{{ record.date.substr(0, 10) }}</span>
+                      <el-icon style="margin-left: 8px; transform: translateY(2px)" @click="deleteFollow(record)"><DeleteFilled /></el-icon>
+                    </div>
+                  </template>
+                  <template #default>
+                    <div style="width: 100%">
+                      <div style="color: #909399; margin: 8px 0">跟进时间: {{ record.date }}</div>
+                      <div style="word-wrap: break-word; margin: 8px 0" v-html="getStyle(record.content)" v-if="record.content"></div>
+                      <div v-else>跟进记录:</div>
+                      <div style="margin: 8px 0; display: flex" v-if="record.fileList && record.fileList.length > 0">
+                        <div style="width: 36px">附件:</div>
+                        <div style="width: calc(100% - 36px)">
+                          <div v-for="(file, index) in record.fileList" :key="index">
+                            <a style="color: #409eff; cursor: pointer" @click="openFile(file.fileUrl)">{{ file.fileName }}</a>
                           </div>
                         </div>
                       </div>
-                    </template>
-                  </el-popover>
-                </div>
-                <div
-                  style="line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer"
-                  @click="clickMore(item)"
-                  v-if="item.customerFollowRecordsList.length >= 3">
-                  更多
-                </div>
-              </template>
-            </div>
+                    </div>
+                  </template>
+                </el-popover>
+              </div>
+              <div
+                style="line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer"
+                @click="clickMore(item)"
+                v-if="item.customerFollowRecordsList.length >= 3">
+                更多
+              </div>
+            </template>
           </div>
-        </template>
-      </byTable>
-    </div>
+        </div>
+      </template>
+    </byTable>
 
     <el-dialog :title="modalType == 'add' ? '新增' : '编辑'" v-if="dialogVisible" v-model="dialogVisible" width="800" v-loading="loadingOperation">
       <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit">
@@ -307,6 +366,20 @@ const contactType = ref([]);
 const userList = ref([]);
 const fileList = ref([]);
 const uploadData = ref({});
+const statisticsType = ref([
+  {
+    label: "客户来源统计",
+    value: 1,
+  },
+  {
+    label: "客户类型统计",
+    value: 2,
+  },
+  {
+    label: "业务员统计",
+    value: 3,
+  },
+]);
 const sourceList = ref({
   data: [],
   pagination: {
@@ -317,6 +390,10 @@ const sourceList = ref({
     source: "",
     type: "",
   },
+  paginationTwo: {
+    statisticsType: 1,
+    type: null,
+  },
 });
 const selectConfig = computed(() => {
   return [
@@ -498,6 +575,7 @@ const config = computed(() => {
                       type: "success",
                     });
                     getList();
+                    obtainStatisticalData();
                   });
               });
             },
@@ -574,6 +652,7 @@ const formConfig = computed(() => {
       prop: "userId",
       itemWidth: 100,
       data: userList.value,
+      clearable: true,
     },
     {
       type: "select",
@@ -611,6 +690,7 @@ const formConfigAllocation = computed(() => {
       prop: "userId",
       itemWidth: 100,
       data: userList.value,
+      clearable: true,
     },
   ];
 });
@@ -743,6 +823,7 @@ const submitAllocation = () => {
       });
       openAllocation.value = false;
       getList();
+      obtainStatisticalData();
     });
   });
 };
@@ -788,6 +869,7 @@ const submitForm = () => {
           dialogVisible.value = false;
           submitLoading.value = false;
           getList();
+          obtainStatisticalData();
         },
         (err) => {
           console.log(err);
@@ -1059,6 +1141,41 @@ const addTop = (item) => {
     item.isTop = 1;
   });
 };
+const searchItemSelect = (val) => {
+  sourceList.value.paginationTwo.statisticsType = val;
+  obtainStatisticalData();
+};
+const statisticalData = ref({
+  countAmount: 0,
+  customerList: [],
+});
+const obtainStatisticalData = () => {
+  proxy.post("/customer/sourceStatistics", sourceList.value.paginationTwo).then((res) => {
+    statisticalData.value = res;
+  });
+};
+obtainStatisticalData();
+const getNum = (val) => {
+  let num = 0;
+  if (statisticalData.value.customerList && statisticalData.value.customerList.length > 0) {
+    statisticalData.value.customerList.map((item) => {
+      if (sourceList.value.paginationTwo.statisticsType === 1) {
+        if (item.source === val) {
+          num = item.count;
+        }
+      } else if (sourceList.value.paginationTwo.statisticsType === 2) {
+        if (item.status === val) {
+          num = item.count;
+        }
+      } else if (sourceList.value.paginationTwo.statisticsType === 3) {
+        if (item.userId === val) {
+          num = item.count;
+        }
+      }
+    });
+  }
+  return num;
+};
 </script>
 
 <style lang="scss" scoped>
@@ -1072,4 +1189,69 @@ const addTop = (item) => {
     width: 0px;
   }
 }
+.by-dropdown {
+  position: relative;
+  text-align: left;
+  height: 32px;
+  z-index: 1010;
+  padding: 0 10px;
+  transition: all 0.5s ease;
+  cursor: pointer;
+  line-height: 32px;
+  .by-dropdown-title {
+    font-size: 14px;
+    background-color: #fff;
+  }
+  ul {
+    position: absolute;
+    left: 0;
+    top: 32px;
+    padding: 0;
+    margin: 0;
+    z-index: 1200;
+    display: none;
+    white-space: nowrap;
+    background-color: #fff;
+    li {
+      list-style: none;
+      z-index: 1200;
+      font-size: 12px;
+      height: 30px;
+      padding: 0 10px;
+    }
+    li:hover {
+      background-color: #eff6ff;
+      color: #0084ff;
+    }
+  }
+}
+.by-dropdown::before {
+  display: block;
+  width: 1px;
+  content: " ";
+  position: absolute;
+  height: 14px;
+  top: 8px;
+  background-color: #ddd;
+  right: 0;
+  z-index: 1011;
+}
+.by-dropdown:hover {
+  background: #ffffff;
+  border-radius: 2px 2px 2px 2px;
+  opacity: 1;
+  ul {
+    background: #ffffff;
+    box-shadow: 0px 2px 16px 1px rgba(0, 0, 0, 0.06);
+    border-radius: 2px 2px 2px 2px;
+    opacity: 1;
+    display: block;
+    text-align: left;
+  }
+}
+.by-dropdown-lists {
+  max-height: 50vh;
+  overflow-y: auto;
+  line-height: 1;
+}
 </style>

+ 271 - 90
src/views/customer/highseas/index.vue

@@ -1,105 +1,164 @@
 <template>
   <div class="tenant">
-    <div class="content">
-      <byTable
-        :source="sourceList.data"
-        :pagination="sourceList.pagination"
-        :config="config"
-        :loading="loading"
-        :selectConfig="selectConfig"
-        highlight-current-row
-        :action-list="[
-          {
-            text: '添加客户',
-            action: () => openModal(),
-          },
-        ]"
-        @get-list="getList">
-        <template #isTop="{ item }">
-          <div>
-            <img style="cursor: pointer; width: 20px; transform: translateY(5px)" :src="'/img/isTop.png'" @click="deleteTop(item)" v-if="item.isTop === 1" />
-            <img style="cursor: pointer; width: 20px; transform: translateY(5px)" :src="'/img/noTop.png'" @click="addTop(item)" v-else />
+    <div style="padding: 20px; background: #fff; margin-bottom: 20px">
+      <el-button type="primary" style="margin-left: 10px" @click="openModal()">添加客户</el-button>
+    </div>
+    <div style="padding: 20px 20px 0 20px; background: #fff; margin-bottom: 20px">
+      <div style="display: flex">
+        <div style="font-size: 14px; cursor: pointer" class="by-dropdown">
+          <div class="by-dropdown-title">
+            <span>{{ dictValueLabel(sourceList.paginationTwo.statisticsType, statisticsType) }}</span>
+            <el-icon style="margin-left: 5px; font-size: 16px"><CaretBottom /></el-icon>
+          </div>
+          <ul class="by-dropdown-lists">
+            <li
+              v-for="item in statisticsType"
+              :key="item.value"
+              @click="searchItemSelect(item.value)"
+              style="display: flex; align-items: center; justify-content: center">
+              {{ item.label }}
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div style="display: flex; width: 100%; margin: 10px 0 0 10px; flex-wrap: wrap">
+        <div style="padding: 20px; border-radius: 10px; width: 200px; background-color: #d1caff59; margin: 0 20px 20px 0">
+          <div style="margin-bottom: 10px; display: flex">
+            <div style="width: 8px; height: 8px; background-color: #5bacff; border-radius: 50px; margin-top: 6px"></div>
+            <span style="padding-left: 8px">合计</span>
+          </div>
+          <div style="color: black; font-size: 20px; font-weight: 700">{{ statisticalData.countAmount }}</div>
+        </div>
+        <template v-if="sourceList.paginationTwo.statisticsType === 1">
+          <div
+            style="padding: 20px; border-radius: 10px; width: 200px; background-color: #a2d8ff70; margin: 0 20px 20px 0"
+            v-for="(item, index) in customerSource"
+            :key="index">
+            <div style="margin-bottom: 10px; display: flex">
+              <div style="width: 8px; height: 8px; background-color: #5bacff; border-radius: 50px; margin-top: 6px"></div>
+              <span style="padding-left: 8px">{{ item.label }}</span>
+            </div>
+            <div style="color: black; font-size: 20px; font-weight: 700">{{ getNum(item.value) }}</div>
           </div>
         </template>
-        <template #address="{ item }">
-          <span>{{ item.countryName }}</span>
-          <span v-if="item.provinceName"> ,{{ item.provinceName }}</span>
-          <span v-if="item.cityName"> ,{{ item.cityName }}</span>
-        </template>
-        <template #name="{ item }">
-          <div style="cursor: pointer; color: #409eff" @click="handleClickName(item)">
-            {{ item.name }}
+        <template v-else-if="sourceList.paginationTwo.statisticsType === 2">
+          <div
+            style="padding: 20px; border-radius: 10px; width: 200px; background-color: #a2d8ff70; margin: 0 20px 20px 0"
+            v-for="(item, index) in customerStatus"
+            :key="index">
+            <div style="margin-bottom: 10px; display: flex">
+              <div style="width: 8px; height: 8px; background-color: #5bacff; border-radius: 50px; margin-top: 6px"></div>
+              <span style="padding-left: 8px">{{ item.label }}</span>
+            </div>
+            <div style="color: black; font-size: 20px; font-weight: 700">{{ getNum(item.value) }}</div>
           </div>
         </template>
-        <template #tags="{ item }">
-          <div style="width: 100%">
-            <el-tag style="margin-right: 8px" type="success" v-for="(tag, index) in item.tag" closable :key="index" @close="tagClose(tag, item)">
-              {{ dictValueLabel(tag, customerTag) }}
-            </el-tag>
-            <template v-if="item.tag.length !== customerTag.length">
-              <el-select
-                v-if="item.addTagShow"
-                v-model="addTag"
-                style="width: 100%"
-                @change="
-                  (val) => {
-                    return changeTag(val, item);
-                  }
-                ">
-                <el-option v-for="tag in customerTag" :key="tag.value" :label="tag.label" :value="tag.value" :disabled="judgeTagSelect(item.tag, tag.value)" />
-              </el-select>
-              <el-tag style="cursor: pointer" type="success" @click="showSelect(item)" v-else> + </el-tag>
-            </template>
+        <template v-else-if="sourceList.paginationTwo.statisticsType === 3">
+          <div
+            style="padding: 20px; border-radius: 10px; width: 200px; background-color: #a2d8ff70; margin: 0 20px 20px 0"
+            v-for="(item, index) in userList"
+            :key="index">
+            <div style="margin-bottom: 10px; display: flex">
+              <div style="width: 8px; height: 8px; background-color: #5bacff; border-radius: 50px; margin-top: 6px"></div>
+              <span style="padding-left: 8px">{{ item.label }}</span>
+            </div>
+            <div style="color: black; font-size: 20px; font-weight: 700">{{ getNum(item.value) }}</div>
           </div>
         </template>
-        <template #follow="{ item }">
-          <div :class="'getWidth' + item.id" style="width: 100%">
-            <div style="width: 100%; display: flex">
-              <template v-if="item.customerFollowRecordsList && item.customerFollowRecordsList.length > 0">
-                <div
-                  :style="
-                    index > 2
-                      ? 'line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer; display: none'
-                      : 'line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer'
-                  "
-                  v-for="(record, index) in item.customerFollowRecordsList"
-                  :key="record.id">
-                  <el-popover placement="bottom" :width="300" trigger="hover" @show="recordShow(record)">
-                    <template #reference>
-                      <div>
-                        <span v-if="record.date">{{ record.date.substr(0, 10) }}</span>
-                        <el-icon style="margin-left: 8px; transform: translateY(2px)" @click="deleteFollow(record)"><DeleteFilled /></el-icon>
-                      </div>
-                    </template>
-                    <template #default>
-                      <div style="width: 100%">
-                        <div style="color: #909399; margin: 8px 0">跟进时间: {{ record.date }}</div>
-                        <div style="word-wrap: break-word; margin: 8px 0" v-html="getStyle(record.content)" v-if="record.content"></div>
-                        <div v-else>跟进记录:</div>
-                        <div style="margin: 8px 0; display: flex" v-if="record.fileList && record.fileList.length > 0">
-                          <div style="width: 36px">附件:</div>
-                          <div style="width: calc(100% - 36px)">
-                            <div v-for="(file, index) in record.fileList" :key="index">
-                              <a style="color: #409eff; cursor: pointer" @click="openFile(file.fileUrl)">{{ file.fileName }}</a>
-                            </div>
+      </div>
+    </div>
+    <byTable
+      :source="sourceList.data"
+      :pagination="sourceList.pagination"
+      :config="config"
+      :loading="loading"
+      :selectConfig="selectConfig"
+      highlight-current-row
+      @get-list="getList">
+      <template #isTop="{ item }">
+        <div>
+          <img style="cursor: pointer; width: 20px; transform: translateY(5px)" :src="'/img/isTop.png'" @click="deleteTop(item)" v-if="item.isTop === 1" />
+          <img style="cursor: pointer; width: 20px; transform: translateY(5px)" :src="'/img/noTop.png'" @click="addTop(item)" v-else />
+        </div>
+      </template>
+      <template #address="{ item }">
+        <span>{{ item.countryName }}</span>
+        <span v-if="item.provinceName"> ,{{ item.provinceName }}</span>
+        <span v-if="item.cityName"> ,{{ item.cityName }}</span>
+      </template>
+      <template #name="{ item }">
+        <div style="cursor: pointer; color: #409eff" @click="handleClickName(item)">
+          {{ item.name }}
+        </div>
+      </template>
+      <template #tags="{ item }">
+        <div style="width: 100%">
+          <el-tag style="margin-right: 8px" type="success" v-for="(tag, index) in item.tag" closable :key="index" @close="tagClose(tag, item)">
+            {{ dictValueLabel(tag, customerTag) }}
+          </el-tag>
+          <template v-if="item.tag.length !== customerTag.length">
+            <el-select
+              v-if="item.addTagShow"
+              v-model="addTag"
+              style="width: 100%"
+              @change="
+                (val) => {
+                  return changeTag(val, item);
+                }
+              ">
+              <el-option v-for="tag in customerTag" :key="tag.value" :label="tag.label" :value="tag.value" :disabled="judgeTagSelect(item.tag, tag.value)" />
+            </el-select>
+            <el-tag style="cursor: pointer" type="success" @click="showSelect(item)" v-else> + </el-tag>
+          </template>
+        </div>
+      </template>
+      <template #follow="{ item }">
+        <div :class="'getWidth' + item.id" style="width: 100%">
+          <div style="width: 100%; display: flex">
+            <template v-if="item.customerFollowRecordsList && item.customerFollowRecordsList.length > 0">
+              <div
+                :style="
+                  index > 2
+                    ? 'line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer; display: none'
+                    : 'line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer'
+                "
+                v-for="(record, index) in item.customerFollowRecordsList"
+                :key="record.id">
+                <el-popover placement="bottom" :width="300" trigger="hover" @show="recordShow(record)">
+                  <template #reference>
+                    <div>
+                      <span v-if="record.date">{{ record.date.substr(0, 10) }}</span>
+                      <el-icon style="margin-left: 8px; transform: translateY(2px)" @click="deleteFollow(record)"><DeleteFilled /></el-icon>
+                    </div>
+                  </template>
+                  <template #default>
+                    <div style="width: 100%">
+                      <div style="color: #909399; margin: 8px 0">跟进时间: {{ record.date }}</div>
+                      <div style="word-wrap: break-word; margin: 8px 0" v-html="getStyle(record.content)" v-if="record.content"></div>
+                      <div v-else>跟进记录:</div>
+                      <div style="margin: 8px 0; display: flex" v-if="record.fileList && record.fileList.length > 0">
+                        <div style="width: 36px">附件:</div>
+                        <div style="width: calc(100% - 36px)">
+                          <div v-for="(file, index) in record.fileList" :key="index">
+                            <a style="color: #409eff; cursor: pointer" @click="openFile(file.fileUrl)">{{ file.fileName }}</a>
                           </div>
                         </div>
                       </div>
-                    </template>
-                  </el-popover>
-                </div>
-                <div
-                  style="line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer"
-                  @click="clickMore(item)"
-                  v-if="item.customerFollowRecordsList.length >= 3">
-                  更多
-                </div>
-              </template>
-            </div>
+                    </div>
+                  </template>
+                </el-popover>
+              </div>
+              <div
+                style="line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer"
+                @click="clickMore(item)"
+                v-if="item.customerFollowRecordsList.length >= 3">
+                更多
+              </div>
+            </template>
           </div>
-        </template>
-      </byTable>
-    </div>
+        </div>
+      </template>
+    </byTable>
 
     <el-dialog :title="modalType == 'add' ? '新增' : '编辑'" v-if="dialogVisible" v-model="dialogVisible" width="800" v-loading="loadingOperation">
       <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit">
@@ -307,6 +366,20 @@ const contactType = ref([]);
 const userList = ref([]);
 const fileList = ref([]);
 const uploadData = ref({});
+const statisticsType = ref([
+  {
+    label: "客户来源统计",
+    value: 1,
+  },
+  {
+    label: "客户类型统计",
+    value: 2,
+  },
+  {
+    label: "业务员统计",
+    value: 3,
+  },
+]);
 const sourceList = ref({
   data: [],
   pagination: {
@@ -317,6 +390,10 @@ const sourceList = ref({
     source: "",
     type: "0",
   },
+  paginationTwo: {
+    statisticsType: 1,
+    type: 0,
+  },
 });
 const selectConfig = computed(() => {
   return [
@@ -473,6 +550,7 @@ const config = computed(() => {
                       type: "success",
                     });
                     getList();
+                    obtainStatisticalData();
                   });
               });
             },
@@ -549,6 +627,7 @@ const formConfig = computed(() => {
       prop: "userId",
       itemWidth: 100,
       data: userList.value,
+      clearable: true,
     },
     {
       type: "select",
@@ -586,6 +665,7 @@ const formConfigAllocation = computed(() => {
       prop: "userId",
       itemWidth: 100,
       data: userList.value,
+      clearable: true,
     },
   ];
 });
@@ -763,6 +843,7 @@ const submitForm = () => {
           dialogVisible.value = false;
           submitLoading.value = false;
           getList();
+          obtainStatisticalData();
         },
         (err) => {
           console.log(err);
@@ -1034,6 +1115,41 @@ const addTop = (item) => {
     item.isTop = 1;
   });
 };
+const searchItemSelect = (val) => {
+  sourceList.value.paginationTwo.statisticsType = val;
+  obtainStatisticalData();
+};
+const statisticalData = ref({
+  countAmount: 0,
+  customerList: [],
+});
+const obtainStatisticalData = () => {
+  proxy.post("/customer/sourceStatistics", sourceList.value.paginationTwo).then((res) => {
+    statisticalData.value = res;
+  });
+};
+obtainStatisticalData();
+const getNum = (val) => {
+  let num = 0;
+  if (statisticalData.value.customerList && statisticalData.value.customerList.length > 0) {
+    statisticalData.value.customerList.map((item) => {
+      if (sourceList.value.paginationTwo.statisticsType === 1) {
+        if (item.source === val) {
+          num = item.count;
+        }
+      } else if (sourceList.value.paginationTwo.statisticsType === 2) {
+        if (item.status === val) {
+          num = item.count;
+        }
+      } else if (sourceList.value.paginationTwo.statisticsType === 3) {
+        if (item.userId === val) {
+          num = item.count;
+        }
+      }
+    });
+  }
+  return num;
+};
 </script>
 
 <style lang="scss" scoped>
@@ -1047,4 +1163,69 @@ const addTop = (item) => {
     width: 0px;
   }
 }
+.by-dropdown {
+  position: relative;
+  text-align: left;
+  height: 32px;
+  z-index: 1010;
+  padding: 0 10px;
+  transition: all 0.5s ease;
+  cursor: pointer;
+  line-height: 32px;
+  .by-dropdown-title {
+    font-size: 14px;
+    background-color: #fff;
+  }
+  ul {
+    position: absolute;
+    left: 0;
+    top: 32px;
+    padding: 0;
+    margin: 0;
+    z-index: 1200;
+    display: none;
+    white-space: nowrap;
+    background-color: #fff;
+    li {
+      list-style: none;
+      z-index: 1200;
+      font-size: 12px;
+      height: 30px;
+      padding: 0 10px;
+    }
+    li:hover {
+      background-color: #eff6ff;
+      color: #0084ff;
+    }
+  }
+}
+.by-dropdown::before {
+  display: block;
+  width: 1px;
+  content: " ";
+  position: absolute;
+  height: 14px;
+  top: 8px;
+  background-color: #ddd;
+  right: 0;
+  z-index: 1011;
+}
+.by-dropdown:hover {
+  background: #ffffff;
+  border-radius: 2px 2px 2px 2px;
+  opacity: 1;
+  ul {
+    background: #ffffff;
+    box-shadow: 0px 2px 16px 1px rgba(0, 0, 0, 0.06);
+    border-radius: 2px 2px 2px 2px;
+    opacity: 1;
+    display: block;
+    text-align: left;
+  }
+}
+.by-dropdown-lists {
+  max-height: 50vh;
+  overflow-y: auto;
+  line-height: 1;
+}
 </style>

+ 269 - 90
src/views/customer/privatesea/index.vue

@@ -1,105 +1,164 @@
 <template>
   <div class="tenant">
-    <div class="content">
-      <byTable
-        :source="sourceList.data"
-        :pagination="sourceList.pagination"
-        :config="config"
-        :loading="loading"
-        :selectConfig="selectConfig"
-        highlight-current-row
-        :action-list="[
-          {
-            text: '添加客户',
-            action: () => openModal(),
-          },
-        ]"
-        @get-list="getList">
-        <template #isTop="{ item }">
-          <div>
-            <img style="cursor: pointer; width: 20px; transform: translateY(5px)" :src="'/img/isTop.png'" @click="deleteTop(item)" v-if="item.isTop === 1" />
-            <img style="cursor: pointer; width: 20px; transform: translateY(5px)" :src="'/img/noTop.png'" @click="addTop(item)" v-else />
+    <div style="padding: 20px; background: #fff; margin-bottom: 20px">
+      <el-button type="primary" style="margin-left: 10px" @click="openModal()">添加客户</el-button>
+    </div>
+    <div style="padding: 20px 20px 0 20px; background: #fff; margin-bottom: 20px">
+      <div style="display: flex">
+        <div style="font-size: 14px; cursor: pointer" class="by-dropdown">
+          <div class="by-dropdown-title">
+            <span>{{ dictValueLabel(sourceList.paginationTwo.statisticsType, statisticsType) }}</span>
+            <el-icon style="margin-left: 5px; font-size: 16px"><CaretBottom /></el-icon>
+          </div>
+          <ul class="by-dropdown-lists">
+            <li
+              v-for="item in statisticsType"
+              :key="item.value"
+              @click="searchItemSelect(item.value)"
+              style="display: flex; align-items: center; justify-content: center">
+              {{ item.label }}
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div style="display: flex; width: 100%; margin: 10px 0 0 10px; flex-wrap: wrap">
+        <div style="padding: 20px; border-radius: 10px; width: 200px; background-color: #d1caff59; margin: 0 20px 20px 0">
+          <div style="margin-bottom: 10px; display: flex">
+            <div style="width: 8px; height: 8px; background-color: #5bacff; border-radius: 50px; margin-top: 6px"></div>
+            <span style="padding-left: 8px">合计</span>
+          </div>
+          <div style="color: black; font-size: 20px; font-weight: 700">{{ statisticalData.countAmount }}</div>
+        </div>
+        <template v-if="sourceList.paginationTwo.statisticsType === 1">
+          <div
+            style="padding: 20px; border-radius: 10px; width: 200px; background-color: #a2d8ff70; margin: 0 20px 20px 0"
+            v-for="(item, index) in customerSource"
+            :key="index">
+            <div style="margin-bottom: 10px; display: flex">
+              <div style="width: 8px; height: 8px; background-color: #5bacff; border-radius: 50px; margin-top: 6px"></div>
+              <span style="padding-left: 8px">{{ item.label }}</span>
+            </div>
+            <div style="color: black; font-size: 20px; font-weight: 700">{{ getNum(item.value) }}</div>
           </div>
         </template>
-        <template #address="{ item }">
-          <span>{{ item.countryName }}</span>
-          <span v-if="item.provinceName"> ,{{ item.provinceName }}</span>
-          <span v-if="item.cityName"> ,{{ item.cityName }}</span>
-        </template>
-        <template #name="{ item }">
-          <div style="cursor: pointer; color: #409eff" @click="handleClickName(item)">
-            {{ item.name }}
+        <template v-else-if="sourceList.paginationTwo.statisticsType === 2">
+          <div
+            style="padding: 20px; border-radius: 10px; width: 200px; background-color: #a2d8ff70; margin: 0 20px 20px 0"
+            v-for="(item, index) in customerStatus"
+            :key="index">
+            <div style="margin-bottom: 10px; display: flex">
+              <div style="width: 8px; height: 8px; background-color: #5bacff; border-radius: 50px; margin-top: 6px"></div>
+              <span style="padding-left: 8px">{{ item.label }}</span>
+            </div>
+            <div style="color: black; font-size: 20px; font-weight: 700">{{ getNum(item.value) }}</div>
           </div>
         </template>
-        <template #tags="{ item }">
-          <div style="width: 100%">
-            <el-tag style="margin-right: 8px" type="success" v-for="(tag, index) in item.tag" closable :key="index" @close="tagClose(tag, item)">
-              {{ dictValueLabel(tag, customerTag) }}
-            </el-tag>
-            <template v-if="item.tag.length !== customerTag.length">
-              <el-select
-                v-if="item.addTagShow"
-                v-model="addTag"
-                style="width: 100%"
-                @change="
-                  (val) => {
-                    return changeTag(val, item);
-                  }
-                ">
-                <el-option v-for="tag in customerTag" :key="tag.value" :label="tag.label" :value="tag.value" :disabled="judgeTagSelect(item.tag, tag.value)" />
-              </el-select>
-              <el-tag style="cursor: pointer" type="success" @click="showSelect(item)" v-else> + </el-tag>
-            </template>
+        <template v-else-if="sourceList.paginationTwo.statisticsType === 3">
+          <div
+            style="padding: 20px; border-radius: 10px; width: 200px; background-color: #a2d8ff70; margin: 0 20px 20px 0"
+            v-for="(item, index) in userList"
+            :key="index">
+            <div style="margin-bottom: 10px; display: flex">
+              <div style="width: 8px; height: 8px; background-color: #5bacff; border-radius: 50px; margin-top: 6px"></div>
+              <span style="padding-left: 8px">{{ item.label }}</span>
+            </div>
+            <div style="color: black; font-size: 20px; font-weight: 700">{{ getNum(item.value) }}</div>
           </div>
         </template>
-        <template #follow="{ item }">
-          <div :class="'getWidth' + item.id" style="width: 100%">
-            <div style="width: 100%; display: flex">
-              <template v-if="item.customerFollowRecordsList && item.customerFollowRecordsList.length > 0">
-                <div
-                  :style="
-                    index > 2
-                      ? 'line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer; display: none'
-                      : 'line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer'
-                  "
-                  v-for="(record, index) in item.customerFollowRecordsList"
-                  :key="record.id">
-                  <el-popover placement="bottom" :width="300" trigger="hover" @show="recordShow(record)">
-                    <template #reference>
-                      <div>
-                        <span v-if="record.date">{{ record.date.substr(0, 10) }}</span>
-                        <el-icon style="margin-left: 8px; transform: translateY(2px)" @click="deleteFollow(record)"><DeleteFilled /></el-icon>
-                      </div>
-                    </template>
-                    <template #default>
-                      <div style="width: 100%">
-                        <div style="color: #909399; margin: 8px 0">跟进时间: {{ record.date }}</div>
-                        <div style="word-wrap: break-word; margin: 8px 0" v-html="getStyle(record.content)" v-if="record.content"></div>
-                        <div v-else>跟进记录:</div>
-                        <div style="margin: 8px 0; display: flex" v-if="record.fileList && record.fileList.length > 0">
-                          <div style="width: 36px">附件:</div>
-                          <div style="width: calc(100% - 36px)">
-                            <div v-for="(file, index) in record.fileList" :key="index">
-                              <a style="color: #409eff; cursor: pointer" @click="openFile(file.fileUrl)">{{ file.fileName }}</a>
-                            </div>
+      </div>
+    </div>
+    <byTable
+      :source="sourceList.data"
+      :pagination="sourceList.pagination"
+      :config="config"
+      :loading="loading"
+      :selectConfig="selectConfig"
+      highlight-current-row
+      @get-list="getList">
+      <template #isTop="{ item }">
+        <div>
+          <img style="cursor: pointer; width: 20px; transform: translateY(5px)" :src="'/img/isTop.png'" @click="deleteTop(item)" v-if="item.isTop === 1" />
+          <img style="cursor: pointer; width: 20px; transform: translateY(5px)" :src="'/img/noTop.png'" @click="addTop(item)" v-else />
+        </div>
+      </template>
+      <template #address="{ item }">
+        <span>{{ item.countryName }}</span>
+        <span v-if="item.provinceName"> ,{{ item.provinceName }}</span>
+        <span v-if="item.cityName"> ,{{ item.cityName }}</span>
+      </template>
+      <template #name="{ item }">
+        <div style="cursor: pointer; color: #409eff" @click="handleClickName(item)">
+          {{ item.name }}
+        </div>
+      </template>
+      <template #tags="{ item }">
+        <div style="width: 100%">
+          <el-tag style="margin-right: 8px" type="success" v-for="(tag, index) in item.tag" closable :key="index" @close="tagClose(tag, item)">
+            {{ dictValueLabel(tag, customerTag) }}
+          </el-tag>
+          <template v-if="item.tag.length !== customerTag.length">
+            <el-select
+              v-if="item.addTagShow"
+              v-model="addTag"
+              style="width: 100%"
+              @change="
+                (val) => {
+                  return changeTag(val, item);
+                }
+              ">
+              <el-option v-for="tag in customerTag" :key="tag.value" :label="tag.label" :value="tag.value" :disabled="judgeTagSelect(item.tag, tag.value)" />
+            </el-select>
+            <el-tag style="cursor: pointer" type="success" @click="showSelect(item)" v-else> + </el-tag>
+          </template>
+        </div>
+      </template>
+      <template #follow="{ item }">
+        <div :class="'getWidth' + item.id" style="width: 100%">
+          <div style="width: 100%; display: flex">
+            <template v-if="item.customerFollowRecordsList && item.customerFollowRecordsList.length > 0">
+              <div
+                :style="
+                  index > 2
+                    ? 'line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer; display: none'
+                    : 'line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer'
+                "
+                v-for="(record, index) in item.customerFollowRecordsList"
+                :key="record.id">
+                <el-popover placement="bottom" :width="300" trigger="hover" @show="recordShow(record)">
+                  <template #reference>
+                    <div>
+                      <span v-if="record.date">{{ record.date.substr(0, 10) }}</span>
+                      <el-icon style="margin-left: 8px; transform: translateY(2px)" @click="deleteFollow(record)"><DeleteFilled /></el-icon>
+                    </div>
+                  </template>
+                  <template #default>
+                    <div style="width: 100%">
+                      <div style="color: #909399; margin: 8px 0">跟进时间: {{ record.date }}</div>
+                      <div style="word-wrap: break-word; margin: 8px 0" v-html="getStyle(record.content)" v-if="record.content"></div>
+                      <div v-else>跟进记录:</div>
+                      <div style="margin: 8px 0; display: flex" v-if="record.fileList && record.fileList.length > 0">
+                        <div style="width: 36px">附件:</div>
+                        <div style="width: calc(100% - 36px)">
+                          <div v-for="(file, index) in record.fileList" :key="index">
+                            <a style="color: #409eff; cursor: pointer" @click="openFile(file.fileUrl)">{{ file.fileName }}</a>
                           </div>
                         </div>
                       </div>
-                    </template>
-                  </el-popover>
-                </div>
-                <div
-                  style="line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer"
-                  @click="clickMore(item)"
-                  v-if="item.customerFollowRecordsList.length >= 3">
-                  更多
-                </div>
-              </template>
-            </div>
+                    </div>
+                  </template>
+                </el-popover>
+              </div>
+              <div
+                style="line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer"
+                @click="clickMore(item)"
+                v-if="item.customerFollowRecordsList.length >= 3">
+                更多
+              </div>
+            </template>
           </div>
-        </template>
-      </byTable>
-    </div>
+        </div>
+      </template>
+    </byTable>
 
     <el-dialog :title="modalType == 'add' ? '新增' : '编辑'" v-if="dialogVisible" v-model="dialogVisible" width="800" v-loading="loadingOperation">
       <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit">
@@ -298,6 +357,20 @@ const contactType = ref([]);
 const userList = ref([]);
 const fileList = ref([]);
 const uploadData = ref({});
+const statisticsType = ref([
+  {
+    label: "客户来源统计",
+    value: 1,
+  },
+  {
+    label: "客户类型统计",
+    value: 2,
+  },
+  {
+    label: "业务员统计",
+    value: 3,
+  },
+]);
 const sourceList = ref({
   data: [],
   pagination: {
@@ -308,6 +381,10 @@ const sourceList = ref({
     source: "",
     type: "",
   },
+  paginationTwo: {
+    statisticsType: 1,
+    type: 1,
+  },
 });
 const selectConfig = computed(() => {
   return [
@@ -464,6 +541,7 @@ const config = computed(() => {
                       type: "success",
                     });
                     getList();
+                    obtainStatisticalData();
                   });
               });
             },
@@ -717,6 +795,7 @@ const submitForm = () => {
           dialogVisible.value = false;
           submitLoading.value = false;
           getList();
+          obtainStatisticalData();
         },
         (err) => {
           console.log(err);
@@ -968,6 +1047,41 @@ const addTop = (item) => {
     item.isTop = 1;
   });
 };
+const searchItemSelect = (val) => {
+  sourceList.value.paginationTwo.statisticsType = val;
+  obtainStatisticalData();
+};
+const statisticalData = ref({
+  countAmount: 0,
+  customerList: [],
+});
+const obtainStatisticalData = () => {
+  proxy.post("/customer/sourceStatistics", sourceList.value.paginationTwo).then((res) => {
+    statisticalData.value = res;
+  });
+};
+obtainStatisticalData();
+const getNum = (val) => {
+  let num = 0;
+  if (statisticalData.value.customerList && statisticalData.value.customerList.length > 0) {
+    statisticalData.value.customerList.map((item) => {
+      if (sourceList.value.paginationTwo.statisticsType === 1) {
+        if (item.source === val) {
+          num = item.count;
+        }
+      } else if (sourceList.value.paginationTwo.statisticsType === 2) {
+        if (item.status === val) {
+          num = item.count;
+        }
+      } else if (sourceList.value.paginationTwo.statisticsType === 3) {
+        if (item.userId === val) {
+          num = item.count;
+        }
+      }
+    });
+  }
+  return num;
+};
 </script>
 
 <style lang="scss" scoped>
@@ -981,4 +1095,69 @@ const addTop = (item) => {
     width: 0px;
   }
 }
+.by-dropdown {
+  position: relative;
+  text-align: left;
+  height: 32px;
+  z-index: 1010;
+  padding: 0 10px;
+  transition: all 0.5s ease;
+  cursor: pointer;
+  line-height: 32px;
+  .by-dropdown-title {
+    font-size: 14px;
+    background-color: #fff;
+  }
+  ul {
+    position: absolute;
+    left: 0;
+    top: 32px;
+    padding: 0;
+    margin: 0;
+    z-index: 1200;
+    display: none;
+    white-space: nowrap;
+    background-color: #fff;
+    li {
+      list-style: none;
+      z-index: 1200;
+      font-size: 12px;
+      height: 30px;
+      padding: 0 10px;
+    }
+    li:hover {
+      background-color: #eff6ff;
+      color: #0084ff;
+    }
+  }
+}
+.by-dropdown::before {
+  display: block;
+  width: 1px;
+  content: " ";
+  position: absolute;
+  height: 14px;
+  top: 8px;
+  background-color: #ddd;
+  right: 0;
+  z-index: 1011;
+}
+.by-dropdown:hover {
+  background: #ffffff;
+  border-radius: 2px 2px 2px 2px;
+  opacity: 1;
+  ul {
+    background: #ffffff;
+    box-shadow: 0px 2px 16px 1px rgba(0, 0, 0, 0.06);
+    border-radius: 2px 2px 2px 2px;
+    opacity: 1;
+    display: block;
+    text-align: left;
+  }
+}
+.by-dropdown-lists {
+  max-height: 50vh;
+  overflow-y: auto;
+  line-height: 1;
+}
 </style>