From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目

---
 src/views/mp/statistics/index.vue |  357 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 357 insertions(+), 0 deletions(-)

diff --git a/src/views/mp/statistics/index.vue b/src/views/mp/statistics/index.vue
new file mode 100644
index 0000000..7b29a69
--- /dev/null
+++ b/src/views/mp/statistics/index.vue
@@ -0,0 +1,357 @@
+<template>
+  <!-- 鎼滅储宸ヤ綔鏍� -->
+  <ContentWrap>
+    <el-form class="-mb-15px" ref="queryForm" :inline="true" label-width="68px">
+      <el-form-item label="鍏紬鍙�" prop="accountId">
+        <WxAccountSelect @change="onAccountChanged" />
+      </el-form-item>
+      <el-form-item label="鏃堕棿鑼冨洿" prop="dateRange">
+        <el-date-picker
+          v-model="dateRange"
+          type="daterange"
+          start-placeholder="寮�濮嬫棩鏈�"
+          end-placeholder="缁撴潫鏃ユ湡"
+          :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
+          @change="getSummary"
+          class="!w-240px"
+        />
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <!-- 鍥捐〃 -->
+  <ContentWrap>
+    <el-row>
+      <el-col :span="12" class="card-box">
+        <el-card>
+          <template #header>
+            <div>
+              <span>鐢ㄦ埛澧炲噺鏁版嵁</span>
+            </div>
+          </template>
+          <Echart :options="userSummaryOption" :height="420" />
+        </el-card>
+      </el-col>
+      <el-col :span="12" class="card-box">
+        <el-card>
+          <template #header>
+            <div>
+              <span>绱鐢ㄦ埛鏁版嵁</span>
+            </div>
+          </template>
+          <Echart :options="userCumulateOption" :height="420" />
+        </el-card>
+      </el-col>
+      <el-col :span="12" class="card-box">
+        <el-card>
+          <template #header>
+            <div>
+              <span>娑堟伅姒傚喌鏁版嵁</span>
+            </div>
+          </template>
+          <Echart :options="upstreamMessageOption" :height="420" />
+        </el-card>
+      </el-col>
+      <el-col :span="12" class="card-box">
+        <el-card>
+          <template #header>
+            <div>
+              <span>鎺ュ彛鍒嗘瀽鏁版嵁</span>
+            </div>
+          </template>
+          <Echart :options="interfaceSummaryOption" :height="420" />
+        </el-card>
+      </el-col>
+    </el-row>
+  </ContentWrap>
+</template>
+
+<script lang="ts" setup>
+import { formatDate, addTime, betweenDay, beginOfDay, endOfDay } from '@/utils/formatTime'
+import * as StatisticsApi from '@/api/mp/statistics'
+import WxAccountSelect from '@/views/mp/components/wx-account-select'
+
+defineOptions({ name: 'MpStatistics' })
+
+const message = useMessage() // 娑堟伅寮圭獥
+
+// 榛樿寮�濮嬫椂闂存槸褰撳墠鏃ユ湡-7锛岀粨鏉熸椂闂存槸褰撳墠鏃ユ湡-1
+const dateRange = ref([
+  beginOfDay(new Date(new Date().getTime() - 3600 * 1000 * 24 * 7)),
+  endOfDay(new Date(new Date().getTime() - 3600 * 1000 * 24))
+])
+const accountId = ref(-1) // 閫変腑鐨勫叕浼楀彿缂栧彿
+
+const xAxisDate = ref([] as any[]) // X 杞寸殑鏃ユ湡鑼冨洿
+// 鐢ㄦ埛澧炲噺鏁版嵁鍥捐〃閰嶇疆椤�
+const userSummaryOption = reactive({
+  color: ['#67C23A', '#E5323E'],
+  legend: {
+    data: ['鏂板鐢ㄦ埛', '鍙栨秷鍏虫敞鐨勭敤鎴�']
+  },
+  tooltip: {},
+  xAxis: {
+    data: [] as any[] // X 杞寸殑鏃ユ湡鑼冨洿
+  },
+  yAxis: {
+    minInterval: 1
+  },
+  series: [
+    {
+      name: '鏂板鐢ㄦ埛',
+      type: 'bar' as const,
+      label: {
+        show: true
+      },
+      barGap: 0,
+      data: [] as any[] // 鏂板鐢ㄦ埛鐨勬暟鎹�
+    },
+    {
+      name: '鍙栨秷鍏虫敞鐨勭敤鎴�',
+      type: 'bar' as const,
+      label: {
+        show: true
+      },
+      data: [] as any[] // 鍙栨秷鍏虫敞鐨勭敤鎴风殑鏁版嵁
+    }
+  ]
+})
+// 绱鐢ㄦ埛鏁版嵁鍥捐〃閰嶇疆椤�
+const userCumulateOption = reactive({
+  legend: {
+    data: ['绱鐢ㄦ埛閲�']
+  },
+  xAxis: {
+    type: 'category' as const,
+    data: [] as any[]
+  },
+  yAxis: {
+    minInterval: 1
+  },
+  series: [
+    {
+      name: '绱鐢ㄦ埛閲�',
+      data: [] as any[], // 绱鐢ㄦ埛閲忕殑鏁版嵁
+      type: 'line' as const,
+      smooth: true,
+      label: {
+        show: true
+      }
+    }
+  ]
+})
+// 娑堟伅鍙戦�佹鍐垫暟鎹浘琛ㄩ厤缃」
+const upstreamMessageOption = reactive({
+  color: ['#67C23A', '#E5323E'],
+  legend: {
+    data: ['鐢ㄦ埛鍙戦�佷汉鏁�', '鐢ㄦ埛鍙戦�佹潯鏁�']
+  },
+  tooltip: {},
+  xAxis: {
+    data: [] as any[] // X 杞寸殑鏃ユ湡鑼冨洿
+  },
+  yAxis: {
+    minInterval: 1
+  },
+  series: [
+    {
+      name: '鐢ㄦ埛鍙戦�佷汉鏁�',
+      type: 'line' as const,
+      smooth: true,
+      label: {
+        show: true
+      },
+      data: [] as any[] // 鐢ㄦ埛鍙戦�佷汉鏁扮殑鏁版嵁
+    },
+    {
+      name: '鐢ㄦ埛鍙戦�佹潯鏁�',
+      type: 'line' as const,
+      smooth: true,
+      label: {
+        show: true
+      },
+      data: [] as any[] // 鐢ㄦ埛鍙戦�佹潯鏁扮殑鏁版嵁
+    }
+  ]
+})
+// 鎺ュ彛鍒嗘瀽鍐垫暟鎹浘琛ㄩ厤缃」
+const interfaceSummaryOption = reactive({
+  color: ['#67C23A', '#E5323E', '#E6A23C', '#409EFF'],
+  legend: {
+    data: ['琚姩鍥炲鐢ㄦ埛娑堟伅鐨勬鏁�', '澶辫触娆℃暟', '鏈�澶ц�楁椂', '鎬昏�楁椂']
+  },
+  tooltip: {},
+  xAxis: {
+    data: [] as any[] // X 杞寸殑鏃ユ湡鑼冨洿
+  },
+  yAxis: {},
+  series: [
+    {
+      name: '琚姩鍥炲鐢ㄦ埛娑堟伅鐨勬鏁�',
+      type: 'bar' as const,
+      label: {
+        show: true
+      },
+      barGap: 0,
+      data: [] as any[] // 琚姩鍥炲鐢ㄦ埛娑堟伅鐨勬鏁扮殑鏁版嵁
+    },
+    {
+      name: '澶辫触娆℃暟',
+      type: 'bar' as const,
+      label: {
+        show: true
+      },
+      data: [] as any[] // 澶辫触娆℃暟鐨勬暟鎹�
+    },
+    {
+      name: '鏈�澶ц�楁椂',
+      type: 'bar' as const,
+      label: {
+        show: true
+      },
+      data: [] as any[] // 鏈�澶ц�楁椂鐨勬暟鎹�
+    },
+    {
+      name: '鎬昏�楁椂',
+      type: 'bar' as const,
+      label: {
+        show: true
+      },
+      data: [] as any[] // 鎬昏�楁椂鐨勬暟鎹�
+    }
+  ]
+})
+
+/** 渚﹀惉鍏紬鍙峰彉鍖� **/
+const onAccountChanged = (id: number) => {
+  accountId.value = id
+  getSummary()
+}
+
+/** 鍔犺浇鏁版嵁 */
+const getSummary = () => {
+  // 濡傛灉娌℃湁閫変腑鍏紬鍙疯处鍙凤紝鍒欒繘琛屾彁绀恒��
+  if (!accountId) {
+    message.error('鏈�変腑鍏紬鍙凤紝鏃犳硶缁熻鏁版嵁')
+    return false
+  }
+  // 蹇呴』閫夋嫨 7 澶╁唴锛屽洜涓哄叕浼楀彿鏈夋椂闂磋法搴﹂檺鍒朵负 7
+  if (betweenDay(dateRange.value[0], dateRange.value[1]) >= 7) {
+    message.error('鏃堕棿闂撮殧 7 澶╀互鍐咃紝璇烽噸鏂伴�夋嫨')
+    return false
+  }
+  // 娓呯┖妯潗鏍囨棩鏈�
+  xAxisDate.value = []
+  // 妯潗鏍囧姞杞芥棩鏈熸暟鎹�
+  const days = betweenDay(dateRange.value[0], dateRange.value[1]) // 鐩稿樊澶╂暟
+  for (let i = 0; i <= days; i++) {
+    xAxisDate.value.push(
+      formatDate(addTime(dateRange.value[0], 3600 * 1000 * 24 * i), 'YYYY-MM-DD')
+    )
+  }
+  // 鍒濆鍖栧浘琛�
+  initUserSummaryChart()
+  initUserCumulateChart()
+  initUpstreamMessageChart()
+  interfaceSummaryChart()
+}
+
+/** 鐢ㄦ埛澧炲噺鏁版嵁 */
+const initUserSummaryChart = async () => {
+  userSummaryOption.xAxis.data = []
+  userSummaryOption.series[0].data = []
+  userSummaryOption.series[1].data = []
+  try {
+    // 鐢ㄦ埛澧炲噺鏁版嵁
+    const data = await StatisticsApi.getUserSummary({
+      accountId: accountId.value,
+      date: [formatDate(dateRange.value[0]), formatDate(dateRange.value[1])]
+    })
+    // 妯潗鏍�
+    userSummaryOption.xAxis.data = xAxisDate.value
+    // 澶勭悊鏁版嵁
+    xAxisDate.value.forEach((date, index) => {
+      data.forEach((item) => {
+        // 鍖归厤鏃ユ湡
+        const refDate = formatDate(new Date(item.refDate), 'YYYY-MM-DD')
+        if (refDate.indexOf(date) === -1) {
+          return
+        }
+        // 璁剧疆鏁版嵁鍒板搴旂殑浣嶇疆
+        userSummaryOption.series[0].data[index] = item.newUser
+        userSummaryOption.series[1].data[index] = item.cancelUser
+      })
+    })
+  } catch {
+    //
+  }
+}
+
+/** 绱鐢ㄦ埛鏁版嵁 */
+const initUserCumulateChart = async () => {
+  userCumulateOption.xAxis.data = []
+  userCumulateOption.series[0].data = []
+  // 鍙戣捣璇锋眰
+  try {
+    const data = await StatisticsApi.getUserCumulate({
+      accountId: accountId.value,
+      date: [formatDate(dateRange.value[0]), formatDate(dateRange.value[1])]
+    })
+    userCumulateOption.xAxis.data = xAxisDate.value
+    // 澶勭悊鏁版嵁
+    data.forEach((item, index) => {
+      userCumulateOption.series[0].data[index] = item.cumulateUser
+    })
+  } catch {
+    //
+  }
+}
+
+/** 娑堟伅姒傚喌鏁版嵁 */
+const initUpstreamMessageChart = async () => {
+  upstreamMessageOption.xAxis.data = []
+  upstreamMessageOption.series[0].data = []
+  upstreamMessageOption.series[1].data = []
+  // 鍙戣捣璇锋眰
+  try {
+    const data = await StatisticsApi.getUpstreamMessage({
+      accountId: accountId.value,
+      date: [formatDate(dateRange.value[0]), formatDate(dateRange.value[1])]
+    })
+    upstreamMessageOption.xAxis.data = xAxisDate.value
+    // 澶勭悊鏁版嵁
+    data.forEach((item, index) => {
+      upstreamMessageOption.series[0].data[index] = item.messageUser
+      upstreamMessageOption.series[1].data[index] = item.messageCount
+    })
+  } catch {
+    //
+  }
+}
+
+/** 鎺ュ彛鍒嗘瀽鏁版嵁 */
+const interfaceSummaryChart = async () => {
+  interfaceSummaryOption.xAxis.data = []
+  interfaceSummaryOption.series[0].data = []
+  interfaceSummaryOption.series[1].data = []
+  interfaceSummaryOption.series[2].data = []
+  interfaceSummaryOption.series[3].data = []
+  // 鍙戣捣璇锋眰
+  try {
+    const data = await StatisticsApi.getInterfaceSummary({
+      accountId: accountId.value,
+      date: [formatDate(dateRange.value[0]), formatDate(dateRange.value[1])]
+    })
+    interfaceSummaryOption.xAxis.data = xAxisDate.value
+    // 澶勭悊鏁版嵁
+    data.forEach((item, index) => {
+      interfaceSummaryOption.series[0].data[index] = item.callbackCount
+      interfaceSummaryOption.series[1].data[index] = item.failCount
+      interfaceSummaryOption.series[2].data[index] = item.maxTimeCost
+      interfaceSummaryOption.series[3].data[index] = item.totalTimeCost
+    })
+  } catch {
+    //
+  }
+}
+</script>

--
Gitblit v1.8.0