feat: 收支汇总 出货产品汇总 收货产品汇总 收货汇总

This commit is contained in:
admin 2024-09-12 14:48:22 +08:00
parent 32742835ed
commit 3b2f785c73
16 changed files with 812 additions and 693 deletions

View File

@ -0,0 +1,45 @@
<template>
<summaryTemplate :tableTitleList="tableTitleList" :summary="state.summary" @getList="getList"></summaryTemplate>
</template>
<script setup lang="ts">
import summaryTemplate from "@/components/Template/summaryTemplate.vue";
import { FinanceApi } from "@/services";
import { template } from "underscore";
const state = reactive<any>({
summary: {
calculateResult: []
}
})
const tableTitleList = reactive([
{
name: "收支方式",
key: "paymentName",
},
{
name: "付款金额/元",
key: "paymentPrice",
desc: '收货的付款金额(已付款状态)+出货(已收款状态)的运费杂费'
},
{
name: "收款金额/元",
key: "revenuePrice",
desc: '出货的已收款状态的实际收入(实际付款)之和'
}
]);
function getList(params:any) {
FinanceApi.getRevenuePaymentPage(params).then((res:any) => {
if (res.code === 200) {
state.summary = res.data.map(item => {return {...item, paymentName: ['', '现金支付', '银行卡支付', '线上支付(微信)', '支付宝', '其他'][item.paymentMethod]}});
let paymentPrice = 0;
let revenuePrice = 0;
res.data.forEach((item:any) => {
paymentPrice += item.paymentPrice
revenuePrice += item.revenuePrice
});
state.summary.calculateResult = ['合计', paymentPrice, revenuePrice]
}
});
}
</script>

View File

