Browse Source

Merge branch 'after-sale' into redesign‌-260706

shish 21 hours ago
parent
commit
1f42df8199

+ 77 - 15
ghs/src/views/assets/cgItem.vue

@@ -1,3 +1,7 @@
+<!--
+  PC 采购花材排行:与小程序 admin/stat/cgItem 同源 /stat-cg/profit。
+  入库日净量 + 隔天通过日扣数量/金额(可为负);请求参数与小程序对齐。
+-->
 <template>
 	<div class="shop-list">
 		<x-crud @load="onLoad">
@@ -10,15 +14,26 @@
 			</template>
 
             <template #slot-total-amount>
-				<span style="font-size:15px;font-weight:bold;"></span>
+				<div class="cg-total-wrap">
+					<div class="cg-total-nums">
+						<span style="font-size:15px;font-weight:bold;">
+							<span :style="negStyle(totalNum)">{{ formatNum(totalNum) }}</span> 扎
+							¥<span :style="negStyle(totalAmount)">{{ formatNum(totalAmount) }}</span>
+						</span>
+						<span v-if="Number(nextDayDeduct) > 0" style="font-size:15px;font-weight:bold;margin-left:15px;color:#e67e22;">隔天售后扣减:¥{{ formatNum(nextDayDeduct) }}</span>
+					</div>
+					<div class="cg-tip">
+						数量、金额已按售后扣减(隔天售后记在通过日,可为负)。入库日不含隔天退货量。
+					</div>
+				</div>
 			</template>
 
-			<template #table-column-mll="{scope}">
-				<span>{{ scope.row.mll }}%</span>
+			<template #table-column-num="{scope}">
+				<span :style="negStyle(scope.row.num)">{{ formatNum(scope.row.num) }}</span>
         	</template>
 
-			<template #table-column-num="{scope}">
-				<span>{{ scope.row.num?parseFloat(scope.row.num):0 }}</span>
+			<template #table-column-amount="{scope}">
+				<span :style="negStyle(scope.row.amount)">{{ formatNum(scope.row.amount) }}</span>
         	</template>
 
 		</x-crud>
