Commit 79d4a3b6382feec60612ea413cc58e5ca1310705
1 parent
71a2ef45
计划管理增加草稿和继续编辑功能
Showing
6 changed files
with
112 additions
and
43 deletions
src/pages/pms/partPlan/PlanManage/api.ts
... | ... | @@ -26,7 +26,7 @@ export interface ListVO { |
26 | 26 | planDate?: string; // 计划日期 |
27 | 27 | approvalOrderNo?: string; // 审核单号 |
28 | 28 | userName?: string; // 计划人员 |
29 | - status?: string; // 计划状态 1:待审核2:已通过9:已拒绝 | |
29 | + status?: number; // 计划状态 1:待审核2:已通过9:已拒绝 | |
30 | 30 | settleShopId?: string; // 结算门店门店id |
31 | 31 | settleShopName?: string; // 结算门店名称 |
32 | 32 | prepayToken?: string; // 预付token | ... | ... |
src/pages/pms/partPlan/PlanManage/index.tsx
... | ... | @@ -13,6 +13,7 @@ import DetailModal from "@/pages/pms/partPlan/PlanManage/components/DetailModal" |
13 | 13 | |
14 | 14 | // 计划状态 1:待审核2:已通过3待付款4已付款9:已拒绝 |
15 | 15 | const statusName: {[key: number]: string} = { |
16 | + 0: '草稿', | |
16 | 17 | 1: '待审核', |
17 | 18 | 2: '已通过', |
18 | 19 | 3: '待付款', |
... | ... | @@ -69,6 +70,7 @@ export default function Index() { |
69 | 70 | onChange={v => setParams({status: v }, true)} |
70 | 71 | optionFilterProp="children" |
71 | 72 | > |
73 | + <Select.Option value={0} key={0}>草稿</Select.Option> | |
72 | 74 | <Select.Option value={1} key={1}>待审核</Select.Option> |
73 | 75 | <Select.Option value={2} key={2}>已通过</Select.Option> |
74 | 76 | <Select.Option value={9} key={9}>已拒绝</Select.Option> |
... | ... | @@ -95,9 +97,16 @@ export default function Index() { |
95 | 97 | fixed="right" |
96 | 98 | render={(text, _item: ListVO) => ( |
97 | 99 | <> |
98 | - <a onClick={() => history.push(`/pms/partPlan/planManage/detail/${_item.planId}`)}> | |
99 | - 查看 | |
100 | - </a> | |
100 | + {[0, 9].includes(_item.status || 0) ? ( | |
101 | + <a onClick={() => history.push(`/pms/partPlan/planManage/apply?planId=${_item.planId}`)}> | |
102 | + 编辑 | |
103 | + </a> | |
104 | + ) | |
105 | + : ( | |
106 | + <a onClick={() => history.push(`/pms/partPlan/planManage/detail/${_item.planId}`)}> | |
107 | + 查看 | |
108 | + </a> | |
109 | + )} | |
101 | 110 | <Divider type="vertical" /> |
102 | 111 | <a onClick={() => { |
103 | 112 | setItem(_item); | ... | ... |
src/pages/pms/partPlan/PlanManage/subpages/Apply/api.ts
... | ... | @@ -16,3 +16,9 @@ export interface SaveParams { |
16 | 16 | export function saveApi(params?: SaveParams): http.PromiseResp<void> { |
17 | 17 | return request.post(`${PMS_HOST}/erp/plan/pool/save/plan`, params); |
18 | 18 | } |
19 | +/** | |
20 | + * 草稿 | |
21 | + */ | |
22 | +export function draftApi(params?: SaveParams): http.PromiseResp<void> { | |
23 | + return request.post(`${PMS_HOST}/erp/plan/pool/save/draft`, params); | |
24 | +} | ... | ... |
src/pages/pms/partPlan/PlanManage/subpages/Apply/components/DealerModal.tsx
... | ... | @@ -11,9 +11,9 @@ interface Props { |
11 | 11 | } |
12 | 12 | const {Option} = Select; |
13 | 13 | export default function Index({ onCancel, visible, onOk, dealerList = [] }: Props) { |
14 | - const [dealer, setDealer] = useState<any>({dealerId: null, dealerName: null}); | |
14 | + const [dealer, setDealer] = useState<any>({ settleDealerId: null, settleDealerName: null}); | |
15 | 15 | const { data: dealers } = useInitail<CommonApi.OptionVO[], CommonApi.DealerParam>(getDealerApi, [], {}); |
16 | - const suIds = dealerList.map(it => it.dealerId); | |
16 | + const suIds = dealerList.map(it => it.settleDealerId); | |
17 | 17 | |
18 | 18 | useEffect(() => { |
19 | 19 | if (!visible) { |
... | ... | @@ -22,7 +22,7 @@ export default function Index({ onCancel, visible, onOk, dealerList = [] }: Prop |
22 | 22 | }, [visible]); |
23 | 23 | |
24 | 24 | const handSave = () => { |
25 | - if (!dealer.dealerId) { | |
25 | + if (!dealer.settleDealerId) { | |
26 | 26 | message.error('请选择采购商家'); |
27 | 27 | return; |
28 | 28 | } |
... | ... | @@ -40,7 +40,7 @@ export default function Index({ onCancel, visible, onOk, dealerList = [] }: Prop |
40 | 40 | <Button key="cancel" onClick={onCancel}>取消</Button>, |
41 | 41 | <Button |
42 | 42 | key="submit" |
43 | - disabled={!dealer.dealerId} | |
43 | + disabled={!dealer.settleDealerId} | |
44 | 44 | onClick={handSave} |
45 | 45 | type="primary" |
46 | 46 | htmlType="submit" |
... | ... | @@ -52,14 +52,14 @@ export default function Index({ onCancel, visible, onOk, dealerList = [] }: Prop |
52 | 52 | <div style={{display: 'flex', flexDirection: 'row', alignItems: 'center', marginBottom: 10}}> |
53 | 53 | <span>商家:</span> |
54 | 54 | <Select |
55 | - value={dealer.dealerId} | |
55 | + value={dealer.settleDealerId} | |
56 | 56 | style={{ width: 250 }} |
57 | 57 | placeholder="请选择商家" |
58 | 58 | showSearch |
59 | 59 | optionFilterProp="children" |
60 | - onChange={(dealerId) => { | |
61 | - const d = dealers.find(it => it.id == dealerId) || {}; | |
62 | - setDealer({dealerId, dealerName: d.name}); | |
60 | + onChange={(settleDealerId) => { | |
61 | + const d = dealers.find(it => it.id == settleDealerId) || {}; | |
62 | + setDealer({ settleDealerId, settleDealerName: d.name}); | |
63 | 63 | }} |
64 | 64 | > |
65 | 65 | {dealers.filter(it => !suIds.includes(it.id)).map((b) => ( | ... | ... |
src/pages/pms/partPlan/PlanManage/subpages/Apply/index.tsx
... | ... | @@ -8,16 +8,24 @@ import {throttle, sum} from 'lodash'; |
8 | 8 | import useInitial from "@/hooks/useInitail"; |
9 | 9 | import * as API from "@/common/api"; |
10 | 10 | import {getList, Params, ListVO} from "@/pages/pms/partPlan/PlanPool/api"; |
11 | -import {saveApi} from './api'; | |
11 | +import {saveApi, draftApi} from './api'; | |
12 | 12 | import zhCN from "antd/lib/locale-provider/zh_CN"; |
13 | 13 | import st from "@/pages/pms/partPlan/PlanManage/style.less"; |
14 | -import StepBnt from "@/pages/pms/comonents/StepBnt"; | |
15 | 14 | import PartModal from "@/pages/pms/partPlan/PlanManage/subpages/Apply/components/PartModal"; |
16 | 15 | import {groupBys, flattenDeep} from '@/pages/pms/entity'; |
17 | 16 | import {PartDetail} from '../../api'; |
17 | +import { history } from 'umi'; | |
18 | +import { getDetail, DetailVO, Params as detailParams } from '../Detail/api'; | |
18 | 19 | |
19 | 20 | const { Option } = Select; |
21 | +const apiObj: { [key: number]: any } = { | |
22 | + 1: saveApi, | |
23 | + 2: draftApi | |
24 | +}; | |
20 | 25 | export default function Index() { |
26 | + const planId = history.location.query; | |
27 | + const [detaildelay, setDetaildelay] = useState(true); | |
28 | + const { data, setParams: detailsetParams } = useInitial<DetailVO[], detailParams>(getDetail, [], { ...planId }, detaildelay); | |
21 | 29 | const [delay, setDelay] = useState<boolean>(true); |
22 | 30 | const [loading, setLoading] = useState<boolean>(false); |
23 | 31 | const { data: brands } = useInitial(API.getBrandFilterApi, [], {}); |
... | ... | @@ -32,9 +40,25 @@ export default function Index() { |
32 | 40 | const partList = flattenDeep(dealerList.map(it => (it.suppliers || []).map((su: any) => (su.storages || []).map((st: any) => (st.parts || []))))); |
33 | 41 | const poolIds = partList.map((it: any) => it.poolId); |
34 | 42 | |
43 | + useEffect(() => { | |
44 | + if (planId?.planId) { | |
45 | + setDetaildelay(false); | |
46 | + detailsetParams({ ...planId }, true); | |
47 | + } | |
48 | + }, []); | |
49 | + | |
50 | + useEffect(() => { | |
51 | + if (data.length) { | |
52 | + setDfParams({brandId: data[0].brandId}); | |
53 | + setParams({}, true); | |
54 | + setDelay(false); | |
55 | + setDealerList(data); | |
56 | + } | |
57 | + }, [data.length]); | |
58 | + | |
35 | 59 | function onOk(parts: ListVO[] = []) { |
36 | 60 | setDealerList(dealerList.map(it => { |
37 | - if (it.dealerId == dealer.dealerId) { | |
61 | + if (it.settleDealerId == dealer.settleDealerId) { | |
38 | 62 | return { |
39 | 63 | ...it, |
40 | 64 | suppliers: (it.suppliers || []).map((su: any) => { |
... | ... | @@ -64,7 +88,7 @@ export default function Index() { |
64 | 88 | |
65 | 89 | function onOkSupplier(supplier: any = {}) { |
66 | 90 | setDealerList(dealerList.map(it => { |
67 | - if (it.dealerId == dealer.dealerId) { | |
91 | + if (it.settleDealerId == dealer.settleDealerId) { | |
68 | 92 | return { |
69 | 93 | ...it, |
70 | 94 | suppliers: [...(it.suppliers || []), supplier] |
... | ... | @@ -76,7 +100,7 @@ export default function Index() { |
76 | 100 | |
77 | 101 | function deleteSupplier(dealer: any = {}, supplier: any = {}) { |
78 | 102 | setDealerList(dealerList.map(it => { |
79 | - if (it.dealerId == dealer.dealerId) { | |
103 | + if (it.settleDealerId == dealer.settleDealerId) { | |
80 | 104 | return { |
81 | 105 | ...it, |
82 | 106 | suppliers: (it.suppliers || []).filter((su: any) => su.supplierId != supplier.supplierId) |
... | ... | @@ -88,7 +112,7 @@ export default function Index() { |
88 | 112 | |
89 | 113 | function deletePart(dealer: any = {}, supplier: any = {}, storage: any = {}, part: any = {}) { |
90 | 114 | setDealerList(dealerList.map(it => { |
91 | - if (it.dealerId == dealer.dealerId) { | |
115 | + if (it.settleDealerId == dealer.settleDealerId) { | |
92 | 116 | return { |
93 | 117 | ...it, |
94 | 118 | suppliers: (it.suppliers || []).map((su: any) => { |
... | ... | @@ -116,7 +140,7 @@ export default function Index() { |
116 | 140 | |
117 | 141 | function deleteStorage(dealer: any = {}, supplier: any = {}, storage: any = {}) { |
118 | 142 | setDealerList(dealerList.map(it => { |
119 | - if (it.dealerId == dealer.dealerId) { | |
143 | + if (it.settleDealerId == dealer.settleDealerId) { | |
120 | 144 | return { |
121 | 145 | ...it, |
122 | 146 | suppliers: (it.suppliers || []).map((su: any) => { |
... | ... | @@ -134,31 +158,33 @@ export default function Index() { |
134 | 158 | })); |
135 | 159 | } |
136 | 160 | |
137 | - // useEffect(() => { | |
138 | - // if (dfParams.brandId) { | |
139 | - // setParams(dfParams, true); | |
140 | - // setDelay(false); | |
141 | - // } | |
142 | - // }, [dfParams.brandId]); | |
143 | - | |
144 | - const onSubmit = throttle(() => { | |
161 | + const onSubmit = throttle((isSave) => { | |
145 | 162 | setLoading(true); |
146 | 163 | let suppliers = flattenDeep(dealerList.map(de => (de.suppliers || []).map((su: any) => ({...de, ...su})))); |
147 | 164 | suppliers = suppliers.map(su => ({ |
148 | 165 | ...su, |
149 | - settleDealerId: su.dealerId, | |
166 | + settleDealerId: su.settleDealerId, | |
150 | 167 | storages: (su.storages || []).map((st: any) => ({ |
151 | 168 | storageId: st.storageId, |
152 | 169 | poolIds: (st.parts || []).map((pa: any) => pa.poolId) |
153 | 170 | })) |
154 | 171 | })); |
155 | - saveApi({ | |
172 | + const type = isSave ? 1 : 2; | |
173 | + apiObj[type]({ | |
174 | + planId: planId?.planId, | |
156 | 175 | ...dfParams, |
157 | 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 | + // })) | |
158 | 184 | }).then(() => { |
159 | 185 | setLoading(false); |
160 | - history.back(); | |
161 | - }).catch(e => { | |
186 | + history.goBack(); | |
187 | + }).catch((e: any) => { | |
162 | 188 | setLoading(false); |
163 | 189 | message.error(e.message); |
164 | 190 | }); |
... | ... | @@ -204,15 +230,15 @@ export default function Index() { |
204 | 230 | </a> |
205 | 231 | </div> |
206 | 232 | {dealerList.map((dealer: any = {}) => ( |
207 | - <div key={`dealer${dealer.dealerId}`} style={{ marginTop: 10 }}> | |
233 | + <div key={`dealer${dealer.settleDealerId}`} style={{ marginTop: 10 }}> | |
208 | 234 | <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center'}}> |
209 | - <div style={{ fontWeight: "bold" }}>{`商家: ${dealer.dealerName || ''}`}</div> | |
235 | + <div style={{ fontWeight: "bold" }}>{`商家: ${dealer.settleDealerName || ''}`}</div> | |
210 | 236 | <a style={{marginLeft: 40}} onClick={() => { setVisibleSupplier(true); setDealer(dealer); }}> |
211 | 237 | 添加指定供应商 |
212 | 238 | </a> |
213 | 239 | <Popconfirm |
214 | 240 | title="是否删除" |
215 | - onConfirm={() => setDealerList(dealerList.filter(it => it.dealerId!=dealer.dealerId))} | |
241 | + onConfirm={() => setDealerList(dealerList.filter(it => it.settleDealerId!=dealer.settleDealerId))} | |
216 | 242 | okText="确定" |
217 | 243 | cancelText="取消" |
218 | 244 | style={{marginLeft: 20}} |
... | ... | @@ -224,8 +250,6 @@ export default function Index() { |
224 | 250 | </div> |
225 | 251 | {(dealer.suppliers || []).map((supplier: any = {}) => { |
226 | 252 | const paList: any[] = flattenDeep((supplier.storages || []).map((st: any) => (st.parts || []))); |
227 | - // const paList: any[] = pas.length > 0 ? pas[0] : []; | |
228 | - console.log('pas', paList); | |
229 | 253 | return ( |
230 | 254 | <div key={`supplier${supplier.supplierId}`} style={{ marginTop: 10, marginLeft: 40 }}> |
231 | 255 | <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center'}}> |
... | ... | @@ -247,7 +271,7 @@ export default function Index() { |
247 | 271 | </div> |
248 | 272 | <div style={{display: 'flex', marginLeft: 40, marginTop: 10}}> |
249 | 273 | <div style={{marginRight: 20}}> |
250 | - {`总金额: ${sum(paList.map((it: any) => (it.price || 0) * (it.count || 0))).toFixed(2)}元`} | |
274 | + {`总金额: ${sum(paList.map((it: any) => (it.price || 0) * (it.count || it.partCnt || 0))).toFixed(2)}元`} | |
251 | 275 | </div> |
252 | 276 | <div>{`品种数: ${[...new Set((paList || []).map((i: PartDetail) => i.partCode))].length}种`}</div> |
253 | 277 | </div> |
... | ... | @@ -255,7 +279,7 @@ export default function Index() { |
255 | 279 | <div key={`storage${storage.storageId}`} style={{ marginTop: 10, marginLeft: 60 }}> |
256 | 280 | <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center'}}> |
257 | 281 | <div style={{ fontWeight: "bold" }}>{`发运库房: ${storage.storageName || ''}`}</div> |
258 | - <div style={{marginLeft: 20}}>{`总金额: ${sum((storage.parts || []).map((it: any) => (it.price || 0) * (it.count || 0))).toFixed(2)}元`}</div> | |
282 | + <div style={{marginLeft: 20}}>{`总金额: ${sum((storage.parts || []).map((it: any) => (it.price || 0) * (it.count || it.partCnt || 0))).toFixed(2)}元`}</div> | |
259 | 283 | <div style={{marginLeft: 20}}>{`品种数: ${[...new Set((storage.parts || []).map((i: PartDetail) => i.partCode))].length}种`}</div> |
260 | 284 | <a style={{marginLeft: 20}} onClick={() => { setVisiblePartDetail(true); setDealer({dealer, supplier, storage }); }}> |
261 | 285 | 查看配件 |
... | ... | @@ -308,11 +332,40 @@ export default function Index() { |
308 | 332 | deletePart={deletePart} |
309 | 333 | /> |
310 | 334 | </div> |
311 | - <StepBnt | |
312 | - disable={loading} | |
313 | - bntLoading={loading} | |
314 | - submit={onSubmit} | |
315 | - /> | |
335 | + <div style={{display: 'flex', justifyContent: 'center'}}> | |
336 | + <Popconfirm | |
337 | + title="确定取消" | |
338 | + onConfirm={() => history.goBack()} | |
339 | + okText="确定" | |
340 | + cancelText="取消" | |
341 | + > | |
342 | + <Button | |
343 | + disabled={loading} | |
344 | + loading={loading} | |
345 | + style={{marginRight: 20}} | |
346 | + > | |
347 | + 取消 | |
348 | + </Button> | |
349 | + </Popconfirm> | |
350 | + <Button | |
351 | + disabled={loading} | |
352 | + loading={loading} | |
353 | + onClick={() => onSubmit(false)} | |
354 | + type="primary" | |
355 | + style={{marginRight: 20}} | |
356 | + > | |
357 | + 暂存为草稿 | |
358 | + </Button> | |
359 | + <Button | |
360 | + disabled={loading} | |
361 | + loading={loading} | |
362 | + onClick={() => onSubmit(true)} | |
363 | + type="primary" | |
364 | + > | |
365 | + 确认并提交 | |
366 | + </Button> | |
367 | + </div> | |
368 | + | |
316 | 369 | </Card> |
317 | 370 | </ConfigProvider> |
318 | 371 | </PageHeaderWrapper> | ... | ... |
src/pages/pms/partPlan/PlanManage/subpages/Detail/api.ts
... | ... | @@ -7,6 +7,7 @@ import { PMS_HOST } from '@/utils/host'; |
7 | 7 | */ |
8 | 8 | export interface DetailVO { |
9 | 9 | brandName?: string; // 品牌名称 |
10 | + brandId?: number; // 品牌ID | |
10 | 11 | settleDealerName?: string; // 结算商家 |
11 | 12 | settleShopName?: string; // 结算门店 |
12 | 13 | suppliers?: SupplierVO[]; // 配件集合 | ... | ... |