Browse Source

Merge branch 'mergeBranch' into redUrgent

qymljy 8 months ago
parent
commit
172eb8c3f6

+ 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>

+ 0 - 108
src/optionSystem/selectOption/add copy.vue

@@ -1,108 +0,0 @@
-<template>
-  <div style="display: inline">
-    <el-dropdown @command="onShow">
-      <el-button type="primary" size="small"> {{ $t("阀门选型") }} </el-button>
-      <el-dropdown-menu slot="dropdown">
-        <el-dropdown-item
-          :command="item.value"
-          v-for="item in valvetypeList"
-          :key="item.value"
-          >{{ $t(item.remarks) }}</el-dropdown-item
-        >
-      </el-dropdown-menu>
-    </el-dropdown>
-    <el-dialog
-      custom-class="custom-select-option_class"
-      :visible.sync="drawer"
-      width="1100px"
-      append-to-body
-      :show-close="false"
-    >
-      <component
-        :position="position"
-        @close="drawer = false"
-        :is="formComponent"
-        v-on="$listeners"
-      ></component>
-    </el-dialog>
-  </div>
-</template>
-    
-<script>
-import { mapGetters } from "vuex";
-export default {
-  props: ["position"],
-  data() {
-    return {
-      drawer: false,
-      type: "",
-      valvetypeList: [],
-    };
-  },
-  provide() {
-    return {
-      valvetype: () => this.type,
-    };
-  },
-  computed: {
-    ...mapGetters({
-      loading: "loading",
-    }),
-
-    formComponent() {
-      switch (this.type) {
-        case "蝶阀":
-          return () =>
-            import("@/optionSystem/selectOption/components/DieFa.vue");
-          break;
-        default:
-          break;
-      }
-    },
-  },
-  methods: {
-    onShow(type) {
-      this.type = type;
-      this.drawer = true;
-    },
-    onSubmit() {
-      this.$refs.target.$refs["form"].validate(async (valid) => {
-        if (!valid) return false;
-        this.$refs.target.onSubmit(() => {
-          this.$refs.target.refresh();
-          this.drawer = false;
-        });
-      });
-    },
-    optionList() {
-      this.$store.dispatch("optiontypeselect", "valvetype").then((res) => {
-        this.valvetypeList = res.data;
-        console.log(this.valvetypeList, "阀门类型");
-      });
-    },
-  },
-  created() {
-    this.optionList();
-  },
-};
-</script>
-<style scoped>
-.dialog-footer {
-  margin-top: 32px;
-  text-align: center;
-}
-/deep/.el-dialog__header {
-  display: none !important;
-}
-/deep/.el-dialog__body {
-  padding-top: 0 !important;
-}
-</style>
-<style>
-@media screen and (max-width: 1800px) {
-  .custom-select-option_class.el-dialog {
-    margin-top: 10px !important;
-  }
-}
-</style>
-    

+ 56 - 41
src/optionSystem/selectOption/components/DieFa.vue

@@ -222,31 +222,33 @@
             ></MySelect>
           </div>
         </div>
-        <div
-          class="option-line"
-          v-if="guangtouParam.content.where.drivetype == '电动'"
-        >
-          <div class="item">
-            <div class="label">{{ $t("品牌") }}:</div>
-            <MySelect
-              @click="
-                Search('excelParam', 'actuatorbrand');
-                calcTableHieght('excelRef');
-              "
-              :disabled="!excelParam.content.where.actuatordrivetype"
-              :options="actuatorbrand"
-              v-model="excelParam.content.where.actuatorbrand"
-            ></MySelect>
+        <div v-if="actuatorbrand.length">
+          <div
+            class="option-line"
+            v-if="guangtouParam.content.where.drivetype == '电动'"
+          >
+            <div class="item">
+              <div class="label">{{ $t("品牌") }}:</div>
+              <MySelect
+                @click="
+                  Search('excelParam', 'actuatorbrand');
+                  calcTableHieght('excelRef');
+                "
+                :disabled="!excelParam.content.where.actuatordrivetype"
+                :options="actuatorbrand"
+                v-model="excelParam.content.where.actuatorbrand"
+              ></MySelect>
+            </div>
           </div>
-        </div>
-        <div class="option-line" v-else>
-          <div class="item">
-            <div class="label">{{ $t("品牌") }}:</div>
-            <MySelect
-              @click="Search('excelParam', 'actuatorbrand')"
-              :options="actuatorbrand"
-              v-model="excelParam.content.where.actuatorbrand"
-            ></MySelect>
+          <div class="option-line" v-else>
+            <div class="item">
+              <div class="label">{{ $t("品牌") }}:</div>
+              <MySelect
+                @click="Search('excelParam', 'actuatorbrand')"
+                :options="actuatorbrand"
+                v-model="excelParam.content.where.actuatorbrand"
+              ></MySelect>
+            </div>
           </div>
         </div>
         <div
@@ -319,7 +321,6 @@
             ></MySelect>
           </div>
         </div>
-
         <div
           class="option-line"
           v-show="guangtouParam.content.where.drivetype == '气动'"