@ -1,316 +0,0 @@
<template>
<view class="layout-box">
<view class="filter">
<u-input
v-model="state.startTime"
disabled
disabledColor=""
placeholder="请选择开始时间"
></u-input>
<text>-</text>
<u-input
v-model="state.endTime"
disabled
disabledColor=""
placeholder="请选择结束时间"
></u-input>
<u-icon
name="arrow-down"
@click="handleDialog('showTime', true)"
></u-icon>
<text class="btn" @click="handleDialog('showFilter', true)">筛选</text>
</view>
<view class="box">
<up-row>
<up-col span="4">
<view class="inner-box" style="border: none">
<view class="num highlight">{{
formatMoney(state.summary.totalAmount, 2)
}}</view>
<view>收货总净重/kg</view>
</view>
</up-col>
<up-col span="4">
<view class="inner-box">
<view class="num">{{ formatMoney(state.summary.totalPaid, 2) }}</view>
<view>已付/kg</view>
</view>
</up-col>
<up-col span="4">
<view class="inner-box">
<view class="num">{{
formatMoney(state.summary.totalUnpaid,2)
}}</view>
<view>未付/kg</view>
</view>
</up-col>
</up-row>
</view>
<view class="box">
<up-row>
<up-col span="4">
<view class="inner-box" style="border: none">
<view class="num highlight">{{
formatMoney(state.summary.totalPayment,2)
}}</view>
<view>实际总付款/</view>
</view>
</up-col>
<up-col span="4">
<view class="inner-box">
<view class="num">{{
formatMoney(state.summary.totalPaidPrice,2)
}}</view>
<view>已付金额</view>
</view>
</up-col>
<up-col span="4">
<view class="inner-box">
<view class="num">{{
formatMoney(state.summary.totalUnpaidPrice,2)
}}</view>
<view>应付金额</view>
</view>
</up-col>
</up-row>
</view>
<view class="box">
<up-row>
<up-col span="6">
<view class="inner-box" style="border: none">
<view class="num">{{
formatMoney(state.summary.totalReceipt)
}}</view>
<view>收货单</view>
</view>
</up-col>
<up-col span="6">
<view class="inner-box">
<view class="num">{{
formatMoney(state.summary.averagePrice,2)
}}</view>
<view>均价/kg</view>
</view>
</up-col>
</up-row>
</view>
<view class="box">
<uni-table stripe emptyText="暂无更多数据">
<!-- 表头行 -->
<uni-tr>
<uni-th v-for="(item, index) in tableTitleList" :key="index">{{
item.name
}}</uni-th>
</uni-tr>
<!-- 表格数据行 -->
<uni-tr v-for="(item, index) in state.summary.rankings" :key="index">
<uni-td>{{ item.productName }}</uni-td>
<uni-td>{{ item.totalAmount }}</uni-td>
<uni-td>{{ item.totalPayment }}</uni-td>
<uni-td>{{ item.totalOrderNumber }}</uni-td>
<uni-td>{{ item.averagePrice }}</uni-td>
</uni-tr>
</uni-table>
</view>
</view>
<!-- 时间弹框 -->
<TimeDialog
ref="timeDialog"
:show="showDialog.showTime"
@handleDialog="(v:boolean) => {handleDialog('showTime', v)}"
@changeTime="changeTime"
/>
<!-- 筛选弹框 -->
<FilterDialog
:show="showDialog.showFilter"
@handleDialog="(v:boolean) => {handleDialog('showFilter', v)}"
@changeOther="changeOther"
:isShipment="false"
/>
</template>
<script setup lang="ts">
import TimeDialog from "@/components/Dialog/TimeDialog.vue";
import FilterDialog from "./components/FilterDialog.vue";
import { ReceiveApi } from "@/services";
import {
formatDate,
formatMoney,
getCurrentMonthStartAndEnd,
} from "@/utils";
const tableTitleList = reactive([
{
name: "收货产品",
},
{
name: "收货总净重/kg",
},
{
name: "收货总付款",
},
{
name: "收货单数",
},
{
name: "均价(元/kg",
},
]);
const showDialog = <
{
[key: string]: boolean;
}
>reactive({
showTime: false,
showFilter: false,
});
const state = reactive<{
summary: ReceiveSummaryCount;
startTime: string;
endTime: string;
scaleStatus: number;
userId: number;
productId: number;
}>({
summary: {
totalAmount: 0, //
totalPaid: 0, //
totalUnpaid: 0, //
totalPayment: 0, //
totalPaidPrice: 0, //
totalUnpaidPrice: 0, //
totalReceipt: 0, //
averagePrice: 0, //
rankings: [],
},
startTime: formatDate(getCurrentMonthStartAndEnd().start, "{y}-{m}-{d} {h}:{i}:{s}"),
endTime: formatDate(getCurrentMonthStartAndEnd().end, "{y}-{m}-{d} {h}:{i}:{s}"),
scaleStatus: -1,
userId: -1,
productId: -1,
});
const changeTime = (obj: any) => {
state.startTime = obj.startTime;
state.endTime = obj.endTime;
getList();
};
const changeOther = (obj: any) => {
state.userId = obj.userId;
state.productId = obj.productId;
getList();
};
const handleDialog = (key: string, v: boolean) => {
showDialog[key] = v;
};
const getList = () => {
let params: any = {
startTime: state.startTime,
endTime: state.endTime,
};
if (state.scaleStatus > -1) {
params.scaleStatus = state.scaleStatus;
}
if (state.userId > -1) {
params.userId = state.userId;
}
if (state.productId > -1) {
params.productId = state.productId;
}
ReceiveApi.OrderInReceipt(params).then((res) => {
if (res.code === 200) {
state.summary = res.data;
}
});
};
onMounted(() => {
getList();
});
</script>
<style lang="scss" scoped>
.layout-box {
margin: 35.9rpx 25.64rpx;
.filter {
display: flex;
align-items: center;
justify-items: center;
font-family: Source Han Sans CN;
font-size: 28rpx;
color: #000000;
::v-deep .u-input {
padding: 0rpx 16.03rpx !important;
input {
font-family: Source Han Sans CN;
font-weight: 400;
font-size: 24rpx !important;
color: #000000;
}
}
text {
margin: 0px 5rpx;
}
.status {
margin-left: 40rpx;
}
.btn {
color: $u-primary;
margin-left: 40rpx;
margin-right: 0rpx;
}
}
.box {
padding: 28rpx 20rpx;
// display: flex;
// justify-content: space-between;
align-items: center;
font-family: Source Han Sans CN;
font-weight: 400;
font-size: 26rpx;
color: #000000;
text-align: center;
background: #ffffff;
box-shadow: 0rpx 0rpx 10rpx 0rpx rgba(5, 68, 37, 0.12);
border-radius: 13rpx;
margin-top: 30rpx;
}
.inner-box {
text-align: center;
font-family: Source Han Sans CN;
font-weight: 400;
font-size: 26rpx;
color: #000000;
border-left: 1px solid #e9e9e9;
.num {
font-weight: bold;
font-size: 28rpx;
}
.highlight {
color: rgba(236, 15, 62, 1);
}
}
::v-deep .uni-table {
min-width: 500px !important;
.uni-table-th {
font-family: Source Han Sans CN;
font-weight: 500;
font-size: 24rpx;
color: #000000;
padding: 5px 5px;
}
.uni-table-td {
font-family: Source Han Sans CN;
font-weight: 400;
font-size: 24rpx;
color: #000000;
}
}
}
</style>

View File

