123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649 |
- <template>
- <div class="member-statistics-page">
- <!-- 会员统计页面容器 -->
- <div class="member-statistics-container">
- <!-- =================== 顶部查询区域 =================== -->
- <el-form class="filter-container" :inline="true" :model="queryParams" ref="queryForm">
- <div class="filter-item">
- <!-- 按日/按月切换 -->
- <el-radio-group v-model="queryParams.dateType" size="small" @input="handleChangeDateType">
- <el-radio-button label="day">按每日</el-radio-button>
- <el-radio-button label="month">按每月</el-radio-button>
- </el-radio-group>
- </div>
- <div class="filter-item">
- <!-- 日期选择器 -->
- <el-date-picker
- v-model="queryParams.dateRange"
- :key="queryParams.dateType"
- :type="queryParams.dateType === 'day' ? 'daterange' : 'monthrange'"
- size="small"
- range-separator="至"
- start-placeholder="开始日期"
- end-placeholder="结束日期"
- style="width: 260px;"
- :clearable="false"
- />
- </div>
- <!-- 经销商选择 -->
- <el-form-item class="filter-item" label="经销商" prop="dealerId">
- <!-- 经销商选择 -->
- <el-select
- v-model="queryParams.dealerId"
- placeholder="请选择经销商"
- size="small"
- clearable filterable remote
- :remote-method="loadCompanyOptions"
- v-select-load-more="loadMoreCompanyOptions"
- :loading="companyOptionsLoading"
- @change="handleChangeDealer"
- style="width: 140px;"
- >
- <el-option v-for="item in dealerOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
- </el-select>
- </el-form-item>
- <el-form-item class="filter-item" label="群管" prop="groupId">
- <!-- 分组选择 -->
- <el-select
- v-model="queryParams.groupId"
- placeholder="请选择群管"
- size="small"
- clearable filterable remote
- :remote-method="loadCompanyUserOptions"
- v-select-load-more="loadMoreCompanyUserOptions"
- :loading="companyUserOptionsLoading"
- style="width: 140px;"
- >
- <el-option v-for="item in groupOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
- </el-select>
- </el-form-item>
- <el-form-item class="filter-item" label="会员" prop="memberId">
- <!-- 会员选择 -->
- <el-select
- v-model="queryParams.memberId"
- placeholder="请选择会员"
- size="small"
- clearable filterable remote
- :remote-method="loadUserOptions"
- v-select-load-more="loadMoreUserOptions"
- :loading="userOptionsLoading"
- style="width: 140px;"
- >
- <el-option v-for="item in memberOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
- </el-select>
- </el-form-item>
- <el-form-item class="filter-item" label="训练营" prop="trainerId">
- <!-- 训练营选择 -->
- <el-select
- v-model="queryParams.trainerId"
- placeholder="请选择训练营"
- size="small"
- clearable filterable remote
- :remote-method="loadTrainerOptions"
- v-select-load-more="loadMoreTrainerOptions"
- :loading="trainerOptionsLoading"
- @change="changeTrainer"
- style="width: 140px;"
- >
- <el-option v-for="item in trainerOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
- </el-select>
- </el-form-item>
- <el-form-item class="filter-item" label="营期" prop="campPeriod">
- <!-- 营期选择 -->
- <el-select
- v-model="queryParams.campPeriod"
- placeholder="请选择营期"
- size="small"
- clearable filterable remote
- :remote-method="loadPeriodOptions"
- v-select-load-more="loadMorePeriodOptions"
- :loading="campPeriodOptionsLoading"
- @change="changeCampPeriod"
- style="width: 140px;"
- >
- <el-option v-for="item in campPeriodOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
- </el-select>
- </el-form-item>
- <el-form-item class="filter-item" label="课程" prop="courseId">
- <!-- 课程选择 -->
- <el-select
- v-model="queryParams.courseId"
- placeholder="请选择课程"
- size="small"
- clearable filterable remote
- :remote-method="loadCourseOptions"
- v-select-load-more="loadMoreCourseOptions"
- :loading="courseOptionsLoading"
- style="width: 140px;"
- >
- <el-option v-for="item in courseOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
- </el-select>
- </el-form-item>
- <el-form-item class="filter-item" label="手机号" prop="mobile">
- <!-- 手机号输入框 -->
- <el-input
- v-model="queryParams.mobile"
- placeholder="请输入手机号"
- size="small"
- clearable
- style="width: 200px;"
- />
- </el-form-item>
- <div class="filter-item">
- <!-- 操作按钮组 -->
- <el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">搜索</el-button>
- </div>
- <div class="filter-item" style="margin-left: auto; display: none;">
- <el-button size="small">更换所属群管</el-button>
- <el-button type="primary" size="small">导出全部</el-button>
- </div>
- </el-form>
- </div>
- <!-- =================== 表格数据展示区域 =================== -->
- <div class="table-container">
- <el-table
- v-loading="loading"
- :data="tableData"
- border
- style="width: 100%;"
- show-summary
- :summary-row-style="{ background: '#fafafa' }"
- >
- <!-- 选择列 -->
- <el-table-column type="selection" width="50" align="center" />
- <!-- 序号列 -->
- <el-table-column label="序号" type="index" width="60" align="center" />
- <!-- 统计日期列 -->
- <el-table-column prop="date" label="统计日期" min-width="100" align="center" />
- <!-- 会员名称列 -->
- <el-table-column prop="memberName" label="会员名称" min-width="100" align="center" />
- <!-- 性别列 -->
- <el-table-column prop="gender" label="性别" width="60" align="center" />
- <!-- 手机号列 -->
- <el-table-column prop="mobile" label="手机号" min-width="100" align="center" />
- <!-- 会员标签列 -->
- <el-table-column prop="memberTag" label="会员标签" min-width="100" align="center" />
- <!-- 所属群管列 -->
- <el-table-column prop="groupName" label="所属群管" min-width="100" align="center" />
- <!-- 所属经销商列 -->
- <el-table-column prop="dealerName" label="所属经销商" min-width="100" align="center" />
- <!-- 观看课程列 -->
- <el-table-column prop="viewCount" label="观看课程" min-width="80" align="center" />
- <!-- 完课课程列 -->
- <el-table-column prop="finishCount" label="完课课程" min-width="80" align="center" />
- <!-- 完课率列 -->
- <el-table-column prop="finishRate" label="完课率" min-width="80" align="center" />
- <!-- 观看次数列 -->
- <el-table-column prop="viewTimes" label="观看次数" min-width="80" align="center" />
- <!-- 完课次数列 -->
- <el-table-column prop="finishTimes" label="完课次数" min-width="80" align="center" />
- <!-- 视频率列 -->
- <el-table-column prop="videoRate" label="视频率" min-width="80" align="center" />
- <!-- 操作列 -->
- <el-table-column label="操作" fixed="right" min-width="160" align="center">
- <template slot-scope="scope">
- <!-- 会员分析按钮 -->
- <el-button type="text" size="small" style="color: #409EFF;">会员分析</el-button>
- <!-- 红包记录按钮 -->
- <el-button type="text" size="small" style="color: #409EFF;">红包记录</el-button>
- </template>
- </el-table-column>
- </el-table>
- <pagination
- v-show="queryParams.total > 0"
- :total="queryParams.total"
- :page.sync="queryParams.pageNum"
- :limit.sync="queryParams.pageSize"
- @pagination="getList"
- />
- </div>
- </div>
- </template>
- <script>
- import {dailyData} from '@/api/statistics/member'
- import {getCompanyListLikeName} from '@/api/company/company'
- import {getCompanyUserListLikeName} from '@/api/company/companyUser'
- import {getUserListLikeName} from '@/api/users/user'
- import {getCampListLikeName} from '@/api/course/userCourseCamp'
- import {getPeriodListLikeName} from '@/api/course/userCoursePeriod'
- import {getVideoListLikeName} from '@/api/course/userCourseVideo'
- import moment from "moment"
- export default {
- // 组件名称
- name: 'MemberStatistics',
- // 组件数据
- data() {
- return {
- // ============= 查询参数 =============
- queryParams: {
- dateType: 'day', // 日期类型:day-按日,month-按月
- dateRange: [new Date(), new Date()], // 日期范围
- dealerId: '', // 经销商ID
- groupId: '', // 群组ID
- memberId: '', // 会员ID
- trainerId: '', // 训练官ID
- campPeriod: '', // 营期
- courseId: '', // 课程ID
- mobile: '', // 手机号
- pageNum: 1, // 当前页码
- pageSize: 30, // 每页记录数
- total: 0, // 总记录数
- },
- // ============= 页面状态 =============
- loading: false, // 加载状态
- // ============= 数据相关 =============
- tableData: [], // 表格数据
- // ============= 下拉选项数据 =============
- companyOptionsParams: {
- name: undefined,
- hasNextPage: false,
- pageNum: 1,
- pageSize: 10
- },
- companyOptionsLoading: false,
- dealerOptions: [], // 经销商选项
- companyUserOptionsParams: {
- name: undefined,
- companyId: undefined,
- hasNextPage: false,
- pageNum: 1,
- pageSize: 10
- },
- companyUserOptionsLoading: false,
- groupOptions: [], // 群组选项
- userOptionsParams: {
- name: undefined,
- hasNextPage: false,
- pageNum: 1,
- pageSize: 10
- },
- userOptionsLoading: false,
- memberOptions: [], // 会员选项
- trainerOptionsParams: {
- name: undefined,
- hasNextPage: false,
- pageNum: 1,
- pageSize: 10
- },
- trainerOptionsLoading: false,
- trainerOptions: [], // 训练营选项
- campPeriodOptionsParams: {
- name: undefined,
- campId: undefined,
- hasNextPage: false,
- pageNum: 1,
- pageSize: 10
- },
- campPeriodOptionsLoading: false,
- campPeriodOptions: [], // 营期选项
- courseOptionsParams: {
- name: undefined,
- periodId: undefined,
- hasNextPage: false,
- pageNum: 1,
- pageSize: 10
- },
- courseOptionsLoading: false,
- courseOptions: [] // 课程选项
- }
- },
- // ============= 生命周期钩子 =============
- created() {
- // 页面创建时初始化数据
- this.getList() // 加载表格数据
- },
- // ============= 组件方法 =============
- methods: {
- /**
- * 获取表格数据
- * 根据查询参数从服务器获取会员统计数据
- */
- getList() {
- this.loading = true // 显示加载中状态
- // 模拟异步请求
- let query = {
- type: this.queryParams.dateType === 'day' ? 1 : 2,
- startDate: moment(this.queryParams.dateRange[0]).format('YYYY-MM-DD'),
- endDate: moment(this.queryParams.dateRange[1]).format('YYYY-MM-DD'),
- companyId: this.queryParams.dealerId,
- companyUserId: this.queryParams.groupId,
- userId: this.queryParams.memberId,
- phone: this.queryParams.mobile,
- trainCampId: this.queryParams.trainerId,
- periodId: this.queryParams.campPeriod,
- videoId: this.queryParams.courseId,
- pageNum: this.queryParams.pageNum,
- pageSize: this.queryParams.pageSize
- }
- dailyData(query).then(response => {
- if (response && response.code === 200) {
- this.tableData = response.data.list
- this.queryParams.total = response.data.total
- this.loading = false // 隐藏加载中状态
- }
- })
- },
- // 切换日期类型
- handleChangeDateType() {
- this.queryParams.dateRange = [new Date(), new Date()]
- // 重新请求数据
- this.getList()
- },
- /**
- * 查询按钮点击事件
- * 根据筛选条件重新查询数据
- */
- handleQuery() {
- this.queryParams.pageNum = 1 // 重置为第一页
- this.getList() // 重新获取数据
- },
- /**
- * 重置查询条件
- * 清空所有筛选条件并重新加载数据
- */
- resetQuery() {
- // 重置所有查询条件
- this.queryParams = {
- dateType: 'day', // 重置日期类型为按天
- dateRange: [], // 清空日期范围
- publicId: '', // 清空公众号ID
- dealerId: '', // 清空经销商ID
- groupId: '', // 清空群组ID
- memberId: '', // 清空会员ID
- trainerId: '', // 清空训练官ID
- campPeriod: '', // 清空营期
- courseId: '', // 清空课程ID
- mobile: '' // 清空手机号
- }
- this.getList() // 重新获取数据
- },
- // 加载经销商选项
- loadCompanyOptions(query) {
- this.dealerOptions = [];
- if (query === '') {
- return;
- }
- this.companyOptionsParams.pageNum = 1
- this.companyOptionsParams.name = query
- this.companyOptionsLoading = true;
- this.getCompanyListLikeName()
- },
- getCompanyListLikeName() {
- getCompanyListLikeName(this.companyOptionsParams).then(response => {
- this.dealerOptions = [...this.dealerOptions, ...response.data.list]
- this.companyOptionsParams.hasNextPage = response.data.hasNextPage
- this.companyOptionsLoading = false;
- });
- },
- loadMoreCompanyOptions() {
- if (!this.companyOptionsParams.hasNextPage) {
- return;
- }
- this.companyOptionsParams.pageNum += 1
- this.getCompanyListLikeName()
- },
- handleChangeDealer(val) {
- this.groupOptions = [];
- this.companyUserOptionsLoading = true;
- if (!val) {
- this.companyUserOptionsParams.companyId = undefined
- this.getCompanyUserListLikeName()
- return
- }
- this.companyUserOptionsParams.companyId = val
- this.companyUserOptionsParams.pageNum = 1
- this.getCompanyUserListLikeName()
- },
- // 群组选项
- loadCompanyUserOptions(query) {
- this.groupOptions = [];
- if (query === '') {
- return;
- }
- this.companyUserOptionsParams.pageNum = 1
- this.companyUserOptionsParams.name = query
- this.companyUserOptionsLoading = true;
- this.getCompanyUserListLikeName()
- },
- getCompanyUserListLikeName() {
- getCompanyUserListLikeName(this.companyUserOptionsParams).then(response => {
- this.groupOptions = [...this.groupOptions, ...response.data.list]
- this.companyUserOptionsParams.hasNextPage = response.data.hasNextPage
- this.companyUserOptionsLoading = false;
- });
- },
- loadMoreCompanyUserOptions() {
- if (!this.companyUserOptionsParams.hasNextPage) {
- return;
- }
- this.companyUserOptionsParams.pageNum += 1
- this.getCompanyUserListLikeName()
- },
- // 会员选项
- loadUserOptions(query) {
- this.memberOptions = [];
- if (query === '') {
- return;
- }
- this.userOptionsParams.pageNum = 1
- this.userOptionsParams.name = query
- this.userOptionsLoading = true;
- this.getUserListLikeName()
- },
- getUserListLikeName() {
- getUserListLikeName(this.userOptionsParams).then(response => {
- this.memberOptions = [...this.memberOptions, ...response.data.list]
- this.userOptionsParams.hasNextPage = response.data.hasNextPage
- this.userOptionsLoading = false;
- });
- },
- loadMoreUserOptions() {
- if (!this.userOptionsParams.hasNextPage) {
- return;
- }
- this.userOptionsParams.pageNum += 1
- this.getUserListLikeName()
- },
- // 训练营选项
- loadTrainerOptions(query) {
- this.trainerOptions = [];
- if (query === '') {
- return;
- }
- this.trainerOptionsParams.pageNum = 1
- this.trainerOptionsParams.name = query
- this.trainerOptionsLoading = true;
- this.getTrainerListLikeName()
- },
- getTrainerListLikeName() {
- getCampListLikeName(this.trainerOptionsParams).then(response => {
- this.trainerOptions = [...this.trainerOptions, ...response.data.list]
- this.trainerOptionsParams.hasNextPage = response.data.hasNextPage
- this.trainerOptionsLoading = false;
- });
- },
- loadMoreTrainerOptions() {
- if (!this.trainerOptionsParams.hasNextPage) {
- return;
- }
- this.trainerOptionsParams.pageNum += 1
- this.getTrainerListLikeName()
- },
- changeTrainer(val) {
- this.campPeriodOptions = [];
- this.campPeriodOptionsLoading = true;
- if (!val) {
- this.campPeriodOptionsParams.companyId = undefined
- this.getPeriodListLikeName()
- return
- }
- this.campPeriodOptionsParams.companyId = val
- this.campPeriodOptionsParams.pageNum = 1
- this.getPeriodListLikeName()
- },
- // 营期选项
- loadPeriodOptions(query) {
- this.campPeriodOptions = [];
- if (query === '') {
- return;
- }
- this.campPeriodOptionsParams.pageNum = 1
- this.campPeriodOptionsParams.name = query
- this.campPeriodOptionsLoading = true;
- this.getPeriodListLikeName()
- },
- getPeriodListLikeName() {
- getPeriodListLikeName(this.campPeriodOptionsParams).then(response => {
- this.campPeriodOptions = [...this.campPeriodOptions, ...response.data.list]
- this.campPeriodOptionsParams.hasNextPage = response.data.hasNextPage
- this.campPeriodOptionsLoading = false;
- });
- },
- loadMorePeriodOptions() {
- if (!this.campPeriodOptionsParams.hasNextPage) {
- return;
- }
- this.campPeriodOptionsParams.pageNum += 1
- this.getPeriodListLikeName()
- },
- changeCampPeriod(val) {
- this.courseOptions = []
- this.courseOptionsLoading = true;
- if (!val) {
- this.courseOptionsParams.periodId = undefined
- this.getCourseListLikeName()
- return
- }
- this.courseOptionsParams.periodId = val
- this.courseOptionsParams.pageNum = 1
- this.getCourseListLikeName()
- },
- // 课程选项
- loadCourseOptions(query) {
- this.courseOptions = [];
- if (query === '') {
- return;
- }
- this.courseOptionsParams.pageNum = 1
- this.courseOptionsParams.name = query
- this.courseOptionsLoading = true;
- this.getCourseListLikeName()
- },
- getCourseListLikeName() {
- getVideoListLikeName(this.courseOptionsParams).then(response => {
- this.courseOptions = [...this.courseOptions, ...response.data.list]
- this.courseOptionsParams.hasNextPage = response.data.hasNextPage
- this.courseOptionsLoading = false;
- });
- },
- loadMoreCourseOptions() {
- if (!this.courseOptionsParams.hasNextPage) {
- return;
- }
- this.courseOptionsParams.pageNum += 1
- this.getCourseListLikeName()
- },
- }
- }
- </script>
- <style scoped>
- .member-statistics-page {
- padding: 10px;
- }
- /* 会员统计页面容器样式 */
- .member-statistics-container {
- padding: 10px;
- background-color: #fff;
- }
- /* 筛选区域样式 */
- .filter-container {
- display: flex;
- flex-wrap: wrap;
- align-items: center;
- background-color: #fff;
- padding: 15px;
- border-radius: 4px;
- }
- .filter-item {
- margin-right: 15px;
- margin-bottom: 10px;
- }
- /* 表格容器样式 */
- .table-container {
- background-color: #FFF;
- height: 72vh;
- }
- /* 表格深度样式 */
- ::v-deep .el-table th {
- color: #606266;
- font-weight: bold;
- }
- ::v-deep .el-table--border th, ::v-deep .el-table--border td {
- border-right: 1px solid #EBEEF5;
- }
- ::v-deep .el-table {
- border: 1px solid #EBEEF5;
- border-bottom: none;
- }
- ::v-deep .el-input__inner {
- border-radius: 4px;
- }
- ::v-deep .el-button {
- border-radius: 4px;
- }
- </style>
|