<template> <div class="demo-wrap min-flex-right"> <div class="flex-between"> <h2>{{ filterTitle ? filterTitle : pageTitle }}</h2> <CustomDropdown ref="dropdownRef" :placeholder="'('+viewDesc[this.view]+')'+text" width="280px"> <DateSelect slot="normal" :view="view" v-model="selectedDate" @update-count="handleUpdateView" @change="handleDateChange"/> </CustomDropdown> </div> <div class=" flex-common"> <div v-if="total_value>0" style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;"> <h3 style="margin: 0;"></h3> <span style="font-size: 14px; color: #999;">总{{ rank_type_desc[dataRank] }}:{{ total_value }}</span> </div> <el-form> <el-table :data="tableData" :key="dataRank" style="width: 100%" @sort-change="handleSortChange" @cell-mouse-enter="handleRowHover"> <el-table-column prop="sort" label="排序" width="100"></el-table-column> <el-table-column v-if="dataRank == 3 && (dataType == 'ver_type' || dataType == 'check_type')" prop="name" :key="selectedType" :label="type_select[selectedType]"> <template slot="header"> <el-select class="custom-select" popper-class="custom-select-dropdown" v-model="selectedType" @change="changeRankType"> <el-option v-for="(item,type) in type_select" :key="type" :label="item" :value="type"> </el-option> </el-select> </template> <template slot-scope="scope"> {{ scope.row.name }} </template> </el-table-column> <el-table-column v-else prop="name" :label="type_desc[dataType]"></el-table-column> <el-table-column prop="1" :label="rank_type_desc[dataRank]" sortable="custom"> <template v-slot="{ row, $index }"> <template v-if="dataRank == 3"> {{ row.value_1 }} </template> <template v-else> <el-popover v-model="row.id_popover_2" placement="top" trigger="manual" :ref="`popover_2-${$index}`" @show="popshow"> <div class="pop-wrap"> <div class="flex-between flex pop-top"> <h3> {{ text }} {{ row.name }} {{ rank_type_desc[dataRank] }} <span @click="goLookMoreData(row.id)">查看更多</span> </h3> <span class="flex point" @click="closePop(row,'id')"> 关闭<img src="@/assets/register/close.svg"> </span> </div> <el-table :data="tableData1" style="width: 100%"> <el-table-column prop="value_1" width="208" label="日期"></el-table-column> <el-table-column prop="value_2" width="208" :label="rank_type_desc[dataRank]"></el-table-column> </el-table> </div> <div class="flex" slot="reference"> {{ row.value_1 }} <template v-if="Object.keys(growth_list).length > 0"> <span v-if="growth_list[row.id]" class="flex growth-text"> <span v-if="growth_list[row.id].value>0"> <span class="growth-up"> <img class="edit_icon" src="@/assets/super/growth-up.svg"> {{ growth_list[row.id].value }}% </span>同比上年 </span> <span v-if="growth_list[row.id].value<0"> <span class="growth-down"> <img class="edit_icon" src="@/assets/super/growth-down.svg"> {{ growth_list[row.id].value }}% </span>同比上年 </span> <span v-if="growth_list[row.id].value==0"> <img class="edit_icon" src="@/assets/super/growth-flat.svg">同比上年持平 </span> </span> <span v-else class="flex growth-text">上年无数据</span> </template> <img v-if="false && row.value_1>0 && show_detail_index == row.sort" @click="handleClick2(row, $index, 'id')" class="detail_icon" src="@/assets/super/list-detail.svg"> </div> </el-popover> </template> </template> </el-table-column> <el-table-column prop="2" label="退单率" sortable="custom" v-if="dataRank == 3"> <template v-slot="{ row, $index }"> <el-popover v-model="row.id_popover_2" placement="top" trigger="manual" :ref="`popover_2-${$index}`" @show="popshow"> <div class="pop-wrap"> <div class="flex-between flex pop-top"> <h3> {{ text }} {{ row.name }} {{ rank_type_desc[dataRank] }} <span @click="goLookMoreData(row.id)">查看更多</span> </h3> <span class="flex point" @click="closePop(row,'id')"> 关闭<img src="@/assets/register/close.svg"> </span> </div> <el-table :data="tableData1" style="width: 100%"> <el-table-column prop="value_1" width="208" label="日期"></el-table-column> <el-table-column prop="value_2" width="208" label="退单数"></el-table-column> </el-table> </div> <div class="flex" slot="reference"> {{ row.value_2 }} <template v-if="Object.keys(growth_list).length > 0"> <span v-if="growth_list[row.id]" class="flex growth-text"> <span v-if="growth_list[row.id].value>0"> <span class="growth-up"> <img class="edit_icon" src="@/assets/super/growth-up.svg"> {{ growth_list[row.id].value }}% </span>同比上年 </span> <span v-if="growth_list[row.id].value<0"> <span class="growth-down"> <img class="edit_icon" src="@/assets/super/growth-down.svg"> {{ growth_list[row.id].value }}% </span>同比上年 </span> <span v-if="growth_list[row.id].value==0"> <img class="edit_icon" src="@/assets/super/growth-flat.svg">同比上年持平 </span> </span> <span class="flex growth-text" v-else>上年无数据</span> </template> <img @click="handleClick2(row, $index, 'id')" v-if="row.value_1>0 && show_detail_index == row.sort" class="detail_icon" src="@/assets/super/list-detail.svg"> </div> </el-popover> </template> </el-table-column> <el-table-column label="代理商排行" v-if="dataType != 'agent' && dataRank == 3"> <template v-slot="{ row, $index }"> <el-popover v-model="row.id_popover" placement="top" trigger="manual" :ref="`popover-${$index}`" @show="popshow"> <div class="pop-wrap"> <div class="flex-between flex pop-top"> <h3> {{ text }} {{ row.name }} {{ rank_type_desc[dataRank] }} <span @click="goLookMoreRank(row.id)">查看更多</span> </h3> <span class="flex point" @click="closePop(row,'id')"> 关闭<img src="@/assets/register/close.svg"> </span> </div> <el-table :data="tableData1" style="width: 100%"> <el-table-column prop="sort" width="100" label="排行"></el-table-column> <el-table-column prop="name" width="208" label="代理商"></el-table-column> <el-table-column prop="value_1" width="100" label="退单率"></el-table-column> <el-table-column prop="value_2" width="100" label="退单数"></el-table-column> </el-table> </div> <!-- 触发弹框的按钮 --> <span v-if="top_list[row.id]" slot="reference"> No.1 {{ top_list[row.id]['name'] }} <span class="color-red">{{ top_list[row.id]['value_1'] }}%</span> <span class="color-red">{{ top_list[row.id]['value_2'] }}单</span> <img v-if="show_detail_index == row.sort" @click="handleClick(row, $index, 'id')" class="detail_icon" src="@/assets/super/list-detail.svg"> </span> <span v-else slot="reference">暂无排行</span> </el-popover> </template> </el-table-column> </el-table> <el-pagination background @size-change='handleSizeChange' @current-change='handleCurrentChange' :current-page="currentPage" :page-size=pageSize layout="prev, pager, next,jumper" :total="total"> </el-pagination> </el-form> </div> </div> </template> <script> import DateSelect from '@/components/super/DateSelect.vue'; import CustomDropdown from '@/components/CustomDropdown.vue'; export default { name: 'rank_list', props: { pageTitle: { type: String, default: '' }, rank_type: { type: Number, default: 0 }, type: { type: String, default: '' } }, components: { DateSelect, CustomDropdown }, data() { return { rank_type_desc: { 1: '毛利润', 2: '订单数', 3: '退单数', }, type_desc: { 'agent': '代理商昵称', 'ver_type': '品牌名称', 'check_type': '服务名称', }, type_select: { 'ver_type': '按品牌名称', 'check_type': '按服务名称', }, selectedType: 'check_type', viewDesc: { 'month': '月份', 'monthTwo': '月份', 'year': '年份', }, view: 'month', currentPage: 1, //当前页 pageSize: 20, //每页的容量 total: 0, //列表总数 sort_by: 1, sort_order: 2, showfilterTitle: false, filterTitle: "", text: '',//下拉框显示具体文案 selectedDate: new Date(),//默认当天日期 dataType: '', dataRank: '', tableData: [], total_value: 0, tableData1: [], growth_list: [], top_list: [], show_detail_index: 0, } }, mounted() { this.init() }, computed: {}, watch: { '$route'() { this.init() } }, methods: { init() { document.title = this.pageTitle; this.text = this.getNowDate() this.dataType = this.type this.dataRank = this.rank_type this.aid = this.$route.query.aid this.ver_type = this.$route.query.ver_type this.check_type = this.$route.query.check_type if (this.$route.query.date) this.text = this.$route.query.date if (this.$route.query.type) this.dataType = this.$route.query.type if (this.$route.query.rank_type) this.dataRank = this.$route.query.rank_type if (Object.keys(this.$route.query).length > 0) this.showfilterTitle = true this.getRankingData(); // 每次路由变化都重新获取数据 }, handleUpdateView(newView) { this.view = newView; }, getNowDate() { const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份从 0 开始,补零 const currentYearMonth = `${year}-${month}`; return `${currentYearMonth}` }, getDate(dateStr) { const date = new Date(dateStr); const year = date.getFullYear(); // 2025 const month = date.getMonth() + 1; // 3 (表示3月) if (this.view == 'year') { return `${year}` } else { return `${year}-${month}` } }, handleDateChange(date) { this.text = this.getDate(date) this.selectedDate = date; localStorage.setItem('date', JSON.stringify(date)) this.$refs.dropdownRef.closeDropdown(); // 更新数据 this.getRankingData() }, goLookMoreData(id) { let query = {} query.date = this.text query.rank_type = this.dataRank if (this.dataType == 'agent') { query.aid = id } if (this.dataType == 'ver_type') { query.ver_type = id } if (this.dataType == 'check_type') { query.check_type = id } window.open(this.$router.resolve({ path: '/super/ranking/detail', query: query }).href, '_blank') }, goLookMoreRank(id) { let query = {} query.date = this.text query.rank_type = this.dataRank query.type = 'agent' if (this.dataType == 'agent') { query.aid = id } if (this.dataType == 'ver_type') { query.ver_type = id } if (this.dataType == 'check_type') { query.check_type = id } window.open(this.$router.resolve({ path: '/super/ranking/list', query: query }).href, '_blank') }, closePop(row, type) { row[type + '_popover'] = false; row[type + '_popover_2'] = false; }, handleClick(row, index, type) { // 关闭其他行的弹框 this.tableData.forEach((item, i) => { item[type + '_popover_2'] = false; if (i !== index) { item[type + '_popover'] = false; } }); // 打开当前行的弹框 row[type + '_popover'] = true; let obj = {} if (this.dataType == 'agent') { obj.aid = row.id } if (this.dataType == 'ver_type') { obj.ver_type = row.id } if (this.dataType == 'check_type') { obj.check_type = row.id } this.getRankingList(obj); }, handleClick2(row, index, type) { // 关闭其他行的弹框 this.tableData.forEach((item, i) => { item[type + '_popover'] = false; if (i !== index) { item[type + '_popover_2'] = false; } }); // 打开当前行的弹框 row[type + '_popover_2'] = true; let obj = {} if (this.dataType == 'agent') { obj.aid = row.id } if (this.dataType == 'ver_type') { obj.ver_type = row.id } if (this.dataType == 'check_type') { obj.check_type = row.id } this.getRankingDetail(obj); }, popshow() { var ariaEls = document.querySelectorAll('.el-popover') ariaEls.forEach((item) => { item.removeAttribute('aria-hidden') }) ariaEls = document.querySelectorAll('.el-radio__original') ariaEls.forEach((item) => { item.removeAttribute('aria-hidden') }) }, handleSortChange({prop, order}) { this.sort_by = 1; this.sort_order = 2; if (order == 'ascending') { this.sort_by = prop; this.sort_order = 1; } if (order == 'descending') { this.sort_by = prop; this.sort_order = 2; } this.currentPage = 1; this.getRankingData() }, changeRankType() { this.dataType = this.selectedType this.getRankingData() }, handleRowHover(row) { this.show_detail_index = row.sort }, getRankingData() { if (this.dataType == 'agent') { this.getAgentRanking() } if (this.dataType == 'ver_type') { this.getVerRanking() } if (this.dataType == 'check_type') { this.getTypeRanking() } }, getAgentRanking() { const that = this this.$http('POST', '/supernew/ajax_get_agent_rank_list', { ver_type: that.ver_type, check_type: that.check_type, date: that.text, rank_type: that.dataRank, sort_by: that.sort_by, sort_order: that.sort_order, cur_page: that.currentPage, page_size: that.pageSize, }).then(response => { this.$nextTick(() => { that.tableData = response.data.list that.total_value = response.data.total_value that.growth_list = response.data.growth_list that.total = response.data.total if (that.showfilterTitle) that.filterTitle = response.data.title }) }).catch(error => { console.error(error, 'error') }) }, getVerRanking() { const that = this this.$http('POST', '/supernew/ajax_get_ver_rank_list', { aid: that.aid, check_type: that.check_type, date: that.text, rank_type: that.dataRank, sort_by: that.sort_by, sort_order: that.sort_order, cur_page: that.currentPage, page_size: that.pageSize, }).then(response => { this.$nextTick(() => { that.tableData = response.data.list that.total_value = response.data.total_value that.top_list = response.data.top_list that.growth_list = response.data.growth_list that.total = response.data.total if (that.showfilterTitle) that.filterTitle = response.data.title }) }).catch(error => { console.error(error, 'error') }) }, getTypeRanking() { const that = this this.$http('POST', '/supernew/ajax_get_type_rank_list', { aid: that.aid, ver_type: that.ver_type, date: that.text, rank_type: that.dataRank, sort_by: that.sort_by, sort_order: that.sort_order, cur_page: that.currentPage, page_size: that.pageSize, }).then(response => { this.$nextTick(() => { that.tableData = response.data.list that.total_value = response.data.total_value that.top_list = response.data.top_list that.growth_list = response.data.growth_list that.total = response.data.total if (that.showfilterTitle) that.filterTitle = response.data.title }) }).catch(error => { console.error(error, 'error') }) }, getRankingDetail(obj) { const that = this that.tableData1 = [] that.growth_list1 = [] this.$http('POST', '/supernew/ajax_get_rank_detail', { date: that.text, rank_type: that.dataRank, sort_by: 2, sort_order: 2, ...obj }).then(response => { this.$nextTick(() => { that.tableData1 = response.data.list.slice(0, 5) that.growth_list1 = response.data.growth_list }) }).catch(error => { console.error(error, 'error') }) }, getRankingList(obj) { const that = this that.tableData1 = [] that.growth_list1 = [] this.$http('POST', '/supernew/ajax_get_agent_rank_list', { date: that.text, rank_type: that.dataRank, cur_page: 1, page_size: 5, ...obj }).then(response => { this.$nextTick(() => { that.tableData1 = response.data.list }) }).catch(error => { console.error(error, 'error') }) }, handleSizeChange(val) { this.pageSize = val this.getRankingData() }, handleCurrentChange(val) { this.currentPage = val this.getRankingData() }, } } </script> <style scoped lang="scss"> </style>