@ -1,323 +0,0 @@
<template>
<view class="layout-box">
<view class="filter">
<u-input
v-model="state.startTime"
disabled
disabledColor=""
placeholder="请选择开始时间"
></u-input>
<text>-</text>
<u-input
v-model="state.endTime"
disabled
disabledColor=""
placeholder="请选择结束时间"
></u-input>
<u-icon
name="arrow-down"
@click="handleDialog('showTime', true)"
></u-icon>
<text class="btn" @click="handleDialog('showFilter', true)">筛选</text>
</view>
<view class="box">
<up-row>
<up-col span="4">
<view class="inner-box" style="border: none">
<view class="num highlight">{{
formatMoney(state.summary.totalAmount, 2)
}}</view>
<view>出货总净重/kg</view>
</view>
</up-col>
<up-col span="4">
<view class="inner-box">
<view class="num">{{
formatMoney(state.summary.totalPayShipment, 2)
}}</view>
<view>已收/kg</view>
</view>
</up-col>
<up-col span="4">
<view class="inner-box">
<view class="num">{{
formatMoney(state.summary.totalUnPayShipment, 2)
}}</view>
<view>未收/kg</view>
</view>
</up-col>
</up-row>
</view>
<view class="box">
<up-row>
<up-col span="4">
<view class="inner-box" style="border: none">
<view class="num highlight">{{
formatMoney(state.summary.totalCollection, 2)
}}</view>
<view>出货总收款/</view>
</view>
</up-col>
<up-col span="4">
<view class="inner-box">
<view class="num">{{
formatMoney(state.summary.totalPayCollection, 2)
}}</view>
<view>已收/</view>
</view>
</up-col>
<up-col span="4">
<view class="inner-box">
<view class="num">{{
formatMoney(state.summary.totalUnPayCollection, 2)
}}</view>
<view>未收/</view>
</view>
</up-col>
</up-row>
</view>
<view class="box">
<up-row>
<up-col span="6">
<view class="inner-box" style="border: none">
<view class="num">{{
formatMoney(state.summary.totalReceipt)
}}</view>
<view>出货单</view>
</view>
</up-col>
<up-col span="6">
<view class="inner-box">
<view class="num">{{
formatMoney(state.summary.averagePrice, 2)
}}</view>
<view>均价/kg</view>
</view>
</up-col>
</up-row>
</view>
<view class="box">
<uni-table stripe emptyText="暂无更多数据">
<!-- 表头行 -->
<uni-tr>
<uni-th v-for="(item, index) in tableTitleList" :key="index">{{
item.name
}}</uni-th>
</uni-tr>
<!-- 表格数据行 -->
<uni-tr v-for="(item, index) in state.summary.rankings" :key="index">
<uni-td>{{ item.userName }}</uni-td>
<uni-td>{{ item.totalAmount }}</uni-td>
<uni-td>{{ item.totalPayment }}</uni-td>
<uni-td>{{ item.actualPayment }}</uni-td>
<uni-td>{{ item.totalOrderNumber }}</uni-td>
</uni-tr>
</uni-table>
</view>
</view>
<!-- 时间弹框 -->
<TimeDialog
ref="timeDialog"
:show="showDialog.showTime"
@handleDialog="(v:boolean) => {handleDialog('showTime', v)}"
@changeTime="changeTime"
/>
<!-- 筛选弹框 -->
<FilterDialog
:show="showDialog.showFilter"
@handleDialog="(v:boolean) => {handleDialog('showFilter', v)}"
@changeOther="changeOther"
:isShipment="true"
/>
</template>
<script setup lang="ts">
import TimeDialog from "@/components/Dialog/TimeDialog.vue";
import FilterDialog from "./components/FilterDialog.vue";
import { ShipmentApi } from "@/services";
import {
formatDate,
formatMoney,
getCurrentMonthStartAndEnd,
getScaleStatus,
} from "@/utils";
const tableTitleList = reactive([
{
name: "客户",
},
{
name: "结算总净重/kg",
},
{
name: "结算金额",
},
{
name: "实际收款",
},
{
name: "数量",
},
]);
const showDialog = <
{
[key: string]: boolean;
}
>reactive({
showTime: false,
showFilter: false,
});
const state = reactive<{
summary: ShipmentSummaryCount;
startTime: string;
endTime: string;
scaleStatus: number;
userId: number;
productId: number;
}>({
summary: {
totalAmount: 0, //
totalPayShipment: 0, //
totalUnPayShipment: 0, //
totalCollection: 0, //
totalPayCollection: 0, //
totalUnPayCollection: 0, //
totalReceipt: 0, //
averagePrice: 0, //
rankings: [],
},
startTime: formatDate(
getCurrentMonthStartAndEnd().start,
"{y}-{m}-{d} {h}:{i}:{s}"
),
endTime: formatDate(
getCurrentMonthStartAndEnd().end,
"{y}-{m}-{d} {h}:{i}:{s}"
),
scaleStatus: -1,
userId: -1,
productId: -1,
});
const changeTime = (obj: any) => {
state.startTime = obj.startTime;
state.endTime = obj.endTime;
getList();
};
const changeOther = (obj: any) => {
state.userId = obj.userId;
state.productId = obj.productId;
getList();
};
const handleDialog = (key: string, v: boolean) => {
showDialog[key] = v;
};
const getList = () => {
let params: any = {
startTime: state.startTime,
endTime: state.endTime,
};
if (state.scaleStatus > -1) {
params.scaleStatus = state.scaleStatus;
}
if (state.userId > -1) {
params.userId = state.userId;
}
if (state.productId > -1) {
params.productId = state.productId;
}
ShipmentApi.getOrderInReceipt(params).then((res) => {
if (res.code === 200) {
state.summary = res.data;
}
});
};
onMounted(() => {
getList();
});
</script>
<style lang="scss" scoped>
.layout-box {
margin: 35.9rpx 25.64rpx;
.filter {
display: flex;
align-items: center;
justify-items: center;
font-family: Source Han Sans CN;
font-size: 28rpx;
color: #000000;
::v-deep .u-input {
padding: 0rpx 16.03rpx !important;
input {
font-family: Source Han Sans CN;
font-weight: 400;
font-size: 24rpx !important;
color: #000000;
}
}
text {
margin: 0px 5rpx;
}
.status {
margin-left: 40rpx;
}
.btn {
color: $u-primary;
margin-left: 40rpx;
margin-right: 0rpx;
}
}
.box {
padding: 28rpx 20rpx;
// display: flex;
// justify-content: space-between;
align-items: center;
font-family: Source Han Sans CN;
font-weight: 400;
font-size: 26rpx;
color: #000000;
text-align: center;
background: #ffffff;
box-shadow: 0rpx 0rpx 10rpx 0rpx rgba(5, 68, 37, 0.12);
border-radius: 13rpx;
margin-top: 30rpx;
}
.inner-box {
text-align: center;
font-family: Source Han Sans CN;
font-weight: 400;
font-size: 26rpx;
color: #000000;
border-left: 1px solid #e9e9e9;
.num {
font-weight: bold;
font-size: 27rpx;
}
.highlight {
color: rgba(236, 15, 62, 1);
}
}
::v-deep .uni-table {
min-width: 500px !important;
.uni-table-th {
font-family: Source Han Sans CN;
font-weight: 500;
font-size: 24rpx;
color: #000000;
padding: 5px 5px;
}
.uni-table-td {
font-family: Source Han Sans CN;
font-weight: 400;
font-size: 24rpx;
color: #000000;
}
}
}
</style>

