Просмотр исходного кода

Merge branch '官网数据统计' into testToMerge

xiaohaizhao 1 год назад
Родитель
Сommit
95b83a7aff

+ 515 - 0
src/WebsiteManagement/dataStatistics/index.vue

@@ -0,0 +1,515 @@
+<template>
+  <div class="container">
+    <visitorStatistics />
+
+    <div class="card">
+      <cord-top title="访客趋势分析" @returnWhere="getVisitorTrend" />
+      <div ref="visitorTrend" style="margin-top: 20px"></div>
+    </div>
+    <div class="card">
+      <cord-top title="访问量趋势分析" @returnWhere="getPageViewTrend" />
+      <div ref="pageViewTrend" style="margin-top: 20px"></div>
+    </div>
+
+    <div class="card">
+      <cord-top title="用户类型分析" @returnWhere="getUserTypeAnalysis" />
+      <div ref="userTypeAnalysis" style="margin-top: 20px"></div>
+    </div>
+
+    <div class="card">
+      <cord-top
+        title="各模块点击量分析"
+        @returnWhere="getModuleClicksAnalysis"
+      />
+      <div class="module-clicks">
+        <div
+          class="pie-chart"
+          ref="moduleClicksAnalysis"
+          style="margin-top: 20px"
+        ></div>
+
+        <el-table :data="moduleClicksAnalysisTable" border style="width: 100%">
+          <el-table-column prop="module" :label="$t('模块名称')">
+          </el-table-column>
+          <el-table-column prop="clickcount" :label="$t('当前时段模块点击量')">
+          </el-table-column>
+          <el-table-column prop="sumclickcount" :label="$t('模块总点击量')">
+          </el-table-column>
+        </el-table>
+      </div>
+    </div>
+
+    <div class="card">
+      <rankingList />
+    </div>
+
+    <div class="card">
+      <cord-top title="留言分析" @returnWhere="getMessageAnalysis" />
+      <div ref="messageAnalysis" style="margin-top: 20px"></div>
+    </div>
+
+    <div class="card">
+      <cord-top title="服务申请分析" @returnWhere="getServiceRequestAnalysis" />
+      <div ref="serviceRequestAnalysis" style="margin-top: 20px"></div>
+    </div>
+  </div>
+</template>
+
+<script>
+import cordTop from "./modules/header.vue";
+import visitorStatistics from "./modules/visitorStatistics";
+import rankingList from "./modules/rankingList";
+import { Line, Column, Pie } from "@antv/g2plot";
+
+export default {
+  components: { visitorStatistics, cordTop, rankingList },
+  data() {
+    return {
+      visitorTrend: null, //访客趋势
+      pageViewTrend: null, //访问量趋势
+      userTypeAnalysis: null, //用户类型分析
+      moduleClicksAnalysis: null, //各模块点击量分析
+      moduleClicksAnalysisTable: null, //各模块点击量分析表格
+      messageAnalysis: null, //留言分析
+      serviceRequestAnalysis: null, //服务申请分析
+      siteid: "", //站点id
+    };
+  },
+  created() {
+    this.siteid = JSON.parse(sessionStorage.getItem("active_account")).siteid;
+    // 获取访客趋势
+    this.getVisitorTrend();
+    // 获取访问量趋势
+    this.getPageViewTrend();
+    // 获取用户类型分析
+    this.getUserTypeAnalysis();
+    // 获取各模块点击量分析
+    this.getModuleClicksAnalysis();
+    // 获取留言分析
+    this.getMessageAnalysis();
+    // 获取服务申请分析
+    this.getServiceRequestAnalysis();
+  },
+  methods: {
+    // 获取访客趋势
+    getVisitorTrend(detail) {
+      let content = {
+        nocache: true,
+        siteid: this.siteid,
+        type: "近七日",
+        datatype: "访客",
+      };
+      if (detail) {
+        if (detail.type) {
+          content.type = detail.type;
+        } else {
+          content.type = "";
+          content.where = detail;
+        }
+      }
+      this.$api
+        .requested({
+          id: 2025010214275903,
+          content,
+        })
+        .then((res) => {
+          if (res.code != 1) return;
+          let type = this.$t("访客数量");
+          let list = res.data.map((v) => {
+            v.type = type;
+            return v;
+          });
+          if (detail) {
+            this.visitorTrend.update({
+              scrollbar: list.length > 14 ? { type: "horizontal" } : null,
+            });
+            this.visitorTrend.changeData(list);
+          } else {
+            this.visitorTrend = new Line(this.$refs.visitorTrend, {
+              height: 300,
+              data: list,
+              xField: "date",
+              seriesField: "type",
+              yField: "count",
+              color: "#5588F7",
+              tooltip: {
+                formatter: (datum) => {
+                  return {
+                    name: type,
+                    value: datum.count,
+                  };
+                },
+              },
+              point: {
+                shape: "breath-point",
+              },
+            });
+            this.visitorTrend.render();
+          }
+        });
+    },
+    // 获取访问量趋势
+    getPageViewTrend(detail) {
+      let content = {
+        nocache: true,
+        siteid: this.siteid,
+        type: "近七日",
+        datatype: "访问量",
+      };
+      if (detail) {
+        if (detail.type) {
+          content.type = detail.type;
+        } else {
+          content.type = "";
+          content.where = detail;
+        }
+      }
+      this.$api
+        .requested({
+          id: 2025010214275903,
+          content,
+        })
+        .then((res) => {
+          if (res.code != 1) return;
+          let type = this.$t("访问量");
+          let list = res.data.map((v) => {
+            v.type = type;
+            return v;
+          });
+          if (detail) {
+            this.pageViewTrend.update({
+              scrollbar: list.length > 14 ? { type: "horizontal" } : null,
+            });
+            this.pageViewTrend.changeData(list);
+          } else {
+            this.pageViewTrend = new Line(this.$refs.pageViewTrend, {
+              height: 300,
+              data: list,
+              xField: "date",
+              yField: "count",
+              color: "#F29C37",
+              seriesField: "type",
+              tooltip: {
+                formatter: (datum) => {
+                  return { name: type, value: datum.count };
+                },
+              },
+              point: {
+                shape: "breath-point",
+              },
+            });
+            this.pageViewTrend.render();
+          }
+        });
+    },
+    // 获取各模块点击量分析
+    getModuleClicksAnalysis(detail) {
+      let content = {
+        siteid: this.siteid,
+        nocache: true,
+        type: "近七日",
+      };
+      if (detail) {
+        if (detail.type) {
+          content.type = detail.type;
+        } else {
+          content.type = "";
+          content.where = detail;
+        }
+      }
+      this.$api
+        .requested({
+          id: 2025010309594403,
+          content,
+        })
+        .then((res) => {
+          if (res.code != 1) return;
+          let list = res.data.map((v) => {
+            v.module = this.$t(v.module);
+            return v;
+          });
+          this.moduleClicksAnalysisTable = list;
+          if (detail) {
+            this.moduleClicksAnalysis.changeData(list);
+          } else {
+            this.moduleClicksAnalysis = new Pie(
+              this.$refs.moduleClicksAnalysis,
+              {
+                height: 400,
+                appendPadding: 10,
+                angleField: "clickcount",
+                colorField: "module",
+                radius: 1,
+                innerRadius: 0.64,
+                data: list,
+                label: {
+                  type: "inner",
+                  offset: "-50%",
+                  autoRotate: false,
+                  style: { textAlign: "center" },
+                  formatter: ({ percent }) => `${(percent * 100).toFixed(0)}%`,
+                },
+                statistic: {
+                  title: {
+                    offsetY: -8,
+                    customHtml: (container, view, datum) => {
+                      const text = datum ? datum.module : this.$t("点击量总数");
+                      return text;
+                    },
+                  },
+                  content: {
+                    offsetY: -4,
+                  },
+                },
+                legend: {
+                  layout: "horizontal",
+                  position: "bottom",
+                  flipPage: false,
+                },
+                // 添加 中心统计文本 交互
+                interactions: [
+                  { type: "element-selected" },
+                  { type: "element-active" },
+                  {
+                    type: "pie-statistic-active",
+                    cfg: {
+                      start: [
+                        {
+                          trigger: "element:mouseenter",
+                          action: "pie-statistic:change",
+                        },
+                        {
+                          trigger: "legend-item:mouseenter",
+                          action: "pie-statistic:change",
+                        },
+                      ],
+                      end: [
+                        {
+                          trigger: "element:mouseleave",
+                          action: "pie-statistic:reset",
+                        },
+                        {
+                          trigger: "legend-item:mouseleave",
+                          action: "pie-statistic:reset",
+                        },
+                      ],
+                    },
+                  },
+                ],
+              }
+            );
+            this.moduleClicksAnalysis.render();
+          }
+        });
+    },
+    // 获取用户类型分析
+    getUserTypeAnalysis(detail) {
+      let content = {
+        nocache: true,
+        siteid: this.siteid,
+        type: "近七日",
+      };
+      if (detail) {
+        if (detail.type) {
+          content.type = detail.type;
+        } else {
+          content.type = "";
+          content.where = detail;
+        }
+      }
+      this.$api
+        .requested({
+          id: 2025010309354603,
+          content,
+        })
+        .then((res) => {
+          if (res.code != 1) return;
+          let type = [this.$t("登录用户"), this.$t("游客")];
+          let list = [];
+          res.data.filter((v) => {
+            list.push({
+              date: v.date,
+              count: v.visitorcount,
+              type: type[0],
+            });
+            list.push({
+              date: v.date,
+              count: v.logincount,
+              type: type[1],
+            });
+          });
+          if (detail) {
+            this.userTypeAnalysis.update({
+              scrollbar: list.length > 28 ? { type: "horizontal" } : null,
+            });
+            this.userTypeAnalysis.changeData(list);
+          } else {
+            this.userTypeAnalysis = new Column(this.$refs.userTypeAnalysis, {
+              height: 300,
+              data: list,
+              isGroup: true,
+              xField: "date",
+              yField: "count",
+              color: ["#3874F6", "#F29C37"],
+              seriesField: "type",
+              label: {
+                // 可手动配置 label 数据标签位置
+                position: "top", // 'top', 'middle', 'bottom'
+                // 可配置附加的布局方法
+                layout: [
+                  // 柱形图数据标签位置自动调整
+                  { type: "interval-adjust-position" },
+                  // 数据标签防遮挡
+                  { type: "interval-hide-overlap" },
+                  // 数据标签文颜色自动调整
+                  { type: "adjust-color" },
+                ],
+              },
+            });
+            this.userTypeAnalysis.render();
+          }
+        });
+    },
+    // 获取留言分析
+    getMessageAnalysis(detail) {
+      let content = {
+        nocache: true,
+        siteid: this.siteid,
+        type: "近七日",
+      };
+      if (detail) {
+        if (detail.type) {
+          content.type = detail.type;
+        } else {
+          content.type = "";
+          content.where = detail;
+        }
+      }
+      this.$api
+        .requested({
+          id: 2025010310381303,
+          content,
+        })
+        .then((res) => {
+          if (res.code != 1) return;
+          let type = this.$t("留言量");
+          let list = res.data.map((v) => {
+            v.type = type;
+            return v;
+          });
+          if (detail) {
+            this.messageAnalysis.update({
+              scrollbar: list.length > 14 ? { type: "horizontal" } : null,
+            });
+            this.messageAnalysis.changeData(list);
+          } else {
+            this.messageAnalysis = new Line(this.$refs.messageAnalysis, {
+              height: 300,
+              data: list,
+              xField: "date",
+              seriesField: "type",
+              yField: "count",
+              color: "#5588F7",
+              tooltip: {
+                formatter: (datum) => {
+                  return {
+                    name: type,
+                    value: datum.count,
+                  };
+                },
+              },
+              point: {
+                shape: "breath-point",
+              },
+            });
+            this.messageAnalysis.render();
+          }
+        });
+    },
+    // 获取服务申请分析
+    getServiceRequestAnalysis(detail) {
+      let content = {
+        nocache: true,
+        siteid: this.siteid,
+        type: "近七日",
+      };
+      if (detail) {
+        if (detail.type) {
+          content.type = detail.type;
+        } else {
+          content.type = "";
+          content.where = detail;
+        }
+      }
+      this.$api
+        .requested({
+          id: 2025010310402603,
+          content,
+        })
+        .then((res) => {
+          if (res.code != 1) return;
+          let type = this.$t("申请量");
+          let list = res.data.map((v) => {
+            v.type = type;
+            return v;
+          });
+          if (detail) {
+            this.serviceRequestAnalysis.update({
+              scrollbar: list.length > 14 ? { type: "horizontal" } : null,
+            });
+            this.serviceRequestAnalysis.changeData(list);
+          } else {
+            this.serviceRequestAnalysis = new Line(
+              this.$refs.serviceRequestAnalysis,
+              {
+                height: 300,
+                data: list,
+                xField: "date",
+                seriesField: "type",
+                yField: "count",
+                color: "#F29C37",
+                tooltip: {
+                  formatter: (datum) => {
+                    return {
+                      name: type,
+                      value: datum.count,
+                    };
+                  },
+                },
+                point: {
+                  shape: "breath-point",
+                },
+              }
+            );
+            this.serviceRequestAnalysis.render();
+          }
+        });
+    },
+  },
+};
+</script>
+
+<style scoped>
+.container {
+  padding: 20px;
+  box-sizing: border-box;
+}
+.card {
+  width: 100%;
+  padding: 20px;
+  background: #ffffff;
+  box-shadow: 0px 1px 6px 1px rgba(0, 0, 0, 0.16);
+  border-radius: 10px;
+  box-sizing: border-box;
+  margin-top: 20px;
+}
+
+.module-clicks {
+  display: flex;
+  align-items: center;
+}
+
+.pie-chart {
+  width: 450px;
+}
+</style>