@@ -61,17 +76,49 @@ export default {
             startTime:'',
             endTime:'',
             searchTime:'',
+			/** 与小程序 cgItem 一致:默认按数量排序 */
+			sort: 'num',
             totalAmount:0,
 			totalNum:0,
-			totalMl:0
+			nextDayDeduct:0
 		}
 	},
 	computed: {
 		...mapGetters(['shopInfo']),
 	},
 	methods: {
+		/** 数字展示:不用 truthy,避免负数被当成空 */
+		formatNum(val) {
+			const n = parseFloat(val);
+			return isNaN(n) ? 0 : n;
+		},
+		negStyle(val) {
+			const n = Number(val);
+			return (!isNaN(n) && n < 0) ? 'color:#e74c3c;font-weight:bold;' : '';
+		},
+		/** 与小程序 getStatCgItem 对齐的查询参数 */
+		queryParams(extra) {
+			return {
+				searchTime: this.searchTime,
+				startTime: this.startTime,
+				endTime: this.endTime,
+				sort: this.sort,
+				...(extra || {})
+			};
+		},
+		/** 接口未返回合计时,按列表汇总数量/金额(含负数行) */
+		sumListTotals(list) {
+			let totalNum = 0;
+			let totalAmount = 0;
+			(list || []).forEach((row) => {
+				totalNum += this.formatNum(row.num);
+				totalAmount += this.formatNum(row.amount);
+			});
+			this.totalNum = totalNum;
+			this.totalAmount = Math.round(totalAmount * 100) / 100;
+		},
 		exportData(){
-			this.$service.statCg.getProfit({searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime,export:1}).then(res => {
+			this.$service.statCg.getProfit(this.queryParams({export:1})).then(res => {
 				if(res.file){
 					window.location.href = res.file
 				}
@@ -81,11 +128,10 @@ export default {
                 this.app = app;
                 ctx.service({
                     page: () => {
-                        return this.$service.statCg.getProfit({searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime}).then((res) => {
-							this.totalAmount = res.totalAmount||0
-							this.totalMl = res.totalMl||0
-							this.totalNum = res.totalNum||0
-							let list = [...res.list]
+                        return this.$service.statCg.getProfit(this.queryParams()).then((res) => {
+							this.nextDayDeduct = this.formatNum(res.nextDayDeduct)
+							const list = Array.isArray(res.list) ? res.list : Object.keys(res.list || {}).map(k => res.list[k])
+							this.sumListTotals(list)
                             return {
                                 list: list
                             };
@@ -111,7 +157,7 @@ export default {
 						}
 					],
 					op: {
-						visible: true,
+						visible: false,
 						props: {
 							width: 250,
 							align: 'center',
@@ -137,7 +183,7 @@ export default {
             this.searchTime = 'custom'
             this.startTime = this.currentDateList[0]
             this.endTime = this.currentDateList[1]
-            this.app.refresh({searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime});
+            this.app.refresh(this.queryParams());
         }
 	},
 };
@@ -147,4 +193,20 @@ export default {
 .shop-list {
   height: 100%;
 }
-</style>
+.cg-total-wrap {
+  display: block;
+  width: 100%;
+}
+.cg-total-nums {
+  display: block;
+  line-height: 1.6;
+}
+.cg-tip {
+  display: block;
+  width: 100%;
+  margin-top: 8px;
+  font-size: 13px;
+  color: #1c89e0;
+  line-height: 1.6;
+}
+</style>

+ 70 - 14
ghs/src/views/assets/incomeClass.vue

@@ -1,3 +1,7 @@
+<!--
+  PC 收支分类:与小程序 classProfit 同源 /stat/class-profit(StatSaleClass::classProfile)。
+  采购成本、销售收入已含隔天售后通过日扣减;仅退款含隔天通过日金额。
+-->
 <template>
 	<div class="shop-list">
 		<x-crud @load="onLoad">
@@ -8,6 +12,26 @@
 			<template #slot-export-due>
 				<el-button type="primary" size="mini" style="margin-left:60px;" @click="exportData()">导出数据</el-button>
 			</template>
+			<template #slot-class-tip>
+				<div class="class-tip">
+					采购成本、销售收入已按售后扣减(隔天售后记在通过日,分类成本/收入可为负)。采购仅退款、销售仅退款含隔天通过日金额。
+				</div>
+			</template>
+			<template #table-column-income="{scope}">
+				<div :style="negStyle(scope.row.income)">{{ formatNum(scope.row.income) }}</div>
+			</template>
+			<template #table-column-expend="{scope}">
+				<div :style="negStyle(scope.row.expend)">{{ formatNum(scope.row.expend) }}</div>
+			</template>
+			<template #table-column-profit="{scope}">
+				<div :style="negStyle(scope.row.profit)">{{ formatNum(scope.row.profit) }}</div>
+			</template>
+			<template #table-column-saleNum="{scope}">
+				<div :style="negStyle(scope.row.saleNum)">{{ formatNum(scope.row.saleNum) }}</div>
+			</template>
+			<template #table-column-cgNum="{scope}">
+				<div :style="negStyle(scope.row.cgNum)">{{ formatNum(scope.row.cgNum) }}</div>
+			</template>
 		</x-crud>
 	</div>
 </template>
@@ -55,8 +79,27 @@ export default {
 		...mapGetters(['shopInfo']),
 	},
 	methods: {
+		/** 数字展示:避免 undefined / NaN */
+		formatNum(val) {
+			const n = parseFloat(val);
+			return isNaN(n) ? 0 : n;
+		},
+		/** 负数量/金额标红,突出隔天通过日扣减 */
+		negStyle(val) {
+			const n = Number(val);
+			return (!isNaN(n) && n < 0) ? 'color:#e74c3c;font-weight:bold;' : '';
+		},
+		/** 与小程序 classProfit 相同查询参数 */
+		queryParams(extra) {
+			return {
+				searchTime: this.searchTime,
+				startTime: this.startTime,
+				endTime: this.endTime,
+				...(extra || {})
+			};
+		},
 		exportData(){
-			this.$service.stat.getClassProfit({searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime,export:1}).then(res => {
+			this.$service.stat.getClassProfit(this.queryParams({export:1})).then(res => {
 				if(res.file){
 					window.location.href = res.file
 				}
@@ -66,15 +109,20 @@ export default {
                 this.app = app;
                 ctx.service({
                     page: () => {
-                        return this.$service.stat.getClassProfit({searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime}).then((res) => {
+                        return this.$service.stat.getClassProfit(this.queryParams()).then((res) => {
+							const packFreight = this.formatNum(res.packFreight)
+							const onlyRefundCg = this.formatNum(res.onlyRefundCg)
+							const onlyRefund = this.formatNum(res.onlyRefund)
+							const totalLabourCost = this.formatNum(res.totalLabourCost)
+							const totalDiscountAmount = this.formatNum(res.totalDiscountAmount)
 							let list = [
-								...res.list,
-								{className:'物流打包费',income:0,expend:res.packFreight,profit:-res.packFreight,saleNum:0,cgNum:0},
-								{className:'采购仅退款',income:res.onlyRefundCg,expend:0,profit:res.onlyRefundCg,saleNum:0,cgNum:0},
-								{className:'销售仅退款',income:0,expend:res.onlyRefund,profit:-res.onlyRefund,saleNum:0,cgNum:0},
-								{className:'附加人工费',income:res.totalLabourCost,expend:0,profit:res.totalLabourCost,saleNum:0,cgNum:0},
-								{className:'优惠金额',income:-res.totalDiscountAmount,expend:0,profit:-res.totalDiscountAmount,saleNum:0,cgNum:0},
-								{className:'【汇总金额】',income:res.totalIncome,expend:res.totalExpend,profit:res.totalProfit,saleNum:0,cgNum:0}
+								...(res.list || []),
+								{className:'物流打包费',income:0,expend:packFreight,profit:-packFreight,saleNum:0,cgNum:0},
+								{className:'采购仅退款',income:onlyRefundCg,expend:0,profit:onlyRefundCg,saleNum:0,cgNum:0},
+								{className:'销售仅退款',income:0,expend:onlyRefund,profit:-onlyRefund,saleNum:0,cgNum:0},
+								{className:'附加人工费',income:totalLabourCost,expend:0,profit:totalLabourCost,saleNum:0,cgNum:0},
+								{className:'优惠金额',income:-totalDiscountAmount,expend:0,profit:-totalDiscountAmount,saleNum:0,cgNum:0},
+								{className:'【汇总金额】',income:this.formatNum(res.totalIncome),expend:this.formatNum(res.totalExpend),profit:this.formatNum(res.totalProfit),saleNum:0,cgNum:0}
 							]
                             return {
                                 list: list
@@ -116,7 +164,7 @@ export default {
 						},
 					],
 					op: {
-						visible: true,
+						visible: false,
 						props: {
 							width: 250,
 							align: 'center',
@@ -128,12 +176,11 @@ export default {
 				})
 				.set('layout', [
 					[   'slot-date-select',
-                        'slot-order-debt',
 						'slot-export-due',
 						'flex1'
 					],
 					[ 'data-table' ],
-                    ['flex1']
+                    ['slot-class-tip','flex1']
 				])
 				.done();
 			    app.refresh();
@@ -142,7 +189,7 @@ export default {
             this.searchTime = 'custom'
             this.startTime = this.currentDateList[0]
             this.endTime = this.currentDateList[1]
-            this.app.refresh({searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime});
+            this.app.refresh(this.queryParams());
         }
 	},
 };
@@ -152,4 +199,13 @@ export default {
 .shop-list {
   height: 100%;
 }
-</style>
+.class-tip {
+  display: block;
+  width: 100%;
+  margin-top: 10px;
+  padding: 0 4px;
+  font-size: 13px;
+  color: #1c89e0;
+  line-height: 1.6;
+}
+</style>

+ 67 - 14
ghs/src/views/assets/incomeOutItem.vue

@@ -1,3 +1,7 @@
+<!--
+  PC 花材收支明细:与 /stat/income-out-item(StatSaleClass::incomeOutItem)对齐。
+  销售/采购均按隔天售后通过日扣减(数量与金额可为负);仅退款含隔天通过日金额。
+-->
 <template>
 	<div class="shop-list">
 		<x-crud @load="onLoad">
@@ -8,6 +12,26 @@
 			<template #slot-export-due>
 				<el-button type="primary" size="mini" style="margin-left:60px;" @click="exportData()">导出数据</el-button>
 			</template>
+			<template #slot-item-tip>
+				<div class="item-tip">
+					采购成本、销售收入已按售后扣减(隔天售后记在通过日,花材成本/收入/数量可为负)。采购仅退款、销售仅退款含隔天通过日金额。
+				</div>
+			</template>
+			<template #table-column-income="{scope}">
+				<div :style="negStyle(scope.row.income)">{{ formatNum(scope.row.income) }}</div>
+			</template>
+			<template #table-column-expend="{scope}">
+				<div :style="negStyle(scope.row.expend)">{{ formatNum(scope.row.expend) }}</div>
+			</template>
+			<template #table-column-profit="{scope}">
+				<div :style="negStyle(scope.row.profit)">{{ formatNum(scope.row.profit) }}</div>
+			</template>
+			<template #table-column-inNum="{scope}">
+				<div :style="negStyle(scope.row.inNum)">{{ formatNum(scope.row.inNum) }}</div>
+			</template>
+			<template #table-column-outNum="{scope}">
+				<div :style="negStyle(scope.row.outNum)">{{ formatNum(scope.row.outNum) }}</div>
+			</template>
 		</x-crud>
 	</div>
 </template>
@@ -55,8 +79,24 @@ export default {
 		...mapGetters(['shopInfo']),
 	},
 	methods: {
+		formatNum(val) {
+			const n = parseFloat(val);
+			return isNaN(n) ? 0 : n;
+		},
+		negStyle(val) {
+			const n = Number(val);
+			return (!isNaN(n) && n < 0) ? 'color:#e74c3c;font-weight:bold;' : '';
+		},
+		queryParams(extra) {
+			return {
+				searchTime: this.searchTime,
+				startTime: this.startTime,
+				endTime: this.endTime,
+				...(extra || {})
+			};
+		},
 		exportData(){
-			this.$service.stat.getIncomeOutItem({searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime,export:1}).then(res => {
+			this.$service.stat.getIncomeOutItem(this.queryParams({export:1})).then(res => {
 				if(res.file){
 					window.location.href = res.file
 				}
@@ -66,15 +106,20 @@ export default {
                 this.app = app;
                 ctx.service({
                     page: () => {
-                        return this.$service.stat.getIncomeOutItem({searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime}).then((res) => {
+                        return this.$service.stat.getIncomeOutItem(this.queryParams()).then((res) => {
+							const packFreight = this.formatNum(res.packFreight)
+							const onlyRefundCg = this.formatNum(res.onlyRefundCg)
+							const onlyRefund = this.formatNum(res.onlyRefund)
+							const totalLabourCost = this.formatNum(res.totalLabourCost)
+							const totalDiscountAmount = this.formatNum(res.totalDiscountAmount)
 							let list = [
-								...res.list,
-								{name:'物流打包费',income:0,expend:res.packFreight,profit:-res.packFreight,inNum:0,outNum:0},
-								{name:'采购仅退款',income:res.onlyRefundCg,expend:0,profit:res.onlyRefundCg,inNum:0,outNum:0},
-								{name:'销售仅退款',income:0,expend:res.onlyRefund,profit:-res.onlyRefund,inNum:0,outNum:0},
-								{name:'附加人工费',income:res.totalLabourCost,expend:0,profit:res.totalLabourCost,inNum:0,outNum:0},
-								{name:'优惠金额',income:-res.totalDiscountAmount,expend:0,profit:-res.totalDiscountAmount,inNum:0,outNum:0},
-								{name:'【汇总金额】',income:res.totalIncome,expend:res.totalExpend,profit:res.totalProfit,inNum:0,outNum:0}
+								...(res.list || []),
+								{name:'物流打包费',income:0,expend:packFreight,profit:-packFreight,inNum:0,outNum:0},
+								{name:'采购仅退款',income:onlyRefundCg,expend:0,profit:onlyRefundCg,inNum:0,outNum:0},
+								{name:'销售仅退款',income:0,expend:onlyRefund,profit:-onlyRefund,inNum:0,outNum:0},
+								{name:'附加人工费',income:totalLabourCost,expend:0,profit:totalLabourCost,inNum:0,outNum:0},
+								{name:'优惠金额',income:-totalDiscountAmount,expend:0,profit:-totalDiscountAmount,inNum:0,outNum:0},
+								{name:'【汇总金额】',income:this.formatNum(res.totalIncome),expend:this.formatNum(res.totalExpend),profit:this.formatNum(res.totalProfit),inNum:0,outNum:0}
 							]
                             return {
                                 list: list
@@ -116,7 +161,7 @@ export default {
 						},
 					],
 					op: {
-						visible: true,
+						visible: false,
 						props: {
 							width: 250,
 							align: 'center',
@@ -128,12 +173,11 @@ export default {
 				})
 				.set('layout', [
 					[   'slot-date-select',
-                        'slot-order-debt',
 						'slot-export-due',
 						'flex1'
 					],
 					[ 'data-table' ],
-                    ['flex1']
+                    ['slot-item-tip','flex1']
 				])
 				.done();
 			    app.refresh();
@@ -142,7 +186,7 @@ export default {
             this.searchTime = 'custom'
             this.startTime = this.currentDateList[0]
             this.endTime = this.currentDateList[1]
-            this.app.refresh({searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime});
+            this.app.refresh(this.queryParams());
         }
 	},
 };
@@ -152,4 +196,13 @@ export default {
 .shop-list {
   height: 100%;
 }
-</style>
+.item-tip {
+  display: block;
+  width: 100%;
+  margin-top: 10px;
+  padding: 0 4px;
+  font-size: 13px;
+  color: #1c89e0;
+  line-height: 1.6;
+}
+</style>

+ 73 - 14
ghs/src/views/assets/itemSale.vue

@@ -1,3 +1,7 @@
+<!--
+  PC 花材销量:与小程序 productSale 同源 /stat-item/show。
+  支付日净销量 + 隔天通过日扣数量/金额(可为负);仅退款只扣金额。
+-->
 <template>
 	<div class="shop-list">
 		<x-crud @load="onLoad">
@@ -12,15 +16,35 @@
 			</template>
 
             <template #slot-total-amount>
-				<span style="font-size:15px;font-weight:bold;">{{totalNum}} 扎 ¥{{ totalAmount }} 总毛利 {{ totalMl }}</span>
+				<div class="sale-total-wrap">
+					<div class="sale-total-nums">
+						<span style="font-size:15px;font-weight:bold;">
+							<span :style="negStyle(totalNum)">{{ formatNum(totalNum) }}</span> 扎
+							¥<span :style="negStyle(totalAmount)">{{ formatNum(totalAmount) }}</span>
+							总毛利 <span :style="negStyle(totalMl)">{{ formatNum(totalMl) }}</span>
+						</span>
+						<span v-if="Number(nextDayDeduct) > 0" style="font-size:15px;font-weight:bold;margin-left:15px;color:#e67e22;">隔天售后扣减:¥{{ formatNum(nextDayDeduct) }}</span>
+					</div>
+					<div class="sale-tip">
+						数量、金额、毛利已按售后扣减(隔天售后记在通过日,可为负)。仅退款只扣金额不扣扎数。
+					</div>
+				</div>
 			</template>
 
 			<template #table-column-mll="{scope}">
-				<span>{{ scope.row.mll }}%</span>
+				<span>{{ formatNum(scope.row.mll) }}%</span>
         	</template>
 
 			<template #table-column-num="{scope}">
-				<span>{{ scope.row.num?parseFloat(scope.row.num):0 }}</span>
+				<span :style="negStyle(scope.row.num)">{{ formatNum(scope.row.num) }}</span>
+        	</template>
+
+			<template #table-column-amount="{scope}">
+				<span :style="negStyle(scope.row.amount)">{{ formatNum(scope.row.amount) }}</span>
+        	</template>
+
+			<template #table-column-gross="{scope}">
+				<span :style="negStyle(scope.row.gross)">{{ formatNum(scope.row.gross) }}</span>
         	</template>
 
 		</x-crud>
@@ -65,15 +89,34 @@ export default {
             searchTime:'',
             totalAmount:0,
 			totalNum:0,
-			totalMl:0
+			totalMl:0,
+			nextDayDeduct:0
 		}
 	},
 	computed: {
 		...mapGetters(['shopInfo']),
 	},
 	methods: {
+		/** 数字展示:不用 truthy,避免负数被当成空 */
+		formatNum(val) {
+			const n = parseFloat(val);
+			return isNaN(n) ? 0 : n;
+		},
+		negStyle(val) {
+			const n = Number(val);
+			return (!isNaN(n) && n < 0) ? 'color:#e74c3c;font-weight:bold;' : '';
+		},
+		/** 与小程序 productSale 对齐的查询参数 */
+		queryParams(extra) {
+			return {
+				searchTime: this.searchTime,
+				startTime: this.startTime,
+				endTime: this.endTime,
+				...(extra || {})
+			};
+		},
 		exportData(){
-			this.$service.statItem.getShow({searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime,export:1}).then(res => {
+			this.$service.statItem.getShow(this.queryParams({export:1})).then(res => {
 				if(res.file){
 					window.location.href = res.file
 				}
@@ -83,11 +126,12 @@ export default {
                 this.app = app;
                 ctx.service({
                     page: () => {
-                        return this.$service.statItem.getShow({searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime}).then((res) => {
-							this.totalAmount = res.totalAmount||0
-							this.totalMl = res.totalMl||0
-							this.totalNum = res.totalNum||0
-							let list = [...res.list]
+                        return this.$service.statItem.getShow(this.queryParams()).then((res) => {
+							this.totalAmount = this.formatNum(res.totalAmount)
+							this.totalMl = this.formatNum(res.totalMl)
+							this.totalNum = this.formatNum(res.totalNum)
+							this.nextDayDeduct = this.formatNum(res.nextDayDeduct)
+							const list = Array.isArray(res.list) ? res.list : Object.keys(res.list || {}).map(k => res.list[k])
                             return {
                                 list: list
                             };
@@ -123,7 +167,7 @@ export default {
 						}
 					],
 					op: {
-						visible: true,
+						visible: false,
 						props: {
 							width: 250,
 							align: 'center',
@@ -135,7 +179,6 @@ export default {
 				})
 				.set('layout', [
 					[   'slot-date-select',
-                        'slot-order-debt',
                         'slot-export-due',
 						'flex1'
 					],
@@ -149,7 +192,7 @@ export default {
             this.searchTime = 'custom'
             this.startTime = this.currentDateList[0]
             this.endTime = this.currentDateList[1]
-            this.app.refresh({searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime});
+            this.app.refresh(this.queryParams());
         }
 	},
 };
@@ -159,4 +202,20 @@ export default {
 .shop-list {
   height: 100%;
 }
-</style>
+.sale-total-wrap {
+  display: block;
+  width: 100%;
+}
+.sale-total-nums {
+  display: block;
+  line-height: 1.6;
+}
+.sale-tip {
+  display: block;
+  width: 100%;
+  margin-top: 8px;
+  font-size: 13px;
+  color: #1c89e0;
+  line-height: 1.6;
+}
+</style>

+ 71 - 5
ghs/src/views/custom/account.vue

@@ -1,3 +1,6 @@
+<!--
+  PC 应收统计:未扣隔天金额 / 隔天售后金额 / 已扣隔天金额 三分列,便于对照。
+-->
 <template>
 	<div class="shop-list">
 		<x-crud @load="onLoad">
@@ -15,13 +18,30 @@
 			</template>
 
             <template #slot-total-amount>
-				<span style="font-size:15px;font-weight:bold;">累计金额:{{ totalAmount }}</span>
+				<div class="yj-total-wrap">
+					<div class="yj-total-nums">
+						<span style="font-size:15px;font-weight:bold;">未扣隔天:¥{{ formatNum(totalOriginAmount) }}</span>
+						<span v-if="Number(nextDayDeduct) > 0" style="font-size:15px;font-weight:bold;margin-left:15px;color:#e67e22;">隔天售后:¥{{ formatNum(nextDayDeduct) }}</span>
+						<span :style="numStyle(totalAmount, true)">已扣隔天:¥{{ formatNum(totalAmount) }}</span>
+					</div>
+					<div class="yj-total-tip">
+						<div>未扣隔天=开单实付合计;隔天售后=通过日扣减额;已扣隔天=未扣隔天−隔天售后(可为负;订单数不减)。</div>
+					</div>
+				</div>
 			</template>
 
 			<template #slot-export-due>
 				<el-button type="primary" size="mini" style="margin-left:60px;" @click="exportDue()">导出数据</el-button>
 			</template>
 
+			<template #table-column-amount="{scope}">
+				<div :style="negOnly(scope.row.amount)">{{ formatNum(scope.row.amount) }}</div>
+			</template>
+
+			<template #table-column-nextDayAmount="{scope}">
+				<div :style="Number(scope.row.nextDayAmount) > 0 ? 'color:#e67e22;font-weight:bold;' : ''">{{ formatNum(scope.row.nextDayAmount) }}</div>
+			</template>
+
 		</x-crud>
 	</div>
 </template>
@@ -62,7 +82,9 @@ export default {
             startTime:'',
             endTime:'',
             searchTime:'',
+            totalOriginAmount:0,
             totalAmount:0,
+			nextDayDeduct:0,
             debt:'-1'
 		};
 	},
@@ -70,6 +92,22 @@ export default {
 		...mapGetters(['shopInfo']),
 	},
 	methods: {
+		formatNum(val) {
+			const n = parseFloat(val);
+			return isNaN(n) ? 0 : n;
+		},
+		numStyle(val, withMargin) {
+			const n = Number(val);
+			const base = 'font-size:15px;font-weight:bold;' + (withMargin ? 'margin-left:15px;' : '');
+			if (!isNaN(n) && n < 0) {
+				return base + 'color:#e74c3c;';
+			}
+			return base;
+		},
+		negOnly(val) {
+			const n = Number(val);
+			return (!isNaN(n) && n < 0) ? 'color:#e74c3c;font-weight:bold;' : '';
+		},
 		exportDue(){
 			this.$service.order.getAccountList({searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime,debt:this.debt,export:1}).then(res => {
 				if(res.file){
@@ -82,9 +120,11 @@ export default {
                 ctx.service({
                     page: () => {
                         return this.$service.order.getAccountList({searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime,debt:this.debt}).then((res) => {
-                            this.totalAmount = res.totalAmount ? res.totalAmount : 0
+                            this.totalOriginAmount = this.formatNum(res.totalOriginAmount)
+                            this.totalAmount = this.formatNum(res.totalAmount)
+							this.nextDayDeduct = this.formatNum(res.nextDayDeduct)
                             return {
-                                list: res.list
+                                list: res.list || []
                             };
                         });
                     }
@@ -107,7 +147,17 @@ export default {
 							align: 'center',
 						},
 						{
-							label: '金额',
+							label: '未扣隔天金额',
+							prop: 'originAmount',
+							align: 'center',
+						},
+						{
+							label: '隔天售后金额',
+							prop: 'nextDayAmount',
+							align: 'center',
+						},
+						{
+							label: '已扣隔天金额',
 							prop: 'amount',
 							align: 'center',
 						}
@@ -154,4 +204,20 @@ export default {
 .shop-list {
   height: 100%;
 }
-</style>
+.yj-total-wrap {
+  display: block;
+  width: 100%;
+}
+.yj-total-nums {
+  display: block;
+  line-height: 1.6;
+}
+.yj-total-tip {
+  display: block;
+  width: 100%;
+  margin-top: 10px;
+  font-size: 13px;
+  color: #1c89e0;
+  line-height: 1.6;
+}
+</style>

+ 58 - 10
ghs/src/views/custom/yj.vue

@@ -1,3 +1,6 @@
+<!--
+  PC 客户业绩:按账单时间汇总开单;隔天售后按通过日扣实际金额并计入退款(与小程序 customSale 对齐)。
+-->
 <template>
 	<div class="shop-list">
 		<x-crud @load="onLoad">
@@ -17,14 +20,23 @@
 			
 
             <template #slot-total-amount>
-				<span style="font-size:15px;font-weight:bold;">订单数:{{ totalNum }}</span>
-				<span style="font-size:15px;font-weight:bold;margin-left:15px;">订单金额:¥{{ totalOrderPrice }}</span>
-				<span style="font-size:15px;font-weight:bold;margin-left:15px;">退款金额:¥{{ totalTkPrice }}</span>
-				<span style="font-size:15px;font-weight:bold;margin-left:15px;">(仅退款金额:¥{{ totalOnlyTkPrice }})</span>
-				<span style="font-size:15px;font-weight:bold;margin-left:15px;">实际金额:¥{{ totalActPrice }}</span>
-				<span style="font-size:15px;font-weight:bold;margin-left:15px;">含(纸箱:{{ totalCartonNum }}个 ¥{{ totalCarton }}</span>
-				<span style="font-size:15px;font-weight:bold;margin-left:15px;">打包费:¥{{ totalPack }}</span>
-				<span style="font-size:15px;font-weight:bold;margin-left:15px;">运费:¥{{ totalFreight }})</span>
+				<div class="yj-total-wrap">
+					<div class="yj-total-nums">
+						<span style="font-size:15px;font-weight:bold;">订单数:{{ totalNum }}</span>
+						<span style="font-size:15px;font-weight:bold;margin-left:15px;">订单金额:¥{{ totalOrderPrice }}</span>
+						<span style="font-size:15px;font-weight:bold;margin-left:15px;">退款金额:¥{{ totalTkPrice }}</span>
+						<span style="font-size:15px;font-weight:bold;margin-left:15px;">(仅退款金额:¥{{ totalOnlyTkPrice }})</span>
+						<span :style="numStyle(totalActPrice, true)">实际金额:¥{{ totalActPrice }}</span>
+						<span style="font-size:15px;font-weight:bold;margin-left:15px;">含(纸箱:{{ totalCartonNum }}个 ¥{{ totalCarton }}</span>
+						<span style="font-size:15px;font-weight:bold;margin-left:15px;">打包费:¥{{ totalPack }}</span>
+						<span style="font-size:15px;font-weight:bold;margin-left:15px;">运费:¥{{ totalFreight }})</span>
+						<span v-if="Number(nextDayDeduct) > 0" style="font-size:15px;font-weight:bold;margin-left:15px;color:#e67e22;">隔天售后扣减:¥{{ nextDayDeduct }}</span>
+					</div>
+					<div class="yj-total-tip">
+						<div>实际金额、退款已按售后扣减(隔天售后记在通过日,实际金额可为负;订单数不减)。</div>
+						<div>纸箱/打包/运费仍按开单日剩余数量统计。</div>
+					</div>
+				</div>
 			</template>
 
 			<template #slot-export-data>
@@ -36,7 +48,11 @@
 			</template>
 
 			<template #table-column-tkPrice="{scope}">
-				<div style="cursor: pointer;" @click.stop="getTkDetail(scope.row)">{{ scope.row.tkPrice?parseFloat(scope.row.tkPrice):0 }}</div>
+				<div :style="numStyle(scope.row.tkPrice)" style="cursor: pointer;" @click.stop="getTkDetail(scope.row)">{{ formatNum(scope.row.tkPrice) }}</div>
+			</template>
+
+			<template #table-column-actPrice="{scope}">
+				<div :style="numStyle(scope.row.actPrice)">{{ formatNum(scope.row.actPrice) }}</div>
 			</template>
 
 		</x-crud>
@@ -88,6 +104,7 @@ export default {
 			totalTkPrice:0,
 			totalOnlyTkPrice:0,
 			totalNum:0,
+			nextDayDeduct:0,
             debt:'-1'
 		};
 	},
@@ -95,6 +112,20 @@ export default {
 		...mapGetters(['shopInfo']),
 	},
 	methods: {
+		/** 金额展示:空当 0 */
+		formatNum(val) {
+			const n = parseFloat(val);
+			return isNaN(n) ? 0 : n;
+		},
+		/** 负金额标红,便于识别隔天通过日扣减 */
+		numStyle(val, withMargin) {
+			const n = Number(val);
+			const neg = !isNaN(n) && n < 0;
+			if (withMargin) {
+				return 'font-size:15px;font-weight:bold;margin-left:15px;' + (neg ? 'color:#e74c3c;' : '');
+			}
+			return neg ? 'color:#e74c3c;font-weight:bold;' : '';
+		},
 		goChange(data){
 			let query = {};
 			query.customName = data.name
@@ -128,6 +159,7 @@ export default {
 							this.totalTkPrice = res.totalTkPrice ? res.totalTkPrice : 0
 							this.totalOnlyTkPrice = res.totalOnlyTkPrice?res.totalOnlyTkPrice:0
 							this.totalNum = res.totalNum?res.totalNum:0
+							this.nextDayDeduct = res.nextDayDeduct ? res.nextDayDeduct : 0
                             return {
                                 list: res.list
                             };
@@ -233,4 +265,20 @@ export default {
 .shop-list {
   height: 100%;
 }
-</style>
+.yj-total-wrap {
+  display: block;
+  width: 100%;
+}
+.yj-total-nums {
+  display: block;
+  line-height: 1.6;
+}
+.yj-total-tip {
+  display: block;
+  width: 100%;
+  margin-top: 10px;
+  font-size: 13px;
+  color: #1c89e0;
+  line-height: 1.6;
+}
+</style>

+ 71 - 5
ghs/src/views/in/due.vue

@@ -1,3 +1,6 @@
+<!--
+  PC 应付统计:未扣隔天金额 / 隔天售后金额 / 已扣隔天金额 三分列,便于对照。
+-->
 <template>
 	<div class="shop-list">
 		<x-crud @load="onLoad">
@@ -15,13 +18,30 @@
 			</template>
 
             <template #slot-total-amount>
-				<span style="font-size:15px;font-weight:bold;">累计金额:{{ totalAmount }}</span>
+				<div class="yj-total-wrap">
+					<div class="yj-total-nums">
+						<span style="font-size:15px;font-weight:bold;">未扣隔天:¥{{ formatNum(totalOriginAmount) }}</span>
+						<span v-if="Number(nextDayDeduct) > 0" style="font-size:15px;font-weight:bold;margin-left:15px;color:#e67e22;">隔天售后:¥{{ formatNum(nextDayDeduct) }}</span>
+						<span :style="numStyle(totalAmount, true)">已扣隔天:¥{{ formatNum(totalAmount) }}</span>
+					</div>
+					<div class="yj-total-tip">
+						<div>未扣隔天=入库实付合计;隔天售后=通过日扣减额;已扣隔天=未扣隔天−隔天售后(可为负;订单数不减)。</div>
+					</div>
+				</div>
 			</template>
 
 			<template #slot-export-due>
 				<el-button type="primary" size="mini" style="margin-left:60px;" @click="exportDue()">导出数据</el-button>
 			</template>
 
+			<template #table-column-amount="{scope}">
+				<div :style="negOnly(scope.row.amount)">{{ formatNum(scope.row.amount) }}</div>
+			</template>
+
+			<template #table-column-nextDayAmount="{scope}">
+				<div :style="Number(scope.row.nextDayAmount) > 0 ? 'color:#e67e22;font-weight:bold;' : ''">{{ formatNum(scope.row.nextDayAmount) }}</div>
+			</template>
+
 		</x-crud>
 	</div>
 </template>
@@ -62,7 +82,9 @@ export default {
             startTime:'',
             endTime:'',
             searchTime:'',
+            totalOriginAmount:0,
             totalAmount:0,
+			nextDayDeduct:0,
             debt:'0'
 		};
 	},
@@ -70,6 +92,22 @@ export default {
 		...mapGetters(['shopInfo']),
 	},
 	methods: {
+		formatNum(val) {
+			const n = parseFloat(val);
+			return isNaN(n) ? 0 : n;
+		},
+		numStyle(val, withMargin) {
+			const n = Number(val);
+			const base = 'font-size:15px;font-weight:bold;' + (withMargin ? 'margin-left:15px;' : '');
+			if (!isNaN(n) && n < 0) {
+				return base + 'color:#e74c3c;';
+			}
+			return base;
+		},
+		negOnly(val) {
+			const n = Number(val);
+			return (!isNaN(n) && n < 0) ? 'color:#e74c3c;font-weight:bold;' : '';
+		},
 		exportDue(){
 			this.$service.purchaseOrder.dueList({searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime,debt:this.debt,export:1}).then(res => {
 				if(res.file){
@@ -82,9 +120,11 @@ export default {
                 ctx.service({
                     page: () => {
                         return this.$service.purchaseOrder.dueList({searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime,debt:this.debt}).then((res) => {
-                            this.totalAmount = res.totalAmount ? res.totalAmount : 0
+                            this.totalOriginAmount = this.formatNum(res.totalOriginAmount)
+                            this.totalAmount = this.formatNum(res.totalAmount)
+							this.nextDayDeduct = this.formatNum(res.nextDayDeduct)
                             return {
-                                list: res.list
+                                list: res.list || []
                             };
                         });
                     }
@@ -107,7 +147,17 @@ export default {
 							align: 'center',
 						},
 						{
-							label: '金额',
+							label: '未扣隔天金额',
+							prop: 'originAmount',
+							align: 'center',
+						},
+						{
+							label: '隔天售后金额',
+							prop: 'nextDayAmount',
+							align: 'center',
+						},
+						{
+							label: '已扣隔天金额',
 							prop: 'amount',
 							align: 'center',
 						}
@@ -154,4 +204,20 @@ export default {
 .shop-list {
   height: 100%;
 }
-</style>
+.yj-total-wrap {
+  display: block;
+  width: 100%;
+}
+.yj-total-nums {
+  display: block;
+  line-height: 1.6;
+}
+.yj-total-tip {
+  display: block;
+  width: 100%;
+  margin-top: 10px;
+  font-size: 13px;
+  color: #1c89e0;
+  line-height: 1.6;
+}
+</style>

+ 68 - 19
ghs/src/views/in/yj.vue

@@ -1,3 +1,7 @@
+<!--
+  PC 供货业绩:与小程序 cgStat 同源 /stat-cg-ghs/profile;
+  隔天采购售后按通过日扣实际金额(可为负,订单数不减)。
+-->
 <template>
 	<div class="shop-list">
 		<x-crud @load="onLoad">
@@ -15,14 +19,23 @@
 			</template>
 
             <template #slot-total-amount>
-				<span style="font-size:15px;font-weight:bold;">订单数:{{ totalNum }}</span>
-				<span style="font-size:15px;font-weight:bold;margin-left:15px;">订单金额:{{ totalOrderPrice }}</span>
-				<span style="font-size:15px;font-weight:bold;margin-left:15px;">退款金额:{{ totalTkPrice }}</span>
-				<span style="font-size:15px;font-weight:bold;margin-left:15px;">(仅退款金额:{{ totalOnlyTkPrice }})</span>
-				<span style="font-size:15px;font-weight:bold;margin-left:15px;">实际金额:{{ totalActPrice }}</span>
-				<span style="font-size:15px;font-weight:bold;margin-left:15px;">含(纸箱:{{ totalCarton }}</span>
-				<span style="font-size:15px;font-weight:bold;margin-left:15px;">打包费:{{ totalPack }}</span>
-				<span style="font-size:15px;font-weight:bold;margin-left:15px;">运费:{{ totalFreight }})</span>
+				<div class="yj-total-wrap">
+					<div class="yj-total-nums">
+						<span style="font-size:15px;font-weight:bold;">订单数:{{ totalNum }}</span>
+						<span style="font-size:15px;font-weight:bold;margin-left:15px;">订单金额:{{ totalOrderPrice }}</span>
+						<span style="font-size:15px;font-weight:bold;margin-left:15px;">退款金额:{{ totalTkPrice }}</span>
+						<span style="font-size:15px;font-weight:bold;margin-left:15px;">(仅退款金额:{{ totalOnlyTkPrice }})</span>
+						<span :style="numStyle(totalActPrice, true)">实际金额:{{ totalActPrice }}</span>
+						<span style="font-size:15px;font-weight:bold;margin-left:15px;">含(纸箱:{{ totalCarton }}</span>
+						<span style="font-size:15px;font-weight:bold;margin-left:15px;">打包费:{{ totalPack }}</span>
+						<span style="font-size:15px;font-weight:bold;margin-left:15px;">运费:{{ totalFreight }})</span>
+						<span v-if="Number(nextDayDeduct) > 0" style="font-size:15px;font-weight:bold;margin-left:15px;color:#e67e22;">隔天售后扣减:¥{{ nextDayDeduct }}</span>
+					</div>
+					<div class="yj-total-tip">
+						<div>金额已按售后扣减(隔天售后记在通过日,可为负;订单数不减)。</div>
+						<div>纸箱/打包/运费仍按入库日剩余数量统计。</div>
+					</div>
+				</div>
 			</template>
 
 			<template #slot-export-data>
@@ -34,7 +47,11 @@
 			</template>
 
 			<template #table-column-tkPrice="{scope}">
-				<div style="cursor: pointer;" @click.stop="getTkDetail(scope.row)">{{ scope.row.tkPrice?parseFloat(scope.row.tkPrice):0 }}</div>
+				<div :style="numStyle(scope.row.tkPrice)" style="cursor: pointer;" @click.stop="getTkDetail(scope.row)">{{ formatNum(scope.row.tkPrice) }}</div>
+			</template>
+
+			<template #table-column-actPrice="{scope}">
+				<div :style="numStyle(scope.row.actPrice)">{{ formatNum(scope.row.actPrice) }}</div>
 			</template>
 
 		</x-crud>
@@ -85,6 +102,7 @@ export default {
 			totalTkPrice:0,
 			totalOnlyTkPrice:0,
 			totalNum:0,
+			nextDayDeduct:0,
             debt:'0'
 		};
 	},
@@ -92,6 +110,20 @@ export default {
 		...mapGetters(['shopInfo']),
 	},
 	methods: {
+		/** 数字展示:不用 truthy,避免 0/负数被当成空 */
+		formatNum(val) {
+			const n = parseFloat(val);
+			return isNaN(n) ? 0 : n;
+		},
+		/** 负金额标红,与小程序 cgStat 一致 */
+		numStyle(val, withMargin) {
+			const n = Number(val);
+			const neg = !isNaN(n) && n < 0;
+			if (withMargin) {
+				return 'font-size:15px;font-weight:bold;margin-left:15px;' + (neg ? 'color:#e74c3c;' : '');
+			}
+			return neg ? 'color:#e74c3c;font-weight:bold;' : '';
+		},
 		getTkDetail(info){
 			let query = {ghsId:info.id,ghsName:info.name,searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime,status:1};
 			this.$router.push({ path: '/in/refund-list', query })
@@ -117,16 +149,17 @@ export default {
                 ctx.service({
                     page: () => {
                         return this.$service.statCgGhs.getProfile({searchTime:this.searchTime,startTime:this.startTime,endTime:this.endTime,debt:this.debt}).then((res) => {
-                            this.totalActPrice = res.totalActPrice ? res.totalActPrice : 0
-							this.totalOrderPrice = res.totalOrderPrice ? res.totalOrderPrice : 0
-							this.totalCarton = res.totalCarton ? res.totalCarton : 0
-							this.totalPack = res.totalPack ? res.totalPack : 0
-							this.totalFreight = res.totalFreight ? res.totalFreight : 0
-							this.totalTkPrice = res.totalTkPrice ? res.totalTkPrice : 0
-							this.totalOnlyTkPrice = res.totalOnlyTkPrice ? res.totalOnlyTkPrice:0
-							this.totalNum = res.totalNum?res.totalNum:0
+                            this.totalActPrice = this.formatNum(res.totalActPrice)
+							this.totalOrderPrice = this.formatNum(res.totalOrderPrice)
+							this.totalCarton = this.formatNum(res.totalCarton)
+							this.totalPack = this.formatNum(res.totalPack)
+							this.totalFreight = this.formatNum(res.totalFreight)
+							this.totalTkPrice = this.formatNum(res.totalTkPrice)
+							this.totalOnlyTkPrice = this.formatNum(res.totalOnlyTkPrice)
+							this.totalNum = this.formatNum(res.totalNum)
+							this.nextDayDeduct = this.formatNum(res.nextDayDeduct)
                             return {
-                                list: res.list
+                                list: res.list || []
                             };
                         });
                     }
@@ -220,4 +253,20 @@ export default {
 .shop-list {
   height: 100%;
 }
-</style>
+.yj-total-wrap {
+  display: block;
+  width: 100%;
+}
+.yj-total-nums {
+  display: block;
+  line-height: 1.6;
+}
+.yj-total-tip {
+  display: block;
+  width: 100%;
+  margin-top: 10px;
+  font-size: 13px;
+  color: #1c89e0;
+  line-height: 1.6;
+}
+</style>

+ 45 - 11
ghsApp/src/admin/stat/cgItem.vue

@@ -1,3 +1,6 @@
+<!--
+  采购花材排行:入库日净量 + 隔天通过日扣数量/金额(可为负)。
+-->
 <template>
 <view class="app-content">
 	<view class="ex-page">
@@ -21,12 +24,23 @@
 						<view style="color:#1c89e0;font-size:24upx;margin:10upx;line-height:1.5;">
 							数量、金额已按售后扣减(隔天售后记在通过日,可为负)。入库日不含隔天退货量。
 						</view>
-						<block v-if="profile.list && !$util.isEmpty(profile.list)">
-							<view v-for="(item, index) in profile.list" :key="index">
+						<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="itemList && !$util.isEmpty(itemList)">
+							<view v-for="(item, index) in itemList" :key="index">
 								<t-tr>
 									<t-td><view style="color:black;font-size:26upx;">{{item.name}}</view></t-td>
-									<t-td><view style="color:black;font-size:28upx;">{{item.num ? parseFloat(item.num) : 0}}</view></t-td>
-									<t-td><view style="color:black;font-size:28upx;">¥{{item.amount ? parseFloat(item.amount) : 0}}</view></t-td>
+									<t-td>
+										<view :style="Number(item.num) < 0 ? 'color:#e74c3c;font-weight:bold;font-size:28upx;' : 'color:black;font-size:28upx;'">
+											{{ formatNum(item.num) }}
+										</view>
+									</t-td>
+									<t-td>
+										<view :style="Number(item.amount) < 0 ? 'color:#e74c3c;font-weight:bold;font-size:28upx;' : 'color:black;font-size:28upx;'">
+											¥{{ formatNum(item.amount) }}
+										</view>
+									</t-td>
 								</t-tr>
 							</view>
 						</block>
@@ -47,8 +61,21 @@ import AppSearchModule from "@/components/module/app-search";
 export default {
 	components: { AppWrapperEmpty,ShopSelect,DateSelect,AppSearchModule},
 	mixins: [list],
-	computed: {	
-
+	computed: {
+		/** 过滤全零行;搜索按名称/拼音 */
+		itemList() {
+			const kw = (this.searchContent || '').trim().toLowerCase()
+			const list = (this.profile && this.profile.list) ? this.profile.list : []
+			return list.filter(item => {
+				const num = Number(item.num) || 0
+				const amount = Number(item.amount) || 0
+				if (num === 0 && amount === 0) return false
+				if (!kw) return true
+				const name = (item.name || '').toLowerCase()
+				const py = (item.py || '').toLowerCase()
+				return name.indexOf(kw) >= 0 || py.indexOf(kw) >= 0
+			})
+		}
 	},
 	data() {
 		return {
@@ -58,7 +85,9 @@ export default {
 				endTime: "",
 				sort:"num"
 			},
-			profile:[]
+			profile:{},
+			searchContent: '',
+			nextDayDeduct: 0
 		};
 	},
 	onPullDownRefresh() {
@@ -68,8 +97,12 @@ export default {
 		});
 	},
 	methods: {
+		formatNum(val) {
+			const n = parseFloat(val)
+			return isNaN(n) ? 0 : n
+		},
 		searchFn(e){
-
+			this.searchContent = e
 		},
 		selectShopFn(val){
 			this.init();
@@ -88,9 +121,10 @@ export default {
 			let that = this
 			uni.showLoading()
 			this.params.sort = rank
-			getStatCgItem(this.params).then(res => {
+			return getStatCgItem(this.params).then(res => {
 				uni.hideLoading()
-				that.profile = res.data
+				that.profile = res.data || {}
+				that.nextDayDeduct = that.formatNum(res.data && res.data.nextDayDeduct)
 			})
 		}
 	}
@@ -177,4 +211,4 @@ export default {
 		}
 	}
 }
-</style>
+</style>

+ 43 - 10
ghsApp/src/admin/stat/cgStat.vue

@@ -1,3 +1,6 @@
+<!--
+  供货业绩:按供货商汇总采购金额(含隔天售后通过日扣减,金额可为负)。
+-->
 <template>
 <view class="app-content">
 	<view class="ex-page">
@@ -14,15 +17,24 @@
 				<block>
 					<t-table :headerBackgroundColor="'#F0F2F6'">
 						<t-tr header><t-th>供货商</t-th><t-th>订单数</t-th><t-th>金额</t-th><t-th>操作</t-th></t-tr>
-						<view style="font-size:30upx;margin:10upx 0 10upx 10upx;">总金额:{{ totalActPrice }}</view>
+						<view style="font-size:30upx;margin:10upx 0 10upx 10upx;">总金额:
+							<text :style="totalActPrice < 0 ? 'color:#e74c3c;font-weight:bold;' : ''">{{ totalActPrice }}</text>
+						</view>
 						<view style="color:#1c89e0;font-size:24upx;margin:0 10upx 10upx 10upx;line-height:1.5;">
 							金额已按售后扣减(隔天售后记在通过日,可为负;订单数不减)。
 						</view>
-						<view v-for="(item, index) in storageData" :key="index">
+						<view v-if="Number(nextDayDeduct) > 0" style="color:#e67e22;font-size:26upx;margin:0 10upx 10upx 10upx;font-weight:bold;">
+							本时段隔天售后扣减:¥{{ nextDayDeduct }}
+						</view>
+						<view v-for="(item, index) in displayList" :key="index">
 							<t-tr>
 								<t-td><view>{{item.name}}</view></t-td>
-								<t-td><view>{{parseFloat(item.num)}}</view></t-td>
-								<t-td><view>{{parseFloat(item.actPrice)}}</view></t-td>
+								<t-td><view>{{ formatNum(item.num) }}</view></t-td>
+								<t-td>
+									<view :style="Number(item.actPrice) < 0 ? 'color:#e74c3c;font-weight:bold;' : ''">
+										{{ formatNum(item.actPrice) }}
+									</view>
+								</t-td>
 								<t-td></t-td>
 							</t-tr>
 						</view>
@@ -45,7 +57,20 @@ export default {
 	components: { AppWrapperEmpty,ShopSelect,AppSearchModule,DateSelect },
 	mixins: [list],
 	computed: {		
-		...mapGetters(["getDictionariesInfo","getLoginInfo"])
+		...mapGetters(["getDictionariesInfo","getLoginInfo"]),
+		/** 有订单或金额非零才展示,避免全零行淹没隔天负金额 */
+		displayList() {
+			const kw = (this.searchContent || '').trim().toLowerCase()
+			return (this.storageData || []).filter(item => {
+				const num = Number(item.num) || 0
+				const act = Number(item.actPrice) || 0
+				if (num === 0 && act === 0) return false
+				if (!kw) return true
+				const name = (item.name || '').toLowerCase()
+				const py = (item.py || item.mobile || '').toLowerCase()
+				return name.indexOf(kw) >= 0 || py.indexOf(kw) >= 0
+			})
+		}
 	},
 	data() {
 		return {
@@ -66,7 +91,8 @@ export default {
 			params:{ itemId: '', searchTime:'', startTime: "", endTime: "", shopId: "", },
 			storageData:[],
 			searchContent:'',
-			totalActPrice:0
+			totalActPrice:0,
+			nextDayDeduct: 0
 		};
 	},
 	onPullDownRefresh() {
@@ -82,9 +108,13 @@ export default {
 	},
 	methods: {
 		...mapActions(['setUserShopAll']),
+		/** 数字展示:不用 truthy,避免 0/负数被当成空 */
+		formatNum(val) {
+			const n = parseFloat(val)
+			return isNaN(n) ? 0 : n
+		},
 		searchFn(e){
 			this.searchContent = e;
-			this.filterStat()
 		},
 		selectShopFn(val){
 			this.params.shopId = val.id;
@@ -101,13 +131,16 @@ export default {
 		getList() {
 			let that = this
 			uni.showLoading()
-			getStatCgGhsProfile(this.params).then(res => {
+			return getStatCgGhsProfile(this.params).then(res => {
 				uni.hideLoading()
 				if (!this.$util.isEmpty(res.data.list)) {
 					that.storageData = res.data.list
-					that.totalActPrice = res.data.totalActPrice?parseFloat(res.data.totalActPrice):0
+					that.totalActPrice = that.formatNum(res.data.totalActPrice)
+					that.nextDayDeduct = that.formatNum(res.data.nextDayDeduct)
 				}else{
 					that.storageData = []
+					that.totalActPrice = 0
+					that.nextDayDeduct = 0
 				}
 			})
 		}
@@ -199,4 +232,4 @@ export default {
 		}
 	}
 }
-</style>
+</style>

+ 34 - 10
ghsApp/src/admin/stat/cgYj.vue

@@ -1,3 +1,6 @@
+<!--
+  采购人业绩:按采购员汇总(隔天售后通过日扣金额,订单数不减;金额可为负)。
+-->
 <template>
 <view class="app-content">
 	<view class="ex-page">
@@ -21,12 +24,19 @@
 						<view style="color:#1c89e0;font-size:24upx;margin:10upx;line-height:1.5;">
 							金额已按售后扣减(隔天售后记在通过日,可为负;订单数不减)。
 						</view>
-						<block v-if="profile.staffCg && !$util.isEmpty(profile.staffCg)">
-							<view v-for="(cgItem, index) in profile.staffCg" :key="index">
+						<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="staffList && !$util.isEmpty(staffList)">
+							<view v-for="(cgItem, index) in staffList" :key="index">
 								<t-tr>
 									<t-td><view style="color:black;font-size:26upx;">{{cgItem.cgStaffName?cgItem.cgStaffName:'未记名'}}</view></t-td>
-									<t-td><view style="color:black;font-size:28upx;">{{cgItem.num?parseFloat(cgItem.num):0}}</view></t-td>
-									<t-td><view style="color:black;font-size:28upx;">¥{{cgItem.amount?parseFloat(cgItem.amount):0}}</view></t-td>
+									<t-td><view style="color:black;font-size:28upx;">{{ formatNum(cgItem.num) }}</view></t-td>
+									<t-td>
+										<view :style="Number(cgItem.amount) < 0 ? 'color:#e74c3c;font-weight:bold;font-size:28upx;' : 'color:black;font-size:28upx;'">
+											¥{{ formatNum(cgItem.amount) }}
+										</view>
+									</t-td>
 								</t-tr>
 							</view>
 						</block>
@@ -47,8 +57,16 @@ import AppSearchModule from "@/components/module/app-search";
 export default {
 	components: { AppWrapperEmpty,ShopSelect,DateSelect,AppSearchModule},
 	mixins: [list],
-	computed: {	
-
+	computed: {
+		/** 过滤全零行,保留隔天产生的负金额行 */
+		staffList() {
+			const list = (this.profile && this.profile.staffCg) ? this.profile.staffCg : []
+			return list.filter(item => {
+				const num = Number(item.num) || 0
+				const amount = Number(item.amount) || 0
+				return num !== 0 || amount !== 0
+			})
+		}
 	},
 	data() {
 		return {
@@ -58,7 +76,8 @@ export default {
 				endTime: "",
 				sort:"num"
 			},
-			profile:[]
+			profile:{},
+			nextDayDeduct: 0
 		};
 	},
 	onPullDownRefresh() {
@@ -68,6 +87,10 @@ export default {
 		});
 	},
 	methods: {
+		formatNum(val) {
+			const n = parseFloat(val)
+			return isNaN(n) ? 0 : n
+		},
 		searchFn(e){
 
 		},
@@ -88,9 +111,10 @@ export default {
 			let that = this
 			uni.showLoading()
 			this.params.sort = rank
-			getStatCgYj(this.params).then(res => {
+			return getStatCgYj(this.params).then(res => {
 				uni.hideLoading()
-				that.profile = res.data
+				that.profile = res.data || {}
+				that.nextDayDeduct = that.formatNum(res.data && res.data.nextDayDeduct)
 			})
 		}
 	}
@@ -177,4 +201,4 @@ export default {
 		}
 	}
 }
-</style>
+</style>

+ 1 - 2
ghsApp/src/admin/stat/classProfit.vue

@@ -60,9 +60,8 @@
 							<t-td><view style="color:black;font-size:28upx;color:#3385FF;">{{profit.totalProfit}}</view></t-td>
 						</t-tr>
 
-						<view style="margin-left:60upx;">以上暂未统计零售端【花掌柜】数据</view>
 						<view style="margin:10upx 60upx;color:#1c89e0;font-size:24upx;line-height:1.5;">
-							采购成本、销售收入已按售后扣减(隔天售后记在通过日,分类成本/收入可为负)。采购仅退款、销售仅退款含隔天通过日金额。
+							采购成本、销售收入已按售后扣减(隔天售后记在通过日,分类成本/收入可为负)。采购仅退款、销售仅退款含隔天通过日金额。与 PC 收支分类同源接口。
 						</view>
 
 						<view v-if="!$util.isEmpty(tbSaleIncome)">

+ 16 - 2
ghsApp/src/admin/stat/profit.vue

@@ -1,3 +1,6 @@
+<!--
+  经营利润:收入含「采购隔天退货」(通过日,退货并退款+仅退款合计);花材采购仍按入库日实付。
+-->
 <template>
 <view class="app-content">
 	<view class="ex-page">
@@ -12,10 +15,21 @@
 							<t-th>类型</t-th>
 							<t-th>金额</t-th>
 						</t-tr>
+						<view style="color:#1c89e0;font-size:24upx;margin:10upx;line-height:1.5;">
+							「采购隔天退货」按售后通过日记账(含退货并退款与仅退款);花材采购按入库日。
+						</view>
 						<block v-for="(item, inIndex) in profit.income" :key="inIndex">
 							<t-tr v-if="Number(item.amount)!=0">
-								<t-td><view style="color:black;font-size:30upx;">{{item.name}}</view></t-td>
-								<t-td><view style="color:black;font-size:30upx;">{{item.amount}}</view></t-td>
+								<t-td>
+									<view :style="item.id === 'cgNextDay' ? 'color:#e67e22;font-size:30upx;font-weight:bold;' : 'color:black;font-size:30upx;'">
+										{{item.name}}
+									</view>
+								</t-td>
+								<t-td>
+									<view :style="item.id === 'cgNextDay' ? 'color:#e67e22;font-size:30upx;font-weight:bold;' : 'color:black;font-size:30upx;'">
+										{{item.amount}}
+									</view>
+								</t-td>
 							</t-tr>
 						</block>
 						<!--同个节点v-for key重复会报错,所以再包一层-->