Commit da356727c88f74796b5d0f4db8dce22d7d15866a
1 parent
0e37f7ac
配件计划调整
Showing
12 changed files
with
236 additions
and
46 deletions
src/pages/pms/partPlan/CustBuyPlan/subpages/First/components/PartModal.tsx
@@ -73,7 +73,7 @@ export default function DetailModal() { | @@ -73,7 +73,7 @@ export default function DetailModal() { | ||
73 | align="center" | 73 | align="center" |
74 | render={r => ( | 74 | render={r => ( |
75 | <> | 75 | <> |
76 | - <Popconfirm | 76 | + {/* <Popconfirm |
77 | title="确定删除?" | 77 | title="确定删除?" |
78 | onConfirm={() => deletePart(r)} | 78 | onConfirm={() => deletePart(r)} |
79 | okText="确定" | 79 | okText="确定" |
@@ -81,7 +81,7 @@ export default function DetailModal() { | @@ -81,7 +81,7 @@ export default function DetailModal() { | ||
81 | > | 81 | > |
82 | <a>删除</a> | 82 | <a>删除</a> |
83 | </Popconfirm> | 83 | </Popconfirm> |
84 | - <Divider type="vertical" /> | 84 | + <Divider type="vertical" /> */} |
85 | <a onClick={() => onFinish(r)}>完成</a> | 85 | <a onClick={() => onFinish(r)}>完成</a> |
86 | </> | 86 | </> |
87 | )} | 87 | )} |
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 | import { PageHeaderWrapper } from '@ant-design/pro-layout'; | 2 | import { PageHeaderWrapper } from '@ant-design/pro-layout'; |
3 | import React, {useEffect, useState} from "react"; | 3 | import React, {useEffect, useState} from "react"; |
4 | import DealerModal from './components/DealerModal'; | 4 | import DealerModal from './components/DealerModal'; |
@@ -15,7 +15,8 @@ import PartModal from "@/pages/pms/partPlan/PlanManage/subpages/Apply/components | @@ -15,7 +15,8 @@ import PartModal from "@/pages/pms/partPlan/PlanManage/subpages/Apply/components | ||
15 | import {groupBys, flattenDeep} from '@/pages/pms/entity'; | 15 | import {groupBys, flattenDeep} from '@/pages/pms/entity'; |
16 | import {PartDetail} from '../../api'; | 16 | import {PartDetail} from '../../api'; |
17 | import { history } from 'umi'; | 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 | const { Option } = Select; | 21 | const { Option } = Select; |
21 | const apiObj: { [key: number]: any } = { | 22 | const apiObj: { [key: number]: any } = { |
@@ -25,7 +26,7 @@ const apiObj: { [key: number]: any } = { | @@ -25,7 +26,7 @@ const apiObj: { [key: number]: any } = { | ||
25 | export default function Index() { | 26 | export default function Index() { |
26 | const planId = history.location.query; | 27 | const planId = history.location.query; |
27 | const [detaildelay, setDetaildelay] = useState(true); | 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 | const [delay, setDelay] = useState<boolean>(true); | 30 | const [delay, setDelay] = useState<boolean>(true); |
30 | const [loading, setLoading] = useState<boolean>(false); | 31 | const [loading, setLoading] = useState<boolean>(false); |
31 | const { data: brands } = useInitial(API.getBrandFilterApi, [], {}); | 32 | const { data: brands } = useInitial(API.getBrandFilterApi, [], {}); |
@@ -39,6 +40,8 @@ export default function Index() { | @@ -39,6 +40,8 @@ export default function Index() { | ||
39 | const [visiblePartDetail, setVisiblePartDetail] = useState(false); | 40 | const [visiblePartDetail, setVisiblePartDetail] = useState(false); |
40 | const partList = flattenDeep(dealerList.map(it => (it.suppliers || []).map((su: any) => (su.storages || []).map((st: any) => (st.parts || []))))); | 41 | const partList = flattenDeep(dealerList.map(it => (it.suppliers || []).map((su: any) => (su.storages || []).map((st: any) => (st.parts || []))))); |
41 | const poolIds = partList.map((it: any) => it.poolId); | 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 | useEffect(() => { | 46 | useEffect(() => { |
44 | if (planId?.planId) { | 47 | if (planId?.planId) { |
@@ -48,14 +51,16 @@ export default function Index() { | @@ -48,14 +51,16 @@ export default function Index() { | ||
48 | }, []); | 51 | }, []); |
49 | 52 | ||
50 | useEffect(() => { | 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 | setParams({}, true); | 57 | setParams({}, true); |
54 | setDelay(false); | 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]); | ||
58 | - | 62 | + }, [data.list?.length]); |
63 | + console.log(info, 'info'); | ||
59 | function onOk(parts: ListVO[] = []) { | 64 | function onOk(parts: ListVO[] = []) { |
60 | setDealerList(dealerList.map(it => { | 65 | setDealerList(dealerList.map(it => { |
61 | if (it.settleDealerId == dealer.settleDealerId) { | 66 | if (it.settleDealerId == dealer.settleDealerId) { |
@@ -173,7 +178,15 @@ export default function Index() { | @@ -173,7 +178,15 @@ export default function Index() { | ||
173 | apiObj[type]({ | 178 | apiObj[type]({ |
174 | planId: Number(planId?.planId), | 179 | planId: Number(planId?.planId), |
175 | ...dfParams, | 180 | ...dfParams, |
176 | - suppliers | 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() | ||
177 | // suppliers: suppliers.map(i => ({ | 190 | // suppliers: suppliers.map(i => ({ |
178 | // settleDealerId: i.settleDealerId, | 191 | // settleDealerId: i.settleDealerId, |
179 | // settleDealerName: i.settleDealerName, | 192 | // settleDealerName: i.settleDealerName, |
@@ -332,12 +345,29 @@ export default function Index() { | @@ -332,12 +345,29 @@ export default function Index() { | ||
332 | deletePart={deletePart} | 345 | deletePart={deletePart} |
333 | /> | 346 | /> |
334 | </div> | 347 | </div> |
348 | + <div style={{display: 'flex', alignItems: 'flex-start', marginBottom: 20}}> | ||
349 | + <span style={{marginRight: 10}}>备注:</span> | ||
350 | + <Input.TextArea rows={2} style={{ width: 250 }} value={info?.remark} onChange={e => setInfo({...info, remark: e.target.value})} /> | ||
351 | + </div> | ||
352 | + <div style={{ display: 'flex', alignItems: 'flex-start' }}> | ||
353 | + <span style={{ marginRight: 10 }}>附件:</span> | ||
354 | + <ImageUpload | ||
355 | + length={6} | ||
356 | + clear={imageVisible} | ||
357 | + value={info?.fids} | ||
358 | + onChange={v => { | ||
359 | + const ids = v.fileList.map(it => it?.response?.data || it); | ||
360 | + setInfo({ ...info, fids: ids }); | ||
361 | + console.log(ids); | ||
362 | + }} | ||
363 | + /> | ||
364 | + </div> | ||
335 | <div style={{display: 'flex', justifyContent: 'center'}}> | 365 | <div style={{display: 'flex', justifyContent: 'center'}}> |
336 | <Button | 366 | <Button |
337 | disabled={loading} | 367 | disabled={loading} |
338 | loading={loading} | 368 | loading={loading} |
339 | style={{marginRight: 20}} | 369 | style={{marginRight: 20}} |
340 | - onClick={() => history.goBack()} | 370 | + onClick={() => { setImageVisible(true); history.goBack(); }} |
341 | > | 371 | > |
342 | 取消 | 372 | 取消 |
343 | </Button> | 373 | </Button> |
src/pages/pms/partPlan/PlanManage/subpages/Detail/api.ts
@@ -48,9 +48,55 @@ export interface Params { | @@ -48,9 +48,55 @@ export interface Params { | ||
48 | planNo?: string; | 48 | planNo?: string; |
49 | no?: string; | 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 | return request.get(`${PMS_HOST}/erp/part/plan/get/plan/group/detail`, { params }); | 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 | import { PageHeaderWrapper } from '@ant-design/pro-layout'; | 2 | import { PageHeaderWrapper } from '@ant-design/pro-layout'; |
3 | import React, {useState} from "react"; | 3 | import React, {useState} from "react"; |
4 | import useInitial from "@/hooks/useInitail"; | 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 | import zhCN from "antd/lib/locale-provider/zh_CN"; | 6 | import zhCN from "antd/lib/locale-provider/zh_CN"; |
7 | import st from "@/pages/pms/partPlan/PlanManage/style.less"; | 7 | import st from "@/pages/pms/partPlan/PlanManage/style.less"; |
8 | import StepBnt from "@/pages/pms/comonents/StepBnt"; | 8 | import StepBnt from "@/pages/pms/comonents/StepBnt"; |
@@ -14,7 +14,7 @@ import PartDetailModal from './components/PartDetailModal'; | @@ -14,7 +14,7 @@ import PartDetailModal from './components/PartDetailModal'; | ||
14 | 14 | ||
15 | export default function Index({ match }: common.ConnectProps) { | 15 | export default function Index({ match }: common.ConnectProps) { |
16 | const { planId } = match.params; | 16 | const { planId } = match.params; |
17 | - const { data, loading } = useInitial<DetailVO[], Params>(getDetail, [], {planId}); | 17 | + const { data, loading } = useInitial<Item, Params>(getDetail, {}, {planId}); |
18 | const [visiblePart, setVisiblePart] = useState(false); | 18 | const [visiblePart, setVisiblePart] = useState(false); |
19 | const [parts, setParts] = useState<PartVO[]>([]); | 19 | const [parts, setParts] = useState<PartVO[]>([]); |
20 | 20 | ||
@@ -23,7 +23,7 @@ export default function Index({ match }: common.ConnectProps) { | @@ -23,7 +23,7 @@ export default function Index({ match }: common.ConnectProps) { | ||
23 | <Spin spinning={loading}> | 23 | <Spin spinning={loading}> |
24 | <ConfigProvider locale={zhCN}> | 24 | <ConfigProvider locale={zhCN}> |
25 | <Card className={st.page}> | 25 | <Card className={st.page}> |
26 | - {data.map((dealer: DetailVO = {}) => ( | 26 | + {data.list?.map((dealer: DetailVO = {}) => ( |
27 | <div key={`dealer${dealer.settleDealerName}`} style={{ marginTop: 10 }}> | 27 | <div key={`dealer${dealer.settleDealerName}`} style={{ marginTop: 10 }}> |
28 | <div style={{ fontWeight: "bold" }}>{`商家: ${dealer.settleDealerName || ''}`}</div> | 28 | <div style={{ fontWeight: "bold" }}>{`商家: ${dealer.settleDealerName || ''}`}</div> |
29 | {(dealer.suppliers || []).map((supplier: SupplierVO = {}) => { | 29 | {(dealer.suppliers || []).map((supplier: SupplierVO = {}) => { |
@@ -57,6 +57,26 @@ export default function Index({ match }: common.ConnectProps) { | @@ -57,6 +57,26 @@ export default function Index({ match }: common.ConnectProps) { | ||
57 | })} | 57 | })} |
58 | </div> | 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 | <PartDetailModal visible={visiblePart} onCancel={() => setVisiblePart(false)} parts={parts} /> | 80 | <PartDetailModal visible={visiblePart} onCancel={() => setVisiblePart(false)} parts={parts} /> |
61 | <StepBnt | 81 | <StepBnt |
62 | disable={false} | 82 | disable={false} |
src/pages/pms/partPlan/PlanPool/api.ts
@@ -118,7 +118,24 @@ outTime?:string; | @@ -118,7 +118,24 @@ outTime?:string; | ||
118 | */ | 118 | */ |
119 | typeName?:string; | 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,10 +151,14 @@ export function editApi(params: { poolId?: number, partCnt?: number}) { | ||
134 | return request.post(`${PMS_HOST}/erp/plan/pool/update/plan`, {...params}); | 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 | return request.get(`${PMS_HOST}/erp/storage/out/list`, {params}); | 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 | export function custBuyApi(params: { planWaitListIds?: any}):http.PromiseResp<PartVO[]> { | 162 | export function custBuyApi(params: { planWaitListIds?: any}):http.PromiseResp<PartVO[]> { |
142 | return request.get(`${PMS_HOST}/erp/cus/buy/part/get/buy/part/list`, {params}); | 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 "@/hooks/useInitail"; | @@ -4,6 +4,7 @@ import useInitial from "@/hooks/useInitail"; | ||
4 | import {getList, ListVO} from "@/pages/pms/partPlan/PlanPool/api"; | 4 | import {getList, ListVO} from "@/pages/pms/partPlan/PlanPool/api"; |
5 | import DetailModal from './DetailModal'; | 5 | import DetailModal from './DetailModal'; |
6 | import {useStore} from "@/pages/pms/partPlan/PlanPool"; | 6 | import {useStore} from "@/pages/pms/partPlan/PlanPool"; |
7 | +import _ from 'lodash'; | ||
7 | 8 | ||
8 | const { Column } = Table; | 9 | const { Column } = Table; |
9 | interface Props { | 10 | interface Props { |
@@ -33,8 +34,8 @@ export default function Index(props: Props = {}) { | @@ -33,8 +34,8 @@ export default function Index(props: Props = {}) { | ||
33 | <Table rowKey={(v: ListVO) => `${v.id}`} scroll={{y: 500, x: 2500}} dataSource={parts || []} pagination={false} loading={loading}> | 34 | <Table rowKey={(v: ListVO) => `${v.id}`} scroll={{y: 500, x: 2500}} dataSource={parts || []} pagination={false} loading={loading}> |
34 | <Column title="区域库" dataIndex="name" fixed="left" /> | 35 | <Column title="区域库" dataIndex="name" fixed="left" /> |
35 | <Column title="本次计划数量(个)" dataIndex="cnt" fixed="left" /> | 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="planeRatio" render={t => (t ? t.toFixed(2) : "--")} /> | ||
38 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> | 39 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> |
39 | <Column title="客户订件数量(个)" render={r => (r.buyCnt ? <a onClick={() => { setCustVisible(true); setItem(r); }}>{r.buyCnt}</a> : r.buyCnt)} /> | 40 | <Column title="客户订件数量(个)" render={r => (r.buyCnt ? <a onClick={() => { setCustVisible(true); setItem(r); }}>{r.buyCnt}</a> : r.buyCnt)} /> |
40 | <Column title="客户订件金额(元)" dataIndex="buyAmount" /> | 41 | <Column title="客户订件金额(元)" dataIndex="buyAmount" /> |
@@ -42,7 +43,7 @@ export default function Index(props: Props = {}) { | @@ -42,7 +43,7 @@ export default function Index(props: Props = {}) { | ||
42 | 43 | ||
43 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> | 44 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> |
44 | <Column title="在库已锁(个)" dataIndex="storageLockedCnt" /> | 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 | {showAnalyse && ( | 47 | {showAnalyse && ( |
47 | <> | 48 | <> |
48 | <Column | 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 | + console.log(item); | ||
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 | \ No newline at end of file | 55 | \ No newline at end of file |
src/pages/pms/partPlan/PlanPool/components/OutFlowModal.tsx
1 | import React, { useEffect, useState } from 'react'; | 1 | import React, { useEffect, useState } from 'react'; |
2 | import {Button, Modal, Table} from 'antd'; | 2 | import {Button, Modal, Table} from 'antd'; |
3 | import {useStore} from '../index'; | 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 | const {Column} = Table; | 8 | const {Column} = Table; |
8 | 9 | ||
9 | export default function Index() { | 10 | export default function Index() { |
10 | const {outVisible, setOutVisible, item} = useStore(); | 11 | const {outVisible, setOutVisible, item} = useStore(); |
11 | const [delay, setDelay]= useState(true); | 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 | useEffect(() => { | 16 | useEffect(() => { |
15 | if (outVisible && item?.poolIds) { | 17 | if (outVisible && item?.poolIds) { |
@@ -17,6 +19,11 @@ export default function Index() { | @@ -17,6 +19,11 @@ export default function Index() { | ||
17 | setDelay(false); | 19 | setDelay(false); |
18 | } | 20 | } |
19 | }, [outVisible]); | 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 | return ( | 28 | return ( |
22 | <Modal | 29 | <Modal |
@@ -29,19 +36,26 @@ export default function Index() { | @@ -29,19 +36,26 @@ export default function Index() { | ||
29 | <Button onClick={() => setOutVisible(false)}>取消</Button> | 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 | <Table | 48 | <Table |
33 | - dataSource={list} | 49 | + dataSource={data} |
34 | loading={loading} | 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 | </Table> | 57 | </Table> |
58 | + <OutFlowDetailModal visible={current?.visible} setVisible={() => setCurrent({visible: false, itemData: undefined})} item={current?.itemData} /> | ||
45 | </Modal> | 59 | </Modal> |
46 | ); | 60 | ); |
47 | } | 61 | } |
48 | \ No newline at end of file | 62 | \ No newline at end of file |
src/pages/pms/partPlan/PlanPool/components/PartTable.tsx
@@ -4,6 +4,7 @@ import useInitial from "@/hooks/useInitail"; | @@ -4,6 +4,7 @@ import useInitial from "@/hooks/useInitail"; | ||
4 | import {getList, ListVO} from "@/pages/pms/partPlan/PlanPool/api"; | 4 | import {getList, ListVO} from "@/pages/pms/partPlan/PlanPool/api"; |
5 | import DetailModal from './DetailModal'; | 5 | import DetailModal from './DetailModal'; |
6 | import {useStore} from "@/pages/pms/partPlan/PlanPool"; | 6 | import {useStore} from "@/pages/pms/partPlan/PlanPool"; |
7 | +import _ from 'lodash'; | ||
7 | 8 | ||
8 | const { Column } = Table; | 9 | const { Column } = Table; |
9 | interface Props { | 10 | interface Props { |
@@ -39,8 +40,8 @@ export default function Index(props: Props = {}) { | @@ -39,8 +40,8 @@ export default function Index(props: Props = {}) { | ||
39 | <Column title="来源类型" dataIndex="typeName" /> | 40 | <Column title="来源类型" dataIndex="typeName" /> |
40 | <Column title="配件类型" dataIndex="partTypeName" /> | 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="planeRatio" render={t => (t ? t.toFixed(2) : "--")} /> | ||
44 | 45 | ||
45 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> | 46 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> |
46 | <Column title="客户订件数量(个)" render={r => (r.buyCnt ? <a onClick={() => { setCustVisible(true); setItem(r); }}>{r.buyCnt}</a> : r.buyCnt)} /> | 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,7 +50,7 @@ export default function Index(props: Props = {}) { | ||
49 | 50 | ||
50 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> | 51 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> |
51 | <Column title="在库已锁(个)" dataIndex="storageLockedCnt" /> | 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 | {showAnalyse && ( | 54 | {showAnalyse && ( |
54 | <> | 55 | <> |
55 | <Column | 56 | <Column |
src/pages/pms/partPlan/PlanPool/components/SeriesTable.tsx
@@ -4,6 +4,7 @@ import useInitial from "@/hooks/useInitail"; | @@ -4,6 +4,7 @@ import useInitial from "@/hooks/useInitail"; | ||
4 | import {getList, ListVO} from "@/pages/pms/partPlan/PlanPool/api"; | 4 | import {getList, ListVO} from "@/pages/pms/partPlan/PlanPool/api"; |
5 | import DetailModal from './DetailModal'; | 5 | import DetailModal from './DetailModal'; |
6 | import {useStore} from "@/pages/pms/partPlan/PlanPool"; | 6 | import {useStore} from "@/pages/pms/partPlan/PlanPool"; |
7 | +import _ from 'lodash'; | ||
7 | 8 | ||
8 | const { Column } = Table; | 9 | const { Column } = Table; |
9 | interface Props { | 10 | interface Props { |
@@ -34,8 +35,8 @@ export default function Index(props: Props = {}) { | @@ -34,8 +35,8 @@ export default function Index(props: Props = {}) { | ||
34 | <Table rowKey={(v: ListVO) => `${v.id}`} scroll={{y: 500, x: 2500}} dataSource={parts || []} pagination={false} loading={loading}> | 35 | <Table rowKey={(v: ListVO) => `${v.id}`} scroll={{y: 500, x: 2500}} dataSource={parts || []} pagination={false} loading={loading}> |
35 | <Column title="车系" dataIndex="name" fixed="left" /> | 36 | <Column title="车系" dataIndex="name" fixed="left" /> |
36 | <Column title="本次计划数量(个)" dataIndex="cnt" fixed="left" /> | 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="planeRatio" render={t => (t ? t.toFixed(2) : "--")} /> | ||
39 | 40 | ||
40 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> | 41 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> |
41 | <Column title="客户订件数量(个)" render={r => (r.buyCnt ? <a onClick={() => { setCustVisible(true); setItem(r); }}>{r.buyCnt}</a> : r.buyCnt)} /> | 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,7 +45,7 @@ export default function Index(props: Props = {}) { | ||
44 | 45 | ||
45 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> | 46 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> |
46 | <Column title="在库已锁(个)" dataIndex="storageLockedCnt" /> | 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 | {showAnalyse && ( | 49 | {showAnalyse && ( |
49 | <> | 50 | <> |
50 | <Column | 51 | <Column |
src/pages/pms/partPlan/PlanPool/components/StoragePartTable.tsx
@@ -4,6 +4,7 @@ import useInitial from "@/hooks/useInitail"; | @@ -4,6 +4,7 @@ import useInitial from "@/hooks/useInitail"; | ||
4 | import {getList, ListVO} from "@/pages/pms/partPlan/PlanPool/api"; | 4 | import {getList, ListVO} from "@/pages/pms/partPlan/PlanPool/api"; |
5 | import {useStore} from "@/pages/pms/partPlan/PlanPool"; | 5 | import {useStore} from "@/pages/pms/partPlan/PlanPool"; |
6 | import {deleteApi, editApi} from '../api'; | 6 | import {deleteApi, editApi} from '../api'; |
7 | +import _ from 'lodash'; | ||
7 | 8 | ||
8 | const { Column } = Table; | 9 | const { Column } = Table; |
9 | const {Item} = Form; | 10 | const {Item} = Form; |
@@ -64,8 +65,8 @@ export default function Index(props: Props = {}) { | @@ -64,8 +65,8 @@ export default function Index(props: Props = {}) { | ||
64 | <Column title="来源类型" dataIndex="typeName" /> | 65 | <Column title="来源类型" dataIndex="typeName" /> |
65 | <Column title="配件类型" dataIndex="partTypeName" /> | 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="planeRatio" render={t => (t ? t.toFixed(2) : "--")} /> | ||
69 | 70 | ||
70 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> | 71 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> |
71 | <Column title="客户订件数量(个)" render={r => (r.buyCnt ? <a onClick={() => { setCustVisible(true); setItem(r); }}>{r.buyCnt}</a> : r.buyCnt)} /> | 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,7 +74,7 @@ export default function Index(props: Props = {}) { | ||
73 | <Column title="在途未锁(个)" dataIndex="onTheWayUnlockCnt" /> | 74 | <Column title="在途未锁(个)" dataIndex="onTheWayUnlockCnt" /> |
74 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> | 75 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> |
75 | <Column title="在库已锁(个)" dataIndex="storageLockedCnt" /> | 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 | </Table> | 79 | </Table> |
79 | <Modal | 80 | <Modal |
src/pages/pms/partPlan/PlanPool/components/StorageTable.tsx
@@ -4,6 +4,7 @@ import useInitial from "@/hooks/useInitail"; | @@ -4,6 +4,7 @@ import useInitial from "@/hooks/useInitail"; | ||
4 | import {getList, ListVO} from "@/pages/pms/partPlan/PlanPool/api"; | 4 | import {getList, ListVO} from "@/pages/pms/partPlan/PlanPool/api"; |
5 | import DetailModal from './DetailModal'; | 5 | import DetailModal from './DetailModal'; |
6 | import {useStore} from "@/pages/pms/partPlan/PlanPool"; | 6 | import {useStore} from "@/pages/pms/partPlan/PlanPool"; |
7 | +import {floor} from 'lodash'; | ||
7 | 8 | ||
8 | const { Column } = Table; | 9 | const { Column } = Table; |
9 | interface Props { | 10 | interface Props { |
@@ -33,8 +34,8 @@ export default function Index(props: Props = {}) { | @@ -33,8 +34,8 @@ export default function Index(props: Props = {}) { | ||
33 | <Table rowKey={(v: ListVO) => `${v.id}`} scroll={{y: 500, x: 2500}} dataSource={parts || []} pagination={false} loading={loading}> | 34 | <Table rowKey={(v: ListVO) => `${v.id}`} scroll={{y: 500, x: 2500}} dataSource={parts || []} pagination={false} loading={loading}> |
34 | <Column title="库房" dataIndex="name" fixed="left" /> | 35 | <Column title="库房" dataIndex="name" fixed="left" /> |
35 | <Column title="本次计划数量(个)" dataIndex="cnt" fixed="left" /> | 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="planeRatio" render={t => (t ? t.toFixed(2) : "--")} /> | ||
38 | 39 | ||
39 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> | 40 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> |
40 | <Column title="客户订件数量(个)" render={r => (r.buyCnt ? <a onClick={() => { setCustVisible(true); setItem(r); }}>{r.buyCnt}</a> : r.buyCnt)} /> | 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,7 +43,7 @@ export default function Index(props: Props = {}) { | ||
42 | <Column title="在途未锁(个)" dataIndex="onTheWayUnlockCnt" /> | 43 | <Column title="在途未锁(个)" dataIndex="onTheWayUnlockCnt" /> |
43 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> | 44 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> |
44 | <Column title="在库已锁(个)" dataIndex="storageLockedCnt" /> | 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 | {showAnalyse && ( | 47 | {showAnalyse && ( |
47 | <> | 48 | <> |
48 | <Column | 49 | <Column |