+ 129 - 0
src/WebsiteManagement/dataStatistics/modules/header.vue

@@ -0,0 +1,129 @@
+<template>
+  <div class="cord-header">
+    <div v-if="title" class="left" />
+    <el-tooltip v-if="title" :content="$t(title)" placement="top-start">
+      <div class="title text-ellipsis">{{ $t(title) }}</div>
+    </el-tooltip>
+
+    <el-button-group style="margin-right: 20px">
+      <el-button
+        v-for="item in shortcutDate"
+        :key="item.value"
+        :type="tabPosition == item.value ? 'primary' : ''"
+        @click="changeTab(item.value)"
+        >{{ $t(item.label) }}</el-button
+      >
+    </el-button-group>
+
+    <el-date-picker
+      v-model="daterange"
+      :clearable="false"
+      type="daterange"
+      value-format="yyyy-MM-dd"
+      :range-separator="$t('至')"
+      :start-placeholder="$t('开始日期')"
+      :end-placeholder="$t('结束日期')"
+      :picker-options="pickerOptions"
+      @change="pickerChange"
+    >
+    </el-date-picker>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "header",
+  props: {
+    title: String,
+    subTitle: String,
+    shortcutDate: {
+      type: Array,
+      default: () => [
+        {
+          label: "近7日",
+          value: "近七日",
+        },
+        {
+          label: "近1个月",
+          value: "近一月",
+        },
+        {
+          label: "近半年",
+          value: "近半年",
+        },
+      ],
+    },
+    returnWhere: Function,
+  },
+  data() {
+    return {
+      daterange: ["", ""],
+      tabPosition: "近七日",
+      pickerOptions: {
+        disabledDate(time) {
+          return time.getTime() > Date.now();
+        },
+      },
+    };
+  },
+  methods: {
+    changeTab(value) {
+      this.daterange = ["", ""];
+      this.tabPosition = value;
+      this.$emit("returnWhere", {
+        type: value,
+      });
+    },
+    pickerChange(e) {
+      this.tabPosition = "";
+      this.$emit("returnWhere", {
+        begindate: e[0],
+        enddate: e[1],
+      });
+    },
+  },
+};
+</script>
+
+<style scoped>
+.cord-header {
+  display: flex;
+  height: 32px;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.cord-header div {
+  flex-shrink: 0;
+}
+
+.left {
+  width: 6px;
+  height: 26px;
+  background: #3874f6;
+  margin-right: 22px;
+}
+
+.title {
+  flex: 1;
+  width: 0;
+  font-family: Microsoft YaHei, Microsoft YaHei;
+  font-weight: bold;
+  font-size: 20px;
+  color: #333333;
+  padding-right: 20px;
+}
+
+.text-ellipsis {
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  -o-text-overflow: ellipsis;
+}
+/deep/ .el-date-editor {
+  width: 220px;
+}
+/deep/ .el-date-editor .el-range__close-icon {
+  width: 0 !important;
+}
+</style>

+ 168 - 0
src/WebsiteManagement/dataStatistics/modules/rankingList.vue

@@ -0,0 +1,168 @@
+<template>
+  <div>
+    <cord-top title="访问量top10" @returnWhere="getVisits" />
+
+    <div class="ranking-list">
+      <div class="ranking-list-item" v-for="item in list" :key="item.name">
+        <div class="ranking-list-item-name">{{ $t(item.name) }}</div>
+        <div
+          class="ranking-list-item-value"
+          v-for="(it, index) in item.value"
+          :key="it.specificname"
+        >
+          <div
+            class="ranking-list-item-value-rowindex"
+            :style="{
+              background:
+                { 1: '#FF4D4F', 2: '#FA9014', 3: '#FFC148' }[index + 1] ||
+                '#bbbbbb',
+            }"
+          >
+            {{ index + 1 }}
+          </div>
+          <el-tooltip :content="$t(it.specificname)" placement="top-start">
+            <div class="ranking-list-item-value-module">
+              {{ $t(it.specificname) }}
+            </div>
+          </el-tooltip>
+          <div class="ranking-list-item-value-visitcount">
+            {{ it.visitcount }}
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <el-empty v-if="list.length==0" :description="$t('暂无数据')"></el-empty>
+  </div>
+</template>
+
+<script>
+import cordTop from "./header.vue";
+
+export default {
+  components: {
+    cordTop,
+  },
+  data() {
+    return {
+      siteid: "", //站点id
+      list: [],
+    };
+  },
+  created() {
+    this.siteid = JSON.parse(sessionStorage.getItem("active_account")).siteid;
+    this.getVisits();
+  },
+  methods: {
+    // 获取访问量top10
+    getVisits(detail) {
+      let content = {
+        nocache: true,
+        siteid: this.siteid,
+        type: "近七日",
+      };
+      if (detail) {
+        if (detail.type) {
+          content.type = detail.type;
+        } else {
+          content.type = "";
+          content.where = detail;
+        }
+      }
+      this.$api
+        .requested({
+          id: 2025010310134203,
+          content,
+        })
+        .then((res) => {
+          if (res.code != 1) return;
+          let list = [];
+          res.data.forEach((item) => {
+            for (const key in item) {
+              list.push({
+                name: key,
+                value: item[key],
+              });
+            }
+          });
+          this.list = list;
+        });
+    },
+  },
+};
+</script>
+
+<style scoped>
+.ranking-list {
+  width: 100%;
+  display: flex;
+  margin-top: 20px;
+  overflow-x: auto;
+  padding-bottom: 20px;
+}
+
+.ranking-list-item {
+  flex: 1;
+  flex-shrink: 0;
+  min-width: 250px;
+  border-right: 2px solid #e0e0e0;
+  margin-right: 20px;
+  padding-right: 20px;
+}
+
+.ranking-list-item:last-child {
+  border-right: none;
+}
+
+.ranking-list-item-name {
+  font-family: PingFang SC, PingFang SC;
+  font-weight: 500;
+  font-size: 14px;
+  color: #333333;
+  margin-bottom: 12px;
+}
+
+.ranking-list-item-value {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 16px;
+}
+
+.ranking-list-item-value-rowindex {
+  width: 24px;
+  height: 24px;
+  line-height: 24px;
+  color: #ffffff;
+  background: #bbbbbb;
+  border-radius: 2px;
+  text-align: center;
+  font-family: Arial, Arial;
+  font-weight: 400;
+  font-size: 12px;
+  margin-right: 10px;
+}
+
+.ranking-list-item-value-module {
+  flex: 1;
+  width: 0;
+  line-height: 16px;
+  font-family: Arial, Arial;
+  font-size: 12px;
+  color: #333333;
+  white-space: nowrap; /* 禁止换行 */
+  overflow: hidden; /* 超出部分隐藏 */
+  text-overflow: ellipsis; /* 超出部分用省略号显示 */
+  padding-right: 10px;
+  box-sizing: border-box;
+}
+
+.ranking-list-item-value-visitcount {
+  height: 14px;
+  font-family: Arial, Arial;
+  font-weight: 400;
+  font-size: 12px;
+  color: #333333;
+  flex-shrink: 0;
+}
+</style>

