|
|
@@ -1,3 +1,6 @@
|
|
|
+<!--
|
|
|
+ 小程序客户业绩:按客户汇总金额/成本/利润;隔天售后记通过日扣减(后端 statCustomCg)。
|
|
|
+-->
|
|
|
<template>
|
|
|
<view class="app-content">
|
|
|
<view class="ex-page">
|
|
|
@@ -15,49 +18,49 @@
|
|
|
<view class="space-view ex-table">
|
|
|
<block>
|
|
|
<t-table :headerBackgroundColor="'#F0F2F6'">
|
|
|
- <!-- 合计在表头上方:五项同一行,颜色用主题蓝,和灰色表头区分 -->
|
|
|
- <view class="stat-summary">
|
|
|
- <view class="stat-summary-item">
|
|
|
- <view class="stat-summary-label">笔数</view>
|
|
|
- <view class="stat-summary-value">{{profile.totalNum||0}}</view>
|
|
|
- </view>
|
|
|
- <view class="stat-summary-item">
|
|
|
- <view class="stat-summary-label">扎数</view>
|
|
|
- <view class="stat-summary-value">{{totalCount}}</view>
|
|
|
- </view>
|
|
|
- <view class="stat-summary-item">
|
|
|
- <view class="stat-summary-label">金额</view>
|
|
|
- <view class="stat-summary-value">¥{{profile.totalAmount||0}}</view>
|
|
|
- </view>
|
|
|
- <view class="stat-summary-item">
|
|
|
- <view class="stat-summary-label">成本</view>
|
|
|
- <view class="stat-summary-value">¥{{profile.totalCost||0}}</view>
|
|
|
- </view>
|
|
|
- <view class="stat-summary-item">
|
|
|
- <view class="stat-summary-label">利润</view>
|
|
|
- <view class="stat-summary-value">¥{{profile.totalProfit||0}}</view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- <!-- 客户名改为行标题独占一行,表头只保留 5 列指标,避免 6 列均分把长名称挤成单字换行 -->
|
|
|
<t-tr header>
|
|
|
+ <t-th>客户</t-th>
|
|
|
<t-th>笔数</t-th>
|
|
|
<t-th>扎数</t-th>
|
|
|
<t-th>金额</t-th>
|
|
|
<t-th>成本</t-th>
|
|
|
<t-th>利润</t-th>
|
|
|
</t-tr>
|
|
|
- <block v-if="profile.list && !$util.isEmpty(profile.list)">
|
|
|
- <view v-for="(item, index) in profile.list" :key="index" class="sale-item">
|
|
|
- <view class="sale-item-name">{{item.customName?item.customName:'-'}}</view>
|
|
|
- <t-tr>
|
|
|
- <t-td><view class="sale-cell">{{parseFloat(item.num)}}笔</view></t-td>
|
|
|
- <t-td><view class="sale-cell">{{item.count?parseFloat(item.count):0}}扎</view></t-td>
|
|
|
- <t-td><view class="sale-cell">¥{{parseFloat(item.amount)}}</view></t-td>
|
|
|
- <t-td><view class="sale-cell">¥{{parseFloat(item.cost)}}</view></t-td>
|
|
|
- <t-td><view class="sale-cell">¥{{parseFloat(item.profit)}}</view></t-td>
|
|
|
- </t-tr>
|
|
|
- </view>
|
|
|
- </block>
|
|
|
+ <view style="color:#1c89e0;font-size:24upx;margin:10upx;line-height:1.5;">
|
|
|
+ 金额、利润已按售后扣减(隔天售后记在通过日,可为负;笔数不减)。扎数:当天售后未从开单扎数扣除,隔天退货会在通过日扣扎数。成本仍取开单剩余成本。
|
|
|
+ </view>
|
|
|
+ <view v-if="Number(nextDayDeduct) > 0" style="color:#e67e22;font-size:26upx;margin:0 10upx 10upx 10upx;font-weight:bold;">
|
|
|
+ 本时段隔天售后扣减:¥{{ nextDayDeduct }}
|
|
|
+ </view>
|
|
|
+ <block v-if="displayList && !$util.isEmpty(displayList)">
|
|
|
+ <view v-for="(item, index) in displayList" :key="index">
|
|
|
+ <t-tr>
|
|
|
+ <t-td><view style="color:#333333;font-size:28upx;">{{item.customName?item.customName:'-'}}</view></t-td>
|
|
|
+ <t-td><view style="color:#333333;font-size:28upx;">{{parseFloat(item.num)||0}}</view></t-td>
|
|
|
+ <t-td>
|
|
|
+ <!-- 小程序 :style 不能调方法,用三元写死样式 -->
|
|
|
+ <view :style="Number(item.count) < 0 ? 'color:#e74c3c;font-weight:bold;font-size:28upx;' : 'color:#333333;font-size:28upx;'">{{formatNum(item.count)}}</view>
|
|
|
+ </t-td>
|
|
|
+ <t-td>
|
|
|
+ <view :style="Number(item.amount) < 0 ? 'color:#e74c3c;font-weight:bold;font-size:28upx;' : 'color:#333333;font-size:28upx;'">¥{{formatNum(item.amount)}}</view>
|
|
|
+ </t-td>
|
|
|
+ <t-td><view style="color:#333333;font-size:28upx;">¥{{formatNum(item.cost)}}</view></t-td>
|
|
|
+ <t-td>
|
|
|
+ <view :style="Number(item.profit) < 0 ? 'color:#e74c3c;font-weight:bold;font-size:28upx;' : 'color:#333333;font-size:28upx;'">¥{{formatNum(item.profit)}}</view>
|
|
|
+ </t-td>
|
|
|
+ </t-tr>
|
|
|
+ </view>
|
|
|
+ </block>
|
|
|
+ <t-tr><t-td>
|
|
|
+ <view :style="Number(profile.totalAmount) < 0 || Number(profile.totalProfit) < 0 ? 'color:#e74c3c;font-weight:bold;font-size:28upx;' : 'color:black;font-weight:bold;font-size:28upx;'">
|
|
|
+ {{profile.totalNum||0}}笔¥{{formatNum(profile.totalAmount)}} 成本¥{{ formatNum(profile.totalCost) }} 利润¥{{ formatNum(profile.totalProfit) }}
|
|
|
+ </view>
|
|
|
+ </t-td></t-tr>
|
|
|
+ <t-tr><t-td>
|
|
|
+ <view style="color:#1c89e0;font-size:28upx;">
|
|
|
+ 从2025年11月20号起是准确数据,之前的数据不准确
|
|
|
+ </view>
|
|
|
+ </t-td></t-tr>
|
|
|
</t-table>
|
|
|
</block>
|
|
|
</view>
|
|
|
@@ -67,10 +70,6 @@
|
|
|
</view>
|
|
|
</template>
|
|
|
<script>
|
|
|
-/**
|
|
|
- * ghsApp 客户业绩:按客户汇总笔数/扎数/金额/成本/利润。
|
|
|
- * 工作台「客户业绩」进入;长客户名单独占满一行,避免与指标挤在同一行导致排版走样。
|
|
|
- */
|
|
|
import AppWrapperEmpty from "@/components/app-wrapper-empty";
|
|
|
import { getStatKhCgProfile } from "@/api/stat/index";
|
|
|
import { list } from "@/mixins";
|
|
|
@@ -83,35 +82,25 @@ export default {
|
|
|
mixins: [list],
|
|
|
computed: {
|
|
|
...mapGetters(["getDictionariesInfo","getLoginInfo"]),
|
|
|
- // 总扎数:优先用接口 totalCount;list 经 PHP 关联数组 JSON 后可能是对象,不能直接 forEach
|
|
|
- totalCount() {
|
|
|
- const profile = Array.isArray(this.profile) ? {} : (this.profile || {})
|
|
|
- if (profile.totalCount != null && profile.totalCount !== '') {
|
|
|
- return parseFloat(profile.totalCount) || 0
|
|
|
- }
|
|
|
- const list = profile.list
|
|
|
- let rows = []
|
|
|
- if (Array.isArray(list)) {
|
|
|
- rows = list
|
|
|
- } else if (list && typeof list === 'object') {
|
|
|
- rows = Object.keys(list).map(key => list[key])
|
|
|
+ /** 列表统一成数组,避免接口返回对象时 v-for 异常 */
|
|
|
+ displayList() {
|
|
|
+ const raw = (this.profile && this.profile.list) || [];
|
|
|
+ if (Array.isArray(raw)) {
|
|
|
+ return raw;
|
|
|
}
|
|
|
- let sum = 0
|
|
|
- for (let i = 0; i < rows.length; i++) {
|
|
|
- sum += parseFloat(rows[i] && rows[i].count) || 0
|
|
|
- }
|
|
|
- return parseFloat(sum.toFixed(2)) || 0
|
|
|
- }
|
|
|
+ return Object.keys(raw).map(k => raw[k]);
|
|
|
+ },
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
params:{
|
|
|
- searchTime:'',
|
|
|
+ searchTime:'today',
|
|
|
startTime: "",
|
|
|
endTime: "",
|
|
|
},
|
|
|
- profile:[],
|
|
|
+ profile:{},
|
|
|
searchText:'',
|
|
|
+ nextDayDeduct: 0,
|
|
|
};
|
|
|
},
|
|
|
onPullDownRefresh() {
|
|
|
@@ -122,6 +111,10 @@ export default {
|
|
|
},
|
|
|
methods: {
|
|
|
...mapActions(['setUserShopAll']),
|
|
|
+ formatNum(val) {
|
|
|
+ const n = parseFloat(val);
|
|
|
+ return isNaN(n) ? 0 : n;
|
|
|
+ },
|
|
|
searchFn(e){
|
|
|
this.searchText = e;
|
|
|
},
|
|
|
@@ -135,9 +128,13 @@ export default {
|
|
|
getList() {
|
|
|
let that = this
|
|
|
uni.showLoading()
|
|
|
- getStatKhCgProfile(this.params).then(res => {
|
|
|
+ return getStatKhCgProfile(this.params).then(res => {
|
|
|
+ uni.hideLoading()
|
|
|
+ const data = (res && res.data) ? res.data : {}
|
|
|
+ that.profile = data
|
|
|
+ that.nextDayDeduct = that.formatNum(data.nextDayDeduct)
|
|
|
+ }).catch(() => {
|
|
|
uni.hideLoading()
|
|
|
- that.profile = res.data
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
@@ -206,58 +203,6 @@ export default {
|
|
|
::v-deep.icon-info {
|
|
|
color: #333333;
|
|
|
}
|
|
|
- /* 名称与指标拆成两行:名称用满屏宽完整展示,指标 5 列对齐表头且不再被撑高 */
|
|
|
- .sale-item {
|
|
|
- border-bottom: 1upx solid #eeeeee;
|
|
|
- ::v-deep .t-tr {
|
|
|
- border-bottom: none;
|
|
|
- padding-top: 8upx;
|
|
|
- padding-bottom: 16upx;
|
|
|
- }
|
|
|
- }
|
|
|
- /* 客户名用主题蓝加粗,和下面黑色指标数字区分开,当作每组数据的行标题 */
|
|
|
- .sale-item-name {
|
|
|
- padding: 20upx 40upx 4upx;
|
|
|
- color: #3385FF;
|
|
|
- font-size: 28upx;
|
|
|
- font-weight: bold;
|
|
|
- line-height: 1.4;
|
|
|
- word-break: break-all;
|
|
|
- }
|
|
|
- .sale-cell {
|
|
|
- color: #333333;
|
|
|
- font-size: 28upx;
|
|
|
- white-space: nowrap;
|
|
|
- }
|
|
|
- /* 合计五项同一行;排不下才换行。数值用主题蓝,和灰色表头区分 */
|
|
|
- .stat-summary {
|
|
|
- display: flex;
|
|
|
- flex-direction: row;
|
|
|
- flex-wrap: wrap;
|
|
|
- background: #F7F8FA;
|
|
|
- padding: 16upx 8upx 4upx;
|
|
|
- border-bottom: 1upx solid #eeeeee;
|
|
|
- }
|
|
|
- .stat-summary-item {
|
|
|
- flex: 1;
|
|
|
- min-width: 120upx;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- align-items: center;
|
|
|
- margin-bottom: 12upx;
|
|
|
- }
|
|
|
- .stat-summary-label {
|
|
|
- font-size: 24upx;
|
|
|
- color: #666666;
|
|
|
- margin-bottom: 6upx;
|
|
|
- }
|
|
|
- .stat-summary-value {
|
|
|
- font-size: 24upx;
|
|
|
- font-weight: bold;
|
|
|
- color: #333333;
|
|
|
- text-align: center;
|
|
|
- word-break: break-all;
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
.bar-view {
|
|
|
@@ -280,4 +225,4 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-</style>
|
|
|
+</style>
|