This commit is contained in:
ylj20011123 2025-11-12 10:18:06 +08:00
parent 897f4f70fb
commit 0c9b0bc3ad
19 changed files with 5 additions and 2404 deletions

View File

@ -1,6 +1,6 @@
{
"name": "ant-design-pro",
"version": "4.5.81",
"version": "4.5.82",
"private": true,
"description": "An out-of-box UI solution for enterprise applications",
"scripts": {

View File

@ -12,10 +12,8 @@ import numeral from "numeral";
import { QuestionCircleOutlined } from "@ant-design/icons"
import { Col, Row, Space, Tooltip, Typography } from "antd";
import type { AccountReceivablesModel } from "@/pages/busniess/PaymentConfirm/data";
const { Text } = Typography
const ProjectItem = ({ project, selectProject }: { project: AccountReceivablesModel, selectProject: any, }) => {
const ProjectItem = ({ project, selectProject }: { project: any, selectProject: any, }) => {
return (
<Row align="middle" style={{ padding: 16 }} className="project-list-item" >
<Col span={8} >

View File

@ -1,226 +0,0 @@
@import '~antd/es/style/themes/default.less';
.iconGroup {
span.anticon {
margin-left: 16px;
color: @text-color-secondary;
cursor: pointer;
transition: color 0.32s;
&:hover {
color: @text-color;
}
}
}
.rankingList {
margin: 25px 0 0;
padding: 0;
list-style: none;
li {
display: flex;
align-items: center;
margin-top: 16px;
zoom: 1;
&::before,
&::after {
display: table;
content: ' ';
}
&::after {
clear: both;
height: 0;
font-size: 0;
visibility: hidden;
}
span {
color: @text-color;
font-size: 14px;
line-height: 22px;
}
.rankingItemNumber {
display: inline-block;
width: 20px;
height: 20px;
margin-top: 1.5px;
margin-right: 16px;
font-weight: 600;
font-size: 12px;
line-height: 20px;
text-align: center;
background-color: @tag-default-bg;
border-radius: 20px;
&.active {
color: #fff;
background-color: #314659;
}
}
.rankingItemTitle {
flex: 1;
margin-right: 8px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
}
.salesExtra {
display: inline-block;
margin-right: 24px;
a {
margin-left: 24px;
color: @text-color;
&:hover {
color: @primary-color;
}
&.currentDate {
color: @primary-color;
}
}
}
.salesCard {
.salesBar {
padding: 0 0 32px 32px;
}
.salesRank {
padding: 0 32px 24px 72px;
}
:global {
.ant-tabs-bar,
.ant-tabs-nav-wrap {
padding-left: 16px;
.ant-tabs-nav .ant-tabs-tab {
padding-top: 16px;
padding-bottom: 14px;
line-height: 24px;
}
}
.ant-tabs-extra-content {
padding-right: 24px;
line-height: 55px;
}
.ant-card-head {
position: relative;
}
.ant-card-head-title {
align-items: normal;
}
}
}
.tableTitle {
height: 40px;
width: 100%;
background-color: #FAFAFA;
padding-left: 8px;
line-height: 40px;
margin-top: 24px;
}
.rankIndex,.rankIndex1 {
color: #3E455F;
border-radius: 50%;
font-style: italic;
}
.rankIndex {
background-color: #F6F8FE;
width: 24px;
height: 24px;
text-align: center;
}
.rankIndex1 {
position: relative;
.text {
text-align: center;
position: absolute;
width: 30px;
display: block;
top: 6px;
// left: 0;
}
}
.salesCardExtra {
height: inherit;
}
.salesTypeRadio {
position: absolute;
right: 54px;
bottom: 12px;
}
.offlineCard {
:global {
.ant-tabs-ink-bar {
bottom: auto;
}
.ant-tabs-bar {
border-bottom: none;
}
.ant-tabs-nav-container-scrolling {
padding-right: 40px;
padding-left: 40px;
}
.ant-tabs-tab-prev-icon::before {
position: relative;
left: 6px;
}
.ant-tabs-tab-next-icon::before {
position: relative;
right: 6px;
}
.ant-tabs-tab-active h4 {
color: @primary-color;
}
}
}
.trendText {
margin-left: 8px;
color: @heading-color;
}
@media screen and (max-width: @screen-lg) {
.salesExtra {
display: none;
}
.rankingList {
li {
span:first-child {
margin-right: 8px;
}
}
}
}
@media screen and (max-width: @screen-md) {
.rankingTitle {
margin-top: 16px;
}
.salesCard .salesBar {
padding: 16px;
}
}
@media screen and (max-width: @screen-sm) {
.salesExtraWrap {
display: none;
}
.salesCard {
:global {
.ant-tabs-content {
padding-top: 30px;
}
}
}
}
.contract-statistic .ant-pro-statistic-card-chart{
margin-top: 0;
}

View File

@ -1,45 +0,0 @@
/*
* @Author: cclu
* @Date: 2022-01-09 15:46:57
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-04-28 18:54:02
* @FilePath: \cloud-platform\src\pages\busniess\analysis\components\BottomCompletion.tsx
* @Description: /
*
* Copyright (c) 2022 by cclu/驿, All Rights Reserved.
*/
import { Col } from "antd";
import ContactCompletion from "./ContactCompletion";
import { Suspense, useState } from "react";
import ContactYearCompletion from "./ContactYearCompletion";
const BottomCompletion: React.FC = () => {
const [selectDate, setSelectDate] = useState<number>(2022); // 当前 “月度应收总额完成度图例” 选择的年份
return (
<>
<Col xl={8} lg={24} md={24} sm={24} xs={24}>
<Suspense fallback={null}>
{/* 年度应收总额完成度 */}
<ContactYearCompletion
setSelectDate={setSelectDate}
/>
</Suspense>
</Col>
{/* 月度应收总额完成度 */}
<ContactCompletion
selectDate={selectDate}
/>
</>
)
}
export default BottomCompletion;

View File

@ -1,140 +0,0 @@
import { RingProgress, Progress } from "@ant-design/charts";
import { Card, Col, Row, Typography } from "antd";
import { Liquid } from '@ant-design/plots';
import styles from '../analysis.less'
import { StatisticCard } from "@ant-design/pro-card";
import numeral from "numeral";
import '../analysis.less'
const { Statistic, Divider } = StatisticCard;
type CustomerCardProps = {
loading: boolean,
contrctData: any,
totalContractCount: number
}
const ContractCard = ({ loading, contrctData, totalContractCount }: CustomerCardProps) => {
const colors = ["#F3BF2C", "#5B8FF9", "#3EC6C5"]
const liquidConfig = {
height:150,
autoFit: true,
percent: 0.25,
outline: {
border: 2,
distance: 2,
},
wave: {
length: 128,
},
};
const progessConfig = {
height: 30,
width: 230,
autoFit: true,
percent: contrctData?.Expired_HalfYearCount / totalContractCount,
color: ['#5B8FF9', '#E8EDF3'],
}
return (
<Card
title="合同到期预警"
loading={loading}
bordered={false}
bodyStyle={{ padding: 0, paddingTop: 16, paddingBottom: 20 }}
style={{ marginBottom: 24 }}
>
<Row align="middle">
<Col xl={8} lg={24} md={24} sm={24} xs={24}>
<StatisticCard.Group direction={'row'}>
<StatisticCard
className="contract-statistic"
bodyStyle={{ paddingRight: 0 }}
title={<Typography.Text type="secondary"></Typography.Text>}
statistic={{
value: contrctData?.Expired_HalfYearCount,
suffix: <div><Typography.Text type="secondary" style={{ fontSize: 14 }}>()</Typography.Text><Typography.Text type="secondary" style={{ fontSize: 14 ,position:"absolute",right:0,marginTop:16}}>{totalContractCount}</Typography.Text></div>,
valueStyle: {
fontSize: 30,
fontFamily: "Bahnschrift Regular",
lineHeight: 1
},
// description: <Statistic title="" value={totalContractCount} style={{textAlign:"right"}}/>,
}}
chart={
<Progress {...progessConfig} />
}
footer={
<>
{
contrctData?.ContractHalfYearListExpired.map(n => {
return <Statistic value={n.Expired_Count} title={n.Expired_Situation} suffix={<Typography.Text type="secondary" style={{ fontSize: 14 }}>()</Typography.Text>} layout="horizontal" />
})
}
</>
}
style={{ width: "100%",minWidth:250 }}
/>
<Divider type={'vertical'} />
</StatisticCard.Group>
</Col>
<Col xl={16} lg={24} md={24} sm={24} xs={24}>
<Row align="middle" gutter={10}>
{
contrctData?.ContractHalfYearListExpired.map((n, i) => {
const percent = numeral(n.Expired_Count).divide(contrctData.Expired_HalfYearCount).value()
const color = colors[i]
const config = {
...liquidConfig, color, percent
, statistic: {
offsetY: -8,
title: {
style: {
color: 'rgba(0,0,0,0.35)',
fontSize: '12px',
lineHeight: '14px',
},
formatter: () => n.Expired_Situation.replace("到期",""),
},
content:{
// offsetY: -18,
style: {
// color: colors[i],
fontSize: 18,
fontFamily: "Bahnschrift Regular",
}
}
},
}
return <Col span={8} >
<Liquid {...config} />
</Col>
})
}
{/* <Col span={8}>
<RingProgress {...pressConfig2} />
</Col>
<Col span={8}>
<RingProgress {...pressConfig3} />
</Col> */}
</Row>
</Col>
</Row>
</Card>
)
}
export default ContractCard;

View File

@ -1,111 +0,0 @@
/*
* @Author: cclu
* @Date: 2022-04-28 10:47:36
* @LastEditTime: 2022-04-28 18:55:44
* @LastEditors: Please set LastEditors
* @Description:
* @FilePath: \cloud-platform\src\pages\busniess\analysis\components\IntroduceRow.tsx
*/
import { Col, Row, Typography, Card } from "antd"
import { StatisticCard } from '@ant-design/pro-card';
import type { projectSummaryInfo } from '../data'
import type { StatisticProps } from '@ant-design/pro-card';
import { history } from "umi";
import { valueType } from "antd/lib/statistic/utils";
import { ReactChild, ReactFragment, ReactPortal, Key } from "react";
const { Divider, Statistic } = StatisticCard;
const topColResponsiveProps2 = {
xs: 24,
sm: 24,
md: 24,
lg: 24,
xl: 24,
style: { marginBottom: 24 },
};
const bodyStyle = {
padding: '30px 0 30px 24px'
}
const IntroduceRow = ({ loading, visitData, contrctData }: { loading?: boolean, visitData?: projectSummaryInfo, contrctData: any }) => {
const cardStatus = ['error', 'warning', 'processing', 'success', 'default',];
return (
<Card
bordered={false}
loading={loading}
title="合同到期预警"
style={{ marginBottom: 24, height: 410 }}>
<Row gutter={24} >
<Col {...topColResponsiveProps2} >
{/* 合同到期预警 */}
<StatisticCard.Group direction="column" >
<StatisticCard
loading={loading}
className="contract-statistic"
bodyStyle={bodyStyle}
statistic={{
title: <Typography.Text type="secondary" style={{ fontSize: 16 }}></Typography.Text>,
value: contrctData?.Expired_HalfYearCount,
suffix: <div><Typography.Text type="secondary" style={{ fontSize: 14 }}>()</Typography.Text></div>,
valueStyle: {
fontSize: 30,
fontFamily: "Bahnschrift Regular",
lineHeight: 1.5
},
layout: "horizontal",
}}
onClick={() => {
history.push('/busniessproject/contract')
}}
style={{ width: "90%", minWidth: 250, paddingBottom: 26 }}
/>
<Divider type="horizontal" />
<StatisticCard
onClick={() => {
history.push('/busniessproject/contract')
}}
loading={loading}
headerBordered={false}
bodyStyle={{ paddingTop: 40, paddingBottom: 0 }}
>
{
contrctData?.ContractHalfYearListExpired.map((n: { Expired_Count: valueType | undefined; Expired_Situation: boolean | ReactChild | ReactFragment | ReactPortal | null | undefined; }, i: Key) => {
return <Statistic
key={i}
style={{ marginBottom: 16 }}
value={n.Expired_Count}
title={n.Expired_Situation}
valueStyle={i === 0 ? { color: "#EE6363" } : {}}
status={cardStatus[i] as StatisticProps['status']}
suffix={<Typography.Text type="secondary" style={{ fontSize: 14 }}>()</Typography.Text>} layout="horizontal" />
})
}
</StatisticCard>
</StatisticCard.Group>
</Col>
</Row>
</Card>
)
}
export default IntroduceRow;

View File

@ -1,123 +0,0 @@
// PaymentProgessCard
import { G2, Radar } from "@ant-design/charts";
import { Bar } from '@ant-design/plots';
import { Card, Col, Row, Typography } from "antd";
import type { DataItem } from '../data'
export type TimeType = 'today' | 'week' | 'month' | 'year'
type RevenueCardProps = {
loading: boolean,
salesData?: { title: string, data: DataItem[] }
}
const PaymentProgessCard = ({ loading, salesData }: RevenueCardProps) => {
// const G = G2.getEngine('canvas');
const config = {
appendPadding: 16,
autoFit: true,
data: salesData?.data,
xField: 'Account_Amount',
yField: 'Account_Name',
seriesField: 'Account_Name',
legend: {
position: 'top-left',
},
height: 300,
};
return (
<Card
bordered={false}
loading={loading}
title={`${salesData?.title}详细款项完成进度`}
style={{ marginBottom: 24, height: 410 }}
>
{/* <Bar {...config} /> */}
<Radar
height={250}
data={salesData?.data || []}
appendPadding={10}
xField="Account_Name"
yField="Complete_Degree"
autoFit
meta={{
Complete_Degree: {
alias: "完成度",
min: 0,
max: 100,
}
}}
area={{}}
point={{
size: 2,
}}
yAxis={{
line: null,
tickLine: null,
grid: {
line: {
type: 'line',
style: {
lineDash: null,
},
},
alternateColor: 'rgba(0, 0, 0, 0.04)',
},
}}
xAxis={{
line: null,
tickLine: null,
grid: {
line: {
style: {
lineDash: null,
},
},
},
}}
tooltip={
{
customContent: (title, data) => { // title, data
const [nowData] = data
return <div className="g2-tooltip-list" key={title}>
<div className="g2-tooltip-title" style={{ fontWeight: 700 }}>{title}: {nowData?.value || 100}%</div>
{salesData?.data.sort((a, b) => b.Account_Amount - a.Account_Amount).map(n => {
return (
<div className="g2-tooltip-item g2-tooltip-list-item" key={n.Account_Name}>
<div className="g2-tooltip-marker" style={{ backgroundColor: n.Account_Amount ? "#5B8FF9" : "#E8EDF3" }}></div>
<Typography.Text className="g2-tooltip-name">{n.Account_Name}</Typography.Text>
<Typography.Text className="g2-tooltip-value">{n.Account_Amount || 0}</Typography.Text>
</div>
)
})}
</div>;
}
}
}
// point={{
// visible: true,
// }}
// legend={{
// position: 'bottom-center',
// }}
/>
</Card>
);
};
export default PaymentProgessCard;

View File

@ -1,200 +0,0 @@
/*
* @Author: cclu
* @Date: 2022-04-28 10:47:36
* @LastEditTime: 2022-04-28 18:41:15
* @LastEditors: Please set LastEditors
* @Description:
* @FilePath: \cloud-platform\src\pages\busniess\analysis\components\TopCard.tsx
*/
import { Pie, G2 } from "@ant-design/charts";
import { StatisticCard } from "@ant-design/pro-card";
import { Card, Col, Row, Typography } from "antd";
import { useEffect, useState } from "react";
import type { contrctStaticCard, projectSummaryInfo } from '../data'
import numeral from "numeral";
const { Divider } = StatisticCard;
const PaymentWarnig = ({ loading, visitData }: { loading: boolean, visitData: projectSummaryInfo }) => {
const G = G2.getEngine('canvas');
const [activeData, setActiveData] = useState<contrctStaticCard | any>()
const [textColor, setTextColor] = useState<string>()
const pieConfig = {
autoFit: true,
appendPadding: 24,
data: !loading ? visitData?.projectAnasisData : [],
angleField: 'value',
colorField: 'type',
// height: 160,
radius: 0.82,
innerRadius: 0.65,
legend: false,
tooltip: false,
color: ["#5B8FF9", "#3EC6C5", "#F3BF2C"],
statistic: {
title: {
offsetY: -4,
style: {
// whiteSpace: 'pre-wrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
fontSize: 14,
color: 'rgba(0, 0, 0, 0.45)'
},
content: activeData?.type ? `${activeData?.type}占比` : ''
},
content: {
style: {
whiteSpace: 'pre-wrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
fontSize: 18,
fontWeight: 500
},
formatter: () => {
// const { width } = container.getBoundingClientRect();
if (activeData?.contract) {
const total = visitData?.ArrearageList.reduce((r, d) => r + d.ArrearageContract_Count, 0)
return `${numeral(activeData?.contract).divide(total).multiply(100).format('0,0.[00]')}%`;
}
return ''
},
},
},
label: {
type: 'spider',
labelHeight: 28,
// content: '{name}\n{percentage}',
formatter: (data, mappingData) => {
const group = new G.Group({});
group.addShape({
type: 'circle',
attrs: {
x: 0,
y: 0,
width: 6,
height: 6,
r: 5,
fill: mappingData.color,
},
});
group.addShape({
type: 'text',
attrs: {
x: 10,
y: 8,
text: `${data.type}`,
fill: '#333',
},
});
group.addShape({
type: 'text',
attrs: {
x: 0,
y: 25,
text: `${data.des}`,
fill: 'rgba(0, 0, 0, 0.35)',
// fontWeight: 500,
},
});
return group;
}
},
interactions: [
{
type: 'element-selected',
},
// {
// type: 'element-active',
// },
],
};
const splitAmount = (value: any) => {
const stringValue = `${value}`
const [intValue, floatValue] = stringValue.split(".")
return [numeral(intValue).format("0,0"), floatValue]
}
return (
<Card
title="应收账款预警"
bordered={false}
bodyStyle={{ padding:0, paddingLeft: 20, height:320 }}>
<Row align="middle" gutter={10} >
<Col span={8}>
<StatisticCard.Group direction={'column'}>
<StatisticCard
statistic={{
// eslint-disable-next-line no-nested-ternary
value: activeData?.value ? (splitAmount(activeData?.value))[0] : (visitData?.staticCard.value ? (splitAmount(visitData?.staticCard.value))[0] : 0),
// eslint-disable-next-line no-nested-ternary
suffix: <><Typography.Text style={{ fontSize: 16 }}>.{activeData?.value ? (splitAmount(activeData?.value))[1] : (visitData?.staticCard.value ? (splitAmount(visitData?.staticCard.value))[1] : 0)}</Typography.Text> <Typography.Text type="secondary" style={{ fontSize: 14 }}>()</Typography.Text></>,
title: <Typography.Text type="secondary" style={{ color: textColor }}>({activeData?.des||'全部'})</Typography.Text>,
valueStyle: {
fontSize: 30,
fontFamily: "Bahnschrift Regular"
},
}}
bodyStyle={{ paddingRight: 0 }}
style={{ paddingRight: 0 }}
/>
<Divider type="horizontal" />
<StatisticCard
statistic={{
title: <Typography.Text type="secondary" style={{ color: textColor }}></Typography.Text>,
value: activeData?.contract || visitData?.staticCard.contract,
suffix: <Typography.Text type="secondary" style={{ fontSize: 14 }}>()</Typography.Text>,
valueStyle: {
fontSize: 30,
fontFamily: "Bahnschrift Regular"
},
}}
bodyStyle={{ paddingRight: 0 }}
/>
</StatisticCard.Group>
</Col>
<Col span={16} style={{ height: 300 }}>
<Pie {...pieConfig}
onReady={(plot) => {
let state = 0
plot.on('element:click', ({ data }: { evt: { data: any } }) => {
state = 1
const { color } = data.mappingData
setActiveData(data.data)
setTextColor(color)
});
plot.on('click', (evt) => {
// const { data } = evt
if(state===1){
state=0
}else{
setTextColor('rgba(0, 0, 0, 0.45)')
setActiveData(visitData?.staticCard)
}
});
}}
/>
</Col>
</Row>
</Card>
)
}
export default PaymentWarnig;

View File

@ -1,234 +0,0 @@
/*
* @Author: cclu
* @Date: 2022-04-28 10:47:36
* @LastEditTime: 2022-04-28 18:45:01
* @LastEditors: Please set LastEditors
* @Description: 2022
* @FilePath: \cloud-platform\src\pages\busniess\analysis\components\ProportionSales.tsx
*/
import { Pie, G2, Progress, Liquid } from "@ant-design/charts";
import { Card, Col, Row, Typography } from "antd";
import numeral from 'numeral';
import type { RadioChangeEvent } from "antd/es/radio";
type ProportionSalesProps = {
salesType?: 'business' | 'customer' | 'yearwest',
loading: boolean,
salesPieData: any,
handleChangeSalesType?: (e: RadioChangeEvent) => void
}
const ProportionSales = ({ loading, salesPieData, }: ProportionSalesProps) => {
const G = G2.getEngine('canvas');
// 水波进度配置
const liquidConfig = {
height: 300,
padding: 32,
autoFit: true,
color: "#3EC6C5",
percent: !loading && salesPieData ? salesPieData?.Paid_Amount / salesPieData?.Expired_Amount : 0,
outline: {
border: 3,
distance: 6,
},
wave: {
length: 138,
},
statistic: {
offsetY: -8,
title: {
style: {
color: 'rgba(0,0,0,0.25)',
fontSize: '14px',
lineHeight: '14px',
whiteSpace: 'pre-wrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
},
customHtml: () => {
// eslint-disable-next-line no-nested-ternary
return '到期金额收款进度';
},
},
content: {
offsetY: 8,
style: {
// color: colors[i],
fontSize: 26,
fontFamily: "Bahnschrift Regular",
},
customHtml: (container: any, view: any, datum: { percent: number; }) => {
// const { width } = container.getBoundingClientRect();
return <>
<div>{numeral(datum?.percent * 100).format("0.[00]")}%</div>
<div style={{ fontSize: 20 }}><><Typography.Text> {numeral(salesPieData?.Paid_Amount).format('0,0.[0000]')} </Typography.Text>
<Typography.Text type="secondary" style={{ fontSize: 12, fontWeight: 500 }}></Typography.Text></></div>
</>
},
}
}
};
// 饼图配置
const config = {
appendPadding: 22,
data: !loading ? salesPieData?.contractPie : [],
angleField: 'value',
colorField: 'type',
radius: 0.82,
innerRadius: 0.7,
legend: false,
height: 300,
tooltip: false,
autoFit: true,
color: ["#5B8FF9", "#F3BF2C",],
statistic: {
title: {
offsetY: -12,
style: {
whiteSpace: 'pre-wrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
fontSize: 14
},
customHtml: (container: any, view: any, datum: { type: string; }) => {
// eslint-disable-next-line no-nested-ternary
return datum ? datum.type.replace("金额", "占比") : '账款总金额';
},
},
content: {
offsetY: -2,
style: {
whiteSpace: 'pre-wrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
fontSize: 22,
fontWeight: 500,
fontFamily: "Bahnschrift Regular"
},
customHtml: (container: any, view: any, datum: { value: any; }, data: any[]) => {
// const { width } = container.getBoundingClientRect();
const total = data.reduce((r, d) => r + d.value, 0)
return datum ? `${numeral(datum.value).divide(total).multiply(100).format('0,0.[00]')}%` :
<><Typography.Text>{numeral(total).format('0,0.[000000]')} </Typography.Text><Typography.Text type="secondary" style={{ fontSize: 12, fontWeight: 500 }}></Typography.Text></>;
},
},
},
label: {
type: 'spider',
labelHeight: 28,
formatter: (data: { type: any; value: any; }, mappingData: { color: any; }) => {
const group = new G.Group({});
// group.addShape({
// type: 'circle',
// attrs: {
// x: 0,
// y: 0,
// width: 6,
// height: 6,
// r: 5,
// fill: mappingData.color,
// },
// });
group.addShape({
type: 'text',
attrs: {
x: 10,
y: 8,
text: `${data.type}`,
fill: mappingData.color,
fontSize: 14
},
});
group.addShape({
type: 'text',
attrs: {
x: 10,
y: 32,
text: `${numeral(data.value).format('0,0.[000000]')}万元`,
fill: 'rgba(0, 0, 0, 0.65)',
fontSize: 14
// fontWeight: 500,
},
});
return group;
}
},
interactions: [
{
type: 'element-selected',
},
// {
// type: 'element-active',
// },
{
type: 'pie-statistic-active',
},
{
type: 'element-highlight',
},
],
state: {
// 设置 active 激活状态的样式
active: {
// animate: { duration: 100, easing: 'easeLinear' },
style: {
lineWidth: 0,
},
},
}
}
return (
<Card
title="至2022年底整体完成进度"
loading={loading}
style={{ position: "relative", height: 380, marginBottom: 24 }}
bodyStyle={{ padding: 0 }}
>
<Row align="top">
<Col span={9}>
<Liquid {...liquidConfig} />
{/* <Typography.Text type="secondary" >收款占比:</Typography.Text> */}
</Col>
<Col span={15}>
<Pie
{...config}
// onReady={(plot) => {
// plot.on('element:click', (evt) => {
// const { data } = evt
// console.log(data);
// });
// }}
/>
</Col>
</Row>
</Card>
);
}
export default ProportionSales;

View File

@ -1,365 +0,0 @@
/*
* @Author: cclu
* @Date: 2022-04-28 10:47:36
* @LastEditTime: 2022-09-26 11:52:09
* @LastEditors: zzy 411037547@qq.com
* @Description:
* @FilePath: \cloud-platform\src\pages\busniess\analysis\components\TopCard.tsx
*/
import { Col, Row, Typography, Avatar, Space, Card } from "antd"
import { StatisticCard } from '@ant-design/pro-card';
import type { projectSummaryInfo } from '../data'
import numeral from "numeral";
import IconFont from "@/components/IconFont";
import { FileTextOutlined, TransactionOutlined } from "@ant-design/icons";
import { history } from "umi";
import {Pie, RingProgress} from "@ant-design/charts";
import React from "react";
const { Divider, Statistic } = StatisticCard;
const topColResponsiveProps = {
xs: 24,
sm: 24,
md: 24,
lg: 24,
xl: 16,
style: { marginBottom: 24 },
};
const topColResponsiveProps2 = {
xs: 24,
sm: 24,
md: 24,
lg: 24,
xl: 8,
style: { marginBottom: 24 },
};
const bodyStyle = {
padding: '30px 0 30px 24px'
}
const splitAmount = (value: any) => {
const stringValue = `${value}`
const [intValue, floatValue] = stringValue.split(".")
return [numeral(intValue).format("0,0"), floatValue]
}
const TopCard = ({ loading, visitData, contrctData }: { loading: boolean, visitData: projectSummaryInfo, contrctData: any }) => {
const contractColors = ["#6596F6", "#6bdbab"]
const compayColors = ["#F3BF2C", "#5e6aa5"]
// 迷你进度条
const ringProgress = (value: number, color: string) => {
const config = {
height: 66,
width: 66,
autoFit: false,
percent: value,
color: [color || '#F4664A', '#E8EDF3'],
innerRadius: 0.68,
radius: 0.88,
statistic: {
content: {
formatter: () => ''
}
},
};
return <RingProgress {...config} />;
};
// 本年新增招商饼图配置
const pieConfig = {
autoFit: true,
appendPadding: 24,
data: [
{
type: '今年应收',
value: visitData?.NewlyAccount_Amount,
},
{
type: '新增招商金额',
value: visitData?.NewlyContract_Amount,
}],
angleField: 'value',
colorField: 'type',
// height: 160,
radius: 0.98,
innerRadius: 0.65,
legend: false,
tooltip: false,
color: ["#5E6AA5", "#E7EAEE"],
statistic: {
title: {
offsetY: -4,
style: {
// whiteSpace: 'pre-wrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
fontSize: 14,
color: 'rgba(0, 0, 0, 0.45)'
},
customHtml: (container, view, datum) => {
// const { width } = container.getBoundingClientRect();
// const total = data.reduce((r, d) => r + d.value, 0)
return datum ? datum.type : '新增招商金额';
},
},
content: {
offsetY: 4,
style: {
whiteSpace: 'pre-wrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
fontSize: 20,
fontWeight: 500,
fontFamily: "Bahnschrift Regular"
},
customHtml: (container, view, datum) => {
// const { width } = container.getBoundingClientRect();
// const total = data.reduce((r, d) => r + d.value, 0);
return <>
<Typography.Text>{numeral(datum?.value || visitData?.NewlyContract_Amount).format('0.[0000]')}</Typography.Text>
<Typography.Text type="secondary" style={{ fontSize: 12, fontWeight: 500 }}></Typography.Text></>;
},
},
},
label: {
type: 'inner',
autoHide: true,
style: {
display: 'none',
fontSize: 0,
},
},
interactions: [
{
type: 'element-selected',
},
// {
// type: 'element-active',
// },
{
type: 'pie-statistic-active',
},
{
type: 'element-highlight',
},
],
state: {
// 设置 active 激活状态的样式
active: {
// animate: { duration: 100, easing: 'easeLinear' },
style: {
lineWidth: 0,
},
},
}
};
return (
<Row gutter={24} >
{/* 合同信息 */}
<Col {...topColResponsiveProps} >
<StatisticCard.Group direction="row" hoverable>
<StatisticCard
loading={loading}
statistic={{
icon: <Avatar style={{ backgroundColor: "#E8EDF7" }} size={60}
icon={<IconFont name="icon-hetongxinxi" size={"30"} />}></Avatar>,
value: visitData?.Contract_Amount ? (splitAmount(visitData?.Contract_Amount))[0] : 0,
suffix: <>
<Typography.Text style={{ fontSize: 16 }}>
.{(splitAmount(visitData?.Contract_Amount))[1]}</Typography.Text>
<Typography.Text type="secondary" style={{ fontSize: 14 }}>()</Typography.Text></>,
title: <Typography.Text type="secondary"></Typography.Text>,
valueStyle: {
fontSize: 30,
fontFamily: "Bahnschrift Regular"
},
description: (
<>
<StatisticCard.Statistic
title={<Typography.Text type="secondary"></Typography.Text>}
value={visitData?.Contract_SignCount}
style={{ marginTop: 2, fontSize: 14 }}
valueStyle={{ color: "#6596F6" }} />
</>
)
}}
bodyStyle={{ ...bodyStyle, borderLeft: "2px solid #6596f6" }}
onClick={() => {
history.push('/busniessproject/contract')
}}
>
</StatisticCard>
<Divider type="vertical" />
{visitData?.BusinessTypeSummaryList.map((n, i) => <StatisticCard
loading={loading}
key={i}
statistic={{
value: n?.Contract_Amount ? (splitAmount(n?.Contract_Amount))[0] : 0,
suffix: <>
<Typography.Text style={{ fontSize: 16 }}>.{(splitAmount(n?.Contract_Amount))[1]}</Typography.Text>
<Typography.Text type="secondary" style={{ fontSize: 14 }}>()</Typography.Text></>,
title: <Typography.Text type="secondary" >{n.BusinessType === 1000 ? '合作分成' : '固定租金'}</Typography.Text>,
valueStyle: {
fontSize: 30,
fontFamily: "Bahnschrift Regular"
},
description: (
<Space size="large" style={{ marginTop: 2, fontSize: 14 }}>
<Statistic title="合同" value={n?.Contract_SignCount} />
<Statistic title="占比" value={numeral(n?.Contract_SignCount / visitData?.Contract_SignCount * 100).format('0,0.00')} suffix="%" />
</Space>
)
}}
chart={ringProgress(n?.Contract_SignCount / visitData?.Contract_SignCount, contractColors[i])}
chartPlacement="left"
bodyStyle={{ ...bodyStyle }}
onClick={() => {
history.push('/busniessproject/contract')
}}
>
</StatisticCard>)}
</StatisticCard.Group>
{/* 签约商户 */}
<StatisticCard.Group direction="row" hoverable style={{ marginTop: 24 }}>
<StatisticCard
loading={loading}
bordered={false}
statistic={{
icon: <Avatar style={{ backgroundColor: "#E9EBF5" }} size={60}
icon={<IconFont name="icon-qianyueshanghu" style={{ color: "#737FB9" }} size="30" />}></Avatar>,
value: visitData?.Contractor_Count,
suffix: <Typography.Text type="secondary" style={{ fontSize: 14 }}>()</Typography.Text>,
title: <Typography.Text type="secondary"></Typography.Text>,
valueStyle: {
fontSize: 30,
fontFamily: "Bahnschrift Regular"
},
description: (
<>
<StatisticCard.Statistic
title={<Typography.Text type="secondary"></Typography.Text>}
value={visitData?.ArrearageMerchant_Count}
style={{ marginTop: 2, fontSize: 14 }}
valueStyle={{ color: "#F3BF2C" }} />
</>
)
}}
onClick={() => {
history.push('/busniess/payment')
}}
bodyStyle={{ ...bodyStyle, borderLeft: "2px solid #737FB9" }}
>
</StatisticCard>
<Divider type="vertical" />
{visitData?.BusinessTypeSummaryList.map((n, i) => <StatisticCard
loading={loading}
key={i}
statistic={{
value: n?.Contractor_Count,
suffix: <Typography.Text type="secondary" style={{ fontSize: 14 }}>()</Typography.Text>,
title: <Typography.Text type="secondary" >{n.BusinessType === 1000 ? '合作分成' : '固定租金'}</Typography.Text>,
valueStyle: {
fontSize: 30,
fontFamily: "Bahnschrift Regular"
},
description: (
<Space size="large" style={{ marginTop: 2, fontSize: 14 }}>
<Statistic title="欠款商户" value={n?.ArrearageMerchant_Count} />
<Statistic title="欠款占比" value={numeral(n?.Arrearage_Amount / visitData?.Arrearage_Amount * 100).format('0,0.00')} suffix="%" />
</Space>
)
}}
chart={ringProgress(n?.Arrearage_Amount / visitData?.Arrearage_Amount, compayColors[i])}
chartPlacement="left"
bodyStyle={{ ...bodyStyle }}
onClick={() => {
history.push('/busniess/payment')
}}
>
</StatisticCard>)}
</StatisticCard.Group>
</Col>
{/* 本年新增招商 */}
<Col {...topColResponsiveProps2} >
<Card
title="本年新增招商"
bordered={false}
bodyStyle={{ padding: 0, paddingLeft: 20, height: 280 }}>
<Row align="middle" gutter={10} >
<Col span={10}>
<StatisticCard.Group direction={'column'}>
<StatisticCard
statistic={{
icon: <Avatar shape="square" style={{ backgroundColor: "#EBECEE", marginTop: 4, borderRadius: 6 }}
size={30} icon={<FileTextOutlined style={{ color: "#4D5766" }} />}></Avatar>,
title: <Typography.Text type="secondary" ></Typography.Text>,
value: visitData?.NewlyContract_Count,
suffix: <Typography.Text type="secondary" style={{ fontSize: 12 }}>()</Typography.Text>,
valueStyle: {
fontSize: 20,
fontFamily: "Bahnschrift Regular"
},
style: {
fontSize: 14,
}
}}
bodyStyle={{ padding: 12, paddingLeft: 22, backgroundColor: "#F8F8F8", borderRadius: 8, }}
/>
<StatisticCard
statistic={{
icon: <Avatar shape="square" style={{ backgroundColor: "#EBECEE", marginTop: 4, borderRadius: 6 }}
size={30} icon={<TransactionOutlined style={{ color: "#4D5766" }} />}></Avatar>,
value: visitData?.NewlyAccount_Amount ? (splitAmount(visitData?.NewlyAccount_Amount))[0] : 0,
suffix: <>
<Typography.Text style={{ fontSize: 14 }}>
.{visitData?.NewlyAccount_Amount ? (splitAmount(visitData?.NewlyAccount_Amount))[1] : 0}
</Typography.Text>
<Typography.Text type="secondary" style={{ fontSize: 12 }}>()</Typography.Text></>,
title: <Typography.Text type="secondary"></Typography.Text>,
valueStyle: {
fontSize: 20,
fontFamily: "Bahnschrift Regular"
},
style: {
fontSize: 14,
}
}}
bodyStyle={{ padding: 12, paddingLeft: 22, backgroundColor: "#F8F8F8", borderRadius: 8, }}
style={{ marginTop: 24 }}
/>
</StatisticCard.Group>
</Col>
{/* 本年新增招商饼图 */}
<Col span={14} style={{ height: 260 }}>
{visitData?.NewlyContract_Amount && <Pie {...pieConfig} />}
</Col>
</Row>
</Card>
</Col>
</Row>
)
}
export default TopCard;

View File

@ -1,77 +0,0 @@
/*
* @Author: cclu
* @Date: 2022-01-06 14:28:43
* @LastEditors: cclu
* @LastEditTime: 2022-03-03 17:45:08
* @FilePath: \cloud-platform\src\pages\busniess\analysis\data.d.ts
* @Description:
*
* Copyright (c) 2022 by cclu/驿, All Rights Reserved.
*/
import { DataItem } from '@antv/g2plot/esm/interface/config';
export { DataItem };
export type contrctStaticCard = {
merchant: number,
contract: number,
value: number,
type: string,
}
export type projectSummaryInfo = {
Contract_SignCount: number // 合同签约(份) ,
Contract_Amount: number // 合同金额(万元) ,
Contractor_Count: number // 签约商户(家) ,
ArrearageMerchant_Count: number // 欠款商户(家) ,
ArrearageContract_Count: number // 欠款合同(份) ,
Arrearage_Amount: number // 未缴欠款(万元) ,
NewlyContract_Count: number; // 新增招商合同(份) ,
NewlyContract_Amount: number; // 新增招商金额(万元) ,
NewlyAccount_Amount: number; // 今年新增合同应收金额(万元) ,
BusinessTypeSummaryList: BusinessTypeSummaryModel[]; // 项目类型分析数据
ArrearageList: ProjectArrearageModel[] // 项目欠款列表
projectAnasisData: projectAnasisData[]
staticCard: contrctStaticCard;
}
export type ProjectArrearageModel = {
Overdue_Situation: string // 逾期情况 ,
ArrearageMerchant_Count: number // 欠款商户(家) ,
ArrearageContract_Count: number // 欠款合同(份) ,
Arrearage_Amount: number // 未缴欠款(万元)
}
type BusinessTypeSummaryModel = {
BusinessType: number;// 经营模式1000【合作分成】2000【固定租金】 ,
Contract_SignCount: number;// 合同签约(份) ,
Contract_Amount: number;// 合同金额(万元) ,
Contractor_Count: number;// 签约商户(家) ,
ArrearageMerchant_Count: number;// 欠款商户(家) ,
ArrearageContract_Count: number;// 欠款合同(份) ,
Arrearage_Amount: number;// 未缴欠款(万元)
}
type projectAnasisData = {
des: string,
type: string,
merchant: number,
contract: number,
value: number,
}
type ProjectMonthlyCompleteModel = {
Business_Year: number // 经营月份 ,
Business_Month: number // 经营月份 ,
Account_Amount: number // 应收账款(万元) ,
Payment_Amount: number // 已缴金额(万元) ,
Unpaid_Amount: number // 未缴金额(万元) ,
Complete_Degree: number // 完成度(% ,
ProjectCompleteDetailList: ProjectCompleteDetailModel[]// 应收账款明细列表
}
type ProjectCompleteDetailModel = {
Account_Type: number // 经营月份 ,
Account_Name: string // 款项名称 ,
Account_Amount: number // 应收账款(万元) ,
Payment_Amount: number // 已缴金额(万元) ,
Complete_Degree: number // 完成度(%
}

View File

@ -1,3 +0,0 @@
import request from '@/utils/request';

View File

@ -1,22 +0,0 @@
// 分析说明表相关类
export type ANALYSISINSModel = {
ANALYSISINS_ID: number; // 分析说明表内码
ANALYSISINS_PID?: number; // 分析说明表父级内码
STATISTICS_DATE?: number; // 统计时间(日期/月份/年份)
ANALYSISINS_TYPE?: number; // 分析类型从枚举【ANALYSISINS_TYPE】获取解析
ANALYSISINS_TYPES: string; // 分析类型从枚举【ANALYSISINS_TYPE】获取解析(查询条件)
ANALYSISINS_FORMAT?: number; // 数据格式从枚举【ANALYSISINS_FORMAT】获取解析
ANALYSISINS_FORMATS: string; // 数据格式从枚举【ANALYSISINS_FORMAT】获取解析(查询条件)
PROVINCE_CODE?: number; // 省份编码
SPREGIONTYPE_ID?: number; // 片区内码
SERVERPART_ID?: number; // 服务区内码
SERVERPART_IDS: string; // 服务区内码(查询条件)
ANALYSIS_CONTENT: string; // 分析内容
KEY_CONTENT: string; // 关键字段(需要标注显示的内容)
PELLUCIDITY?: number; // 内容透明度
ANALYSISINS_INDEX?: number; // 显示索引
ANALYSISINS_STATE?: number; // 数据状态0删除1有效
STAFF_ID?: number; // 操作人内码
STAFF_NAME: string; // 操作人名称
OPERATE_DATE?: string; // 操作时间
};

View File

@ -1,4 +0,0 @@
import { tableList, wrapTreeNode } from '@/utils/format';
import request from '@/utils/request';
import type { ANALYSISINSModel } from './data'; // 引用标准接口数据对象

View File

@ -1,57 +0,0 @@
/*
* @Author: cclu
* @Date: 2022-03-10 10:02:38
* @LastEditors: cclu
* @LastEditTime: 2022-03-11 14:39:09
* @FilePath: \cloud-platform\src\pages\merchantManagement\reports\SalesFlow\data.d.ts
* @Description:
*
* Copyright (c) 2022 by cclu/驿, All Rights Reserved.
*/
export type CommoditySaleSummaryParams = {
DataType: 1|2,
StartTime: Date,
EndTime: Date,
ServerpartShopIds: string,
}
export type YSSELLMASTERModel = {
SELLMASTER_CODE: string;// 订单唯一标识(同移动支付单号) ,
SERVERPART_ID: number;// 服务区内码 ,
SERVERPARTCODE: string;// 服务区编码 ,
SERVERPART_NAME: string;// 服务区名称 ,
SERVERPARTSHOP_ID: string;// 门店内码 ,
SHOPCODE: string;// 门店编码 ,
SHOPNAME: string;// 门店名称 ,
MACHINECODE: string;// 收银机号 ,
SELLWORKER_CODE: string;// 收银员工号 ,
SELLWORKER_NAME: string;// 收银员名称 ,
SELLMASTER_TYPE: number;// 流水类型 ,
SELLMASTER_TYPE_TEXT: string;// 流水类型(中文) ,
SELLMASTER_DATE: string;// 交易时间 ,
TICKET_CODE: string;// 小票流水号 ,
SELLMASTER_COUNT: number;// 销售数量 ,
SELLMASTER_OFFPRICE: number;// 优惠金额 ,
SELLMASTER_AMOUNT: number;// 应付金额 ,
PAYMENT_TYPE: number;// 支付方式 ,
PAYMENT_TYPE_TEXT: string;// 支付方式(中文) ,
PAYMENT_GROUP: number;// 是否组合支付 ,
MERCHANT_ORDER: string;// 通道退款单号 ,
REFUND_ORDER: string;// 退款原订单号 ,
SELLMASTER_DESC: string;// 备注(预留)
}
export type YSSELLDETAILSModel = {
SELLMASTER_CODE: string;// 订单编码(同移动支付单号) ,
COMMODITY_BARCODE: string;// 商品条码 ,
COMMODITY_NAME: string;// 商品名称 ,
COMMODITY_TYPE: string;// 商品类别 ,
SELLDETAILS_COUNT: number;// 销售数量 ,
SELLDETAILS_PRICE: number;// 商品单价 ,
SELLDETAILS_OFFPRICE: number;// 优惠金额 ,
SELLDETAILS_AMOUNT: number;// 销售金额 ,
LINENUM: number;// 行号 ,
CREATE_DATE: number;// 交易时间 ,
SELLDETAILS_DESC: string;// 备注(预留)
}

View File

@ -1,378 +0,0 @@
/*
* @Author: cclu
* @Date: 2022-03-10 16:59:45
* @LastEditTime: 2024-01-23 18:45:00
* @LastEditors: cclu 1106109051@qq.com
* @Description:
* @FilePath: \cloud-platform\src\pages\merchantManagement\reports\SalesFlow\index.tsx
*/
import { connect } from 'umi';
import useRequest from '@ahooksjs/use-request';
import { PageContainer } from '@ant-design/pro-layout';
import ProTable from '@ant-design/pro-table';
import FlowDetail from './components/FlowDetail';
import ProCard from '@ant-design/pro-card';
import { MenuFoldOutlined } from '@ant-design/icons';
import { Button, Descriptions, message, Modal, Space, Tree, Typography } from 'antd';
import { useRef, useState } from 'react';
import type { ConnectState } from '@/models/connect';
import type { ProFormInstance } from '@ant-design/pro-form';
import type { ActionType, ProColumns } from '@ant-design/pro-table';
import type { YSSELLMASTERModel } from './data';
import type { CurrentUser } from '@/models/user';
import moment from 'moment';
import numeral from 'numeral';
import { exportExcel } from '@/utils/utils';
import { getYSSellMasterList } from './service';
import { getMoney, getUserShopTree } from '@/services/options';
import '../../style.less';
import './salesFlow.less'
import { getYSSellMasterListAllData } from '@/pages/reports/BusinessAnalysis/saleFlow/service';
const { Text } = Typography;
/**
* @description:
* @param {CurrentUser} CurrentUser
* @return {React.FC}
*/
const CommoditysaleTable: React.FC<{ currentUser: CurrentUser | undefined }> = (props) => {
const { currentUser } = props
const actionRef = useRef<ActionType>();
const formRef = useRef<ProFormInstance>();
const [currentRow, setCurrentRow] = useState<YSSELLMASTERModel | undefined>(); // 选中的流水
const [visible, setVisible] = useState<boolean>(); // 流水明显弹出框
const [reqDetailList, setReqDetailList] = useState<YSSELLMASTERModel[]>();
const [collapsible, setCollapsible] = useState<boolean>(false) // 是否隐藏门店服务区筛选
const { loading: shopLoading, data: shopTree } = useRequest(() => { return getUserShopTree(currentUser?.ID) })
const defaultShops = currentUser?.ServerpartShopIds ? currentUser?.ServerpartShopIds.split(',').map(Number) : []
const [shopId, setShopId] = useState<[]>(); // 选择的门店 根据选择的门店筛选数据结果
const [otherData, setOtherData] = useState<any>()
const columns: ProColumns<YSSELLMASTERModel>[] = [
{
dataIndex: 'index',
title: '序号',
hideInSearch: true,
// valueType: 'index',
// fixed: true,
align: 'center',
width: 48,
render: (_, reocrd) => {
return reocrd.index
}
},
{
dataIndex: 'SELLMASTER_DATE',
valueType: "date",
title: '销售时间',
align: 'center',
initialValue: moment().add(-1, 'day'),
render: (_, record) => {
return record?.SELLMASTER_DATE
},
fieldProps: {
disabledDate: (current: any) => current && current > moment().endOf('day').add(-1, 'day')
}
},
{
dataIndex: 'TICKET_CODE',
title: '小票编号',
hideInSearch: true,
align: 'center',
},
{
dataIndex: 'SELLMASTER_COUNT',
title: '销售数量',
hideInSearch: true,
align: 'right',
sorter: (a, b) => a.SELLMASTER_COUNT - b.SELLMASTER_COUNT
},
{
dataIndex: 'SELLMASTER_AMOUNT',
title: '实收金额',
hideInSearch: true,
valueType: "money",
align: 'right',
sorter: (a, b) => a.SELLMASTER_AMOUNT - b.SELLMASTER_AMOUNT
},
{
dataIndex: 'SELLMASTER_OFFPRICE',
title: '优惠金额',
hideInSearch: true,
valueType: "money",
align: 'right',
sorter: (a, b) => a.SELLMASTER_OFFPRICE - b.SELLMASTER_OFFPRICE
},
{
dataIndex: 'PAYMENT_TYPE_TEXT',
title: '支付方式',
hideInSearch: true,
align: 'center',
},
{
dataIndex: 'SHOPNAME',
hideInSearch: true,
title: '门店名称',
align: 'center',
width: '12%',
},
{
dataIndex: 'MACHINECODE',
hideInSearch: true,
title: '收银机号',
align: 'center',
},
{
dataIndex: 'SELLWORKER_NAME',
hideInSearch: true,
title: '收银人员',
align: 'center',
}
];
return (
<PageContainer header={{
title: '',
breadcrumb: {},
}}>
<ProCard split="vertical" style={{ backgroundColor: '#fff' }}>
<ProCard
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20 }}
extra={<MenuFoldOutlined onClick={() => { setCollapsible(!collapsible) }} />}
colSpan={!collapsible ? "240px" : "60px"}
title={!collapsible ? "可筛选门店" : ""}
headerBordered
collapsed={collapsible}
>
{shopTree && <Tree
checkable
treeData={!shopLoading ? shopTree : []}
fieldNames={{
title: "label",
key: "value"
}}
// defaultCheckedKeys={defaultShops}
defaultExpandedKeys={defaultShops}
blockNode
// onSelect={onSelect}
onCheck={(checkedKeys: React.Key[] | any, checkedInfo: any) => {
if (checkedInfo.checkedNodes.length > 0) {
const checkedPart = checkedInfo.checkedNodes.reduce((accumulator: any[], current: { type: number; value: any; }) => {
if (current.type === 2) {
accumulator.push(current.value)
}
return accumulator
}, [])
setShopId(checkedPart.toString())
} else {
setShopId([])
}
// actionRef.current?.reload()
return checkedKeys
}}
>
</Tree>}
</ProCard>
<ProCard className="report-table-card" bodyStyle={{ paddingTop: 0, paddingBottom: 0, paddingRight: 0 }}>
<ProTable<YSSELLMASTERModel>
rowKey="SELLMASTER_CODE"
headerTitle={<Text type="success" style={{ color: "#1890ff", fontSize: 14 }} strong></Text>}
formRef={formRef}
actionRef={actionRef}
search={{ span: 6 }}
request={async (params) => {
if (shopId && shopId.length > 0) {
const data = await getYSSellMasterListAllData({
...params,
SERVERPARTSHOP_ID: shopId && shopId.length > 0 ? shopId.toString() : currentUser?.ServerpartShopIds,
});
setReqDetailList(data.List);
console.log('data', data);
const list: any = JSON.parse(JSON.stringify(data.List))
if (list && list.length > 0) {
list.forEach((item: any, index: number) => {
item.index = index + 1
})
}
console.log('list', list);
data.List = list
setOtherData(data.OtherData)
return { data: data.List, success: true };
}
return { data: [], success: true }
}}
rowClassName="saleflow-row"
bordered
columns={columns}
toolbar={{
actions: [
<Button
key="new"
type="primary"
onClick={async () => {
const success = await exportExcel(
columns.slice(2),
reqDetailList || [],
`销售流水统计_${moment().format('YYYY/MM/DD')}`,
);
if (success.message !== 'ok') {
message.info({ content: success.message });
}
}}
>
excel
</Button>
],
}}
tableExtraRender={
(_, data) => {
if (data) {
const devicesList: any = []
const reduceData = data.reduce((
p: {
SELLMASTER_OFFPRICE: number,
SELLMASTER_COUNT: number,
SELLMASTER_AMOUNT: number,
MACHINECODE: string[],
payway: {},
mobilePay: {}
},
currentValue: YSSELLMASTERModel) => {
const previousValue = { ...p }
previousValue.SELLMASTER_COUNT += currentValue.SELLMASTER_COUNT || 0; // 销售数量
previousValue.SELLMASTER_OFFPRICE += currentValue.SELLMASTER_OFFPRICE || 0; // 优惠金额
previousValue.SELLMASTER_AMOUNT += currentValue.SELLMASTER_AMOUNT || 0; // 实收金额
if (devicesList.indexOf(currentValue.MACHINECODE) === -1) {
devicesList.push(currentValue.MACHINECODE)
}
if (currentValue.PAYMENT_TYPE === 1010 || currentValue.PAYMENT_TYPE === 1020) {
previousValue.payway['移动'] += currentValue.SELLMASTER_AMOUNT
if (!previousValue.mobilePay[currentValue.PAYMENT_TYPE_TEXT]) { // 移动支付方式
previousValue.mobilePay[currentValue.PAYMENT_TYPE_TEXT] = 0
}
previousValue.mobilePay[currentValue.PAYMENT_TYPE_TEXT] += currentValue.SELLMASTER_AMOUNT
} else {
if (!previousValue.payway[currentValue.PAYMENT_TYPE_TEXT]) { // 支付方式
previousValue.payway[currentValue.PAYMENT_TYPE_TEXT] = 0
}
previousValue.payway[currentValue.PAYMENT_TYPE_TEXT] += currentValue.SELLMASTER_AMOUNT
}
if (!previousValue.MACHINECODE.includes(currentValue.MACHINECODE)) {
previousValue.MACHINECODE.push(currentValue.MACHINECODE); // 收银机号
}
return previousValue
}, {
SELLMASTER_OFFPRICE: 0,
SELLMASTER_COUNT: 0,
SELLMASTER_AMOUNT: 0,
MACHINECODE: [],
payway: { '移动': 0, '现金': 0, },
mobilePay: {}
});
return <div style={{ paddingLeft: 24 }}>
<Descriptions
title={<Text type="success" style={{ color: "#1890ff", fontSize: 14 }}></Text>}
size="small" column={7}
className="commity-sale-description"
contentStyle={{ fontWeight: "bolder" }} labelStyle={{ color: "#00000073" }}
>
<Descriptions.Item label="客单数量">{numeral(data.length).format('0,0')}<Text
type="secondary"> </Text></Descriptions.Item>
<Descriptions.Item
label="实收金额">¥{numeral(reduceData.SELLMASTER_AMOUNT).format('0,0.00')}</Descriptions.Item>
<Descriptions.Item
label="优惠金额">¥{numeral(reduceData.SELLMASTER_OFFPRICE).format('0,0.00')}</Descriptions.Item>
<Descriptions.Item
label="客单均价">¥{numeral(reduceData.SELLMASTER_AMOUNT / data.length).format('0,0.00')}</Descriptions.Item>
<Descriptions.Item label="销售数量">{numeral(reduceData.SELLMASTER_COUNT).format('0,0')}<Text
type="secondary"> </Text></Descriptions.Item>
<Descriptions.Item label="设备数量">{devicesList && devicesList.length > 0 ? devicesList.length : '-'}</Descriptions.Item>
<Descriptions.Item label="统计时间">{moment().format('YYYY-MM-DD')}</Descriptions.Item>
</Descriptions>
<Descriptions
title={<Text type="success" style={{ color: "#1890ff", fontSize: 14 }}></Text>}
size="small" column={7}
className="commity-sale-description"
contentStyle={{ fontWeight: "bolder" }} labelStyle={{ color: "#00000073" }}
>
<Descriptions.Item
label="现金支付">{otherData?.CASH ? `¥${numeral(getMoney(otherData?.CASH)).format('0,0.00')}` : '¥0.00'}</Descriptions.Item>
<Descriptions.Item
label="微信支付">{otherData?.TICKETBILL ? `¥${numeral(getMoney(otherData?.TICKETBILL)).format('0,0.00')}` : '¥0.00'}</Descriptions.Item>
<Descriptions.Item label="支付宝支付">{otherData?.OTHERPAY ? `¥${numeral(getMoney(otherData?.OTHERPAY)).format('0,0.00')}` : '¥0.00'}</Descriptions.Item>
<Descriptions.Item label="云闪付">{otherData?.CREDITCARD ? `¥${numeral(getMoney(otherData?.CREDITCARD)).format('0,0.00')}` : '¥0.00'}</Descriptions.Item>
<Descriptions.Item label="银联记账">{otherData?.YUNSHANFU ? `¥${numeral(getMoney(otherData?.YUNSHANFU)).format('0,0.00')}` : '¥0.00'}</Descriptions.Item>
<Descriptions.Item label="企业会员">{otherData?.COUPONTYPE_2010 ? `¥${numeral(getMoney(otherData?.COUPONTYPE_2010)).format('0,0.00')}` : '¥0.00'}</Descriptions.Item>
<Descriptions.Item label="电子优惠券">{otherData?.COUPONTYPE_2020 ? `¥${numeral(getMoney(otherData?.COUPONTYPE_2020)).format('0,0.00')}` : '¥0.00'}</Descriptions.Item>
</Descriptions>
<Descriptions size="small" className="commity-sale-description" column={7}
contentStyle={{ fontWeight: "bolder" }} labelStyle={{ color: "#00000073" }}>
<Descriptions.Item label="大巴优惠券">{otherData?.COUPONTYPE_2030 ? `¥${numeral(getMoney(otherData?.COUPONTYPE_2030)).format('0,0.00')}` : '¥0.00'}</Descriptions.Item>
<Descriptions.Item label="团购餐券">{otherData?.COUPONTYPE_2040 ? `¥${numeral(getMoney(otherData?.COUPONTYPE_2040)).format('0,0.00')}` : '¥0.00'}</Descriptions.Item>
<Descriptions.Item label="促销流水">{otherData?.SELLMASTERTYPE_1010 ? `¥${numeral(getMoney(otherData?.SELLMASTERTYPE_1010)).format('0,0.00')}` : '¥0.00'}</Descriptions.Item>
<Descriptions.Item label="香烟销售">{otherData?.SELLMASTERTYPE_1020 ? `¥${numeral(getMoney(otherData?.SELLMASTERTYPE_1020)).format('0,0.00')}` : '¥0.00'}</Descriptions.Item>
<Descriptions.Item label="在线订单">{otherData?.SELLMASTERTYPE_1030 ? `¥${numeral(getMoney(otherData?.SELLMASTERTYPE_1030)).format('0,0.00')}` : '¥0.00'}</Descriptions.Item>
<Descriptions.Item label="稽核补录">{otherData?.SELLMASTERTYPE_1040 ? `¥${numeral(getMoney(otherData?.SELLMASTERTYPE_1040)).format('0,0.00')}` : '¥0.00'}</Descriptions.Item>
</Descriptions>
</div>
}
return <></>
}
}
onRow={(record) => {
return {
onClick: () => {
setCurrentRow(record)
setVisible(true)
}
}
}}
pagination={{ defaultPageSize: 10 }}
/>
</ProCard>
</ProCard>
<Modal
title={currentRow ? `${currentRow?.SERVERPART_NAME + currentRow?.SHOPNAME}销售流水明细` : '销售流水明细'}
centered
visible={visible}
onOk={() => setVisible(false)}
onCancel={() => setVisible(false)}
width={1024}
bodyStyle={{ padding: 0 }}
destroyOnClose
>
{currentRow && <FlowDetail id={currentRow?.SELLMASTER_CODE} />}
</Modal>
</PageContainer>
);
};
export default connect(({ user }: ConnectState) => ({
currentUser: user.currentUser
}))(CommoditysaleTable);

View File

@ -1,15 +0,0 @@
.mobileMoney{
.ant-descriptions-item-container{
display: flex;
align-items: center;
.ant-descriptions-item-content{
.mobileMoneyText{
font-size: 28px;
color: rgb(250, 173, 20);
font-weight: 500;
line-height: 28px;
}
}
}
}

View File

@ -1,397 +0,0 @@
// 路由配置文件
export default [
{
path: '/',
component: '../layouts/BlankLayout',
routes: [
{
path: '/user',
component: '../layouts/UserLayout',
routes: [
{
path: '/user/login',
name: '用户登录',
component: './User/login',
},
{
path: '/user/register',
name: '用户注册',
component: './User/register',
},
{
path: '/user/forgetPassword',
name: '忘记密码',
component: './User/ForgetPassword',
},
],
},
{
path: '/',
component: '../layouts/SecurityLayout',
routes: [
{
path: '/',
component: '../layouts/BasicLayout',
authority: ['1000', '2000', '3000'],
routes: [
{
path: '/',
redirect: '/dashboard/analysis',
},
{
path: 'dashboard',
name: 'dashboard',
icon: 'DashboardOutlined',
routes: [
{
path: 'contractAnalysis',
name: 'busniess.analysis',
component: './busniess/Analysis',
},
{
path: 'analysisINS',
name: 'analysisINS',
component: './dashboard/analysisINS',
},
],
},
{
path: '/busniessproject',
name: 'busniessproject',
icon: 'FileProtectOutlined',
routes: [
{
path: 'contract',
name: 'contract.list',
component: './contract/list',
},
{
path: 'project',
name: 'project.list',
component: './BussinessProject/list',
},
{
path: 'project/detail/:id',
name: 'project.detail',
component: './BussinessProject/detail',
hideInMenu: true,
},
{
path: 'reports/contract',
name: 'reports.contract.list',
component: './reports/contract/index',
},
{
path: 'reports/refund',
name: 'reports.refund',
component: './reports/contract/refund',
},
{
path: 'reports/businessProject',
name: 'reports.businessProject',
component: './reports/BusinessProject/index',
},
],
},
{
path: '/baseinfo',
name: 'baseinfo',
icon: 'ReadOutlined',
routes: [
{
path: 'ownerunit',
name: 'ownerunit',
component: './basicManage/ownerunit/index',
},
{
path: 'merchats',
name: 'merchats',
component: './basicManage/Merchats/index',
icon: 'ShopOutlined',
},
{
path: 'businesstrade',
name: 'businesstrade',
component: './basicManage/BusinessTrade/index',
icon: 'ShoppingOutlined',
},
{
path: 'brand',
name: 'brand',
component: './basicManage/Brand/index',
icon: 'TrademarkOutlined',
},
{
path: 'serverpartinfo',
name: 'serverpartinfo',
component: './basicManage/Serverpart/index',
},
{
path: 'serverpartshop',
name: 'serverpartshop',
component: './basicManage/ServerpartShop/index',
},
{
path: 'commodity',
name: 'commodity',
component: './basicManage/Commodity/list',
},
{
path: 'qualificationDelay',
name: 'qualificationDelay',
component: './basicManage/QualificationDelay/index',
},
{
path: 'commodityOnshelf',
name: 'commodityOnshelf',
component: './basicManage/Commodity/onshelf',
},
],
},
{
path: '/dataVerification',
name: 'dataVerification',
icon: 'FileDoneOutlined',
routes: [
{
path: '/dataVerification/list',
name: 'list',
component: './DataVerification/list',
},
],
},
{
path: '/financial',
name: 'financial',
icon: 'AccountBookOutlined',
routes: [
{
path: '/financial/list',
name: 'list',
component: './Financial/list',
},
],
},
{
path: '/busniess',
name: 'busniess',
icon: 'ImportOutlined',
routes: [
{
path: 'payment',
name: 'paymentConfrim',
component: './busniess/PaymentConfirm',
},
{
path: 'payment/detail',
name: 'paymentConfrimDetail',
component: './busniess/PaymentConfirm/detail',
},
{
path: 'payment/detail/:id',
name: 'paymentConfrimDetail',
component: './busniess/PaymentConfirm/detail',
hideInMenu: true,
},
{
path: 'test',
name: 'paymentTest',
component: './busniess/test'
},
],
},
{
path: '/setting',
name: 'setting',
icon: 'setting',
routes: [
{
path: 'menu',
name: 'moduleCate',
component: './Setting/Module/index',
},
{
path: '/setting/roles',
name: 'roles',
component: './Setting/Roles/index',
},
{
path: '/setting/users',
name: 'users',
component: './Setting/Users/index',
},
{
path: '/setting/userstype',
name: 'userstype',
component: './Setting/UserType/index',
},
{
path: '/setting/route',
name: 'route',
component: './Setting/Route/index',
},
{
path: '/setting/appmenu',
name: 'appmenu',
component: './Setting/APPMenu/index',
},
{
path: '/setting/appletroute',
name: 'appletroute',
component: './Setting/AppletRoute/index',
},
],
},
{
path: '/account',
name: 'account',
icon: 'UserOutlined',
hideInMenu: true,
routes: [
{
path: 'center',
name: 'center',
component: './account/center',
},
{
path: 'settings',
name: 'settings',
component: './account/setting',
},
],
},
{
path: '/merchantManagement',
name: 'merchantManagement',
icon: 'UserOutlined',
hideInMenu: true,
routes: [
{
path: 'commitysale',
name: 'commitysale',
component: './merchantManagement/reports/CommitySaleReport',
},
{
path: 'salesFlow',
name: 'salesFlow',
component: './merchantManagement/reports/SalesFlow',
},
{
path: 'bankArrival',
name: 'bankArrival',
component: './merchantManagement/mobilePayment/bankArrival',
},
{
path: 'revenueSummary',
name: 'revenueSummary',
component: './merchantManagement/reports/RevenueSummary',
},
{
path: 'commodity',
name: 'commodity',
component: './merchantManagement/commodity/BaseInfo',
},
{
path: 'upSaleCommodity',
name: 'upSaleCommodity',
component: './merchantManagement/commodity/Update',
},
{
path: 'category/:id',
name: 'category',
component: './merchantManagement/category',
},
{
path: 'onsale',
name: 'onsale',
component: './merchantManagement/commodity/OnSale',
},
{
path: 'busniessproinst',
name: 'busniessproinst',
component: './merchantManagement/BusniessProInst/index',
},
{
path: 'busniessproinst/detail',
name: 'busniessproInstDetail',
component: './merchantManagement/BusniessProInst/result',
},
{
path: 'busniessproinst/examineAndApprove/:id',
name: 'examineAndApprove',
component: './merchantManagement/BusniessProInst/examineAndApprove',
},
{
path: 'workplace',
name: 'merchantWorkplace',
component: './merchantManagement/Workplace/index',
},
{
path: 'supplier/list',
name: 'supplier',
component: './merchantManagement/supplier/Management/index',
},
{
path: 'supplier/qualifications',
name: 'qualifications',
component: './merchantManagement/supplier/Qualifications',
},
{
path: 'shops',
name: 'shops',
component: './merchantManagement/Shops',
},
{
path: 'brand',
name: 'brand',
component: './merchantManagement/brand',
},
{
path: 'company/create',
name: '完善商户资料',
component: './account/company',
},
{
path: 'shareRoyalty',
name: 'shareRoyalty',
component: './merchantManagement/mobilePayment/shareRoyalty',
},
],
},
{
path: '/test',
name: 'test',
hideInMenu: true,
routes: [
{
path: 'SALEBILL',
component: './Test/SALEBILL/index',
},
{
path: 'PURCHASE',
component: './Test/PURCHASE/index',
},
],
},
{
component: './404',
},
],
},
{
component: './404',
},
{
component: './500',
},
],
},
],
},
{
component: './404',
},
{
component: './500',
},
];

View File

@ -1,4 +1,4 @@
// 由 scripts/writeVersion.js 自动生成
export const VERSION = "4.5.81";
export const GIT_HASH = "5e6a50d";
export const BUILD_TIME = "2025-11-11T10:15:49.294Z";
export const VERSION = "4.5.82";
export const GIT_HASH = "897f4f7";
export const BUILD_TIME = "2025-11-12T01:55:07.374Z";