Commit febc53240ceebd49e7798c5d478014313ebde495

Authored by 张志伟
2 parents 0e37f7ac 26e33634

Merge branch 'bug_fix' into 'master'

考评数据下载模板优化



See merge request !195
src/pages/performance/EvaDataImport/api.ts
... ... @@ -52,3 +52,17 @@ export function evaDataIndApi(): http.PromiseResp<any> {
52 52 export function saveEvaImportData(params: { key: string }) {
53 53 return request.get(`${MORAX_HOST}/erp/eval-indicator/save-import`, { params });
54 54 }
  55 +
  56 +/** 下载人员模板
  57 + * http://testgate.feewee.cn/morax/erp/eval-indicator/import-detail
  58 + */
  59 +export function upLoadStaffApi(): http.PromiseResp<any> {
  60 + return request.get(`${MORAX_HOST}/erp/eval-indicator/staff/template-file`, {});
  61 +}
  62 +
  63 +/** 下载门店模板
  64 + * http://testgate.feewee.cn/morax/erp/eval-indicator/import-detail
  65 + */
  66 +export function upLoadShopApi(): http.PromiseResp<any> {
  67 + return request.get(`${MORAX_HOST}/erp/eval-indicator/shop/template-file`, {});
  68 +}
... ...
src/pages/performance/EvaDataImport/index.tsx
... ... @@ -2,7 +2,8 @@ import React, { useState } from &quot;react&quot;;
2 2 import { PageHeaderWrapper } from "@ant-design/pro-layout";
3 3 import { Button, Card, Table, Row, message, Space, Typography, Divider, Switch, Upload } from "antd";
4 4 import usePagination from "@/hooks/usePagination";
5   -import { evaDataListApi } from "./api";
  5 +import useInitial from "@/hooks/useInitail";
  6 +import { evaDataListApi, upLoadStaffApi, upLoadShopApi } from "./api";
6 7 import { UploadOutlined } from "@ant-design/icons";
7 8 import type { UploadProps } from "antd";
8 9 import { history } from "umi";
... ... @@ -16,8 +17,12 @@ export default () =&gt; {
16 17 const { loading, list, paginationConfig, setParams, innerParams } = usePagination(evaDataListApi, {
17 18 pageSize: 10,
18 19 });
  20 + const { data: upLoadStaff, loading: upLoadStaffLoading } = useInitial(upLoadStaffApi, [], {});
  21 + const { data: upLoadShop, loading: upLoadShopLoading } = useInitial(upLoadShopApi, [], {});
19 22 const [fileData, setFileData] = useState({});
20 23 const [visible, setVisible] = useState<boolean>(false);
  24 + console.log("upLoadStaff", upLoadStaff);
  25 + console.log("upLoadShop", upLoadShop);
21 26 const uploadPerson: UploadProps = {
22 27 name: "file",
23 28 action: "/api/morax/erp/eval-indicator/analysis-staff",
... ... @@ -59,21 +64,13 @@ export default () =&gt; {
59 64 <Row style={{ marginBottom: 10 }} justify="space-between">
60 65 <Filter setParams={setParams} />
61 66 <div>
62   - <Button type="default" style={{ marginRight: 10 }}>
63   - <a
64   - href="https://gate.feewee.cn/file/download?fid=74d1d724f9be48baa5921f3782037c3b"
65   - target="_blank"
66   - rel="noreferrer"
67   - >
  67 + <Button type="default" style={{ marginRight: 10 }} loading={upLoadStaffLoading}>
  68 + <a href={upLoadStaff} target="_blank" rel="noreferrer">
68 69 下载人员模板
69 70 </a>
70 71 </Button>
71   - <Button type="default" style={{ marginRight: 10 }}>
72   - <a
73   - href="https://gate.feewee.cn/file/download?fid=e4eb136962164264a78753bd1d6061f3"
74   - target="_blank"
75   - rel="noreferrer"
76   - >
  72 + <Button type="default" style={{ marginRight: 10 }} loading={upLoadShopLoading}>
  73 + <a href={upLoadShop} target="_blank" rel="noreferrer">
77 74 下载门店模板
78 75 </a>
79 76 </Button>
... ... @@ -87,12 +84,7 @@ export default () =&gt; {
87 84 </Upload>
88 85 </div>
89 86 </Row>
90   - <Table
91   - loading={loading}
92   - rowKey={(row) => `id${row.id}`}
93   - dataSource={list}
94   - pagination={paginationConfig}
95   - >
  87 + <Table loading={loading} rowKey={(row) => `id${row.id}`} dataSource={list} pagination={paginationConfig}>
96 88 <Column
97 89 title="导入时间"
98 90 dataIndex="createTime"
... ...
src/pages/pms/partPlan/CustBuyPlan/subpages/First/components/PartModal.tsx
... ... @@ -73,7 +73,7 @@ export default function DetailModal() {
73 73 align="center"
74 74 render={r => (
75 75 <>
76   - <Popconfirm
  76 + {/* <Popconfirm
77 77 title="确定删除?"
78 78 onConfirm={() => deletePart(r)}
79 79 okText="确定"
... ... @@ -81,7 +81,7 @@ export default function DetailModal() {
81 81 >
82 82 <a>删除</a>
83 83 </Popconfirm>
84   - <Divider type="vertical" />
  84 + <Divider type="vertical" /> */}
85 85 <a onClick={() => onFinish(r)}>完成</a>
86 86 </>
87 87 )}
... ...
src/pages/pms/partPlan/PlanManage/api.ts
... ... @@ -20,7 +20,7 @@ export interface Params {
20 20 * 列表项
21 21 */
22 22 export interface ListVO {
23   - planId?: string; // 计划Id
  23 + planId?: number; // 计划Id
24 24 planNo?: string; // 计划单号
25 25 brandId?: string; // 品牌ID
26 26 planDate?: string; // 计划日期
... ...
src/pages/pms/partPlan/PlanManage/components/DetailModal.tsx
... ... @@ -6,7 +6,7 @@ import ProgressView from &quot;./ProgressView&quot;;
6 6 import ShippingDetailModal from './ShippingDetailModal';
7 7 import PartDetailModal from './PartDetailModal';
8 8 import {flattenDeep} from "@/pages/pms/entity";
9   -import {getDetail, DetailVO} from "@/pages/pms/partPlan/PlanManage/subpages/Detail/api";
  9 +import {getDetail, DetailVO, Item} from "@/pages/pms/partPlan/PlanManage/subpages/Detail/api";
10 10  
11 11 interface Props {
12 12 visible: boolean,
... ... @@ -22,12 +22,12 @@ export default function DetailModal(props: Props) {
22 22 // @ts-ignore
23 23 const { data: progresss, setParams: setProgresssParams } = useInitial<ProgressVO[], Params>(getProgressDetail, [], params, delay);
24 24 // @ts-ignore
25   - const { data, setParams, loading } = useInitial<DetailVO[], Params>(getDetail, [], params, delay);
  25 + const { data, setParams, loading } = useInitial<Item, Params>(getDetail, {}, params, delay);
26 26 const [visibleDetail, setVisibleDetail] = useState(false);
27 27 const [_item, setItem] = useState<SubmitListVO>({});
28 28 const [visiblePartDetail, setVisiblePartDetail] = useState(false);
29 29 const suppliers = useMemo(() => {
30   - return flattenDeep(data.map((it: DetailVO) => (it.suppliers || []).map(su => ({...it, ...su}))));
  30 + return flattenDeep(data.list?.map((it: DetailVO) => (it.suppliers || []).map(su => ({...it, ...su}))));
31 31 }, [data]);
32 32  
33 33 useEffect(() => {
... ...
src/pages/pms/partPlan/PlanManage/subpages/Apply/index.tsx
1   -import {Card, ConfigProvider, Select, Button, message, Popconfirm} from 'antd';
  1 +import {Card, ConfigProvider, Select, Button, message, Popconfirm, Input} from 'antd';
2 2 import { PageHeaderWrapper } from '@ant-design/pro-layout';
3 3 import React, {useEffect, useState} from "react";
4 4 import DealerModal from './components/DealerModal';
... ... @@ -15,7 +15,8 @@ import PartModal from &quot;@/pages/pms/partPlan/PlanManage/subpages/Apply/components
15 15 import {groupBys, flattenDeep} from '@/pages/pms/entity';
16 16 import {PartDetail} from '../../api';
17 17 import { history } from 'umi';
18   -import { getDetail, DetailVO, Params as detailParams } from '../Detail/api';
  18 +import { getDetail, Params as detailParams, Item } from '../Detail/api';
  19 +import ImageUpload from '@/pages/decoration/deco/DeoGoodsManagement/components/ImageUpload';
19 20  
20 21 const { Option } = Select;
21 22 const apiObj: { [key: number]: any } = {
... ... @@ -25,7 +26,7 @@ const apiObj: { [key: number]: any } = {
25 26 export default function Index() {
26 27 const planId = history.location.query;
27 28 const [detaildelay, setDetaildelay] = useState(true);
28   - const { data, setParams: detailsetParams } = useInitial<DetailVO[], detailParams>(getDetail, [], { ...planId }, detaildelay);
  29 + const { data, setParams: detailsetParams } = useInitial<Item, detailParams>(getDetail, {}, { ...planId }, detaildelay);
29 30 const [delay, setDelay] = useState<boolean>(true);
30 31 const [loading, setLoading] = useState<boolean>(false);
31 32 const { data: brands } = useInitial(API.getBrandFilterApi, [], {});
... ... @@ -39,6 +40,8 @@ export default function Index() {
39 40 const [visiblePartDetail, setVisiblePartDetail] = useState(false);
40 41 const partList = flattenDeep(dealerList.map(it => (it.suppliers || []).map((su: any) => (su.storages || []).map((st: any) => (st.parts || [])))));
41 42 const poolIds = partList.map((it: any) => it.poolId);
  43 + const [imageVisible, setImageVisible] = useState(true);
  44 + const [info, setInfo] = useState<{ remark?: string, fids?: any }>();
42 45  
43 46 useEffect(() => {
44 47 if (planId?.planId) {
... ... @@ -48,13 +51,15 @@ export default function Index() {
48 51 }, []);
49 52  
50 53 useEffect(() => {
51   - if (data.length) {
52   - setDfParams({brandId: data[0].brandId});
  54 + if (data.list?.length) {
  55 + setImageVisible(false);
  56 + setDfParams({brandId: data.list[0].brandId});
53 57 setParams({}, true);
54 58 setDelay(false);
55   - setDealerList(data);
  59 + setDealerList(data.list);
  60 + setInfo({ remark: data.remark, fids: data.fids?.split(',').map(i => `/api/file/show?fid=${i}`) });
56 61 }
57   - }, [data.length]);
  62 + }, [data.list?.length]);
58 63  
59 64 function onOk(parts: ListVO[] = []) {
60 65 setDealerList(dealerList.map(it => {
... ... @@ -173,14 +178,15 @@ export default function Index() {
173 178 apiObj[type]({
174 179 planId: Number(planId?.planId),
175 180 ...dfParams,
176   - suppliers
177   - // suppliers: suppliers.map(i => ({
178   - // settleDealerId: i.settleDealerId,
179   - // settleDealerName: i.settleDealerName,
180   - // supplierId: i.supplierId,
181   - // supplierName: i.supplierName,
182   - // storages: i.storages
183   - // }))
  181 + suppliers,
  182 + remark: info?.remark,
  183 + fids: info?.fids.map((i: any) => {
  184 + if (typeof i == 'object') {
  185 + return i.url.split('=')[1];
  186 + } else {
  187 + return i;
  188 + }
  189 + }).join()
184 190 }).then(() => {
185 191 setLoading(false);
186 192 history.goBack();
... ... @@ -332,12 +338,28 @@ export default function Index() {
332 338 deletePart={deletePart}
333 339 />
334 340 </div>
  341 + <div style={{display: 'flex', alignItems: 'flex-start', marginBottom: 20}}>
  342 + <span style={{marginRight: 10}}>备注:</span>
  343 + <Input.TextArea rows={2} style={{ width: 250 }} value={info?.remark} onChange={e => setInfo({...info, remark: e.target.value})} />
  344 + </div>
  345 + <div style={{ display: 'flex', alignItems: 'flex-start' }}>
  346 + <span style={{ marginRight: 10 }}>附件:</span>
  347 + <ImageUpload
  348 + length={6}
  349 + clear={imageVisible}
  350 + value={info?.fids}
  351 + onChange={v => {
  352 + const ids = v.fileList.map(it => it?.response?.data || it);
  353 + setInfo({ ...info, fids: ids });
  354 + }}
  355 + />
  356 + </div>
335 357 <div style={{display: 'flex', justifyContent: 'center'}}>
336 358 <Button
337 359 disabled={loading}
338 360 loading={loading}
339 361 style={{marginRight: 20}}
340   - onClick={() => history.goBack()}
  362 + onClick={() => { setImageVisible(true); history.goBack(); }}
341 363 >
342 364 取消
343 365 </Button>
... ... @@ -359,7 +381,6 @@ export default function Index() {
359 381 确认并提交
360 382 </Button>
361 383 </div>
362   -
363 384 </Card>
364 385 </ConfigProvider>
365 386 </PageHeaderWrapper>
... ...
src/pages/pms/partPlan/PlanManage/subpages/Detail/api.ts
... ... @@ -48,9 +48,55 @@ export interface Params {
48 48 planNo?: string;
49 49 no?: string;
50 50 }
  51 +export interface Item {
  52 + /**
  53 + * 计划单号
  54 + */
  55 + planNo?: string;
  56 + /**
  57 + * 品牌ID
  58 + */
  59 + brandId?: number;
  60 + /**
  61 + * 计划日期
  62 + */
  63 + planDate?: string;
  64 + /**
  65 + * 审核单号
  66 + */
  67 + approvalOrderNo?: string;
  68 + /**
  69 + * 计划人员
  70 + */
  71 + userName?: string;
  72 + /**
  73 + * 库销比
  74 + */
  75 + ratio?: number;
  76 + /**
  77 + * 计划库销比
  78 + */
  79 + planRatio?: number;
  80 + /**
  81 + * 计划状态 1:待审核2:已通过9:已拒绝
  82 + */
  83 + status?: string;
  84 + /**
  85 + * 备注
  86 + */
  87 + remark?: string;
  88 + /**
  89 + * 附件
  90 + */
  91 + fids?: string;
  92 + /**
  93 + * 计划列表
  94 + */
  95 + list?: DetailVO[];
  96 +}
51 97 /**
52 98 * 查询明细
53 99 */
54   -export function getDetail(params?: Params): http.PromiseResp<DetailVO[]> {
  100 +export function getDetail(params?: Params): http.PromiseResp<Item> {
55 101 return request.get(`${PMS_HOST}/erp/part/plan/get/plan/group/detail`, { params });
56 102 }
... ...
src/pages/pms/partPlan/PlanManage/subpages/Detail/index.tsx
1   -import {Card, ConfigProvider, Spin} from 'antd';
  1 +import { Card, ConfigProvider, Spin, Upload } from 'antd';
2 2 import { PageHeaderWrapper } from '@ant-design/pro-layout';
3 3 import React, {useState} from "react";
4 4 import useInitial from "@/hooks/useInitail";
5   -import {getDetail, DetailVO, Params, SupplierVO, StorageVO, PartVO} from "./api";
  5 +import { getDetail, Item, Params, SupplierVO, StorageVO, PartVO, DetailVO } from "./api";
6 6 import zhCN from "antd/lib/locale-provider/zh_CN";
7 7 import st from "@/pages/pms/partPlan/PlanManage/style.less";
8 8 import StepBnt from "@/pages/pms/comonents/StepBnt";
... ... @@ -14,7 +14,7 @@ import PartDetailModal from &#39;./components/PartDetailModal&#39;;
14 14  
15 15 export default function Index({ match }: common.ConnectProps) {
16 16 const { planId } = match.params;
17   - const { data, loading } = useInitial<DetailVO[], Params>(getDetail, [], {planId});
  17 + const { data, loading } = useInitial<Item, Params>(getDetail, {}, {planId});
18 18 const [visiblePart, setVisiblePart] = useState(false);
19 19 const [parts, setParts] = useState<PartVO[]>([]);
20 20  
... ... @@ -23,7 +23,7 @@ export default function Index({ match }: common.ConnectProps) {
23 23 <Spin spinning={loading}>
24 24 <ConfigProvider locale={zhCN}>
25 25 <Card className={st.page}>
26   - {data.map((dealer: DetailVO = {}) => (
  26 + {data.list?.map((dealer: DetailVO = {}) => (
27 27 <div key={`dealer${dealer.settleDealerName}`} style={{ marginTop: 10 }}>
28 28 <div style={{ fontWeight: "bold" }}>{`商家: ${dealer.settleDealerName || ''}`}</div>
29 29 {(dealer.suppliers || []).map((supplier: SupplierVO = {}) => {
... ... @@ -57,6 +57,26 @@ export default function Index({ match }: common.ConnectProps) {
57 57 })}
58 58 </div>
59 59 ))}
  60 + <div style={{ display: 'flex', alignItems: 'flex-start', marginBottom: 20 }}>
  61 + <span style={{ marginRight: 10 }}>备注:{data.remark}</span>
  62 + </div>
  63 + <div style={{ display: 'flex', alignItems: 'flex-start' }}>
  64 + <span style={{ marginRight: 10 }}>附件:</span>
  65 + <div style={{display: 'flex'}}>
  66 + {data.fids?.split(',').map(i => (
  67 + <Upload
  68 + listType="picture-card"
  69 + fileList={[{
  70 + uid: '-1',
  71 + name: i,
  72 + status: 'done',
  73 + url: `/api/file/show?fid=${i}`,
  74 + }]}
  75 + disabled
  76 + />
  77 + ))}
  78 + </div>
  79 + </div>
60 80 <PartDetailModal visible={visiblePart} onCancel={() => setVisiblePart(false)} parts={parts} />
61 81 <StepBnt
62 82 disable={false}
... ...
src/pages/pms/partPlan/PlanPool/api.ts
... ... @@ -118,7 +118,24 @@ outTime?:string;
118 118 */
119 119 typeName?:string;
120 120 }
121   -
  121 +export interface outListVO {
  122 + /**
  123 + * 时间段
  124 + */
  125 + date?: string;
  126 + /**
  127 + * 出库数量
  128 + */
  129 + outCnt?: number;
  130 + /**
  131 + * 最小时间
  132 + */
  133 + min?: string;
  134 + /**
  135 + * 最大时间
  136 + */
  137 + max?: string;
  138 +}
122 139 /**
123 140 * 查询计划池列表
124 141 */
... ... @@ -134,10 +151,14 @@ export function editApi(params: { poolId?: number, partCnt?: number}) {
134 151 return request.post(`${PMS_HOST}/erp/plan/pool/update/plan`, {...params});
135 152 }
136 153  
137   -export function outFlowApi(params: { poolIds?: any, planId?: number, current?: number, pageSize?:number}):http.PromisePageResp<OutItem> {
  154 +export function outFlowApi(params: { poolIds?: any, planId?: number}):http.PromiseResp<outListVO[]> {
138 155 return request.get(`${PMS_HOST}/erp/storage/out/list`, {params});
139 156 }
140 157  
  158 +export function outFlowDetailApi(params:any):http.PromiseResp<OutItem[]> {
  159 + return request.get(`${PMS_HOST}/erp/storage/out/detail`, {params});
  160 +}
  161 +
141 162 export function custBuyApi(params: { planWaitListIds?: any}):http.PromiseResp<PartVO[]> {
142 163 return request.get(`${PMS_HOST}/erp/cus/buy/part/get/buy/part/list`, {params});
143 164 }
... ...
src/pages/pms/partPlan/PlanPool/components/AreaTable.tsx
... ... @@ -4,6 +4,7 @@ import useInitial from &quot;@/hooks/useInitail&quot;;
4 4 import {getList, ListVO} from "@/pages/pms/partPlan/PlanPool/api";
5 5 import DetailModal from './DetailModal';
6 6 import {useStore} from "@/pages/pms/partPlan/PlanPool";
  7 +import _ from 'lodash';
7 8  
8 9 const { Column } = Table;
9 10 interface Props {
... ... @@ -33,8 +34,8 @@ export default function Index(props: Props = {}) {
33 34 <Table rowKey={(v: ListVO) => `${v.id}`} scroll={{y: 500, x: 2500}} dataSource={parts || []} pagination={false} loading={loading}>
34 35 <Column title="区域库" dataIndex="name" fixed="left" />
35 36 <Column title="本次计划数量(个)" dataIndex="cnt" fixed="left" />
36   - <Column title="计划前库销比" dataIndex="ratio" render={t => (t || 0).toFixed(2)} />
37   - <Column title="计划后库销比" dataIndex="planeRatio" render={t => (t || 0).toFixed(2)} />
  37 + <Column title="计划前库销比" dataIndex="ratio" render={t => (t ? t.toFixed(2) : "--")} />
  38 + <Column title="计划后库销比" dataIndex="planRatio" render={t => (t ? t.toFixed(2) : "--")} />
38 39 <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" />
39 40 <Column title="客户订件数量(个)" render={r => (r.buyCnt ? <a onClick={() => { setCustVisible(true); setItem(r); }}>{r.buyCnt}</a> : r.buyCnt)} />
40 41 <Column title="客户订件金额(元)" dataIndex="buyAmount" />
... ... @@ -42,7 +43,7 @@ export default function Index(props: Props = {}) {
42 43  
43 44 <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" />
44 45 <Column title="在库已锁(个)" dataIndex="storageLockedCnt" />
45   - <Column title="滚动90天出库(个)" render={r => (r.outStockCnt ? <a onClick={() => { setOutVisible(true); setItem(r); }}>{r.outStockCnt}</a> : r.outStockCnt)} />
  46 + <Column title="近90天月均出库(个)" render={r => (r.outStockCnt ? <a onClick={() => { setOutVisible(true); setItem(r); }}>{_.floor(r.outStockCnt/3)}</a> : r.outStockCnt)} />
46 47 {showAnalyse && (
47 48 <>
48 49 <Column
... ...
src/pages/pms/partPlan/PlanPool/components/OutFlowDetailModal.tsx 0 → 100644
  1 +import React, { useEffect, useState } from 'react';
  2 +import { Button, Modal, Table } from 'antd';
  3 +import { outFlowDetailApi, OutItem } from '../api';
  4 +import useInitial from '@/hooks/useInitail';
  5 +import moment from 'moment';
  6 +
  7 +const { Column } = Table;
  8 +interface Props {
  9 + visible?:boolean
  10 + setVisible:Function
  11 + item?:any
  12 +}
  13 +export default function Index(props:Props) {
  14 + const { visible, setVisible, item } = props;
  15 + const [delay, setDelay] = useState(true);
  16 + const { data, setParams, loading } = useInitial(outFlowDetailApi, [], {}, delay);
  17 +
  18 + useEffect(() => {
  19 + if (visible && item?.poolIds) {
  20 + setParams({ min: undefined, max: undefined, date: undefined, outCnt: undefined, ...item }, true);
  21 + setDelay(false);
  22 + } else {
  23 + setVisible();
  24 + }
  25 + }, [visible]);
  26 +
  27 + return (
  28 + <Modal
  29 + title="出库详情"
  30 + width={1000}
  31 + visible={visible}
  32 + maskClosable={false}
  33 + onCancel={() => setVisible()}
  34 + footer={[
  35 + <Button onClick={() => setVisible()}>取消</Button>
  36 + ]}
  37 + >
  38 + <Table
  39 + dataSource={data}
  40 + loading={loading}
  41 + rowKey={(v: OutItem) => `${v.partId}`}
  42 + pagination={false}
  43 + scroll={{ y: 400 }}
  44 + >
  45 + <Column title="配件名称" dataIndex="partName" />
  46 + <Column title="配件编码" dataIndex="partCode" />
  47 + <Column title="出库数量" dataIndex="partCnt" />
  48 + <Column title="出库类型" dataIndex="typeName" />
  49 + <Column title="服务站名称" dataIndex="shopName" />
  50 + <Column title="出库时间" render={r => moment(r.outTime).format('YYYY-MM-DD HH:mm:ss')} />
  51 + </Table>
  52 + </Modal>
  53 + );
  54 +}
0 55 \ No newline at end of file
... ...
src/pages/pms/partPlan/PlanPool/components/OutFlowModal.tsx
1 1 import React, { useEffect, useState } from 'react';
2 2 import {Button, Modal, Table} from 'antd';
3 3 import {useStore} from '../index';
4   -import { outFlowApi, OutItem } from '../api';
5   -import usePagination from '@/hooks/usePagination';
  4 +import { outFlowApi, outListVO } from '../api';
  5 +import useInitial from '@/hooks/useInitail';
  6 +import OutFlowDetailModal from './OutFlowDetailModal';
6 7  
7 8 const {Column} = Table;
8 9  
9 10 export default function Index() {
10 11 const {outVisible, setOutVisible, item} = useStore();
11 12 const [delay, setDelay]= useState(true);
12   - const { list, setParams, loading, paginationConfig } = usePagination(outFlowApi, [], {delay});
  13 + const { data, setParams, loading } = useInitial(outFlowApi, [], {}, delay);
  14 + const [current, setCurrent] = useState<{visible?: boolean, itemData?: any}>();
13 15  
14 16 useEffect(() => {
15 17 if (outVisible && item?.poolIds) {
... ... @@ -17,6 +19,11 @@ export default function Index() {
17 19 setDelay(false);
18 20 }
19 21 }, [outVisible]);
  22 + const total = data
  23 + .map(i => i.outCnt)
  24 + .reduce((prev, cur) => {
  25 + return (prev || 0) + (cur || 0);
  26 + }, 0);
20 27  
21 28 return (
22 29 <Modal
... ... @@ -29,19 +36,26 @@ export default function Index() {
29 36 <Button onClick={() => setOutVisible(false)}>取消</Button>
30 37 ]}
31 38 >
  39 + <div style={{marginBottom: 20}}>
  40 + 滚动90天出库数:
  41 + <span
  42 + style={{ color: '#0000FF', cursor: 'pointer' }}
  43 + onClick={() => setCurrent({ visible: true, itemData: { poolIds: item?.poolIds } })}
  44 + >
  45 + {total}
  46 + </span>
  47 + </div>
32 48 <Table
33   - dataSource={list}
  49 + dataSource={data}
34 50 loading={loading}
35   - pagination={paginationConfig}
36   - rowKey={(v: OutItem) => `${v.partId}`}
  51 + rowKey={(v: outListVO) => `${v.date}`}
  52 + pagination={false}
  53 + scroll={{y: 400}}
37 54 >
38   - <Column title="配件编码" dataIndex="partCode" />
39   - <Column title="配件名称" dataIndex="partName" />
40   - <Column title="出库数量" dataIndex="partCnt" />
41   - <Column title="出库类型" dataIndex="typeName" />
42   - <Column title="服务站名称" dataIndex="shopName" />
43   - <Column title="出库时间" dataIndex="outTime" />
  55 + <Column title="出库日期" dataIndex="date" />
  56 + <Column title="出库数量" render={r => <a onClick={() => setCurrent({ visible: true, itemData: { ...r, poolIds: item?.poolIds }})}>{r.outCnt}</a>} />
44 57 </Table>
  58 + <OutFlowDetailModal visible={current?.visible} setVisible={() => setCurrent({visible: false, itemData: undefined})} item={current?.itemData} />
45 59 </Modal>
46 60 );
47 61 }
48 62 \ No newline at end of file
... ...
src/pages/pms/partPlan/PlanPool/components/PartTable.tsx
... ... @@ -4,6 +4,7 @@ import useInitial from &quot;@/hooks/useInitail&quot;;
4 4 import {getList, ListVO} from "@/pages/pms/partPlan/PlanPool/api";
5 5 import DetailModal from './DetailModal';
6 6 import {useStore} from "@/pages/pms/partPlan/PlanPool";
  7 +import _ from 'lodash';
7 8  
8 9 const { Column } = Table;
9 10 interface Props {
... ... @@ -39,8 +40,8 @@ export default function Index(props: Props = {}) {
39 40 <Column title="来源类型" dataIndex="typeName" />
40 41 <Column title="配件类型" dataIndex="partTypeName" />
41 42  
42   - <Column title="计划前库销比" dataIndex="ratio" render={t => (t || 0).toFixed(2)} />
43   - <Column title="计划后库销比" dataIndex="planeRatio" render={t => (t || 0).toFixed(2)} />
  43 + <Column title="计划前库销比" dataIndex="ratio" render={t => (t ? t.toFixed(2) : "--")} />
  44 + <Column title="计划后库销比" dataIndex="planRatio" render={t => (t ? t.toFixed(2) : "--")} />
44 45  
45 46 <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" />
46 47 <Column title="客户订件数量(个)" render={r => (r.buyCnt ? <a onClick={() => { setCustVisible(true); setItem(r); }}>{r.buyCnt}</a> : r.buyCnt)} />
... ... @@ -49,7 +50,7 @@ export default function Index(props: Props = {}) {
49 50  
50 51 <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" />
51 52 <Column title="在库已锁(个)" dataIndex="storageLockedCnt" />
52   - <Column title="滚动90天出库(个)" render={r => (r.outStockCnt ? <a onClick={() => { setOutVisible(true); setItem(r); }}>{r.outStockCnt}</a> : r.outStockCnt)} />
  53 + <Column title="近90天月均出库(个)" render={r => (r.outStockCnt ? <a onClick={() => { setOutVisible(true); setItem(r); }}>{_.floor(r.outStockCnt/3)}</a> : r.outStockCnt)} />
53 54 {showAnalyse && (
54 55 <>
55 56 <Column
... ...
src/pages/pms/partPlan/PlanPool/components/SeriesTable.tsx
... ... @@ -4,6 +4,7 @@ import useInitial from &quot;@/hooks/useInitail&quot;;
4 4 import {getList, ListVO} from "@/pages/pms/partPlan/PlanPool/api";
5 5 import DetailModal from './DetailModal';
6 6 import {useStore} from "@/pages/pms/partPlan/PlanPool";
  7 +import _ from 'lodash';
7 8  
8 9 const { Column } = Table;
9 10 interface Props {
... ... @@ -34,8 +35,8 @@ export default function Index(props: Props = {}) {
34 35 <Table rowKey={(v: ListVO) => `${v.id}`} scroll={{y: 500, x: 2500}} dataSource={parts || []} pagination={false} loading={loading}>
35 36 <Column title="车系" dataIndex="name" fixed="left" />
36 37 <Column title="本次计划数量(个)" dataIndex="cnt" fixed="left" />
37   - <Column title="计划前库销比" dataIndex="ratio" render={t => (t || 0).toFixed(2)} />
38   - <Column title="计划后库销比" dataIndex="planeRatio" render={t => (t || 0).toFixed(2)} />
  38 + <Column title="计划前库销比" dataIndex="ratio" render={t => (t ? t.toFixed(2) : "--")} />
  39 + <Column title="计划后库销比" dataIndex="planRatio" render={t => (t ? t.toFixed(2) : "--")} />
39 40  
40 41 <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" />
41 42 <Column title="客户订件数量(个)" render={r => (r.buyCnt ? <a onClick={() => { setCustVisible(true); setItem(r); }}>{r.buyCnt}</a> : r.buyCnt)} />
... ... @@ -44,7 +45,7 @@ export default function Index(props: Props = {}) {
44 45  
45 46 <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" />
46 47 <Column title="在库已锁(个)" dataIndex="storageLockedCnt" />
47   - <Column title="滚动90天出库(个)" render={r => (r.outStockCnt ? <a onClick={() => { setOutVisible(true); setItem(r); }}>{r.outStockCnt}</a> : r.outStockCnt)} />
  48 + <Column title="近90天月均出库(个)" render={r => (r.outStockCnt ? <a onClick={() => { setOutVisible(true); setItem(r); }}>{_.floor(r.outStockCnt/3)}</a> : r.outStockCnt)} />
48 49 {showAnalyse && (
49 50 <>
50 51 <Column
... ...
src/pages/pms/partPlan/PlanPool/components/StoragePartTable.tsx
... ... @@ -4,6 +4,7 @@ import useInitial from &quot;@/hooks/useInitail&quot;;
4 4 import {getList, ListVO} from "@/pages/pms/partPlan/PlanPool/api";
5 5 import {useStore} from "@/pages/pms/partPlan/PlanPool";
6 6 import {deleteApi, editApi} from '../api';
  7 +import _ from 'lodash';
7 8  
8 9 const { Column } = Table;
9 10 const {Item} = Form;
... ... @@ -64,8 +65,8 @@ export default function Index(props: Props = {}) {
64 65 <Column title="来源类型" dataIndex="typeName" />
65 66 <Column title="配件类型" dataIndex="partTypeName" />
66 67  
67   - <Column title="计划前库销比" dataIndex="ratio" render={t => (t || 0).toFixed(2)} />
68   - <Column title="计划后库销比" dataIndex="planeRatio" render={t => (t || 0).toFixed(2)} />
  68 + <Column title="计划前库销比" dataIndex="ratio" render={t => (t ? t.toFixed(2) : "--")} />
  69 + <Column title="计划后库销比" dataIndex="planRatio" render={t => (t ? t.toFixed(2) : "--")} />
69 70  
70 71 <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" />
71 72 <Column title="客户订件数量(个)" render={r => (r.buyCnt ? <a onClick={() => { setCustVisible(true); setItem(r); }}>{r.buyCnt}</a> : r.buyCnt)} />
... ... @@ -73,7 +74,7 @@ export default function Index(props: Props = {}) {
73 74 <Column title="在途未锁(个)" dataIndex="onTheWayUnlockCnt" />
74 75 <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" />
75 76 <Column title="在库已锁(个)" dataIndex="storageLockedCnt" />
76   - <Column title="滚动90天出库(个)" render={r => (r.outStockCnt ? <a onClick={() => { setOutVisible(true); setItem(r); }}>{r.outStockCnt}</a> : r.outStockCnt)} />
  77 + <Column title="近90天月均出库(个)" render={r => (r.outStockCnt ? <a onClick={() => { setOutVisible(true); setItem(r); }}>{_.floor(r.outStockCnt/3)}</a> : r.outStockCnt)} />
77 78  
78 79 </Table>
79 80 <Modal
... ...
src/pages/pms/partPlan/PlanPool/components/StorageTable.tsx
... ... @@ -4,6 +4,7 @@ import useInitial from &quot;@/hooks/useInitail&quot;;
4 4 import {getList, ListVO} from "@/pages/pms/partPlan/PlanPool/api";
5 5 import DetailModal from './DetailModal';
6 6 import {useStore} from "@/pages/pms/partPlan/PlanPool";
  7 +import {floor} from 'lodash';
7 8  
8 9 const { Column } = Table;
9 10 interface Props {
... ... @@ -33,8 +34,8 @@ export default function Index(props: Props = {}) {
33 34 <Table rowKey={(v: ListVO) => `${v.id}`} scroll={{y: 500, x: 2500}} dataSource={parts || []} pagination={false} loading={loading}>
34 35 <Column title="库房" dataIndex="name" fixed="left" />
35 36 <Column title="本次计划数量(个)" dataIndex="cnt" fixed="left" />
36   - <Column title="计划前库销比" dataIndex="ratio" render={t => (t || 0).toFixed(2)} />
37   - <Column title="计划后库销比" dataIndex="planeRatio" render={t => (t || 0).toFixed(2)} />
  37 + <Column title="计划前库销比" dataIndex="ratio" render={t => (t ? t.toFixed(2) : "--")} />
  38 + <Column title="计划后库销比" dataIndex="planRatio" render={t => (t ? t.toFixed(2) : "--")} />
38 39  
39 40 <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" />
40 41 <Column title="客户订件数量(个)" render={r => (r.buyCnt ? <a onClick={() => { setCustVisible(true); setItem(r); }}>{r.buyCnt}</a> : r.buyCnt)} />
... ... @@ -42,7 +43,7 @@ export default function Index(props: Props = {}) {
42 43 <Column title="在途未锁(个)" dataIndex="onTheWayUnlockCnt" />
43 44 <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" />
44 45 <Column title="在库已锁(个)" dataIndex="storageLockedCnt" />
45   - <Column title="滚动90天出库(个)" render={r => (r.outStockCnt ? <a onClick={() => { setOutVisible(true); setItem(r); }}>{r.outStockCnt}</a> : r.outStockCnt)} />
  46 + <Column title="近90天月均出库(个)" render={r => (r.outStockCnt ? <a onClick={() => { setOutVisible(true); setItem(r); }}>{floor(r.outStockCnt/3)}</a> : r.outStockCnt)} />
46 47 {showAnalyse && (
47 48 <>
48 49 <Column
... ...
src/pages/pms/transfer/transferPool/comonents/PartTable.tsx
... ... @@ -22,7 +22,7 @@ export default function Index() {
22 22 >
23 23 <Column title="配件名称" dataIndex="name" />
24 24 <Column title="配件编码" dataIndex="code" />
25   - <Column title="动态库销比" dataIndex="ratio" />
  25 + <Column title="动态库销比" dataIndex="ratio" render={t => (t ? t.toFixed(2) : '--')} />
26 26 <Column title="调出池配件数量" dataIndex="transferCnt" />
27 27 <Column title="调出库房分析" render={(r:PoolItem) => <a onClick={() => analysis(r, 6)}>查看</a>} />
28 28 <Column title="调入库房分析" render={(r:PoolItem) => <a onClick={() => analysis(r, 7)}>查看</a>} />
... ...
src/pages/pms/transfer/transferPool/comonents/StorageTable.tsx
... ... @@ -23,7 +23,7 @@ export default function Index(props: {out?:boolean}) {
23 23 scroll={{y: 500}}
24 24 >
25 25 <Column title={out ? "调出库房" : "调入库房"} dataIndex="name" />
26   - <Column title="动态库销比" dataIndex="ratio" />
  26 + <Column title="动态库销比" dataIndex="ratio" render={t => (t ? t.toFixed(2) : '--')} />
27 27 <Column title="调出池配件品种" dataIndex="transferKind" />
28 28 <Column title="调出池配件数量" dataIndex="transferCnt" />
29 29 {out ?
... ...
src/pages/pms/transfer/transferPool/comonents/VehicleTable.tsx
... ... @@ -22,7 +22,7 @@ export default function Index() {
22 22 scroll={{y: 500}}
23 23 >
24 24 <Column title="车系" dataIndex="name" />
25   - <Column title="动态库销比" dataIndex="ratio" />
  25 + <Column title="动态库销比" dataIndex="ratio" render={t => (t ? t.toFixed(2) : '--')} />
26 26 <Column title="调出池配件品种" dataIndex="transferKind" />
27 27 <Column title="调出池配件数量" dataIndex="transferCnt" />
28 28 <Column title="调出库房分析" render={(r) => <a onClick={() => analysis(r, 6)}>查看</a>} />
... ...