OrderStatisticCard.tsx 17.9 KB
import { RESPONSE_CODE } from '@/constants/enum';
import { postServiceOrderUpdateReportFormsTarget } from '@/services';
import { EditTwoTone } from '@ant-design/icons';
import {
  ModalForm,
  ProCard,
  ProFormDatePicker,
  ProFormDigit,
} from '@ant-design/pro-components';
import { useLocation } from '@umijs/max';
import { Flex, Form, message } from 'antd';
import { useEffect, useState } from 'react';

export default ({ data, statisticsMethod, reFreshData }) => {
  const location = useLocation();
  const [targetEditable, setTargetEditable] = useState(false);

  // 使用URLSearchParams来解析查询参数
  const params = new URLSearchParams(location.search);

  // 获取名为"param"的查询参数
  useEffect(() => {
    setTargetEditable(true);
    const urlEditable = params.get('editable');
    if (urlEditable === null) {
      setTargetEditable(false);
    }
  }, []);

  function getStatisticsMethodString() {
    if (statisticsMethod === 'MONTH_STATISTICS') {
      return '本月';
    }

    if (statisticsMethod === 'LAST_MONTH_STATISTICS') {
      return '上月';
    }

    if (statisticsMethod === 'YEAR_STATISTICS') {
      return '本年';
    }

    return '';
  }

  const [edit, setEdit] = useState(false);
  const [form] = Form.useForm<{
    statisticsMethod: string;
    target: number;
    daysOfMonth: number;
    month: string;
  }>();
  const [targetValue, setTargetValue] = useState(0);

  // const UpBig = () => (
  //   <svg width="44" height="auto" fill="#d81e06" viewBox="0 0 1024 1024">
  //     <path
  //       d="M255.857413 855.291523h-58.175337c-16.996324 0-30.798708-13.802384-30.798707-30.798708V166.084884c0-16.996324 13.802384-30.798708 30.798707-30.798708h58.175337c16.996324 0 30.798708 13.802384 30.798708 30.798708v658.293862c0 16.996324-13.916453 30.912777-30.798708 30.912777z m-54.867327-34.220787h51.331179V169.506962h-51.331179v651.563774zM442.816977 855.291523h-58.175337c-16.996324 0-30.798708-13.802384-30.798708-30.798708V348.367606c0-16.996324 13.802384-30.798708 30.798708-30.798708h58.175337c16.996324 0 30.798708 13.802384 30.798708 30.798708v476.01114c0 16.996324-13.802384 30.912777-30.798708 30.912777z m-54.753259-34.220787h51.33118V351.789685h-51.33118v469.281051zM629.890609 855.291523h-58.175337c-16.996324 0-30.798708-13.802384-30.798707-30.798708V525.517211c0-16.996324 13.802384-30.798708 30.798707-30.798708h58.175337c16.996324 0 30.798708 13.802384 30.798708 30.798708v298.975604c0 16.882255-13.802384 30.798708-30.798708 30.798708z m-54.753258-34.220787h51.33118V528.939289h-51.33118v292.131447zM816.964242 855.291523h-58.175337c-16.996324 0-30.798708-13.802384-30.798708-30.798708V702.552746c0-16.996324 13.802384-30.798708 30.798708-30.798708h58.175337c16.996324 0 30.798708 13.802384 30.798708 30.798708v121.940069c0 16.882255-13.802384 30.798708-30.798708 30.798708z m-54.753258-34.220787h51.331179V705.974825h-51.331179v115.095911zM830.652557 589.167873c-6.38788 0-12.547622-3.650217-15.513424-9.809958l-71.977721-152.168431-162.206527-45.855854c-6.844157-1.939178-11.863206-7.98485-12.433553-15.057146l-10.950651-133.803275-143.271026-77.567116c-8.327058-4.448702-11.406929-14.829007-6.844158-23.156065 4.448702-8.327058 14.829007-11.406929 23.156066-6.844157l151.484015 82.015818c5.133118 2.737663 8.441127 7.870781 8.897404 13.688314l10.722513 131.179682 158.328172 44.715161c4.79091 1.368831 8.669266 4.676841 10.836583 9.125543l75.28573 159.126657c3.992425 8.555197 0.342208 18.707363-8.09892 22.813857-2.509524 1.026624-5.019049 1.59697-7.414503 1.59697z"
  //       fill="#d81e06"
  //     ></path>
  //     <path d="M456.163083 261.903086c-6.844157 0-13.232037-4.106494-15.855631-10.722513l-42.433775-106.426646c-1.825109-4.676841-1.59697-10.038097 0.798485-14.4868 2.395455-4.448702 6.616019-7.642642 11.635068-8.669266l130.153057-26.692213c9.239612-1.939178 18.251086 4.106494 20.190264 13.346106 1.939178 9.239612-4.106494 18.251086-13.346106 20.190264l-110.076863 22.58572 34.905202 87.377074c3.536148 8.783335-0.798485 18.707363-9.58182 22.243511-2.053247 0.798485-4.220564 1.254762-6.387881 1.254763z" />
  //   </svg>
  // );

  // const DownBig = () => (
  //   <svg width="44" height="auto" fill="#1DB302" viewBox="0 0 1024 1024">
  //     <path
  //       d="M727.990197 852.667929V194.374067c0-16.996324 13.802384-30.798708 30.798708-30.798708h58.175337c16.996324 0 30.798708 13.802384 30.798708 30.798708v658.293862c0 16.996324-13.802384 30.798708-30.798708 30.798708h-58.175337c-16.996324 0-30.798708-13.802384-30.798708-30.798708z m85.551966-654.871783h-51.331179v651.449705h51.331179V197.796146zM540.916565 852.667929V376.65679c0-16.996324 13.802384-30.798708 30.798707-30.798708h58.175337c16.996324 0 30.798708 13.802384 30.798708 30.798708v476.011139c0 16.996324-13.802384 30.798708-30.798708 30.798708h-58.175337c-16.996324 0-30.798708-13.802384-30.798707-30.798708z m85.551966-472.589061h-51.33118v469.166983h51.33118V380.078868zM353.842932 852.667929v-298.861535c0-16.996324 13.802384-30.798708 30.798708-30.798708h58.175337c16.996324 0 30.798708 13.802384 30.798708 30.798708v298.975604c0 16.996324-13.802384 30.798708-30.798708 30.798708h-58.175337c-16.996324-0.114069-30.798708-13.916453-30.798708-30.912777z m85.551966-295.439456h-51.33118v292.131447h51.33118V557.228473zM166.769299 852.667929V730.72786c0-16.996324 13.802384-30.798708 30.798708-30.798708h58.175337c16.996324 0 30.798708 13.802384 30.798708 30.798708v121.940069c0 16.996324-13.802384 30.798708-30.798708 30.798708h-58.175337c-16.882255 0-30.798708-13.802384-30.798708-30.798708z m85.666036-118.51799h-51.33118v115.095912h51.33118V734.149939zM660.347109 189.012811c-0.684416 6.38788-4.904979 12.091345-11.406929 14.37273l-158.898518 55.437674-62.738108 156.503063c-2.623594 6.616019-9.125543 10.950652-16.311909 10.722513l-134.145483-3.308009-92.282054 134.259552c-5.361257 7.756712-15.9697 9.809959-23.840481 4.448702-7.756712-5.361257-9.809959-15.9697-4.448702-23.840481l97.529241-141.902194c3.308009-4.79091 8.783335-7.528573 14.4868-7.414504l131.521889 3.308009 61.255208-152.738777c1.825109-4.562772 5.589395-8.212989 10.266236-9.809958L637.647321 171.103932c8.897404-3.079871 18.707363 1.59697 21.787234 10.494375 0.912554 2.509524 1.140693 5.019049 0.912554 7.414504z"
  //       fill="#1DB302"
  //     ></path>
  //     <path
  //       d="M295.211318 526.771973c-0.684416 6.730088-5.475326 12.77576-12.433553 14.714938l-110.305001 30.912777c-4.904979 1.368831-10.152167 0.456277-14.258661-2.395455-4.220564-2.851732-6.844157-7.414504-7.414504-12.433552l-12.661691-132.206305c-0.912554-9.353682 6.045672-17.794809 15.399354-18.707364 9.353682-0.912554 17.794809 6.045672 18.707363 15.399354l10.722513 111.901972 90.571015-25.437451c9.125543-2.509524 18.593294 2.737663 21.102818 11.863206 0.684416 2.053247 0.798485 4.220564 0.570347 6.38788z"
  //       fill="#1DB302"
  //     />
  //   </svg>
  // );

  // const UpSmall = () => (
  //   <svg width="14" height="auto" fill="#d81e06" viewBox="0 0 1024 1024">
  //     <path d="M511.976976 945.959599c-239.47514 0-433.597349-194.300264-433.597349-433.964716 0-239.677754 194.122209-433.955506 433.597349-433.955506s433.642374 194.277752 433.642374 433.955506C945.61935 751.659335 751.453139 945.959599 511.976976 945.959599zM666.05312 408.869155l-131.822304-132.292002c-2.899026-4.303003-7.091512-7.870248-12.509918-9.766434-2.876514-1.137916-5.952572-1.64957-9.119705-1.582031-0.222057 0-0.401136-0.112564-0.623193-0.112564-0.289596 0-0.535189 0.13303-0.847298 0.156566-3.03308-0.044002-6.021134 0.423649-8.830109 1.515516-5.507434 1.918699-9.787924 5.528923-12.664438 9.945513L357.945857 408.869155c-9.275247 9.29776-8.562003 25.061792 1.560542 35.184337 10.168594 10.146081 25.463951 10.413164 34.739199 1.11438 0.73678-0.735757 1.471514-1.248434 2.073218-2.073218l89.747024-89.456405 0.245593 399.136489c-0.155543 0.936325 0 1.783623 0 2.76395 0 12.352329 10.992355 22.342868 25.352411 22.342868 14.314007 0 25.976628-9.990538 25.976628-22.342868l0.289596-401.923976 89.771583 89.478917c0.599657 0.825808 1.335415 1.337461 2.049682 2.073218 9.29776 9.29776 24.595164 9.030677 34.740222-1.11438C674.615123 433.930947 675.351903 418.166915 666.05312 408.869155z" />{' '}
  //   </svg>
  // );

  // const DownSmall = () => (
  //   <svg width="14" height="auto" fill="#1DB302" viewBox="0 0 1024 1024">
  //     <path d="M945.61935 512.005117c0 239.677754-194.166211 433.955506-433.642374 433.955506S78.379627 751.682871 78.379627 512.005117c0-239.664452 194.122209-433.964716 433.597349-433.964716S945.61935 272.340665 945.61935 512.005117zM664.492578 579.947532c-10.145058-10.146081-25.442462-10.413164-34.740222-1.115404-0.714268 0.735757-1.450025 1.248434-2.049682 2.073218l-89.771583 89.478917-0.289596-401.923976c0-12.352329-11.661597-22.342868-25.976628-22.342868-14.360056 0-25.352411 9.990538-25.352411 22.342868 0 0.980327-0.155543 1.827625 0 2.76395l-0.245593 399.136489-89.747024-89.456405c-0.602727-0.825808-1.337461-1.338485-2.073218-2.073218-9.275247-9.29776-24.571628-9.030677-34.739199 1.115404-10.123568 10.122545-10.836813 25.886577-1.560542 35.184337l131.689275 132.135436c2.876514 4.415566 7.157004 8.027837 12.664438 9.945513 2.808976 1.091868 5.79703 1.559519 8.830109 1.515516 0.312108 0.022513 0.557702 0.155543 0.847298 0.155543 0.223081 0 0.402159-0.11154 0.623193-0.11154 3.167133 0.067538 6.244214-0.445138 9.119705-1.583055 5.418406-1.895163 9.610892-5.462408 12.509918-9.765411l131.822304-132.292002C675.351903 605.833085 674.615123 590.069053 664.492578 579.947532z" />{' '}
  //   </svg>
  // );

  const CardTitle = ({ title }) => {
    return <span className="text-sm text-stone-600">{title}</span>;
  };

  const CardContent = ({
    unit = '',
    content = 0,
    sameMonthPercentageChange = -1000,
    editable = false,
  }) => {
    //如果是可编辑的说明是指标,设置指标值,可用在弹窗中的回显
    if (editable) {
      setTargetValue(content);
    }

    let trendIcon;
    let trendPercentage;
    // if (sameMonthPercentageChange > 0) {
    //   trendIcon = <Icon component={UpBig} />;
    //   trendPercentage = (
    //     <div style={{ minWidth: '130px' }}>
    //       <span className="text-xs text-stone-500">
    //         同比上
    //         {statisticsMethod === 'MONTH_STATISTICS' ? '个月' : '年'}
    //       </span>
    //       <Icon component={UpSmall} />
    //       <span className="text-[#d81e06]">+{sameMonthPercentageChange}%</span>
    //     </div>
    //   );
    // }

    // if (sameMonthPercentageChange < 0) {
    //   trendIcon = <Icon component={DownBig} />;
    //   trendPercentage = (
    //     <div style={{ minWidth: '130px' }}>
    //       <span className="text-xs text-stone-500">
    //         同比上
    //         {statisticsMethod === 'MONTH_STATISTICS' ? '个月' : '年'}
    //       </span>
    //       <Icon component={DownSmall} />
    //       <span className="text-[#1DB302]">{sameMonthPercentageChange}%</span>
    //     </div>
    //   );
    // }

    if (sameMonthPercentageChange === -1000) {
      trendIcon = '';
      trendPercentage = '';
    }

    return (
      <Flex vertical>
        <Flex>
          <Flex align="center">
            <span className="pr-1 text-base">{unit}</span>
            <div style={{ width: 'max-content', display: 'flex' }}>
              <span className="text-2xl">
                {content}
                {editable ? (
                  <span className="pl-1 text-xs">
                    {statisticsMethod === 'YEAR_STATISTICS'
                      ? '平均每月'
                      : '每月'}
                  </span>
                ) : (
                  ''
                )}
              </span>
              {editable && targetEditable ? (
                <EditTwoTone
                  style={{ fontSize: '20px' }}
                  onClick={() => {
                    setEdit(true);
                  }}
                />
              ) : (
                ''
              )}

              {/* {editable ? (
                edit ? (
                  <InputNumber
                    placeholder="请输入指标(¥)"
                    width={200}
                    value={targetValue}
                    max={100000000}
                    onChange={(value) => {
                      setTargetValue(value);
                    }}
                  />
                ) : (
                  <span className="text-2xl">
                    {content}
                    {editable ? <span className="px-1 text-xs">每月</span> : ''}
                  </span>
                )
              ) : (
                ''
              )}

              {!editable ? (
                <span className="text-2xl">
                  {content}
                  {editable ? <span className="pl-1 text-xs">每月</span> : ''}
                </span>
              ) : (
                ''
              )} */}

              {/* {editable ? (
                edit ? (
                  [
                    <CheckCircleTwoTone
                      key="confirm"
                      style={{ fontSize: '20px', paddingLeft: '5px' }}
                      onClick={async () => {
                        let body = {
                          statisticsMethod: statisticsMethod,
                          target: targetValue,
                        };
                        let res = await postServiceOrderUpdateReportFormsTarget(
                          { data: body },
                        );
                        if (res.result === RESPONSE_CODE.SUCCESS) {
                          message.success(res.message);
                          setEdit(false);
                          reFreshData();
                        }
                      }}
                    />,
                    <CloseCircleTwoTone
                      key="cancel"
                      style={{ fontSize: '20px', paddingLeft: '5px' }}
                      onClick={async () => {
                        setEdit(false);
                      }}
                    />,
                  ]
                ) : (
                  <EditTwoTone
                    style={{ fontSize: '20px' }}
                    onClick={() => {
                      setEdit(true);
                    }}
                  />
                )
              ) : (
                ''
              )} */}
            </div>
          </Flex>
          {trendIcon}
        </Flex>

        {trendPercentage}
      </Flex>
    );
  };

  return (
    <>
      <ProCard title="" ghost gutter={8}>
        <ProCard
          className="order-statictis-card"
          bordered
          title={<CardTitle title={getStatisticsMethodString() + '总收入'} />}
        >
          <CardContent
            unit="¥"
            content={data?.totalPayment}
            sameMonthPercentageChange={data?.totalPaymentTrend}
          />
        </ProCard>
        <ProCard
          className="order-statictis-card"
          title={<CardTitle title={getStatisticsMethodString() + '指标'} />}
          bordered
        >
          <CardContent unit="¥" content={data?.target} editable={true} />
        </ProCard>
        <ProCard
          className="order-statictis-card"
          title={<CardTitle title={getStatisticsMethodString() + '总订单量'} />}
          bordered
        >
          <CardContent
            unit="单"
            content={data?.totalOrderNumber}
            sameMonthPercentageChange={data?.totalOrderNumberTrend}
          />
        </ProCard>
        <ProCard
          className="order-statictis-card"
          title={
            <CardTitle title={getStatisticsMethodString() + '总子订单量'} />
          }
          bordered
        >
          <CardContent unit="单" content={data?.subTotalOrderNumber} />
        </ProCard>
        <ProCard
          className="order-statictis-card"
          title={
            <CardTitle title={getStatisticsMethodString() + '未审核子订单'} />
          }
          bordered
        >
          <CardContent unit="单" content={data?.unCheckOrderNumber} />
        </ProCard>
        <ProCard
          className="order-statictis-card"
          title={
            <CardTitle title={getStatisticsMethodString() + '待发货子订单'} />
          }
          bordered
        >
          <CardContent unit="单" content={data?.unSendOrderNumber} />
        </ProCard>
      </ProCard>

      <ModalForm<{
        statisticsMethod: string;
        target: number;
        daysOfMonth: number;
        month: string;
      }>
        title="编辑指标"
        width={500}
        form={form}
        open={edit}
        autoFocusFirstInput
        modalProps={{
          destroyOnClose: true,
          onCancel: () => setEdit(false),
        }}
        onFinish={async (values) => {
          values.statisticsMethod = statisticsMethod;
          let res = await postServiceOrderUpdateReportFormsTarget({
            data: values,
          });
          if (res.result === RESPONSE_CODE.SUCCESS) {
            message.success(res.message);
            setEdit(false);
            reFreshData();
          }
        }}
      >
        <ProFormDigit
          width="md"
          name="target"
          label="指标(¥)"
          min={0}
          initialValue={targetValue}
          placeholder="请输入指标"
          rules={[{ required: true, message: '指标必填' }]}
        />
        <ProFormDatePicker
          width="md"
          name="month"
          fieldProps={{
            picker: 'month',
            format: 'YYYY-MM',
          }}
          label="日期"
          placeholder="请输入日期"
          rules={[{ required: true, message: '日期必填' }]}
        />

        {statisticsMethod === 'MONTH_STATISTICS' ? (
          <ProFormDigit
            width="md"
            name="weekday"
            label={
              statisticsMethod === 'YEAR_STATISTICS'
                ? '每月工作日天数'
                : '本月工作日天数'
            }
            min={0}
            placeholder="工作日天数"
            rules={[{ required: true, message: '工作日天数必填' }]}
          />
        ) : (
          ''
        )}
      </ModalForm>
    </>
  );
};