Ver Fonte

红包充值限制/红包发送消耗统计

三七 há 1 dia atrás
pai
commit
f4c79c4a4d

+ 17 - 0
src/api/course/courseRedPacketLog.js

@@ -18,6 +18,14 @@ export function listCourseRedPacketLogPage(data) {
   })
 }
 
+export function getRedPacketLogCount(data) {
+  return request({
+    url: '/course/courseRedPacketLog/getRedPacketLogCount',
+    method: 'post',
+    data: data
+  })
+}
+
 // 查询短链课程看课记录详细
 export function getCourseRedPacketLog(logId) {
   return request({
@@ -77,3 +85,12 @@ export function exportCourseRedPacketLog(data) {
     data: data
   })
 }
+
+// 导出短链课程看课记录
+export function exportCourseRedPacketLogCountExport(data) {
+  return request({
+    url: '/course/courseRedPacketLog/countExport',
+    method: 'post',
+    data: data
+  })
+}

+ 403 - 0
src/views/course/courseRedPacketLogCount/index.vue

@@ -0,0 +1,403 @@
+<template>
+  <div class="course-red-packet-statistics">
+    <!-- 查询条件 -->
+    <el-card class="search-card">
+      <el-form :model="queryParams" ref="queryParams" label-width="80px" inline>
+          <el-form-item label="筛选类型" prop="status">
+            <el-select v-model="queryParams.changeType" placeholder="请选择筛选类型" clearable style="width: 100%" @change="changeType">
+              <el-option label="按销售公司" :value="1"></el-option>
+              <el-option label="按员工" :value="2"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="公司名" prop="companyId" v-if="queryParams.changeType ==1 ">
+            <el-select filterable style="width: 220px" v-model="queryParams.companyIds"
+                       @change="handleSeller" placeholder="请选择公司名"
+                       clearable size="small"
+                       multiple >
+              <el-option
+                v-for="item in companys"
+                :key="item.companyId"
+                :label="item.companyName"
+                :value="item.companyId"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="选择员工" prop="userIds" v-if="queryParams.changeType ==2 ">
+            <select-tree
+              v-model="selectedCompanyList"
+              :raw-data="deptList"
+              :parentSelectable="true"
+              placeholder="请选择销售"
+              :multiple="true"
+              component-width="300px"
+              :max-display-tags="3"
+              :check-strictly="false"
+              :return-leaf-only="false"
+            ></select-tree>
+          </el-form-item>
+          <el-form-item label="状态" prop="status">
+            <el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 100%">
+              <el-option label="全部" value=""></el-option>
+              <el-option label="发送中" value="0"></el-option>
+              <el-option label="已发送" value="1"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="创建时间" prop="createTime">
+            <el-date-picker
+              v-model="createTimeText"
+              type="datetimerange"
+              range-separator="至"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              @change="createChange"
+              :default-time="['00:00:00', '23:59:59']"
+            />
+          </el-form-item>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button
+              type="warning"
+              plain
+              icon="el-icon-download"
+              size="mini"
+              :loading="exportLoading"
+              @click="handleExport"
+              v-hasPermi="['course:courseRedPacketLog:countExport']"
+            >导出
+            </el-button>
+          </el-col>
+          <el-col :span="24" class="text-right">
+            <el-button type="primary" @click="handleSearch">查询</el-button>
+            <el-button @click="resetQuery">重置</el-button>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-card>
+
+    <!-- 统计结果 -->
+    <el-card class="result-card">
+      <div slot="header">
+        <span>红包发送统计</span>
+      </div>
+
+      <el-table :data="statisticsData" border style="width: 100%" v-loading="loading"
+                show-summary :summary-method="getSummaries"> >
+        <el-table-column prop="companyName" label="公司名称" align="center"></el-table-column>
+        <div v-if="queryParams.changeType==2">
+          <el-table-column prop="nickName" label="员工姓名" align="center"></el-table-column>
+          <el-table-column prop="companyUserId" label="员工编号" align="center"></el-table-column>
+          <el-table-column prop="deptId" label="部门编号" align="center"></el-table-column>
+          <el-table-column prop="deptName" label="部门昵称" align="center"></el-table-column>
+        </div>
+        <el-table-column prop="amount" label="已发红包金额" align="center"></el-table-column>
+      </el-table>
+
+      <pagination
+        v-show="total>0"
+        :total="total"
+        :page.sync="queryParams.pageNum"
+        :limit.sync="queryParams.pageSize"
+        @pagination="getList"
+      />
+    </el-card>
+  </div>
+</template>
+
+<script>
+import {getCompanyList} from "@/api/company/company";
+import {getUserList} from "@/api/company/companyUser";
+import SelectTree from '@/components/TreeSelect/index.vue'
+import { getDeptData } from '@/api/system/employeeStats'
+import {
+  exportCourseRedPacketLogCountExport,
+  getRedPacketLogCount
+} from '@/api/course/courseRedPacketLog'
+
+export default {
+  name: 'courseRedPacketLogCount',
+  components: { SelectTree },
+  data() {
+    return {
+      // 总条数
+      total: 0,
+      companys:[],
+      companyUserList:[],
+      selectedCompanyList: [],
+      deptList: [],
+      createTimeText: [],
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        changeType: 1,
+        companyId: null,
+        companyIds: null,
+        companyUserId: null,
+        startTime:null,
+        endTime:null,
+        status: null,
+        sTime:null,
+        eTime:null,
+        userIds: null
+      },
+      exportLoading: false,
+      statisticsData: [],
+      loading: false,
+      pageInfo: {
+        currentPage: 1,
+        pageSize: 10,
+        total: 0
+      }
+    }
+  },
+  mounted() {
+  },
+  created() {
+      getCompanyList().then(response => {
+          this.companys = response.data;
+          if(this.companys!=null&&this.companys.length>0){
+            this.companyId=this.companys[0].companyId;
+          }
+      });
+
+    getDeptData().then(response => {
+      this.deptList = response.data;
+    })
+  },
+  methods: {
+
+    changeType(){
+      this.statisticsData=[];
+      if (this.queryParams.changeType == 1){
+        this.selectedCompanyList=[];
+      }
+      if (this.queryParams.changeType == 2){
+        this.queryParams.companyIds=null;
+      }
+    },
+
+    getSummaries(param) {
+      const { columns, data } = param; // data 就是当前表格的 statisticsData
+      const sums = [];
+
+      columns.forEach((column, index) => {
+        if (index === 0) {
+          sums[index] = '总计';
+          return;
+        }
+
+        if (column.property === 'amount') {
+          // 直接从当前表格数据计算
+          const total = data.reduce((sum, item) => {
+            return sum + (parseFloat(item.amount) || 0);
+          }, 0);
+          sums[index] = '¥' + this.formatAmount(total);
+        } else {
+          sums[index] = '';
+        }
+      });
+
+      return sums;
+    },
+
+
+    // 格式化金额(不四舍五入,保留两位小数)
+    formatAmount(value) {
+      if (isNaN(value)) return '0.00';
+
+      // 方法1:使用 Math.floor 截断
+      const truncated = Math.floor(value * 100) / 100;
+
+      // 方法2:更精确的截断方法
+      // const truncated = Number(value.toString().match(/^\d+(?:\.\d{0,2})?/));
+
+      return truncated.toFixed(2);
+    },
+
+
+    handleSearch() {
+      this.pageInfo.currentPage = 1
+      this.getList();
+    },
+
+    createChange(createTime) {
+      if (createTime && createTime.length >= 2) {
+        if(!this.checkDateRangeLimit(createTime)){
+          this.createTimeText = null;
+          this.queryParams.sTime=null;
+          this.queryParams.eTime=null;
+          return;
+        }
+
+        this.queryParams.sTime = this.formatDate(createTime[0]) || null;
+        this.queryParams.eTime = this.formatDate(createTime[1]) || null;
+      } else {
+        this.createTimeText = [];
+        this.queryParams.sTime = null;
+        this.queryParams.eTime = null;
+      }
+    },
+    formatDate(date) {
+      if (!date) return ''
+
+      // 确保 date 是 Date 对象
+      let dateObj = date
+      if (typeof date === 'string') {
+        dateObj = new Date(date)
+      }
+
+      // 如果转换失败,返回空字符串
+      if (!(dateObj instanceof Date) || isNaN(dateObj.getTime())) {
+        return ''
+      }
+
+      // 使用更安全的格式化方法
+      const year = dateObj.getFullYear()
+      const month = String(dateObj.getMonth() + 1).padStart(2, '0')
+      const day = String(dateObj.getDate()).padStart(2, '0')
+      const hours = String(dateObj.getHours()).padStart(2, '0')
+      const minutes = String(dateObj.getMinutes()).padStart(2, '0')
+      const seconds = String(dateObj.getSeconds()).padStart(2, '0')
+
+      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
+    },
+    checkDateRangeLimit(dateRange) {
+      if (dateRange && dateRange.length >= 2) {
+        const startDate = new Date(dateRange[0]);
+        const endDate = new Date(dateRange[1]);
+
+        // 设置时间为当天开始,避免时间部分影响计算
+        startDate.setHours(0, 0, 0, 0);
+        endDate.setHours(0, 0, 0, 0);
+
+        const timeDiff = Math.abs(endDate - startDate);
+        const diffDays = Math.ceil(timeDiff / (1000 * 60 * 60 * 24));
+
+        if (diffDays > 31) { // maxDays-1 因为包含起始日
+          this.$message.warning('时间区间不能超过一个月');
+          return false;
+        }
+      }
+      return true;
+    },
+    handleSeller(){
+
+      if(this.queryParams.companyId != null) {
+        getUserList(this.queryParams.companyId).then(res=>{
+          if(res.code === 200) {
+            this.companyUserList = res.data
+          }
+        })
+      }
+    },
+
+    resetQuery() {
+      this.$refs.queryParams.resetFields();
+      this.createTimeText = [];
+      this.queryParams.dateRange = [];
+      this.selectedCompanyList = [];
+      this.statisticsData=[];
+      this.handleSearch()
+    },
+
+    getList() {
+
+      if (this.queryParams.changeType == 1 && this.queryParams.companyIds.length == 0) {
+        return this.$message.warning('请选择公司');
+      }
+
+      if (this.isEmptyArray(this.createTimeText)) {
+        this.$message.warning('请选择创建时间');
+        return;
+      }
+
+      console.log(this.queryParams.changeType)
+      console.log(this.selectedCompanyList)
+
+      if (this.queryParams.changeType == 2){
+        if( this.selectedCompanyList != null && this.selectedCompanyList.length > 0) {
+          this.queryParams.userIds = this.selectedCompanyList;
+        }else {
+          return this.$message.warning('请选择员工');
+        }
+      }
+
+      this.loading = true
+      // 查询统计
+      getRedPacketLogCount(this.queryParams).then(response => {
+        this.statisticsData = response.data.list;
+        this.total = response.data.total;
+        this.loading = false;
+      });
+    },
+    // 添加辅助方法
+    isEmptyArray(arr) {
+      return !arr || arr.length === 0;
+    },
+    handleSizeChange(val) {
+      this.pageInfo.pageSize = val
+      this.pageInfo.currentPage = 1
+      this.getList()
+    },
+
+    handleCurrentChange(val) {
+      this.pageInfo.currentPage = val
+      this.getList()
+    },
+
+    /** 导出按钮操作 */
+    handleExport() {
+
+      if(this.selectedCompanyList != null && this.selectedCompanyList.length > 0) {
+        this.queryParams.userIds = this.selectedCompanyList;
+      }else {
+        this.queryParams.userIds = [];
+      }
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有红包记录数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        const loadingInstance = this.$loading({
+          lock: true,
+          text: '正在导出数据,请稍候...',
+          background: 'rgba(0, 0, 0, 0.7)'
+        });
+
+        this.exportLoading = true;
+
+        return exportCourseRedPacketLogCountExport(queryParams).finally(res=>{
+          loadingInstance.close();
+        })
+      }).then(response => {
+        this.download(response.msg);
+        this.exportLoading = false;
+      }).catch(() => {}).finally(res=>{
+
+      });
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.course-red-packet-statistics {
+  padding: 20px;
+
+  .search-card {
+    margin-bottom: 20px;
+  }
+
+  .result-card {
+    .pagination-container {
+      margin-top: 20px;
+      text-align: right;
+    }
+  }
+
+  .text-right {
+    text-align: right;
+  }
+}
+</style>

+ 0 - 2
src/views/his/company/index.vue

@@ -197,7 +197,6 @@
           >扣款
           </el-button>
           <el-button
-            v-if="showRedPacket"
             size="mini"
             type="text"
             icon="el-icon-edit"
@@ -206,7 +205,6 @@
           >红包充值
           </el-button>
           <el-button
-            v-if="showRedPacket"
             size="mini"
             type="text"
             icon="el-icon-edit"