Procházet zdrojové kódy

feat: 活动统计弹窗提交

xyh před 5 měsíci
rodič
revize
710841f234

+ 38 - 7
src/api/points/rules_api.js

@@ -1,6 +1,4 @@
 import request from '@/utils/request'
-
-
 /**
  * 获取活动列表的函数
  * @param {Object} query - 查询参数对象,包含查询条件
@@ -33,9 +31,42 @@ export function getActivityList(query) {
       resolve(res)
     }, 1000);
   });
-  // return request({
-  //   url: '/ylxAlarm/getAlarmList', // 请求的API地址
-  //   method: 'get', // 请求方法为GET
-  //   params: query // 将查询参数作为请求参数发送
-  // })
+}
+
+/**
+ * 获取单一活动统计信息
+ * @param {Object} query - 查询参数对象,包含查询条件
+ */
+export function getActivityStatistics(query) {
+  let res = {
+    "data": {
+      "basicInfo": {
+        name: "2029签到活动第一期",
+        type: "活动任务",
+        time: "2026-03-01 - 2027-03-01",
+        city: "太原"
+      },
+      "overviewData": {
+        totalPeople: 1280,
+        completedPeople: 885,
+        completedTimes: 3420,
+        issuedPoints: 46800
+      },
+      "detailData": [
+        {taskName: "完成订单", completedPeople: 885, completedTimes: 3420, issuedPoints: 46800},
+        {taskName: "充值任务", completedPeople: 885, completedTimes: 3420, issuedPoints: 46800},
+        {taskName: "分享服务号", completedPeople: 885, completedTimes: 3420, issuedPoints: 46800},
+        {taskName: "浏览动态", completedPeople: 885, completedTimes: 3420, issuedPoints: 46800},
+        {taskName: "浏览商户", completedPeople: 885, completedTimes: 3420, issuedPoints: 46800}
+      ]
+    },
+    "code": 200,
+    "msg": "查询成功"
+  }
+  return new Promise((resolve, reject) => {
+    // 模拟网络延迟 1000ms
+    setTimeout(() => {
+      resolve(res)
+    }, 1000);
+  });
 }

+ 312 - 0
src/views/pointsManagement/pointsRules/compontents/Activity_statistics.vue

