负毛利统计 #26

Merged
pengda merged 1 commits from wpd_loss2 into master 1 week ago
  1. 130
      src/components/Pagination.vue
  2. 8
      src/components/super/RankingLeftMenu.vue
  3. 26
      src/router/index.js
  4. 89
      src/views/super/Ranking/RankDetail.vue
  5. 33
      src/views/super/Ranking/RankList.vue

130
src/components/Pagination.vue

@ -0,0 +1,130 @@
<template>
<div class="pagination">
<button @click="click('first')" :disabled="cur_page === 1">首页</button>
<button @click="click('prev')" :disabled="cur_page === 1">上一页</button>
<span class="page-info"> {{ cur_page }} </span>
<button @click="click('next')" :disabled="!hasNext">下一页</button>
<button @click="click('last')" :disabled="!hasNext">尾页</button>
<input type="number" v-model.number="jumpPage" min="1" />
<button @click="click('jump')">跳转</button>
</div>
</template>
<script>
export default {
name: 'SimplePager',
props: {
curPage: {
type: Number,
required: true
},
hasNext: {
type: Boolean,
default: true
}
},
data() {
return {
jumpPage: null,
cur_page: this.curPage,
};
},
watch: {
curPage(newVal) {
this.jumpPage = newVal;
this.cur_page = newVal;
}
},
methods: {
click(type) {
let payload = {
first: 0,
prev: 0,
next: 0,
last: 0,
jump: 0,
cur_page: this.cur_page
};
switch (type) {
case 'first':
payload.first = 1;
payload.cur_page = 1;
break;
case 'prev':
payload.prev = 1;
payload.cur_page = Math.max(1, this.cur_page - 1);
break;
case 'next':
if (!this.hasNext) return;
payload.next = 1;
payload.cur_page = this.cur_page + 1;
break;
case 'last':
payload.last = 1;
payload.cur_page = this.cur_page;
break;
case 'jump':
if (this.jumpPage && this.jumpPage > 0) {
payload.jump = this.jumpPage;
payload.cur_page = this.jumpPage;
} else {
return;
}
break;
}
this.$emit('change', payload);
}
}
};
</script>
<style scoped>
.pagination {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
margin: 12px 0;
}
button {
padding: 6px 12px;
border: 1px solid #ccc;
background-color: #f8f8f8;
cursor: pointer;
border-radius: 4px;
font-size: 14px;
transition: all 0.2s;
}
button:hover:not(:disabled) {
background-color: #e6f7ff;
border-color: #91d5ff;
}
button:disabled {
cursor: not-allowed;
opacity: 0.5;
}
.page-info {
font-size: 14px;
margin: 0 6px;
}
input[type='number'] {
width: 70px;
padding: 8px 8px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 14px;
transition: border-color 0.2s, box-shadow 0.2s;
outline: none;
}
input[type='number']:focus {
border-color: #40a9ff;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
</style>

8
src/components/super/RankingLeftMenu.vue

@ -53,6 +53,10 @@ export default {
name: '退单数排行',
path: '/super/ranking/checkRefund',
},
{
name: '负毛利排行',
path: '/super/ranking/loss',
},
]
},
{
@ -78,10 +82,6 @@ export default {
imgActive: require('@/assets/super/ranking-menu.svg'),
list: [
{
name: '负毛利',
path: '/super/ranking/loss',
},
{
name: '采购价',
path: '/super/ranking/purchase',
},

26
src/router/index.js

@ -161,6 +161,12 @@ const routes = [{
props: {pageTitle:'产品 - 退单数排行', rank_type: 3, type: 'check_type'}
},
{
path: 'loss',
name: '产品负毛利排行',
component: () => import( /* webpackChunkName: "Ranking" */ '../views/super/Ranking/RankList.vue'),
props: {pageTitle:'产品 - 负毛利排行', rank_type: 5, type: 'loss'}
},
{
path: 'agentProfit',
name: '代理商毛利润排行',
component: () => import( /* webpackChunkName: "Ranking" */ '../views/super/Ranking/RankBatchList.vue'),
@ -179,12 +185,6 @@ const routes = [{
props: {pageTitle:'代理商 - 新加盟', type: 'agentnew', showDateSelect: false}
},
{
path: 'loss',
name: '负毛利',
component: () => import( /* webpackChunkName: "Ranking" */ '../views/super/Ranking/RankDetail.vue'),
props: {pageTitle:'负毛利 - 排行', type: 'loss'}
},
{
path: 'purchase',
name: '采购价',
component: () => import( /* webpackChunkName: "Ranking" */ '../views/super/Ranking/Purchase.vue'),
@ -196,20 +196,26 @@ const routes = [{
component: () => import( /* webpackChunkName: "Ranking" */ '../views/super/Ranking/Purchase.vue'),
props: {pageTitle:'设置 - 阶段采购', type: 'stagePurchase'}
},
]
},
{
path: '/super/ranking/detail',
path: 'detail',
name: '详情',
component: () => import( /* webpackChunkName: "Ranking" */ '../views/super/Ranking/RankDetail.vue'),
props: {pageTitle:'详情', type: 'day', showDateSelect: false, lookMore:false}
},
{
path: '/super/ranking/list',
path: 'list',
name: '列表',
component: () => import( /* webpackChunkName: "Ranking" */ '../views/super/Ranking/RankList.vue'),
props: {pageTitle:'详情', showDateSelect: false, lookMore:false}
},
{
path: 'order',
name: '订单统计',
component: () => import( /* webpackChunkName: "Ranking" */ '../views/super/Ranking/RankDetail.vue'),
props: {pageTitle:'订单统计', type: 'order', showDateSelect: false}
},
]
},
]
const router = new VueRouter({

89
src/views/super/Ranking/RankDetail.vue

@ -199,33 +199,22 @@
</el-form>
</div>
<div class=" flex-common" v-if="dataType == 'loss'">
<div 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;">总负毛利{{ total_value }}</span>
</div>
<div class=" flex-common" v-if="dataType == 'order'">
<el-form>
<el-table :data="tableData"
style="width: 100%"
@sort-change="handleSortChange"
@cell-mouse-enter="handleRowHover">
<el-table-column prop="sort" label="排序"></el-table-column>
<el-table-column prop="1" label="日期" sortable="custom">
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="sale_id" label="订单ID"></el-table-column>
<el-table-column prop="income" label="收入"></el-table-column>
<el-table-column prop="cost" label="成本"></el-table-column>
<el-table-column prop="profit" label="毛利"></el-table-column>
<el-table-column prop="is_refund" label="是否退款">
<template slot-scope="scope">
{{ scope.row.value_1 }}
</template>
</el-table-column>
<el-table-column prop="2" label="负毛利" sortable="custom">
<template slot-scope="scope">
{{ scope.row.value_2 }}
{{ scope.row.is_refund == 1 ? '是' : '否' }}
</template>
</el-table-column>
<el-table-column prop="sale_date" label="销售日期"></el-table-column>
</el-table>
</el-form>
<Pagination :curPage="cur_page" :hasNext="has_next" @change="handleChange" />
</div>
</div>
</template>
@ -233,6 +222,7 @@
import DateSelect from '@/components/super/DateSelect.vue';
import CustomDropdown from '@/components/CustomDropdown.vue';
import HoverImage from "@/components/super/HoverImage.vue";
import Pagination from "@/components/Pagination.vue";
export default {
name: 'rank_detail',
@ -259,6 +249,7 @@ export default {
},
},
components: {
Pagination,
HoverImage,
DateSelect,
CustomDropdown
@ -292,6 +283,10 @@ export default {
top_list: [],
growth_list: [],
show_detail_index: 0,
has_next: false,
cur_page: 1,
page_size: 20,
page_point: 0,
}
},
mounted() {
@ -408,9 +403,8 @@ export default {
return true;
}
if (this.dataType == 'loss') {
this.onlyYear = false;
this.getLossDetail(obj)
if (this.dataType == 'order') {
this.getOrderList()
return true;
}
@ -441,28 +435,6 @@ export default {
console.error(error, 'error')
})
},
getLossDetail(obj) {
const that = this
that.tableData = []
that.total_value = 0
this.$http('POST', '/supernew/ajax_get_loss_detail', {
aid: that.aid,
ver_type: that.ver_type,
check_type: that.check_type,
date: that.text,
...obj
}).then(response => {
this.$nextTick(() => {
that.tableData = response.data.list
that.total_value = response.data.total_value
that.total = response.data.total
if (that.showfilterTitle) that.filterTitle = response.data.title
})
}).catch(error => {
console.error(error, 'error')
})
},
getRankingList(obj) {
const that = this
that.tableData1 = []
@ -492,6 +464,31 @@ export default {
console.error(error, 'error')
})
},
getOrderList(obj) {
const that = this
that.tableData = []
this.$http('POST', '/supernew/ajax_get_order_check_list', {
aid: that.aid,
ver_type: that.ver_type,
check_type: that.check_type,
page_point: that.page_point,
lose: 1,
...obj
}).then(response => {
this.$nextTick(() => {
that.tableData = response.data.list
that.has_next = response.data.hasNext
if(!that.has_next) that.cur_page = response.data.cur_page
that.page_point = response.data.page_point
})
}).catch(error => {
console.error(error, 'error')
})
},
handleChange(payload) {
this.cur_page = payload.cur_page
this.getOrderList(payload)
}
}
}
</script>

33
src/views/super/Ranking/RankList.vue

@ -219,11 +219,13 @@ export default {
1: '毛利润',
2: '订单数',
3: '退单数',
5: '负毛利',
},
type_desc: {
'agent': '代理商昵称',
'ver_type': '品牌名称',
'check_type': '服务名称',
'loss': '服务名称',
},
type_select: {
'ver_type': '按品牌名称',
@ -278,6 +280,10 @@ export default {
if (this.$route.query.rank_type) this.dataRank = this.$route.query.rank_type
if (Object.keys(this.$route.query).length > 0) this.showfilterTitle = true
if (this.dataType == 'loss') {
this.sort_order = 1;
}
this.getRankingData(); //
},
handleUpdateView(newView) {
@ -439,6 +445,9 @@ export default {
if (this.dataType == 'check_type') {
this.getTypeRanking()
}
if (this.dataType == 'loss') {
this.getLossList()
}
},
getAgentRanking() {
const that = this
@ -550,6 +559,30 @@ export default {
console.error(error, 'error')
})
},
getLossList() {
const that = this
that.tableData = []
this.$http('POST', '/supernew/ajax_get_loss_list', {
aid: that.aid,
ver_type: that.ver_type,
check_type: that.check_type,
date: that.text,
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.total = response.data.total
if (that.showfilterTitle) that.filterTitle = response.data.title
})
}).catch(error => {
console.error(error, 'error')
})
},
handleSizeChange(val) {
this.pageSize = val
this.getRankingData()

Loading…
Cancel
Save