+ 249 - 0
src/WebsiteManagement/dataStatistics/modules/visitorStatistics.vue

@@ -0,0 +1,249 @@
+<template>
+  <div>
+    <div class="cards" v-if="visitor && visits">
+      <div class="card" v-if="visitor">
+        <div class="title">{{ $t("访客统计") }}</div>
+        <div class="content">
+          <div class="item">
+            <el-tooltip :content="visitor.day" placement="top-start">
+              <div class="data text-ellipsis">
+                {{ visitor.day }}
+              </div>
+            </el-tooltip>
+            <el-tooltip :content="$t('日访客')" placement="top-start">
+              <div class="explain text-ellipsis">
+                {{ $t("日访客") }}
+              </div>
+            </el-tooltip>
+          </div>
+
+          <div class="item">
+            <el-tooltip :content="visitor.week" placement="top-start">
+              <div class="data text-ellipsis">
+                {{ visitor.week }}
+              </div>
+            </el-tooltip>
+            <el-tooltip :content="$t('周访客')" placement="top-start">
+              <div class="explain text-ellipsis">
+                {{ $t("周访客") }}
+              </div>
+            </el-tooltip>
+          </div>
+
+          <div class="item">
+            <el-tooltip :content="visitor.month" placement="top-start">
+              <div class="data text-ellipsis">
+                {{ visitor.month }}
+              </div>
+            </el-tooltip>
+            <el-tooltip :content="$t('月访客')" placement="top-start">
+              <div class="explain text-ellipsis">
+                {{ $t("月访客") }}
+              </div>
+            </el-tooltip>
+          </div>
+
+          <div class="item">
+            <el-tooltip :content="visitor.year" placement="top-start">
+              <div class="data text-ellipsis">
+                {{ visitor.year }}
+              </div>
+            </el-tooltip>
+            <el-tooltip :content="$t('年访客')" placement="top-start">
+              <div class="explain text-ellipsis">
+                {{ $t("年访客") }}
+              </div>
+            </el-tooltip>
+          </div>
+
+          <div class="item">
+            <el-tooltip :content="visitor.all" placement="top-start">
+              <div class="data text-ellipsis">
+                {{ visitor.all }}
+              </div>
+            </el-tooltip>
+            <el-tooltip :content="$t('总访客')" placement="top-start">
+              <div class="explain text-ellipsis">
+                {{ $t("总访客") }}
+              </div>
+            </el-tooltip>
+          </div>
+        </div>
+      </div>
+      <div class="card" v-if="visits">
+        <div class="title">{{ $t("访问量统计") }}</div>
+        <div class="content">
+          <div class="item">
+            <el-tooltip :content="visits.day" placement="top-start">
+              <div class="data text-ellipsis">
+                {{ visits.day }}
+              </div>
+            </el-tooltip>
+            <el-tooltip :content="$t('日访问量')" placement="top-start">
+              <div class="explain text-ellipsis">
+                {{ $t("日访问量") }}
+              </div>
+            </el-tooltip>
+          </div>
+
+          <div class="item">
+            <el-tooltip :content="visits.week" placement="top-start">
+              <div class="data text-ellipsis">
+                {{ visits.week }}
+              </div>
+            </el-tooltip>
+            <el-tooltip :content="$t('周访问量')" placement="top-start">
+              <div class="explain text-ellipsis">
+                {{ $t("周访问量") }}
+              </div>
+            </el-tooltip>
+          </div>
+
+          <div class="item">
+            <el-tooltip :content="visits.month" placement="top-start">
+              <div class="data text-ellipsis">
+                {{ visits.month }}
+              </div>
+            </el-tooltip>
+            <el-tooltip :content="$t('月访问量')" placement="top-start">
+              <div class="explain text-ellipsis">
+                {{ $t("月访问量") }}
+              </div>
+            </el-tooltip>
+          </div>
+
+          <div class="item">
+            <el-tooltip :content="visits.year" placement="top-start">
+              <div class="data text-ellipsis">
+                {{ visits.year }}
+              </div>
+            </el-tooltip>
+            <el-tooltip :content="$t('年访问量')" placement="top-start">
+              <div class="explain text-ellipsis">
+                {{ $t("年访问量") }}
+              </div>
+            </el-tooltip>
+          </div>
+
+          <div class="item">
+            <el-tooltip :content="visits.all" placement="top-start">
+              <div class="data text-ellipsis">
+                {{ visits.all }}
+              </div>
+            </el-tooltip>
+            <el-tooltip :content="$t('总访问量')" placement="top-start">
+              <div class="explain text-ellipsis">
+                {{ $t("总访问量") }}
+              </div>
+            </el-tooltip>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import cordTop from "./header.vue";
+
+/* 访客统计模块 */
+export default {
+  name: "visitorStatistics",
+  components: { cordTop },
+  data() {
+    return {
+      visitor: null, //访客
+      visits: null, //访问量
+    };
+  },
+  created() {
+    this.siteid = JSON.parse(sessionStorage.getItem("active_account")).siteid;
+    this.getCardData("访客");
+    this.getCardData("访问量");
+  },
+  methods: {
+    getCardData(type) {
+      this.$api
+        .requested({
+          id: 2025010214243003,
+          content: {
+            siteid: this.siteid,
+            nocache: true,
+            type,
+          },
+        })
+        .then((res) => {
+          if (res.code != 1) return;
+          if (type == "访客") {
+            this.visitor = res.data;
+          } else {
+            this.visits = res.data;
+          }
+        });
+    },
+  },
+};
+</script>
+
+<style scoped>
+.text-ellipsis {
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  -o-text-overflow: ellipsis;
+}
+
+/* 卡片 */
+.cards {
+  display: flex;
+  justify-content: space-between;
+}
+
+.card {
+  width: 49%;
+  background: #ffffff;
+  box-sizing: border-box;
+  box-shadow: 0px 1px 6px 1px rgba(0, 0, 0, 0.16);
+  border-radius: 10px;
+  padding: 20px;
+}
+
+.card .title {
+  font-family: Microsoft YaHei, Microsoft YaHei;
+  font-weight: bold;
+  font-size: 20px;
+  color: #333333;
+  line-height: 24px;
+}
+
+.card .content {
+  display: flex;
+  justify-content: space-between;
+  margin-top: 20px;
+}
+
+.card .content .item {
+  width: 20%;
+  flex-shrink: 0;
+  box-sizing: border-box;
+  padding-right: 10px;
+}
+
+.card .content .item .data {
+  font-family: Microsoft YaHei, Microsoft YaHei;
+  font-size: 26px;
+  color: #333333;
+  line-height: 24px;
+}
+.card .content .item .explain {
+  font-family: Microsoft YaHei, Microsoft YaHei;
+  font-size: 16px;
+  color: #333333;
+  line-height: 24px;
+  margin-top: 16px;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  -o-text-overflow: ellipsis;
+}
+</style>