View File

@ -0,0 +1,111 @@
<template>
<u-popup :show="show" mode="bottom" :round="10" :closeable="false" @close="handleClose">
<view class="c-dialog">
<view>
<view class="box">
<text @click="handleClose">取消</text>
<text class="btn" @click="handleOk">完成</text>
</view>
<uni-calendar
:insert="true"
:lunar="true"
:start-date="'2014-1-1'"
:end-date="'2099-1-1'"
:range="true"
@change="handleChangeDate"
/>
</view>
</view>
</u-popup>
</template>
<script setup lang="ts">
import { formatDate } from '@/utils';
const props = defineProps<{
show: boolean,
}>()
const emit = defineEmits(['handleDialog', 'handleOk']);
const handleClose = () => {
emit('handleDialog', false)
}
const handleOk = () => {
emit('handleOk', {startTime: state.startTime, endTime: state.endTime})
emit('handleDialog', false)
}
const showCalendar = ref(false)
const state = reactive({
startTime: '',
endTime: ''
})
const handleChangeDate = (v: any) => {
const time1 = v.range.before;
const time2 = v.range.after;
if (time1 && time2) {
const date1 = new Date(time1);
const date2 = new Date(time2);
if (date1 < date2) {
state.startTime = formatDate(time1, "{y}-{m}-{d}");
state.endTime = formatDate(time2, "{y}-{m}-{d}");
} else if (date1 > date2) {
state.startTime = formatDate(time2, "{y}-{m}-{d}");
state.endTime = formatDate(time1, "{y}-{m}-{d}");
} else {
state.startTime = formatDate(time1, "{y}-{m}-{d}");
state.endTime = formatDate(time2, "{y}-{m}-{d}");
}
}
};
</script>
<style lang="scss" scoped>
::v-deep .u-popup__content {
box-shadow: 0rpx 0rpx 10rpx 0rpx rgba(5, 68, 37, 0.12);
border-radius: 32rpx 32rpx 0rpx 0rpx;
}
.c-dialog {
margin: 30rpx;
font-family: Source Han Sans CN;
font-weight: 500;
font-size: 24rpx;
color: #000000;
.box-btn,
.box {
line-height: 80rpx;
display: flex;
justify-content: space-between;
}
.box-btn {
line-height: 40rpx;
margin-bottom: 30rpx;
text {
font-weight: 400;
font-size: 24rpx;
color: #999999;
width: 117rpx;
background: #ffffff;
border-radius: 6rpx;
border: 1px solid rgba(153, 153, 153, 0.64);
text-align: center;
cursor: pointer;
}
.active {
border-color: $u-primary;
color: $u-primary;
}
}
.btn {
font-weight: 500;
font-size: 24rpx;
color: $u-primary;
}
.box-border {
border-top: 1px solid rgba(233, 233, 233, 0.76);
}
.line {
height: 18rpx;
background: #f8f8f8;
}
}
</style>

View File