@@ -382,9 +383,8 @@
                 size="mini"
                 @click="selectTarget(scope.data, '执行器')"
                 :disabled="
-                  loading ||
-                  (guangtouParam.content.where.drivetype == '电动' &&
-                    resultArr.length == 2)
+                  guangtouParam.content.where.drivetype == '电动' &&
+                  resultArr.length == 2
                 "
                 >{{ $t("选择") }}</el-button
               >
@@ -421,9 +421,8 @@
               size="mini"
               @click="selectTarget(scope.data, '执行器')"
               :disabled="
-                loading ||
-                (guangtouParam.content.where.drivetype == '电动' &&
-                  resultArr.length == 2)
+                guangtouParam.content.where.drivetype == '电动' &&
+                resultArr.length == 2
               "
               >{{ $t("选择") }}</el-button
             >
@@ -535,7 +534,9 @@
                     guangtouParam.content.where.drivetype == "电动" &&
                     resultArr[1] &&
                     resultArr[1].gearboxname
-                      ? ` + ${$t('减速箱')}:${resultArr[1] && resultArr[1].gearboxname}`
+                      ? ` + ${$t("减速箱")}:${
+                          resultArr[1] && resultArr[1].gearboxname
+                        }`
                       : ""
                   }}</span
                 >
@@ -721,14 +722,18 @@
             </td>
           </tr>
           <tr>
-            <td class="title">{{ $t(product.itemno ? "牌价" : "最低经销价") }}</td>
+            <td class="title">
+              {{ $t(product.itemno ? "牌价" : "最低经销价") }}
+            </td>
             <td class="text2">
               ¥{{
                 Object.keys(product).length
                   ? tool.formatAmount(product.price, 2)
                   : "xxxxxx"
               }}
-                <div style="color:#1C1919;font-weight: normal;font-size: 12px;">*{{$t('非标准产品,当前价格仅供参考')}}!</div>
+              <div style="color: #1c1919; font-weight: normal; font-size: 12px">
+                *{{ $t("非标准产品,当前价格仅供参考") }}!
+              </div>
             </td>
           </tr>
         </table>
@@ -755,7 +760,9 @@
           @click="onSubmit"
           class="normal-btn-width"
           v-if="active == 4"
-          >{{ $t(position == "单独选型" ? "保存选型单" : "确认添加") }}</el-button
+          >{{
+            $t(position == "单独选型" ? "保存选型单" : "确认添加")
+          }}</el-button
         >
       </div>
     </div>
@@ -984,7 +991,8 @@ export default {
             whereKeys[i].indexOf("maxrounddiameter") != -1 ||
             whereKeys[i].indexOf("maxsquarewidth") != -1 ||
             whereKeys[i].indexOf("torque") != -1 ||
-            whereKeys[i].indexOf("drivetype") != -1 || whereKeys[i].indexOf('caliber') != -1
+            whereKeys[i].indexOf("drivetype") != -1 ||
+            whereKeys[i].indexOf("caliber") != -1
           )
             continue;
           this[type].content.where[whereKeys[i]] = "";
@@ -1144,11 +1152,17 @@ export default {
       }
     },
     async onSubmit() {
-      this.$confirm(this.$t(this.position == '单独选型' ? '是否确认保存':"确认加入单据吗") + "?", this.$t("提示"), {
-        confirmButtonText: this.$t("确定"),
-        cancelButtonText: this.$t("取消"),
-        type: "warning",
-      })
+      this.$confirm(
+        this.$t(
+          this.position == "单独选型" ? "是否确认保存" : "确认加入单据吗"
+        ) + "?",
+        this.$t("提示"),
+        {
+          confirmButtonText: this.$t("确定"),
+          cancelButtonText: this.$t("取消"),
+          type: "warning",
+        }
+      )
         .then(async () => {
           let mainvalve = Object.keys(this.guangtouParam.content.where)
             .filter((v) => v.indexOf("condition") == -1)
@@ -1202,6 +1216,7 @@ export default {
         this.excelParam.content.where.flh = data.flh;
         this.excelParam.content.where.maxsquarewidth = data.maxsquarewidth;
         this.excelParam.content.where.maxrounddiameter = data.maxrounddiameter;
+        this.actuatorbrand = [];
         if (this.guangtouParam.content.where.drivetype == "电动") {
           this.excelParam.content.where.caliber = this.resultArr[0].caliber;
         }

+ 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;

+ 3 - 0
src/views/mediaStatistics/modules/salesfunnel.vue

@@ -142,6 +142,9 @@
           <div v-else-if="scope.column.columnname == 'scale'">
             <span>{{scope.column.data[[scope.column.columnname]]?scope.column.data[[scope.column.columnname]] + scope.column.data.unitname:'--'}}</span>
           </div>
+          <div v-else-if="scope.column.columnname == 'address'">
+            <span>{{scope.column.data.province?scope.column.data.province + scope.column.data.city + scope.column.data.county + scope.column.data[[scope.column.columnname]]:'--'}}</span>
+          </div>
           <div v-else>
             {{scope.column.data[[scope.column.columnname]]?scope.column.data[[scope.column.columnname]]:'--'}}
           </div>