Bladeren bron

1、总后台红包信息,核销卷信息,优惠卷信息进行展示

yys 3 weken geleden
bovenliggende
commit
54439271ad
3 gewijzigde bestanden met toevoegingen van 209 en 10 verwijderingen
  1. 8 0
      src/api/live/liveData.js
  2. 182 0
      src/views/live/liveData/UserClaimTypeActions.vue
  3. 19 10
      src/views/live/liveData/index.vue

+ 8 - 0
src/api/live/liveData.js

@@ -57,6 +57,14 @@ export function exportLiveUserDetail(liveId) {
   })
 }
 
+// 查询用户在指定直播间的领取记录
+export function getUserClaimRecords(liveId, userId) {
+  return request({
+    url: '/liveData/liveData/getUserClaimRecords?liveId=' + liveId + '&userId=' + userId,
+    method: 'get'
+  })
+}
+
 export function exportLiveData(query) {
   return request({
     url: '/liveData/liveData/export',

+ 182 - 0
src/views/live/liveData/UserClaimTypeActions.vue

@@ -0,0 +1,182 @@
+<template>
+  <div class="user-claim-type-actions">
+    <div class="claim-type-actions">
+      <el-button type="text" size="mini" @click="handleViewClaim('redPoints')">红包/积分</el-button>
+      <el-button type="text" size="mini" @click="handleViewClaim('verifyCoupon')">核销券</el-button>
+      <el-button type="text" size="mini" @click="handleViewClaim('coupon')">优惠券</el-button>
+    </div>
+
+    <el-dialog
+      :title="dialogTitle"
+      :visible.sync="dialogVisible"
+      :width="dialogWidth"
+      append-to-body
+      custom-class="claim-record-dialog"
+    >
+      <el-table
+        :key="'claim-' + claimType"
+        :data="recordList"
+        v-loading="loading"
+        border
+        size="mini"
+        max-height="420"
+        empty-text="暂无领取记录"
+        style="width: 100%"
+      >
+        <el-table-column type="index" label="序号" width="50" align="center" />
+        <el-table-column prop="opTypeName" label="领取类型" width="110" align="center" />
+        <el-table-column prop="bizName" label="名称" min-width="140" show-overflow-tooltip />
+        <el-table-column
+          v-if="claimType === 'verifyCoupon'"
+          label="核销状态"
+          width="90"
+          align="center"
+        >
+          <template slot-scope="scope">
+            <el-tag
+              v-if="scope.row.verifyStatusName"
+              size="mini"
+              :type="verifyStatusTagType(scope.row.verifyStatus)"
+            >{{ scope.row.verifyStatusName }}</el-tag>
+            <span v-else>-</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          v-if="claimType === 'verifyCoupon'"
+          prop="verifyUserName"
+          label="核销人"
+          width="90"
+          show-overflow-tooltip
+        >
+          <template slot-scope="scope">
+            {{ scope.row.verifyUserName || '-' }}
+          </template>
+        </el-table-column>
+        <el-table-column
+          v-if="claimType === 'verifyCoupon'"
+          prop="verifyTime"
+          label="核销时间"
+          width="150"
+          align="center"
+        >
+          <template slot-scope="scope">
+            {{ scope.row.verifyTime || '-' }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="couponCount" label="数量" width="60" align="center">
+          <template slot-scope="scope">
+            {{ scope.row.couponCount || '-' }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="createTime" label="领取时间" width="150" align="center" />
+      </el-table>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">关 闭</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { getUserClaimRecords } from '@/api/live/liveData'
+
+const CLAIM_TYPE_TITLE = {
+  redPoints: '红包/积分领取信息',
+  verifyCoupon: '核销券领取信息',
+  coupon: '优惠券领取信息'
+}
+
+export default {
+  name: 'UserClaimTypeActions',
+  props: {
+    /** 直播间ID */
+    liveId: {
+      type: [Number, String],
+      required: true
+    },
+    /** 用户行数据,至少包含 userId、userName */
+    user: {
+      type: Object,
+      required: true
+    }
+  },
+  data() {
+    return {
+      dialogVisible: false,
+      dialogTitle: '领取记录',
+      loading: false,
+      recordList: [],
+      claimType: null
+    }
+  },
+  computed: {
+    dialogWidth() {
+      // 核销券列更多,弹窗加宽避免横向滚动
+      return this.claimType === 'verifyCoupon' ? '900px' : '640px'
+    }
+  },
+  methods: {
+    handleViewClaim(claimType) {
+      if (!this.liveId || !this.user || !this.user.userId) {
+        this.$message.warning('无法获取用户信息')
+        return
+      }
+      this.claimType = claimType
+      this.dialogTitle = (this.user.userName || '用户') + ' - ' + (CLAIM_TYPE_TITLE[claimType] || '领取记录')
+      this.dialogVisible = true
+      this.loading = true
+      this.recordList = []
+      getUserClaimRecords(this.liveId, this.user.userId).then(response => {
+        if (response.code === 200) {
+          const list = response.data || []
+          this.recordList = list.filter(item => this.matchClaimType(item.opType, claimType))
+        }
+        this.loading = false
+      }).catch(() => {
+        this.loading = false
+      })
+    },
+    /** 与后端 LiveConsoleOpLog.opType 保持一致 */
+    matchClaimType(opType, claimType) {
+      const type = Number(opType)
+      if (claimType === 'redPoints') {
+        // 5红包发放 6抽奖发放 7完课积分 9观看奖励积分 11签到金额红包
+        return [5, 6, 7, 9, 11].includes(type)
+      }
+      if (claimType === 'verifyCoupon') {
+        return type === 2
+      }
+      if (claimType === 'coupon') {
+        // 1优惠券展示 8完课优惠券 10观看奖励优惠券
+        return [1, 8, 10].includes(type)
+      }
+      return true
+    },
+    verifyStatusTagType(status) {
+      const map = { 0: 'info', 1: 'success', 2: 'danger' }
+      return map[Number(status)] || 'info'
+    }
+  }
+}
+</script>
+
+<style scoped>
+.claim-type-actions {
+  display: flex;
+  flex-wrap: nowrap;
+  justify-content: center;
+  align-items: center;
+  white-space: nowrap;
+}
+
+.claim-type-actions .el-button {
+  margin: 0 2px;
+  padding: 0 4px;
+}
+</style>
+
+<style>
+.claim-record-dialog .el-dialog__body {
+  overflow-x: hidden;
+}
+</style>

+ 19 - 10
src/views/live/liveData/index.vue

@@ -532,32 +532,39 @@
         <el-table
           :data="userDetailList"
           v-loading="userDetailLoading"
-          border          style="width: 100%"
+          border
+          size="mini"
+          class="user-detail-table"
+          style="width: 100%"
         >
-          <el-table-column type="index" label="序号" width="60" align="center" fixed></el-table-column>
-          <el-table-column prop="userName" label="用户名称" min-width="120" show-overflow-tooltip></el-table-column>
-          <el-table-column prop="signFirst" label="打卡1" width="80" align="center" show-overflow-tooltip></el-table-column>
-          <el-table-column prop="signSecond" label="打卡2" width="80" align="center" show-overflow-tooltip></el-table-column>
-          <el-table-column prop="signThird" label="打卡3" width="80" align="center" show-overflow-tooltip></el-table-column>
-          <el-table-column prop="liveWatchDuration" label="直播观看时长" width="130" align="center">
+          <el-table-column type="index" label="序号" width="55" align="center" fixed></el-table-column>
+          <el-table-column prop="userName" label="用户名称" min-width="120" show-overflow-tooltip fixed></el-table-column>
+          <el-table-column prop="liveWatchDuration" label="直播观看时长" width="120" align="center">
             <template slot-scope="scope">
               {{ formatDuration(scope.row.liveWatchDuration || 0) }}
             </template>
           </el-table-column>
-          <el-table-column prop="playbackWatchDuration" label="回放观看时长" width="130" align="center">
+          <el-table-column prop="playbackWatchDuration" label="回放观看时长" width="120" align="center">
             <template slot-scope="scope">
               {{ formatDuration(scope.row.playbackWatchDuration || 0) }}
             </template>
           </el-table-column>
           <el-table-column prop="orderCount" label="订单数" width="80" align="center"></el-table-column>
-          <el-table-column prop="orderAmount" label="订单金额" width="110" align="center">
+          <el-table-column prop="orderAmount" label="订单金额" width="100" align="center">
             <template slot-scope="scope">
               {{ formatMoney(scope.row.orderAmount) }}
             </template>
           </el-table-column>
+          <el-table-column prop="liveBelongName" label="直播归属" min-width="120" show-overflow-tooltip></el-table-column>
           <el-table-column prop="salesName" label="邀请销售" min-width="100" show-overflow-tooltip></el-table-column>
           <el-table-column prop="companyName" label="销售公司" min-width="120" show-overflow-tooltip></el-table-column>
+          <el-table-column label="领取类型" width="220" align="center" fixed="right">
+            <template slot-scope="scope">
+              <user-claim-type-actions :live-id="currentLiveId" :user="scope.row" />
+            </template>
+          </el-table-column>
         </el-table>
+
         <!-- 用户详情分页组件 -->
         <pagination
           v-show="userDetailTotal > 0"
@@ -574,12 +581,14 @@
 </template>
 
 <script>
-import { listLiveData, exportLiveData,  dashboardData, getLiveDataDetailBySql, getLiveUserDetailListBySql, exportLiveUserDetail } from "@/api/live/liveData";
+import { listLiveData, exportLiveData, dashboardData, getLiveDataDetailBySql, getLiveUserDetailListBySql, exportLiveUserDetail } from "@/api/live/liveData";
 import { batchUpdateExternalContactNotes } from "@/api/qw/externalContact";
 import { addTag } from "@/api/qw/externalContact";
+import UserClaimTypeActions from "./UserClaimTypeActions.vue";
 
 export default {
   name: "LiveData",
+  components: { UserClaimTypeActions },
   data() {
     return {
       liveId: '',