@ -0,0 +1,285 @@
<template>
<view class="layout-box">
<view class="c-layout">
<view class="card-box">
<view class="c-tab">
<text
v-for="(item, index) in tabList"
:key="index"
:class="{ active: currentTab === item.id }"
@click="handleTab(item)"
>
{{ item.name }}
</text>
</view>
<view class="c-grid">
<view v-if="currentTab === 5" class="time"
>{{ state.startTime.split(" ")[0] }} -
{{ state.endTime.split(" ")[0] }}</view
>
</view>
<view class="box">
<uni-table stripe emptyText="暂无更多数据">
<!-- 表头行 -->
<uni-tr>
<uni-th v-for="(item, index) in tableTitleList" :key="index"
>{{ item.name }}
<uni-tooltip v-if="item.desc" placement="bottom">
<u-icon color="#C1C1C1" name="info-circle" size="14"></u-icon>
<template v-slot:content>
<view
style="
min-width: 100px;
overflow: scroll;
word-break: break-word;
"
>
{{ item.desc }}
</view>
</template>
</uni-tooltip>
</uni-th>
</uni-tr>
<!-- 表格数据行 -->
<uni-tr v-for="(item, index) in summary" :key="index">
<uni-td v-for="(tItem, index) in tableTitleList" :key="index">{{
item[tItem.key]
}}</uni-td>
</uni-tr>
<uni-tr>
<uni-td
v-for="(item, index) in summary.calculateResult"
:key="index"
>
{{ item }}
</uni-td>
</uni-tr>
</uni-table>
</view>
</view>
</view>
<TimeRangeFilter
:show="isShowTimeDialog"
@handleDialog="handleDialog"
@handleOk="handleOk"
/>
</view>
</template>
<script setup lang="ts">
import {
formatDate,
getCurrentMonthStartAndEnd,
timeRange,
} from "@/utils";
import TimeRangeFilter from "@/components/Dialog/TimeRangeFilter.vue";
const props = defineProps<{
tableTitleList: Array<any>;
summary: any;
}>();
const emit = defineEmits(["getList"]);
const currentTab = ref(3);
const tabList = reactive([
// {
// id: 2,
// name: "",
// },
{
id: 1,
name: "当日",
},
{
id: 6,
name: "本周",
},
{
id: 3,
name: "本月",
},
{
id: 7,
name: "本季",
},
{
id: 4,
name: "本年",
},
{
id: 5,
name: "自定义",
},
]);
const state = reactive<{
startTime: string;
endTime: string;
}>({
startTime: formatDate(
getCurrentMonthStartAndEnd().start,
"{y}-{m}-{d} {h}:{i}:{s}"
),
endTime: formatDate(
getCurrentMonthStartAndEnd().end,
"{y}-{m}-{d} {h}:{i}:{s}"
),
});
const getList = () => {
if (currentTab.value !== 5) {
const range = timeRange(currentTab.value);
state.startTime = range.startTime + " 00:00:00";
state.endTime = range.endTime + " 23:59:59";
} else if (currentTab.value === 5) {
state.startTime = state.startTime + " 00:00:00";
state.endTime = state.endTime + " 23:59:59";
}
let params: any = {
startTime: state.startTime,
endTime: state.endTime,
};
console.log("*******", state.startTime);
console.log("*******", state.endTime);
emit("getList", params);
};
const handleTab = (item: any) => {
if (item.id === 5) {
handleDialog(true);
} else {
currentTab.value = item.id;
getList();
}
};
const isShowTimeDialog = ref(false);
const handleDialog = (v: boolean) => {
isShowTimeDialog.value = v;
};
const handleOk = (v: any) => {
state.startTime = v.startTime;
state.endTime = v.endTime;
currentTab.value = 5;
getList();
};
onMounted(() => {
getList();
});
</script>
<style lang="scss" scoped>
.card-box {
background: #ffffff;
box-shadow: 0rpx 0rpx 10rpx 0rpx rgba(5, 68, 37, 0.12);
border-radius: 13rpx;
.c-tab {
font-family: Source Han Sans CN;
font-weight: 400;
font-size: 28rpx;
color: #999999;
line-height: 41rpx;
display: flex;
align-items: center;
justify-content: space-around;
border-bottom: 1rpx solid rgba(233, 233, 233, 0.76);
text {
padding: 16rpx;
}
.active {
color: $u-primary;
border-bottom: 5rpx solid $u-primary;
border-radius: 5rpx;
}
}
.c-grid {
font-family: Source Han Sans CN;
font-weight: 400;
font-size: 24rpx;
color: #000000;
.time {
margin-top: 30rpx;
margin-right: 30rpx;
text-align: right;
font-size: 26rpx;
font-weight: bold;
}
}
}
.layout-box {
.filter {
display: flex;
align-items: center;
justify-items: center;
font-family: Source Han Sans CN;
font-size: 28rpx;
color: #000000;
::v-deep .u-input {
padding: 0rpx 16.03rpx !important;
input {
font-family: Source Han Sans CN;
font-weight: 400;
font-size: 24rpx !important;
color: #000000;
}
}
text {
margin: 0px 5rpx;
}
.status {
margin-left: 40rpx;
}
.btn {
color: $u-primary;
margin-left: 40rpx;
margin-right: 0rpx;
}
}
.box {
padding: 28rpx 20rpx;
// display: flex;
// justify-content: space-between;
align-items: center;
font-family: Source Han Sans CN;
font-weight: 400;
font-size: 26rpx;
color: #000000;
text-align: center;
background: #ffffff;
// box-shadow: 0rpx 0rpx 10rpx 0rpx rgba(5, 68, 37, 0.12);
border-radius: 13rpx;
}
.inner-box {
text-align: center;
font-family: Source Han Sans CN;
font-weight: 400;
font-size: 26rpx;
color: #000000;
border-left: 1px solid #e9e9e9;
.num {
font-weight: bold;
font-size: 28rpx;
}
.highlight {
color: rgba(236, 15, 62, 1);
}
}
::v-deep .uni-table {
.uni-table-th {
font-family: Source Han Sans CN;
font-weight: 500;
font-size: 24rpx;
color: #000000;
padding: 5px 5px;
}
.uni-table-td {
font-family: Source Han Sans CN;
font-weight: 400;
font-size: 24rpx;
color: #000000;
}
}
}
</style>