@@ -0,0 +1,312 @@
+<template>
+  <div>
+    <el-drawer
+      title="活动统计"
+      :visible.sync="drawerVisible"
+      direction="rtl"
+      size="50%"
+      :destroy-on-close="true"
+    >
+      <div class="drawer-content">
+        <el-card class="activity-info" shadow="hover">
+          <div class="refresh-btn-container">
+            <el-button size="mini" circle icon="el-icon-refresh" @click="handleRefresh()" :loading="loading" />
+          </div>
+          <div class="info-item">
+            <i class="el-icon-document info-icon"></i>
+            <span class="info-label">活动名称:</span>
+            <span class="info-value">
+              <el-skeleton v-if="loading" :rows="1" animated />
+              <template v-else>{{ basicInfo.name || '--' }}</template>
+            </span>
+          </div>
+          <div class="info-item">
+            <i class="el-icon-menu info-icon"></i>
+            <span class="info-label">活动类型:</span>
+            <span class="info-value">
+              <el-skeleton v-if="loading" :rows="1" animated />
+              <template v-else>{{ basicInfo.type || '--'  }}</template>
+            </span>
+          </div>
+          <div class="info-item">
+            <i class="el-icon-date info-icon"></i>
+            <span class="info-label">活动时间:</span>
+            <span class="info-value">
+              <el-skeleton v-if="loading" :rows="1" animated />
+              <template v-else>{{ basicInfo.time || '--' }}</template>
+            </span>
+          </div>
+          <div class="info-item">
+            <i class="el-icon-position info-icon"></i>
+            <span class="info-label">活动城市:</span>
+            <span class="info-value">
+              <el-skeleton v-if="loading" :rows="1" animated />
+              <template v-else>{{ basicInfo.city || '--'  }}</template>
+            </span>
+          </div>
+        </el-card>
+
+        <div class="data-overview">
+          <h3>数据总览</h3>
+          <el-row :gutter="20">
+            <el-col :span="6">
+              <el-card class="overview-card card-1" shadow="hover">
+                <i class="el-icon-user card-icon"></i>
+                <div class="overview-label">参与总人数</div>
+                <div class="overview-value">
+                  <el-skeleton v-if="loading" :rows="1" animated />
+                  <template v-else>{{ overviewData.totalPeople || '--'  }}</template>
+                </div>
+              </el-card>
+            </el-col>
+            <el-col :span="6">
+              <el-card class="overview-card card-2" shadow="hover">
+                <i class="el-icon-check card-icon"></i>
+                <div class="overview-label">完成总人数</div>
+                <div class="overview-value">
+                  <el-skeleton v-if="loading" :rows="1" animated />
+                  <template v-else>{{ overviewData.completedPeople || '--'  }}</template>
+                </div>
+              </el-card>
+            </el-col>
+            <el-col :span="6">
+              <el-card class="overview-card card-3" shadow="hover">
+                <i class="el-icon-s-order card-icon"></i>
+                <div class="overview-label">任务完成人次</div>
+                <div class="overview-value">
+                  <el-skeleton v-if="loading" :rows="1" animated />
+                  <template v-else>{{ overviewData.completedTimes || '--'  }}</template>
+                </div>
+              </el-card>
+            </el-col>
+            <el-col :span="6">
+              <el-card class="overview-card card-4" shadow="hover">
+                <i class="el-icon-coin card-icon"></i>
+                <div class="overview-label">已发放积分</div>
+                <div class="overview-value">
+                  <el-skeleton v-if="loading" :rows="1" animated />
+                  <template v-else>{{ overviewData.issuedPoints || '--'  }}</template>
+                </div>
+              </el-card>
+            </el-col>
+          </el-row>
+        </div>
+
+        <div class="data-detail">
+          <h3>数据详情</h3>
+          <el-card shadow="hover">
+            <el-table v-if="!loading" :data="detailData" style="width: 100%">
+              <el-table-column prop="taskName" label="任务名称" width="180"></el-table-column>
+              <el-table-column prop="completedPeople" label="完成人数" width="120" align="center"></el-table-column>
+              <el-table-column prop="completedTimes" label="完成人次" width="120" align="center"></el-table-column>
+              <el-table-column prop="issuedPoints" label="发放积分" align="center"></el-table-column>
+            </el-table>
+            <el-skeleton v-else :rows="5" animated style="width: 100%"></el-skeleton>
+          </el-card>
+        </div>
+      </div>
+    </el-drawer>
+  </div>
+</template>
+
+<script>
+import { getActivityStatistics } from "@/api/points/rules_api";
+export default {
+  name: "Activity_statistics",
+  data() {
+    return {
+      drawerVisible: false,
+      currentId:'',
+      loading: false,
+      basicInfo:{},
+      overviewData: {},
+      detailData: []
+    }
+  },
+  methods: {
+    openDrawer(row) {
+      this.basicInfo = {};
+      this.overviewData = {};
+      this.detailData = [];
+      this.drawerVisible = true;
+      this.currentId = row.id;
+      this.loading = true;
+      this.getActivityInfo(this.currentId)
+    },
+    async getActivityInfo(id) {
+      try {
+        const res = await getActivityStatistics(id)
+        if (res.data) {
+          let {basicInfo, overviewData, detailData} = res.data;
+          this.basicInfo = basicInfo || {};
+          this.overviewData = overviewData || {};
+          this.detailData = detailData || [];
+        }
+      } catch (error) {
+        this.$message.error('获取数据失败,请稍后重试');
+      } finally {
+        this.loading = false;
+      }
+    },
+    async handleRefresh() {
+      this.loading = true;
+      try {
+        await this.getActivityInfo(this.currentId)
+        this.$message.success('数据已刷新');
+      } finally {
+        this.loading = false;
+      }
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.drawer-content {
+  padding: 0 20px;
+}
+
+.refresh-btn-container {
+  position: absolute;
+  top: 15px;
+  right: 15px;
+  z-index: 1;
+
+  .refresh-btn {
+    margin-right: 0;
+    padding: 4px;
+    font-size: 16px;
+    color: #909399;
+
+    &:hover {
+      color: #409eff;
+    }
+  }
+}
+
+.activity-info {
+  margin-bottom: 20px;
+  position: relative;
+
+  .info-item {
+    margin-bottom: 12px;
+    display: flex;
+    align-items: center;
+
+    .info-icon {
+      margin-right: 10px;
+      color: #409eff;
+      font-size: 16px;
+    }
+
+    .info-label {
+      font-weight: 500;
+      width: 80px;
+      color: #606266;
+    }
+
+    .info-value {
+      flex: 1;
+      color: #303133;
+      font-size: 14px;
+    }
+  }
+}
+
+.data-overview {
+  margin-bottom: 20px;
+
+  h3 {
+    font-size: 14px;
+    font-weight: 600;
+    margin-bottom: 15px;
+    color: #303133;
+  }
+
+  .overview-card {
+    text-align: center;
+    transition: all 0.3s ease;
+    position: relative;
+    overflow: hidden;
+
+    &:hover {
+      transform: translateY(-5px);
+      box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
+    }
+
+    .card-icon {
+      font-size: 24px;
+      margin-bottom: 10px;
+    }
+
+    .overview-label {
+      font-size: 12px;
+      color: #909399;
+      margin-bottom: 5px;
+    }
+
+    .overview-value {
+      font-size: 20px;
+      font-weight: 600;
+      color: #303133;
+    }
+
+    &.card-1 {
+      background-color: #ecf5ff;
+      .card-icon {
+        color: #409eff;
+      }
+    }
+
+    &.card-2 {
+      background-color: #f0f9eb;
+      .card-icon {
+        color: #67c23a;
+      }
+    }
+
+    &.card-3 {
+      background-color: #fdf6ec;
+      .card-icon {
+        color: #e6a23c;
+      }
+    }
+
+    &.card-4 {
+      background-color: #f5f0ff;
+      .card-icon {
+        color: #909399;
+      }
+    }
+  }
+}
+
+.data-detail {
+  h3 {
+    font-size: 14px;
+    font-weight: 600;
+    margin-bottom: 15px;
+    color: #303133;
+  }
+
+  .el-table {
+    width: 100%;
+  }
+
+  .el-table__header-wrapper {
+    background-color: #f5f7fa;
+  }
+
+  .el-table th {
+    font-weight: 600;
+  }
+
+  .el-table tr {
+    transition: background-color 0.3s ease;
+  }
+
+  .el-table tr:hover {
+    background-color: #f5f7fa !important;
+  }
+}
+</style>

+ 2 - 2
src/views/pointsManagement/pointsRules/Expiration_points.vue → src/views/pointsManagement/pointsRules/compontents/Expiration_points.vue

@@ -5,7 +5,7 @@ export default {
     return {
       validityPeriod: false,
       tabList: [],
-      activeTab: "sign",
+      activeTab: "",
       radio: 3, // 3: 永久有效, 6: 逐笔过期, 9: 逐年过期
       days: "",
       years: ""
@@ -15,7 +15,7 @@ export default {
     clickSet(row) {
       this.validityPeriod = true;
       this.tabList = row || this.tabList;
-      this.activeTab = row && row.length > 0 ? row[0].value : this.tabList[0].value;
+      this.activeTab = row && row.length > 0 ? row[0].value : '';
     },
     handleClose() {
       this.validityPeriod = false;

+ 8 - 4
src/views/pointsManagement/pointsRules/index.vue

@@ -68,8 +68,10 @@
       :limit.sync="queryParams.pageSize"
       @pagination="getList"
     />
-
+    <!-- 积分时效 -->
     <expiration-points ref="expirationPointsRef" />
+    <!-- 活动统计 -->
+    <activity-statistics ref="activityStatisticsRef" />
   </div>
 </template>
 
@@ -77,13 +79,15 @@
 import { getActivityList } from "@/api/points/rules_api";
 import tableCompontent from "@/components/tableCompontent/index.vue";
 import listMixin from '@/utils/listMixin';
-import ExpirationPoints from "./Expiration_points.vue";
+import ExpirationPoints from "./compontents/Expiration_points.vue";
+import ActivityStatistics from "./compontents/Activity_statistics.vue";
 export default {
   name: "pointsRules",
   mixins: [listMixin],
   components: {
     tableCompontent,
-    ExpirationPoints
+    ExpirationPoints,
+    ActivityStatistics
   },
   data() {
     return {
@@ -183,7 +187,7 @@ export default {
     },
     /** 查看统计 */
     viewStatistics(row){
-
+      this.$refs.activityStatisticsRef?.openDrawer(row);
     },
     /** 查看详情 */
     handleView(row) {