+ 19 - 13
src/router/WebsiteManagement.js

@@ -1,5 +1,4 @@
-const WebsiteManagement = [
-    {
+const WebsiteManagement = [{
         path: '/consultManage',
         name: 'consultManage',
         meta: {
@@ -28,17 +27,15 @@ const WebsiteManagement = [
             keeproute: true,
         },
         component: () => import('@/WebsiteManagement/serviceAppointMag/index'),
-        children:[
-            {
-                path: '/serviceAppointMagDetail',
-                name: 'serviceAppointMag',
-                meta: {
-                    title: '服务预约管理详情',
-                    ast_nav: true,
-                },
-                component: () => import(/* webpackChunkName: "about" */ '@/WebsiteManagement/serviceAppointMag/detail/index'),
+        children: [{
+            path: '/serviceAppointMagDetail',
+            name: 'serviceAppointMag',
+            meta: {
+                title: '服务预约管理详情',
+                ast_nav: true,
             },
-        ]
+            component: () => import( /* webpackChunkName: "about" */ '@/WebsiteManagement/serviceAppointMag/detail/index'),
+        }, ]
     },
     {
         path: '/marketproductMag',
@@ -49,6 +46,15 @@ const WebsiteManagement = [
             keeproute: true,
         },
         component: () => import('@/WebsiteManagement/marketproductMag/index')
+    }, {
+        path: '/dataStatistics',
+        name: 'dataStatistics',
+        meta: {
+            title: '数据统计',
+            ast_nav: true,
+            keeproute: true,
+        },
+        component: () => import('@/WebsiteManagement/dataStatistics/index')
     },
 ];
-export default WebsiteManagement;
+export default WebsiteManagement;