View File

@ -114,6 +114,18 @@
}
]
},
{
"root": "pagesShipmentData",
"pages": [
{
"path": "productSummary",
"style": {
"navigationBarTitleText": "出货产品汇总"
}
}
]
},
{
"root": "pagesShipment",
"pages": [
@ -182,24 +194,12 @@
{
"root": "pagesStatistics",
"pages": [
{
"path": "receivePanel",
"style": {
"navigationBarTitleText": "收货汇总"
}
},
{
"path": "supplierRanking",
"style": {
"navigationBarTitleText": "供应商排行"
}
},
{
"path": "shipmentPanel",
"style": {
"navigationBarTitleText": "出货汇总"
}
},
{
"path": "customerRanking",
"style": {
@ -241,6 +241,29 @@
"style": {
"navigationBarTitleText": "客户详情"
}
},
{
"path": "paymentSummary",
"style": {
"navigationBarTitleText": "收支汇总"
}
},
]
},
{
"root": "pagesReceiveData",
"pages": [
{
"path": "summary",
"style": {
"navigationBarTitleText": "收货汇总"
}
},
{
"path": "productSummary",
"style": {
"navigationBarTitleText": "收货产品汇总"
}
}
]
},
@ -505,4 +528,5 @@
"backgroundColor": "#F8F8F8"
},
"lazyCodeLoading": "requiredComponents"
}

View File

@ -29,7 +29,7 @@
height="60rpx"
></up-image>
</view>
<view v-if="isShowModule([{ title: child.title }])">{{
<view v-if="isShowModule([{ title: child.title }])" :style="{'font-size': child.title.length>=6 ? '23rpx' : ''}">{{
child.title
}}</view>
</view>
@ -63,11 +63,20 @@ const list = reactive([
color: "green",
child: [
{
icon: "1.png",
icon: "15.png",
title: "收货汇总",
fn: (item: any) => {
uni.navigateTo({
url: "/pagesStatistics/receivePanel", //
url: "/pagesReceiveData/summary", //
});
},
},
{
icon: "1.png",
title: "收货产品汇总",
fn: (item: any) => {
uni.navigateTo({
url: "/pagesReceiveData/productSummary", //
});
},
},
@ -106,10 +115,10 @@ const list = reactive([
child: [
{
icon: "5.png",
title: "出货汇总",
title: "出货产品汇总",
fn: (item: any) => {
uni.navigateTo({
url: "/pagesStatistics/shipmentPanel", //
url: "/pagesShipmentData/productSummary", //
});
},
},
@ -192,6 +201,15 @@ const list = reactive([
});
},
},
{
icon: "16.png",
title: "收支汇总",
fn: (item: any) => {
uni.navigateTo({
url: "/pagesStatistics/paymentSummary", //
});
},
},
],
},
]);

View File

@ -45,13 +45,18 @@
<view>
<text class="title">收货入库</text>
<up-grid :border="false">
<up-empty
<view
v-if="!isShowModule(stateNew.receiveList)"
mode="permission"
icon="http://cdn.uviewui.com/uview/empty/permission.png"
:text="'暂无相关权限, 请联系管理员'"
style="text-align: center; width: 100%"
>
</up-empty>
<up-empty
mode="permission"
icon="http://cdn.uviewui.com/uview/empty/permission.png"
:text="'暂无相关权限, 请联系管理员'"
>
</up-empty>
</view>
<block v-for="(item, index) in stateNew.receiveList" :key="index">
<up-grid-item
@click="handleClick(item)"
@ -76,13 +81,18 @@
<view style="margin: 30rpx 0rpx">
<text class="title title-shipment">出货销售</text>
<up-grid :border="false">
<up-empty
v-if="!isShowModule(stateNew.shipmentList)"
mode="permission"
icon="http://cdn.uviewui.com/uview/empty/permission.png"
:text="'暂无相关权限, 请联系管理员'"
<view
v-if="!isShowModule(stateNew.receiveList)"
style="text-align: center; width: 100%"
>
</up-empty>
<up-empty
v-if="!isShowModule(stateNew.shipmentList)"
mode="permission"
icon="http://cdn.uviewui.com/uview/empty/permission.png"
:text="'暂无相关权限, 请联系管理员'"
>
</up-empty>
</view>
<block v-for="(item, index) in stateNew.shipmentList" :key="index">
<up-grid-item
@click="handleClick(item)"
@ -105,16 +115,6 @@
</up-grid>
</view>
</view>
<!-- <up-empty
v-if="
!isShowModule(receiveList.concat(shipmentList)) &&
!isShowModule(appList)
"
mode="permission"
icon="http://cdn.uviewui.com/uview/empty/permission.png"
:text="'暂无相关权限, 请联系管理员'"
>
</up-empty> -->
</view>
<TabBar />

View File

@ -0,0 +1,63 @@
<template>
<summaryTemplate :tableTitleList="tableTitleList" :summary="state.summary" @getList="getList"></summaryTemplate>
</template>
<script setup lang="ts">
import summaryTemplate from "@/components/Template/summaryTemplate.vue";
import { ReceiveApi } from "@/services";
const state = reactive<any>({
summary: {
calculateResult: []
}
})
const tableTitleList = reactive([
{
name: "产品类别",
key: "categoryName",
},
{
name: "产品名称",
key: "productName",
},
{
name: "总净重/KG",
key: "totalAmount",
desc: "待付款、已付款状态的付款金额之和",
},
{
name: "均价/元",
key: "averagePrice",
},
{
name: "付款总金额/元",
key: "totalPayment",
desc: "净重=毛重-皮重-扣杂",
},
{
name: "已付金额/元",
key: "payTotalPrice",
},
{
name: "未付金额/元",
key: "unPayTotalPrice",
},
]);
function getList(params:any) {
ReceiveApi.OrderInReceipt(params).then((res:any) => {
if (res.code === 200) {
state.summary = res.data.rankings;
let totalAmount = 0;
let totalPayment = 0;
let payTotalPrice = 0;
let unPayTotalPrice = 0;
res.data.rankings.forEach((item:any) => {
totalAmount += item.totalAmount
totalPayment += item.totalPayment
payTotalPrice += item.payTotalPrice
unPayTotalPrice += item.unPayTotalPrice
});
state.summary.calculateResult = ['-', '合计', totalAmount, '-', totalPayment, payTotalPrice, unPayTotalPrice]
}
});
}
</script>

View File

@ -0,0 +1,67 @@
<template>
<summaryTemplate :tableTitleList="tableTitleList" :summary="state.summary" @getList="getList"></summaryTemplate>
</template>
<script setup lang="ts">
import summaryTemplate from "@/components/Template/summaryTemplate.vue";
import { ReceiveApi } from "@/services";
const state = reactive<any>({
summary: {
calculateResult: []
}
})
const tableTitleList = reactive([
{
name: "设备",
key: "deviceName",
},
{
name: "单数",
key: "orderNum",
},
{
name: "总毛重/KG",
key: "totalGrossWeight",
},
{
name: "总净重/KG",
key: "totalNetWeight",
desc: '净重=毛重-皮重-扣杂'
},
{
name: "总金额/元",
key: "totalAmount",
desc: '待付款和已付款状态的实际付款之和'
},
{
name: "已付金额/元",
key: "payTotalAmount",
},
{
name: "未付金额/元",
key: "unPayTotalAmount",
}
]);
function getList(params:any) {
ReceiveApi.deviceGroupBy(params).then((res:any) => {
if (res.code === 200) {
state.summary = res.data;
let orderNum = 0;
let totalGrossWeight = 0;
let totalNetWeight = 0;
let totalAmount = 0;
let payTotalAmount = 0;
let unPayTotalAmount = 0;
res.data.forEach((item:any) => {
orderNum += item.orderNum
totalGrossWeight += item.totalGrossWeight
totalNetWeight += item.totalNetWeight
totalAmount += item.totalAmount
payTotalAmount += item.payTotalAmount
unPayTotalAmount += item.unPayTotalAmount
});
state.summary.calculateResult = ['合计', orderNum, totalGrossWeight, totalNetWeight, totalAmount, payTotalAmount, unPayTotalAmount]
}
});
}
</script>

View File

@ -0,0 +1,70 @@
<template>
<summaryTemplate :tableTitleList="tableTitleList" :summary="state.summary" @getList="getList"></summaryTemplate>
</template>
<script setup lang="ts">
import summaryTemplate from "@/components/Template/summaryTemplate.vue";
import { ShipmentApi } from "@/services";
const state = reactive<any>({
summary: {
calculateResult: []
}
})
const tableTitleList = reactive([
{
name: "产品类别",
key: "categoryName",
},
{
name: "产品名称",
key: "productName",
},
{
name: "货场净重/KG",
key: "freightNet",
desc: "货场在自己场内的过磅净重",
},
{
name: "货场总净重/KG",
key: "totalAmount",
desc: "客户出具的结算毛重-结算净重-扣杂",
},
{
name: "均价/元",
key: "averagePrice",
},
{
name: "收款总金额/元",
key: "totalPayment",
desc: "待收款和已收款状态的实际收款之和",
},
{
name: "已收金额/元",
key: "payTotalPrice",
},
{
name: "未付金额/元",
key: "unPayTotalPrice",
},
]);
function getList(params:any) {
ShipmentApi.getOrderInReceipt(params).then((res:any) => {
if (res.code === 200) {
state.summary = res.data.rankings;
let freightNet = 0;
let totalAmount = 0;
let totalPayment = 0;
let payTotalPrice = 0;
let unPayTotalPrice = 0;
res.data.rankings.forEach((item:any) => {
freightNet += item.freightNet
totalAmount += item.totalAmount
totalPayment += item.totalPayment
payTotalPrice += item.payTotalPrice
unPayTotalPrice += item.unPayTotalPrice
});
state.summary.calculateResult = ['-', '合计', freightNet, totalAmount, '-', totalPayment, payTotalPrice, unPayTotalPrice]
}
});
}
</script>

View File

@ -86,3 +86,13 @@ export const deleteRevenueDes = (data: any) => {
data,
})
}
// 收支汇总
export const getRevenuePaymentPage = (data: any) => {
return http({
method: 'GET',
url: '/api/revenuedetails/getRevenuePaymentPage',
data,
})
}

View File

@ -136,6 +136,15 @@ export const getTotal = () => {
};
// 收货汇总:根据设备分组
export const deviceGroupBy = (data:any) => {
return http({
method: "GET",
url: "/api/orderIn/deviceGroupBy",
data
});
};

View File

@ -89,12 +89,14 @@ export enum StockCardType {
// 今日 昨日 本月 本年 自定义
export enum TimeRange {
Today = 1,
Today = 1, // 今日
Yesterday = 2,
Month = 3,
Year = 4,
Custom = 5,
Week = 6
Month = 3, // 本月
Year = 4, // 本年
Custom = 5, // 自定义
Week = 6, // 本周
Quarter = 7 // 本季
}
// 消息跳转类型 0=收货待定价1=收货待审核2=待出库3=出库审核

View File

@ -17,7 +17,7 @@ const obj = {
invoke(options: UniApp.RequestOptions) {
// 超时时间
options.timeout = 10000;
options.url = baseUrl + '/prod/sh0001' + options.url;
options.url = baseUrl + '/test/sh0001' + options.url;
// 请求头标识
// 1.小程序唯一标识
// 'source-client' 'miniapp'

View File

@ -58,17 +58,37 @@ export function getCurrentYearStartAndEnd() {
}
export function getCurrentWeekStartAndEnd() {
let startTime = getMonday("s", 0);
let endTime = getMonday("e", 0);
let time1 = new Date(getMonday("s", 0)).getTime();
let time2 = new Date(new Date(new Date().setHours(0, 0, 0))).getTime();
if (time1 > time2) {
startTime = getMonday("s", -1);
endTime = getMonday("e", -1);
}
// let startTime = getMonday("s", 0);
// let endTime = getMonday("e", 0);
// const time1 = new Date(getMonday("s", 0)).getTime();
// const time2 = new Date(new Date(new Date().setHours(0, 0, 0))).getTime();
// if (time1 > time2) {
// startTime = getMonday("s", -1);
// endTime = getMonday("e", -1);
// }
const currentDate = new Date();
// 获取本周第一天的日期
const firstDay = new Date(
currentDate.setDate(currentDate.getDate() - currentDate.getDay() + 1)
);
// 获取本周最后一天的日期
const lastDay = new Date(
currentDate.setDate(currentDate.getDate() - currentDate.getDay() + 7)
);
// 格式化日期为字符串,例如:"YYYY-MM-DD"
const format = function (date: any) {
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
return year + "-" + month + "-" + day;
};
return {
start: startTime,
end: endTime,
start: format(firstDay),
end: format(lastDay),
};
}
@ -94,6 +114,35 @@ function getMonday(type: string, dates: number) {
return y + "-" + m + "-" + d;
}
function getQuarterDates(date?:any) {
if (!date) date = new Date(); // 如果没有提供日期,则使用当前日期
let quarterStart;
let quarterEnd;
const month = date.getMonth(); // 获取月份0-11
// 计算季度的起始日期和结束日期
if (month >= 0 && month <= 2) {
quarterStart = new Date(date.getFullYear(), 0, 1);
quarterEnd = new Date(date.getFullYear(), 3, 0);
} else if (month >= 3 && month <= 5) {
quarterStart = new Date(date.getFullYear(), 3, 1);
quarterEnd = new Date(date.getFullYear(), 6, 0);
} else if (month >= 6 && month <= 8) {
quarterStart = new Date(date.getFullYear(), 6, 1);
quarterEnd = new Date(date.getFullYear(), 9, 0);
} else {
quarterStart = new Date(date.getFullYear(), 9, 1);
quarterEnd = new Date(date.getFullYear(), 12, 0);
}
// 返回季度的起止时间字符串
return {
start: formatDate(quarterStart, '{y}-{m}-{d}'),
end: formatDate(quarterEnd, '{y}-{m}-{d}')
};
}
export function deleteBaseKey(obj: any) {
delete obj.createTime;
delete obj.createUserId;
@ -197,7 +246,12 @@ export function timeRange(id: number) {
} else if (id === TimeRange.Week) {
startTime = formatDate(getCurrentWeekStartAndEnd().start, "{y}-{m}-{d}");
endTime = formatDate(getCurrentWeekStartAndEnd().end, "{y}-{m}-{d}");
} else if (id === TimeRange.Quarter) {
startTime = formatDate(getQuarterDates().start, "{y}-{m}-{d}");
endTime = formatDate(getQuarterDates().end, "{y}-{m}-{d}");
}
return { startTime: startTime, endTime: endTime };
}