Commit 82ac825a88de73cf37ba61e9d129e3fc93bfe52d
Merge branch 'cas' into 'master'
Cas add See merge request !194
Showing
28 changed files
with
790 additions
and
108 deletions
config/routers/pms.ts
@@ -163,4 +163,8 @@ export default [ | @@ -163,4 +163,8 @@ export default [ | ||
163 | path: '/pms/transfer/storageOverStock', // 可调出配件 | 163 | path: '/pms/transfer/storageOverStock', // 可调出配件 |
164 | component: './pms/transfer/StorageOverStock' | 164 | component: './pms/transfer/StorageOverStock' |
165 | }, | 165 | }, |
166 | + { | ||
167 | + path: '/pms/transfer/huolalaSetting', // 货拉拉账户配置 | ||
168 | + component: './pms/transfer/HuolalaSetting' | ||
169 | + }, | ||
166 | ]; | 170 | ]; |
src/pages/pms/partPlan/PlanManage/api.ts
@@ -26,7 +26,7 @@ export interface ListVO { | @@ -26,7 +26,7 @@ export interface ListVO { | ||
26 | planDate?: string; // 计划日期 | 26 | planDate?: string; // 计划日期 |
27 | approvalOrderNo?: string; // 审核单号 | 27 | approvalOrderNo?: string; // 审核单号 |
28 | userName?: string; // 计划人员 | 28 | userName?: string; // 计划人员 |
29 | - status?: string; // 计划状态 1:待审核2:已通过9:已拒绝 | 29 | + status?: number; // 计划状态 1:待审核2:已通过9:已拒绝 |
30 | settleShopId?: string; // 结算门店门店id | 30 | settleShopId?: string; // 结算门店门店id |
31 | settleShopName?: string; // 结算门店名称 | 31 | settleShopName?: string; // 结算门店名称 |
32 | prepayToken?: string; // 预付token | 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,6 +13,7 @@ import DetailModal from "@/pages/pms/partPlan/PlanManage/components/DetailModal" | ||
13 | 13 | ||
14 | // 计划状态 1:待审核2:已通过3待付款4已付款9:已拒绝 | 14 | // 计划状态 1:待审核2:已通过3待付款4已付款9:已拒绝 |
15 | const statusName: {[key: number]: string} = { | 15 | const statusName: {[key: number]: string} = { |
16 | + 0: '草稿', | ||
16 | 1: '待审核', | 17 | 1: '待审核', |
17 | 2: '已通过', | 18 | 2: '已通过', |
18 | 3: '待付款', | 19 | 3: '待付款', |
@@ -69,6 +70,7 @@ export default function Index() { | @@ -69,6 +70,7 @@ export default function Index() { | ||
69 | onChange={v => setParams({status: v }, true)} | 70 | onChange={v => setParams({status: v }, true)} |
70 | optionFilterProp="children" | 71 | optionFilterProp="children" |
71 | > | 72 | > |
73 | + <Select.Option value={0} key={0}>草稿</Select.Option> | ||
72 | <Select.Option value={1} key={1}>待审核</Select.Option> | 74 | <Select.Option value={1} key={1}>待审核</Select.Option> |
73 | <Select.Option value={2} key={2}>已通过</Select.Option> | 75 | <Select.Option value={2} key={2}>已通过</Select.Option> |
74 | <Select.Option value={9} key={9}>已拒绝</Select.Option> | 76 | <Select.Option value={9} key={9}>已拒绝</Select.Option> |
@@ -95,9 +97,16 @@ export default function Index() { | @@ -95,9 +97,16 @@ export default function Index() { | ||
95 | fixed="right" | 97 | fixed="right" |
96 | render={(text, _item: ListVO) => ( | 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 | <Divider type="vertical" /> | 110 | <Divider type="vertical" /> |
102 | <a onClick={() => { | 111 | <a onClick={() => { |
103 | setItem(_item); | 112 | setItem(_item); |
src/pages/pms/partPlan/PlanManage/subpages/Apply/api.ts
@@ -16,3 +16,9 @@ export interface SaveParams { | @@ -16,3 +16,9 @@ export interface SaveParams { | ||
16 | export function saveApi(params?: SaveParams): http.PromiseResp<void> { | 16 | export function saveApi(params?: SaveParams): http.PromiseResp<void> { |
17 | return request.post(`${PMS_HOST}/erp/plan/pool/save/plan`, params); | 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,9 +11,9 @@ interface Props { | ||
11 | } | 11 | } |
12 | const {Option} = Select; | 12 | const {Option} = Select; |
13 | export default function Index({ onCancel, visible, onOk, dealerList = [] }: Props) { | 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 | const { data: dealers } = useInitail<CommonApi.OptionVO[], CommonApi.DealerParam>(getDealerApi, [], {}); | 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 | useEffect(() => { | 18 | useEffect(() => { |
19 | if (!visible) { | 19 | if (!visible) { |
@@ -22,7 +22,7 @@ export default function Index({ onCancel, visible, onOk, dealerList = [] }: Prop | @@ -22,7 +22,7 @@ export default function Index({ onCancel, visible, onOk, dealerList = [] }: Prop | ||
22 | }, [visible]); | 22 | }, [visible]); |
23 | 23 | ||
24 | const handSave = () => { | 24 | const handSave = () => { |
25 | - if (!dealer.dealerId) { | 25 | + if (!dealer.settleDealerId) { |
26 | message.error('请选择采购商家'); | 26 | message.error('请选择采购商家'); |
27 | return; | 27 | return; |
28 | } | 28 | } |
@@ -40,7 +40,7 @@ export default function Index({ onCancel, visible, onOk, dealerList = [] }: Prop | @@ -40,7 +40,7 @@ export default function Index({ onCancel, visible, onOk, dealerList = [] }: Prop | ||
40 | <Button key="cancel" onClick={onCancel}>取消</Button>, | 40 | <Button key="cancel" onClick={onCancel}>取消</Button>, |
41 | <Button | 41 | <Button |
42 | key="submit" | 42 | key="submit" |
43 | - disabled={!dealer.dealerId} | 43 | + disabled={!dealer.settleDealerId} |
44 | onClick={handSave} | 44 | onClick={handSave} |
45 | type="primary" | 45 | type="primary" |
46 | htmlType="submit" | 46 | htmlType="submit" |
@@ -52,14 +52,14 @@ export default function Index({ onCancel, visible, onOk, dealerList = [] }: Prop | @@ -52,14 +52,14 @@ export default function Index({ onCancel, visible, onOk, dealerList = [] }: Prop | ||
52 | <div style={{display: 'flex', flexDirection: 'row', alignItems: 'center', marginBottom: 10}}> | 52 | <div style={{display: 'flex', flexDirection: 'row', alignItems: 'center', marginBottom: 10}}> |
53 | <span>商家:</span> | 53 | <span>商家:</span> |
54 | <Select | 54 | <Select |
55 | - value={dealer.dealerId} | 55 | + value={dealer.settleDealerId} |
56 | style={{ width: 250 }} | 56 | style={{ width: 250 }} |
57 | placeholder="请选择商家" | 57 | placeholder="请选择商家" |
58 | showSearch | 58 | showSearch |
59 | optionFilterProp="children" | 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 | {dealers.filter(it => !suIds.includes(it.id)).map((b) => ( | 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,16 +8,24 @@ import {throttle, sum} from 'lodash'; | ||
8 | import useInitial from "@/hooks/useInitail"; | 8 | import useInitial from "@/hooks/useInitail"; |
9 | import * as API from "@/common/api"; | 9 | import * as API from "@/common/api"; |
10 | import {getList, Params, ListVO} from "@/pages/pms/partPlan/PlanPool/api"; | 10 | import {getList, Params, ListVO} from "@/pages/pms/partPlan/PlanPool/api"; |
11 | -import {saveApi} from './api'; | 11 | +import {saveApi, draftApi} from './api'; |
12 | import zhCN from "antd/lib/locale-provider/zh_CN"; | 12 | import zhCN from "antd/lib/locale-provider/zh_CN"; |
13 | import st from "@/pages/pms/partPlan/PlanManage/style.less"; | 13 | import st from "@/pages/pms/partPlan/PlanManage/style.less"; |
14 | -import StepBnt from "@/pages/pms/comonents/StepBnt"; | ||
15 | import PartModal from "@/pages/pms/partPlan/PlanManage/subpages/Apply/components/PartModal"; | 14 | import PartModal from "@/pages/pms/partPlan/PlanManage/subpages/Apply/components/PartModal"; |
16 | import {groupBys, flattenDeep} from '@/pages/pms/entity'; | 15 | import {groupBys, flattenDeep} from '@/pages/pms/entity'; |
17 | import {PartDetail} from '../../api'; | 16 | import {PartDetail} from '../../api'; |
17 | +import { history } from 'umi'; | ||
18 | +import { getDetail, DetailVO, Params as detailParams } from '../Detail/api'; | ||
18 | 19 | ||
19 | const { Option } = Select; | 20 | const { Option } = Select; |
21 | +const apiObj: { [key: number]: any } = { | ||
22 | + 1: saveApi, | ||
23 | + 2: draftApi | ||
24 | +}; | ||
20 | export default function Index() { | 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 | const [delay, setDelay] = useState<boolean>(true); | 29 | const [delay, setDelay] = useState<boolean>(true); |
22 | const [loading, setLoading] = useState<boolean>(false); | 30 | const [loading, setLoading] = useState<boolean>(false); |
23 | const { data: brands } = useInitial(API.getBrandFilterApi, [], {}); | 31 | const { data: brands } = useInitial(API.getBrandFilterApi, [], {}); |
@@ -32,9 +40,25 @@ export default function Index() { | @@ -32,9 +40,25 @@ export default function Index() { | ||
32 | const partList = flattenDeep(dealerList.map(it => (it.suppliers || []).map((su: any) => (su.storages || []).map((st: any) => (st.parts || []))))); | 40 | const partList = flattenDeep(dealerList.map(it => (it.suppliers || []).map((su: any) => (su.storages || []).map((st: any) => (st.parts || []))))); |
33 | const poolIds = partList.map((it: any) => it.poolId); | 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 | function onOk(parts: ListVO[] = []) { | 59 | function onOk(parts: ListVO[] = []) { |
36 | setDealerList(dealerList.map(it => { | 60 | setDealerList(dealerList.map(it => { |
37 | - if (it.dealerId == dealer.dealerId) { | 61 | + if (it.settleDealerId == dealer.settleDealerId) { |
38 | return { | 62 | return { |
39 | ...it, | 63 | ...it, |
40 | suppliers: (it.suppliers || []).map((su: any) => { | 64 | suppliers: (it.suppliers || []).map((su: any) => { |
@@ -64,7 +88,7 @@ export default function Index() { | @@ -64,7 +88,7 @@ export default function Index() { | ||
64 | 88 | ||
65 | function onOkSupplier(supplier: any = {}) { | 89 | function onOkSupplier(supplier: any = {}) { |
66 | setDealerList(dealerList.map(it => { | 90 | setDealerList(dealerList.map(it => { |
67 | - if (it.dealerId == dealer.dealerId) { | 91 | + if (it.settleDealerId == dealer.settleDealerId) { |
68 | return { | 92 | return { |
69 | ...it, | 93 | ...it, |
70 | suppliers: [...(it.suppliers || []), supplier] | 94 | suppliers: [...(it.suppliers || []), supplier] |
@@ -76,7 +100,7 @@ export default function Index() { | @@ -76,7 +100,7 @@ export default function Index() { | ||
76 | 100 | ||
77 | function deleteSupplier(dealer: any = {}, supplier: any = {}) { | 101 | function deleteSupplier(dealer: any = {}, supplier: any = {}) { |
78 | setDealerList(dealerList.map(it => { | 102 | setDealerList(dealerList.map(it => { |
79 | - if (it.dealerId == dealer.dealerId) { | 103 | + if (it.settleDealerId == dealer.settleDealerId) { |
80 | return { | 104 | return { |
81 | ...it, | 105 | ...it, |
82 | suppliers: (it.suppliers || []).filter((su: any) => su.supplierId != supplier.supplierId) | 106 | suppliers: (it.suppliers || []).filter((su: any) => su.supplierId != supplier.supplierId) |
@@ -88,7 +112,7 @@ export default function Index() { | @@ -88,7 +112,7 @@ export default function Index() { | ||
88 | 112 | ||
89 | function deletePart(dealer: any = {}, supplier: any = {}, storage: any = {}, part: any = {}) { | 113 | function deletePart(dealer: any = {}, supplier: any = {}, storage: any = {}, part: any = {}) { |
90 | setDealerList(dealerList.map(it => { | 114 | setDealerList(dealerList.map(it => { |
91 | - if (it.dealerId == dealer.dealerId) { | 115 | + if (it.settleDealerId == dealer.settleDealerId) { |
92 | return { | 116 | return { |
93 | ...it, | 117 | ...it, |
94 | suppliers: (it.suppliers || []).map((su: any) => { | 118 | suppliers: (it.suppliers || []).map((su: any) => { |
@@ -116,7 +140,7 @@ export default function Index() { | @@ -116,7 +140,7 @@ export default function Index() { | ||
116 | 140 | ||
117 | function deleteStorage(dealer: any = {}, supplier: any = {}, storage: any = {}) { | 141 | function deleteStorage(dealer: any = {}, supplier: any = {}, storage: any = {}) { |
118 | setDealerList(dealerList.map(it => { | 142 | setDealerList(dealerList.map(it => { |
119 | - if (it.dealerId == dealer.dealerId) { | 143 | + if (it.settleDealerId == dealer.settleDealerId) { |
120 | return { | 144 | return { |
121 | ...it, | 145 | ...it, |
122 | suppliers: (it.suppliers || []).map((su: any) => { | 146 | suppliers: (it.suppliers || []).map((su: any) => { |
@@ -134,31 +158,33 @@ export default function Index() { | @@ -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 | setLoading(true); | 162 | setLoading(true); |
146 | let suppliers = flattenDeep(dealerList.map(de => (de.suppliers || []).map((su: any) => ({...de, ...su})))); | 163 | let suppliers = flattenDeep(dealerList.map(de => (de.suppliers || []).map((su: any) => ({...de, ...su})))); |
147 | suppliers = suppliers.map(su => ({ | 164 | suppliers = suppliers.map(su => ({ |
148 | ...su, | 165 | ...su, |
149 | - settleDealerId: su.dealerId, | 166 | + settleDealerId: su.settleDealerId, |
150 | storages: (su.storages || []).map((st: any) => ({ | 167 | storages: (su.storages || []).map((st: any) => ({ |
151 | storageId: st.storageId, | 168 | storageId: st.storageId, |
152 | poolIds: (st.parts || []).map((pa: any) => pa.poolId) | 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: Number(planId?.planId), | ||
156 | ...dfParams, | 175 | ...dfParams, |
157 | suppliers | 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 | }).then(() => { | 184 | }).then(() => { |
159 | setLoading(false); | 185 | setLoading(false); |
160 | - history.back(); | ||
161 | - }).catch(e => { | 186 | + history.goBack(); |
187 | + }).catch((e: any) => { | ||
162 | setLoading(false); | 188 | setLoading(false); |
163 | message.error(e.message); | 189 | message.error(e.message); |
164 | }); | 190 | }); |
@@ -204,15 +230,15 @@ export default function Index() { | @@ -204,15 +230,15 @@ export default function Index() { | ||
204 | </a> | 230 | </a> |
205 | </div> | 231 | </div> |
206 | {dealerList.map((dealer: any = {}) => ( | 232 | {dealerList.map((dealer: any = {}) => ( |
207 | - <div key={`dealer${dealer.dealerId}`} style={{ marginTop: 10 }}> | 233 | + <div key={`dealer${dealer.settleDealerId}`} style={{ marginTop: 10 }}> |
208 | <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center'}}> | 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 | <a style={{marginLeft: 40}} onClick={() => { setVisibleSupplier(true); setDealer(dealer); }}> | 236 | <a style={{marginLeft: 40}} onClick={() => { setVisibleSupplier(true); setDealer(dealer); }}> |
211 | 添加指定供应商 | 237 | 添加指定供应商 |
212 | </a> | 238 | </a> |
213 | <Popconfirm | 239 | <Popconfirm |
214 | title="是否删除" | 240 | title="是否删除" |
215 | - onConfirm={() => setDealerList(dealerList.filter(it => it.dealerId!=dealer.dealerId))} | 241 | + onConfirm={() => setDealerList(dealerList.filter(it => it.settleDealerId!=dealer.settleDealerId))} |
216 | okText="确定" | 242 | okText="确定" |
217 | cancelText="取消" | 243 | cancelText="取消" |
218 | style={{marginLeft: 20}} | 244 | style={{marginLeft: 20}} |
@@ -224,8 +250,6 @@ export default function Index() { | @@ -224,8 +250,6 @@ export default function Index() { | ||
224 | </div> | 250 | </div> |
225 | {(dealer.suppliers || []).map((supplier: any = {}) => { | 251 | {(dealer.suppliers || []).map((supplier: any = {}) => { |
226 | const paList: any[] = flattenDeep((supplier.storages || []).map((st: any) => (st.parts || []))); | 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 | return ( | 253 | return ( |
230 | <div key={`supplier${supplier.supplierId}`} style={{ marginTop: 10, marginLeft: 40 }}> | 254 | <div key={`supplier${supplier.supplierId}`} style={{ marginTop: 10, marginLeft: 40 }}> |
231 | <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center'}}> | 255 | <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center'}}> |
@@ -247,7 +271,7 @@ export default function Index() { | @@ -247,7 +271,7 @@ export default function Index() { | ||
247 | </div> | 271 | </div> |
248 | <div style={{display: 'flex', marginLeft: 40, marginTop: 10}}> | 272 | <div style={{display: 'flex', marginLeft: 40, marginTop: 10}}> |
249 | <div style={{marginRight: 20}}> | 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 | </div> | 275 | </div> |
252 | <div>{`品种数: ${[...new Set((paList || []).map((i: PartDetail) => i.partCode))].length}种`}</div> | 276 | <div>{`品种数: ${[...new Set((paList || []).map((i: PartDetail) => i.partCode))].length}种`}</div> |
253 | </div> | 277 | </div> |
@@ -255,7 +279,7 @@ export default function Index() { | @@ -255,7 +279,7 @@ export default function Index() { | ||
255 | <div key={`storage${storage.storageId}`} style={{ marginTop: 10, marginLeft: 60 }}> | 279 | <div key={`storage${storage.storageId}`} style={{ marginTop: 10, marginLeft: 60 }}> |
256 | <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center'}}> | 280 | <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center'}}> |
257 | <div style={{ fontWeight: "bold" }}>{`发运库房: ${storage.storageName || ''}`}</div> | 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 | <div style={{marginLeft: 20}}>{`品种数: ${[...new Set((storage.parts || []).map((i: PartDetail) => i.partCode))].length}种`}</div> | 283 | <div style={{marginLeft: 20}}>{`品种数: ${[...new Set((storage.parts || []).map((i: PartDetail) => i.partCode))].length}种`}</div> |
260 | <a style={{marginLeft: 20}} onClick={() => { setVisiblePartDetail(true); setDealer({dealer, supplier, storage }); }}> | 284 | <a style={{marginLeft: 20}} onClick={() => { setVisiblePartDetail(true); setDealer({dealer, supplier, storage }); }}> |
261 | 查看配件 | 285 | 查看配件 |
@@ -308,11 +332,34 @@ export default function Index() { | @@ -308,11 +332,34 @@ export default function Index() { | ||
308 | deletePart={deletePart} | 332 | deletePart={deletePart} |
309 | /> | 333 | /> |
310 | </div> | 334 | </div> |
311 | - <StepBnt | ||
312 | - disable={loading} | ||
313 | - bntLoading={loading} | ||
314 | - submit={onSubmit} | ||
315 | - /> | 335 | + <div style={{display: 'flex', justifyContent: 'center'}}> |
336 | + <Button | ||
337 | + disabled={loading} | ||
338 | + loading={loading} | ||
339 | + style={{marginRight: 20}} | ||
340 | + onClick={() => history.goBack()} | ||
341 | + > | ||
342 | + 取消 | ||
343 | + </Button> | ||
344 | + <Button | ||
345 | + disabled={loading} | ||
346 | + loading={loading} | ||
347 | + onClick={() => onSubmit(false)} | ||
348 | + type="primary" | ||
349 | + style={{marginRight: 20}} | ||
350 | + > | ||
351 | + 暂存为草稿 | ||
352 | + </Button> | ||
353 | + <Button | ||
354 | + disabled={loading} | ||
355 | + loading={loading} | ||
356 | + onClick={() => onSubmit(true)} | ||
357 | + type="primary" | ||
358 | + > | ||
359 | + 确认并提交 | ||
360 | + </Button> | ||
361 | + </div> | ||
362 | + | ||
316 | </Card> | 363 | </Card> |
317 | </ConfigProvider> | 364 | </ConfigProvider> |
318 | </PageHeaderWrapper> | 365 | </PageHeaderWrapper> |
src/pages/pms/partPlan/PlanManage/subpages/Detail/api.ts
@@ -7,6 +7,7 @@ import { PMS_HOST } from '@/utils/host'; | @@ -7,6 +7,7 @@ import { PMS_HOST } from '@/utils/host'; | ||
7 | */ | 7 | */ |
8 | export interface DetailVO { | 8 | export interface DetailVO { |
9 | brandName?: string; // 品牌名称 | 9 | brandName?: string; // 品牌名称 |
10 | + brandId?: number; // 品牌ID | ||
10 | settleDealerName?: string; // 结算商家 | 11 | settleDealerName?: string; // 结算商家 |
11 | settleShopName?: string; // 结算门店 | 12 | settleShopName?: string; // 结算门店 |
12 | suppliers?: SupplierVO[]; // 配件集合 | 13 | suppliers?: SupplierVO[]; // 配件集合 |
src/pages/pms/partPlan/PlanPool/api.ts
1 | import { http } from '@/typing/http'; | 1 | import { http } from '@/typing/http'; |
2 | import request from '@/utils/request'; | 2 | import request from '@/utils/request'; |
3 | import { PMS_HOST } from '@/utils/host'; | 3 | import { PMS_HOST } from '@/utils/host'; |
4 | +import { PartVO } from '@/pages/pms/partPlan/CustBuyPlan/api'; | ||
4 | 5 | ||
5 | export interface Params { | 6 | export interface Params { |
6 | brandId?: number, // 品牌ID | 7 | brandId?: number, // 品牌ID |
@@ -18,6 +19,7 @@ export interface Params { | @@ -18,6 +19,7 @@ export interface Params { | ||
18 | 19 | ||
19 | export interface ListVO { | 20 | export interface ListVO { |
20 | poolId: number; // 计划池id | 21 | poolId: number; // 计划池id |
22 | + poolIds?: string, | ||
21 | id?: number; | 23 | id?: number; |
22 | name?: string; // 名称 | 24 | name?: string; // 名称 |
23 | code?: string; // 编码 | 25 | code?: string; // 编码 |
@@ -61,7 +63,60 @@ export interface ListVO { | @@ -61,7 +63,60 @@ export interface ListVO { | ||
61 | unit?: string; // 采购规格(配件展示) | 63 | unit?: string; // 采购规格(配件展示) |
62 | splitUnit?: string; // 拆分件规格(配件展示) | 64 | splitUnit?: string; // 拆分件规格(配件展示) |
63 | splitCnt?: number; // 拆分件数量(配件展示) | 65 | splitCnt?: number; // 拆分件数量(配件展示) |
64 | - partType?:number | 66 | + partType?:number, |
67 | + planWaitListIds?:string | ||
68 | +} | ||
69 | + | ||
70 | +export interface OutItem{ | ||
71 | + /** | ||
72 | + * 配件ID | ||
73 | + */ | ||
74 | +partId?:number; | ||
75 | +/** | ||
76 | + * 配件编码 | ||
77 | + */ | ||
78 | +partCode?:string; | ||
79 | +/** | ||
80 | + * 配件名称 | ||
81 | + */ | ||
82 | +partName?:string; | ||
83 | +/** | ||
84 | + * 出库数量 | ||
85 | + */ | ||
86 | +partCnt?:number; | ||
87 | +/** | ||
88 | + * 成本价 | ||
89 | + */ | ||
90 | +costPrice?:number; | ||
91 | +/** | ||
92 | + * 出库类型1工单2装潢 | ||
93 | + */ | ||
94 | +type?:number; | ||
95 | +/** | ||
96 | + * 出库类型ID | ||
97 | + */ | ||
98 | +typeId?:string; | ||
99 | +/** | ||
100 | + * 服务站id | ||
101 | + */ | ||
102 | +shopId?:number; | ||
103 | +/** | ||
104 | + * 服务站名称 | ||
105 | + */ | ||
106 | +shopName?:string; | ||
107 | +/** | ||
108 | + * 集团ID | ||
109 | + */ | ||
110 | +groupId?:number; | ||
111 | +/** | ||
112 | + * 出库时间 | ||
113 | + */ | ||
114 | +outTime?:string; | ||
115 | + | ||
116 | +/** | ||
117 | + * 类型名称 | ||
118 | + */ | ||
119 | +typeName?:string; | ||
65 | } | 120 | } |
66 | 121 | ||
67 | /** | 122 | /** |
@@ -74,6 +129,15 @@ export function getList(params: Params): http.PromiseResp<ListVO[]> { | @@ -74,6 +129,15 @@ export function getList(params: Params): http.PromiseResp<ListVO[]> { | ||
74 | export function deleteApi(params: {poolId: number}) { | 129 | export function deleteApi(params: {poolId: number}) { |
75 | return request.post(`${PMS_HOST}/erp/plan/pool/delete/plan`, {...params}); | 130 | return request.post(`${PMS_HOST}/erp/plan/pool/delete/plan`, {...params}); |
76 | } | 131 | } |
132 | + | ||
77 | export function editApi(params: { poolId?: number, partCnt?: number}) { | 133 | export function editApi(params: { poolId?: number, partCnt?: number}) { |
78 | return request.post(`${PMS_HOST}/erp/plan/pool/update/plan`, {...params}); | 134 | return request.post(`${PMS_HOST}/erp/plan/pool/update/plan`, {...params}); |
79 | } | 135 | } |
136 | + | ||
137 | +export function outFlowApi(params: { poolIds?: any, planId?: number, current?: number, pageSize?:number}):http.PromisePageResp<OutItem> { | ||
138 | + return request.get(`${PMS_HOST}/erp/storage/out/list`, {params}); | ||
139 | +} | ||
140 | + | ||
141 | +export function custBuyApi(params: { planWaitListIds?: any}):http.PromiseResp<PartVO[]> { | ||
142 | + return request.get(`${PMS_HOST}/erp/cus/buy/part/get/buy/part/list`, {params}); | ||
143 | +} |
src/pages/pms/partPlan/PlanPool/components/AreaTable.tsx
@@ -14,7 +14,7 @@ interface Props { | @@ -14,7 +14,7 @@ interface Props { | ||
14 | id?: number, // 上一个列表ID | 14 | id?: number, // 上一个列表ID |
15 | } | 15 | } |
16 | export default function Index(props: Props = {}) { | 16 | export default function Index(props: Props = {}) { |
17 | - const { dfParams, key } = useStore(); | 17 | + const { dfParams, key, setItem, setOutVisible, setCustVisible } = useStore(); |
18 | const {showAnalyse=true} = props; | 18 | const {showAnalyse=true} = props; |
19 | const { data: parts, setParams, loading } = useInitial(getList, [], {...dfParams, ...props}); | 19 | const { data: parts, setParams, loading } = useInitial(getList, [], {...dfParams, ...props}); |
20 | const [visible, setVisible] = useState(false); | 20 | const [visible, setVisible] = useState(false); |
@@ -23,7 +23,6 @@ export default function Index(props: Props = {}) { | @@ -23,7 +23,6 @@ export default function Index(props: Props = {}) { | ||
23 | const [id, setId] = useState<number>(); | 23 | const [id, setId] = useState<number>(); |
24 | 24 | ||
25 | useEffect(() => { | 25 | useEffect(() => { |
26 | - console.log('dfParams11', dfParams, key, props); | ||
27 | if (key == props.type) { | 26 | if (key == props.type) { |
28 | setParams(dfParams, true); | 27 | setParams(dfParams, true); |
29 | } | 28 | } |
@@ -37,13 +36,13 @@ export default function Index(props: Props = {}) { | @@ -37,13 +36,13 @@ export default function Index(props: Props = {}) { | ||
37 | <Column title="计划前库销比" dataIndex="ratio" render={t => (t || 0).toFixed(2)} /> | 36 | <Column title="计划前库销比" dataIndex="ratio" render={t => (t || 0).toFixed(2)} /> |
38 | <Column title="计划后库销比" dataIndex="planeRatio" render={t => (t || 0).toFixed(2)} /> | 37 | <Column title="计划后库销比" dataIndex="planeRatio" render={t => (t || 0).toFixed(2)} /> |
39 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> | 38 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> |
40 | - <Column title="客户订件数量(个)" dataIndex="buyCnt" /> | 39 | + <Column title="客户订件数量(个)" render={r => (r.buyCnt ? <a onClick={() => { setCustVisible(true); setItem(r); }}>{r.buyCnt}</a> : r.buyCnt)} /> |
41 | <Column title="客户订件金额(元)" dataIndex="buyAmount" /> | 40 | <Column title="客户订件金额(元)" dataIndex="buyAmount" /> |
42 | <Column title="在途未锁(个)" dataIndex="onTheWayUnlockCnt" /> | 41 | <Column title="在途未锁(个)" dataIndex="onTheWayUnlockCnt" /> |
43 | 42 | ||
44 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> | 43 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> |
45 | <Column title="在库已锁(个)" dataIndex="storageLockedCnt" /> | 44 | <Column title="在库已锁(个)" dataIndex="storageLockedCnt" /> |
46 | - <Column title="滚动90天出库(个)" dataIndex="outStockCnt" /> | 45 | + <Column title="滚动90天出库(个)" render={r => (r.outStockCnt ? <a onClick={() => { setOutVisible(true); setItem(r); }}>{r.outStockCnt}</a> : r.outStockCnt)} /> |
47 | {showAnalyse && ( | 46 | {showAnalyse && ( |
48 | <> | 47 | <> |
49 | <Column | 48 | <Column |
src/pages/pms/partPlan/PlanPool/components/CustBuyModal.tsx
0 → 100644
1 | +import React, { useEffect, useState } from 'react'; | ||
2 | +import { Button, Modal, Table } from 'antd'; | ||
3 | +import { useStore } from '../index'; | ||
4 | +import { custBuyApi } from '../api'; | ||
5 | +import { PartVO } from '@/pages/pms/partPlan/CustBuyPlan/api'; | ||
6 | +import useInitial from '@/hooks/useInitail'; | ||
7 | + | ||
8 | +const { Column } = Table; | ||
9 | + | ||
10 | +export default function Index() { | ||
11 | + const { custVisible, setCustVisible, item } = useStore(); | ||
12 | + const [delay, setDelay] = useState(true); | ||
13 | + const { data, setParams, loading } = useInitial(custBuyApi, [], {}, delay); | ||
14 | + | ||
15 | + useEffect(() => { | ||
16 | + if (custVisible && item?.planWaitListIds) { | ||
17 | + setParams({ planWaitListIds: item.planWaitListIds }, true); | ||
18 | + setDelay(false); | ||
19 | + } | ||
20 | + }, [custVisible]); | ||
21 | + | ||
22 | + return ( | ||
23 | + <Modal | ||
24 | + title="客户订件详情" | ||
25 | + width={1100} | ||
26 | + visible={custVisible} | ||
27 | + maskClosable={false} | ||
28 | + onCancel={() => setCustVisible(false)} | ||
29 | + footer={[ | ||
30 | + <Button onClick={() => setCustVisible(false)}>取消</Button> | ||
31 | + ]} | ||
32 | + > | ||
33 | + <Table | ||
34 | + rowKey={(v: PartVO) => `${v.waitListIds}`} | ||
35 | + dataSource={data} | ||
36 | + pagination={false} | ||
37 | + loading={loading} | ||
38 | + scroll={{x: 1400, y: 500}} | ||
39 | + > | ||
40 | + <Column title="时间" dataIndex="planTime" /> | ||
41 | + <Column title="VIN" dataIndex="typeId" /> | ||
42 | + <Column title="工单号" dataIndex="remark" /> | ||
43 | + <Column title="车牌号" dataIndex="plateNo" /> | ||
44 | + <Column title="配件编码" dataIndex="partCode" /> | ||
45 | + <Column title="配件名称" dataIndex="partName" /> | ||
46 | + <Column title="接车服务顾问" dataIndex="userName" /> | ||
47 | + <Column title="门店名称" dataIndex="shopName" /> | ||
48 | + <Column title="库房名称" dataIndex="storageName" /> | ||
49 | + <Column title="订件数量" dataIndex="splitCnt" /> | ||
50 | + <Column title="采购单价" dataIndex="price" /> | ||
51 | + <Column title="采购数量" dataIndex="cnt" /> | ||
52 | + </Table> | ||
53 | + </Modal> | ||
54 | + ); | ||
55 | +} | ||
0 | \ No newline at end of file | 56 | \ No newline at end of file |
src/pages/pms/partPlan/PlanPool/components/OutFlowModal.tsx
0 → 100644
1 | +import React, { useEffect, useState } from 'react'; | ||
2 | +import {Button, Modal, Table} from 'antd'; | ||
3 | +import {useStore} from '../index'; | ||
4 | +import { outFlowApi, OutItem } from '../api'; | ||
5 | +import usePagination from '@/hooks/usePagination'; | ||
6 | + | ||
7 | +const {Column} = Table; | ||
8 | + | ||
9 | +export default function Index() { | ||
10 | + const {outVisible, setOutVisible, item} = useStore(); | ||
11 | + const [delay, setDelay]= useState(true); | ||
12 | + const { list, setParams, loading, paginationConfig } = usePagination(outFlowApi, [], {delay}); | ||
13 | + | ||
14 | + useEffect(() => { | ||
15 | + if (outVisible && item?.poolIds) { | ||
16 | + setParams({poolIds: item.poolIds}, true); | ||
17 | + setDelay(false); | ||
18 | + } | ||
19 | + }, [outVisible]); | ||
20 | + | ||
21 | + return ( | ||
22 | + <Modal | ||
23 | + title={`${item?.partName}滚动90天出库流水`} | ||
24 | + width={1000} | ||
25 | + visible={outVisible} | ||
26 | + maskClosable={false} | ||
27 | + onCancel={() => setOutVisible(false)} | ||
28 | + footer={[ | ||
29 | + <Button onClick={() => setOutVisible(false)}>取消</Button> | ||
30 | + ]} | ||
31 | + > | ||
32 | + <Table | ||
33 | + dataSource={list} | ||
34 | + loading={loading} | ||
35 | + pagination={paginationConfig} | ||
36 | + rowKey={(v: OutItem) => `${v.partId}`} | ||
37 | + > | ||
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" /> | ||
44 | + </Table> | ||
45 | + </Modal> | ||
46 | + ); | ||
47 | +} | ||
0 | \ No newline at end of file | 48 | \ No newline at end of file |
src/pages/pms/partPlan/PlanPool/components/PartTable.tsx
@@ -16,7 +16,7 @@ interface Props { | @@ -16,7 +16,7 @@ interface Props { | ||
16 | id?: number, // 上一个列表ID | 16 | id?: number, // 上一个列表ID |
17 | } | 17 | } |
18 | export default function Index(props: Props = {}) { | 18 | export default function Index(props: Props = {}) { |
19 | - const { dfParams, key } = useStore(); | 19 | + const { dfParams, key, setItem, setOutVisible, setCustVisible } = useStore(); |
20 | const {showAnalyse=true} = props; | 20 | const {showAnalyse=true} = props; |
21 | const { data: parts, setParams, loading } = useInitial(getList, [], {...dfParams, ...props}); | 21 | const { data: parts, setParams, loading } = useInitial(getList, [], {...dfParams, ...props}); |
22 | const [visible, setVisible] = useState(false); | 22 | const [visible, setVisible] = useState(false); |
@@ -43,13 +43,13 @@ export default function Index(props: Props = {}) { | @@ -43,13 +43,13 @@ export default function Index(props: Props = {}) { | ||
43 | <Column title="计划后库销比" dataIndex="planeRatio" render={t => (t || 0).toFixed(2)} /> | 43 | <Column title="计划后库销比" dataIndex="planeRatio" render={t => (t || 0).toFixed(2)} /> |
44 | 44 | ||
45 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> | 45 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> |
46 | - <Column title="客户订件数量(个)" dataIndex="buyCnt" /> | 46 | + <Column title="客户订件数量(个)" render={r => (r.buyCnt ? <a onClick={() => { setCustVisible(true); setItem(r); }}>{r.buyCnt}</a> : r.buyCnt)} /> |
47 | <Column title="客户订件金额(元)" dataIndex="buyAmount" /> | 47 | <Column title="客户订件金额(元)" dataIndex="buyAmount" /> |
48 | <Column title="在途未锁(个)" dataIndex="onTheWayUnlockCnt" /> | 48 | <Column title="在途未锁(个)" dataIndex="onTheWayUnlockCnt" /> |
49 | 49 | ||
50 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> | 50 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> |
51 | <Column title="在库已锁(个)" dataIndex="storageLockedCnt" /> | 51 | <Column title="在库已锁(个)" dataIndex="storageLockedCnt" /> |
52 | - <Column title="滚动90天出库(个)" dataIndex="outStockCnt" /> | 52 | + <Column title="滚动90天出库(个)" render={r => (r.outStockCnt ? <a onClick={() => { setOutVisible(true); setItem(r); }}>{r.outStockCnt}</a> : r.outStockCnt)} /> |
53 | {showAnalyse && ( | 53 | {showAnalyse && ( |
54 | <> | 54 | <> |
55 | <Column | 55 | <Column |
src/pages/pms/partPlan/PlanPool/components/SeriesTable.tsx
@@ -15,7 +15,7 @@ interface Props { | @@ -15,7 +15,7 @@ interface Props { | ||
15 | id?: number, // 上一个列表ID | 15 | id?: number, // 上一个列表ID |
16 | } | 16 | } |
17 | export default function Index(props: Props = {}) { | 17 | export default function Index(props: Props = {}) { |
18 | - const { dfParams, key } = useStore(); | 18 | + const { dfParams, key, setItem, setOutVisible, setCustVisible } = useStore(); |
19 | const {showAnalyse=true} = props; | 19 | const {showAnalyse=true} = props; |
20 | const { data: parts, setParams, loading } = useInitial(getList, [], {...dfParams, ...props}); | 20 | const { data: parts, setParams, loading } = useInitial(getList, [], {...dfParams, ...props}); |
21 | const [visible, setVisible] = useState(false); | 21 | const [visible, setVisible] = useState(false); |
@@ -38,13 +38,13 @@ export default function Index(props: Props = {}) { | @@ -38,13 +38,13 @@ export default function Index(props: Props = {}) { | ||
38 | <Column title="计划后库销比" dataIndex="planeRatio" render={t => (t || 0).toFixed(2)} /> | 38 | <Column title="计划后库销比" dataIndex="planeRatio" render={t => (t || 0).toFixed(2)} /> |
39 | 39 | ||
40 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> | 40 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> |
41 | - <Column title="客户订件数量(个)" dataIndex="buyCnt" /> | 41 | + <Column title="客户订件数量(个)" render={r => (r.buyCnt ? <a onClick={() => { setCustVisible(true); setItem(r); }}>{r.buyCnt}</a> : r.buyCnt)} /> |
42 | <Column title="客户订件金额(元)" dataIndex="buyAmount" /> | 42 | <Column title="客户订件金额(元)" dataIndex="buyAmount" /> |
43 | <Column title="在途未锁(个)" dataIndex="onTheWayUnlockCnt" /> | 43 | <Column title="在途未锁(个)" dataIndex="onTheWayUnlockCnt" /> |
44 | 44 | ||
45 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> | 45 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> |
46 | <Column title="在库已锁(个)" dataIndex="storageLockedCnt" /> | 46 | <Column title="在库已锁(个)" dataIndex="storageLockedCnt" /> |
47 | - <Column title="滚动90天出库(个)" dataIndex="outStockCnt" /> | 47 | + <Column title="滚动90天出库(个)" render={r => (r.outStockCnt ? <a onClick={() => { setOutVisible(true); setItem(r); }}>{r.outStockCnt}</a> : r.outStockCnt)} /> |
48 | {showAnalyse && ( | 48 | {showAnalyse && ( |
49 | <> | 49 | <> |
50 | <Column | 50 | <Column |
src/pages/pms/partPlan/PlanPool/components/StoragePartTable.tsx
@@ -12,11 +12,11 @@ interface Props { | @@ -12,11 +12,11 @@ interface Props { | ||
12 | type?: number, // 类型1区域库2库房3车系4车型5配件 | 12 | type?: number, // 类型1区域库2库房3车系4车型5配件 |
13 | } | 13 | } |
14 | export default function Index(props: Props = {}) { | 14 | export default function Index(props: Props = {}) { |
15 | - const { dfParams, key } = useStore(); | 15 | + const { dfParams, key, setItem, setOutVisible, setCustVisible } = useStore(); |
16 | const [form] = Form.useForm(); | 16 | const [form] = Form.useForm(); |
17 | const { data: parts, setParams, loading } = useInitial(getList, [], dfParams); | 17 | const { data: parts, setParams, loading } = useInitial(getList, [], dfParams); |
18 | const [visible, setVisible] = useState(false); | 18 | const [visible, setVisible] = useState(false); |
19 | - const [item, setItem] = useState<ListVO>(); | 19 | + const [itemPrice, setItemPrice] = useState<ListVO>(); |
20 | 20 | ||
21 | useEffect(() => { | 21 | useEffect(() => { |
22 | if (key == props.type) { | 22 | if (key == props.type) { |
@@ -25,8 +25,8 @@ export default function Index(props: Props = {}) { | @@ -25,8 +25,8 @@ export default function Index(props: Props = {}) { | ||
25 | }, [dfParams, key]); | 25 | }, [dfParams, key]); |
26 | 26 | ||
27 | useEffect(() => { | 27 | useEffect(() => { |
28 | - if (visible && item?.poolId) { | ||
29 | - form.setFieldsValue({cnt: item.cnt}); | 28 | + if (visible && itemPrice?.poolId) { |
29 | + form.setFieldsValue({ cnt: itemPrice.cnt}); | ||
30 | } else { | 30 | } else { |
31 | form.resetFields; | 31 | form.resetFields; |
32 | } | 32 | } |
@@ -43,7 +43,7 @@ export default function Index(props: Props = {}) { | @@ -43,7 +43,7 @@ export default function Index(props: Props = {}) { | ||
43 | fixed="left" | 43 | fixed="left" |
44 | render={r => ( | 44 | render={r => ( |
45 | <> | 45 | <> |
46 | - <a onClick={() => { setVisible(true); setItem(r); }}>编辑</a> | 46 | + <a onClick={() => { setVisible(true); setItemPrice(r); }}>编辑</a> |
47 | <Divider type="vertical" /> | 47 | <Divider type="vertical" /> |
48 | <Popconfirm | 48 | <Popconfirm |
49 | title="确认删除?" | 49 | title="确认删除?" |
@@ -68,12 +68,12 @@ export default function Index(props: Props = {}) { | @@ -68,12 +68,12 @@ export default function Index(props: Props = {}) { | ||
68 | <Column title="计划后库销比" dataIndex="planeRatio" render={t => (t || 0).toFixed(2)} /> | 68 | <Column title="计划后库销比" dataIndex="planeRatio" render={t => (t || 0).toFixed(2)} /> |
69 | 69 | ||
70 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> | 70 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> |
71 | - <Column title="客户订件数量(个)" dataIndex="buyCnt" /> | 71 | + <Column title="客户订件数量(个)" render={r => (r.buyCnt ? <a onClick={() => { setCustVisible(true); setItem(r); }}>{r.buyCnt}</a> : r.buyCnt)} /> |
72 | <Column title="客户订件金额(元)" dataIndex="buyAmount" /> | 72 | <Column title="客户订件金额(元)" dataIndex="buyAmount" /> |
73 | <Column title="在途未锁(个)" dataIndex="onTheWayUnlockCnt" /> | 73 | <Column title="在途未锁(个)" dataIndex="onTheWayUnlockCnt" /> |
74 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> | 74 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> |
75 | <Column title="在库已锁(个)" dataIndex="storageLockedCnt" /> | 75 | <Column title="在库已锁(个)" dataIndex="storageLockedCnt" /> |
76 | - <Column title="滚动90天出库(个)" dataIndex="outStockCnt" /> | 76 | + <Column title="滚动90天出库(个)" render={r => (r.outStockCnt ? <a onClick={() => { setOutVisible(true); setItem(r); }}>{r.outStockCnt}</a> : r.outStockCnt)} /> |
77 | 77 | ||
78 | </Table> | 78 | </Table> |
79 | <Modal | 79 | <Modal |
@@ -90,7 +90,7 @@ export default function Index(props: Props = {}) { | @@ -90,7 +90,7 @@ export default function Index(props: Props = {}) { | ||
90 | htmlType="submit" | 90 | htmlType="submit" |
91 | onClick={() => { | 91 | onClick={() => { |
92 | form.validateFields().then(fields => { | 92 | form.validateFields().then(fields => { |
93 | - editApi({poolId: item?.poolId, partCnt: fields.cnt}).then(res => { | 93 | + editApi({ poolId: itemPrice?.poolId, partCnt: fields.cnt}).then(res => { |
94 | setVisible(false); | 94 | setVisible(false); |
95 | message.success("操作成功"); | 95 | message.success("操作成功"); |
96 | setParams({}, true); | 96 | setParams({}, true); |
src/pages/pms/partPlan/PlanPool/components/StorageTable.tsx
@@ -14,7 +14,7 @@ interface Props { | @@ -14,7 +14,7 @@ interface Props { | ||
14 | id?: number, // 上一个列表ID | 14 | id?: number, // 上一个列表ID |
15 | } | 15 | } |
16 | export default function Index(props: Props = {}) { | 16 | export default function Index(props: Props = {}) { |
17 | - const { dfParams, key } = useStore(); | 17 | + const { dfParams, key, setItem, setOutVisible, setCustVisible } = useStore(); |
18 | const {showAnalyse=true} = props; | 18 | const {showAnalyse=true} = props; |
19 | const { data: parts, setParams, loading } = useInitial(getList, [], {...dfParams, ...props}); | 19 | const { data: parts, setParams, loading } = useInitial(getList, [], {...dfParams, ...props}); |
20 | const [visible, setVisible] = useState(false); | 20 | const [visible, setVisible] = useState(false); |
@@ -37,12 +37,12 @@ export default function Index(props: Props = {}) { | @@ -37,12 +37,12 @@ export default function Index(props: Props = {}) { | ||
37 | <Column title="计划后库销比" dataIndex="planeRatio" render={t => (t || 0).toFixed(2)} /> | 37 | <Column title="计划后库销比" dataIndex="planeRatio" render={t => (t || 0).toFixed(2)} /> |
38 | 38 | ||
39 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> | 39 | <Column title="本次计划金额(元)" dataIndex="thisTimeAmount" /> |
40 | - <Column title="客户订件数量(个)" dataIndex="buyCnt" /> | 40 | + <Column title="客户订件数量(个)" render={r => (r.buyCnt ? <a onClick={() => { setCustVisible(true); setItem(r); }}>{r.buyCnt}</a> : r.buyCnt)} /> |
41 | <Column title="客户订件金额(元)" dataIndex="buyAmount" /> | 41 | <Column title="客户订件金额(元)" dataIndex="buyAmount" /> |
42 | <Column title="在途未锁(个)" dataIndex="onTheWayUnlockCnt" /> | 42 | <Column title="在途未锁(个)" dataIndex="onTheWayUnlockCnt" /> |
43 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> | 43 | <Column title="在库未锁(个)" dataIndex="storageUnlockCnt" /> |
44 | <Column title="在库已锁(个)" dataIndex="storageLockedCnt" /> | 44 | <Column title="在库已锁(个)" dataIndex="storageLockedCnt" /> |
45 | - <Column title="滚动90天出库(个)" dataIndex="outStockCnt" /> | 45 | + <Column title="滚动90天出库(个)" render={r => (r.outStockCnt ? <a onClick={() => { setOutVisible(true); setItem(r); }}>{r.outStockCnt}</a> : r.outStockCnt)} /> |
46 | {showAnalyse && ( | 46 | {showAnalyse && ( |
47 | <> | 47 | <> |
48 | <Column | 48 | <Column |
src/pages/pms/partPlan/PlanPool/index.tsx
@@ -11,6 +11,8 @@ import st from "@/pages/pms/partPlan/PlanShipping/style.less"; | @@ -11,6 +11,8 @@ import st from "@/pages/pms/partPlan/PlanShipping/style.less"; | ||
11 | import Filter from './components/Filter'; | 11 | import Filter from './components/Filter'; |
12 | import {createStore} from "@/hooks/moz"; | 12 | import {createStore} from "@/hooks/moz"; |
13 | import store from "./useStore"; | 13 | import store from "./useStore"; |
14 | +import OutFlowModal from './components/OutFlowModal'; | ||
15 | +import CustBuyModal from './components/CustBuyModal'; | ||
14 | 16 | ||
15 | export const { Provider, useStore } = createStore(store); | 17 | export const { Provider, useStore } = createStore(store); |
16 | 18 | ||
@@ -38,6 +40,8 @@ function Index() { | @@ -38,6 +40,8 @@ function Index() { | ||
38 | <StoragePartTable type={6} /> | 40 | <StoragePartTable type={6} /> |
39 | </Tabs.TabPane> | 41 | </Tabs.TabPane> |
40 | </Tabs> | 42 | </Tabs> |
43 | + <OutFlowModal /> | ||
44 | + <CustBuyModal /> | ||
41 | </Card> | 45 | </Card> |
42 | </ConfigProvider> | 46 | </ConfigProvider> |
43 | </PageHeaderWrapper> | 47 | </PageHeaderWrapper> |
src/pages/pms/partPlan/PlanPool/useStore.ts
1 | import { useState } from 'react'; | 1 | import { useState } from 'react'; |
2 | import useInitail from "@/hooks/useInitail"; | 2 | import useInitail from "@/hooks/useInitail"; |
3 | import { getPartTypeApi } from '@/pages/pms/part/Repertory/api'; | 3 | import { getPartTypeApi } from '@/pages/pms/part/Repertory/api'; |
4 | +import {ListVO} from './api'; | ||
4 | 5 | ||
5 | export default function useStore() { | 6 | export default function useStore() { |
6 | const [dfParams, setDfParams] = useState<any>({}); | 7 | const [dfParams, setDfParams] = useState<any>({}); |
7 | const [key, setKey] = useState<any>('1'); | 8 | const [key, setKey] = useState<any>('1'); |
8 | const { data: partTypeData } = useInitail(getPartTypeApi, [], {}); | 9 | const { data: partTypeData } = useInitail(getPartTypeApi, [], {}); |
10 | + const [outVisible, setOutVisible] = useState(false); | ||
11 | + const [custVisible, setCustVisible] = useState(false); | ||
12 | + const [item, setItem] = useState<ListVO>(); | ||
9 | 13 | ||
10 | return { | 14 | return { |
11 | dfParams, | 15 | dfParams, |
12 | setDfParams, | 16 | setDfParams, |
13 | key, | 17 | key, |
14 | setKey, | 18 | setKey, |
15 | - partTypeData | 19 | + partTypeData, |
20 | + outVisible, | ||
21 | + setOutVisible, | ||
22 | + item, | ||
23 | + setItem, | ||
24 | + custVisible, | ||
25 | + setCustVisible, | ||
16 | }; | 26 | }; |
17 | } | 27 | } |
src/pages/pms/storage/partShop/api.ts
@@ -42,6 +42,12 @@ export function getLockDetail(params?: PmsStoragePartShop.LockParams): http.Prom | @@ -42,6 +42,12 @@ export function getLockDetail(params?: PmsStoragePartShop.LockParams): http.Prom | ||
42 | export function getFlowDetail(params?: PmsStoragePartShop.FlowParams): http.PromisePageResp<PmsStoragePartShop.FlowVO> { | 42 | export function getFlowDetail(params?: PmsStoragePartShop.FlowParams): http.PromisePageResp<PmsStoragePartShop.FlowVO> { |
43 | return request.get(`${PMS_HOST}/erp/part/shop/get/record`, { params }); | 43 | return request.get(`${PMS_HOST}/erp/part/shop/get/record`, { params }); |
44 | } | 44 | } |
45 | +/** | ||
46 | + * 查询门店备件锁库流水明细列表 | ||
47 | + */ | ||
48 | +export function getLockFlowDetail(params?: PmsStoragePartShop.FlowParams): http.PromisePageResp<PmsStoragePartShop.FlowVO> { | ||
49 | + return request.get(`${PMS_HOST}/erp/part/shop/get/lock/record`, { params }); | ||
50 | +} | ||
45 | // 释放库存 | 51 | // 释放库存 |
46 | export function unLock(params: PmsStoragePartShop.unLock): http.PromiseResp<string> { | 52 | export function unLock(params: PmsStoragePartShop.unLock): http.PromiseResp<string> { |
47 | return request.post(`${PMS_HOST}/erp/part/shop/cancel/lock`, { ...params }, { contentType: "form-urlencoded" }); | 53 | return request.post(`${PMS_HOST}/erp/part/shop/cancel/lock`, { ...params }, { contentType: "form-urlencoded" }); |
src/pages/pms/storage/partShop/components/Filter.tsx
@@ -32,14 +32,14 @@ export default function Filter() { | @@ -32,14 +32,14 @@ export default function Filter() { | ||
32 | return ( | 32 | return ( |
33 | <div> | 33 | <div> |
34 | <Search | 34 | <Search |
35 | - style={{ width: 200, marginRight: 10 }} | 35 | + style={{ width: 180, marginRight: 10, marginBottom: 10 }} |
36 | allowClear | 36 | allowClear |
37 | enterButton | 37 | enterButton |
38 | placeholder="配件编码|名称" | 38 | placeholder="配件编码|名称" |
39 | onSearch={v => handleChangeKeywords(v)} | 39 | onSearch={v => handleChangeKeywords(v)} |
40 | /> | 40 | /> |
41 | <PmsSelect | 41 | <PmsSelect |
42 | - style={{ width: 180, marginRight: 10}} | 42 | + style={{ width: 180, marginRight: 10, marginBottom: 10 }} |
43 | allowClear | 43 | allowClear |
44 | value={innerParams.shopId} | 44 | value={innerParams.shopId} |
45 | onChange={value => { | 45 | onChange={value => { |
@@ -52,7 +52,7 @@ export default function Filter() { | @@ -52,7 +52,7 @@ export default function Filter() { | ||
52 | .map((item: PmsStoragePartShop.Option) => ({value: item.id, label: item.name}))} | 52 | .map((item: PmsStoragePartShop.Option) => ({value: item.id, label: item.name}))} |
53 | /> | 53 | /> |
54 | <PmsSelect | 54 | <PmsSelect |
55 | - style={{ width: 150, marginRight: 10}} | 55 | + style={{ width: 180, marginRight: 10, marginBottom: 10 }} |
56 | allowClear | 56 | allowClear |
57 | value={innerParams.storageId} | 57 | value={innerParams.storageId} |
58 | onChange={value => { | 58 | onChange={value => { |
@@ -66,7 +66,7 @@ export default function Filter() { | @@ -66,7 +66,7 @@ export default function Filter() { | ||
66 | /> | 66 | /> |
67 | <PmsSelect | 67 | <PmsSelect |
68 | allowClear | 68 | allowClear |
69 | - style={{ width: 150, marginRight: 10}} | 69 | + style={{ width: 180, marginRight: 10, marginBottom: 10 }} |
70 | onChange={(type) => { | 70 | onChange={(type) => { |
71 | setParams({ ...innerParams, current: 1, type }, true); | 71 | setParams({ ...innerParams, current: 1, type }, true); |
72 | }} | 72 | }} |
@@ -77,7 +77,7 @@ export default function Filter() { | @@ -77,7 +77,7 @@ export default function Filter() { | ||
77 | allowClear | 77 | allowClear |
78 | placeholder="有无库存筛选" | 78 | placeholder="有无库存筛选" |
79 | onChange={v => isStock(v)} | 79 | onChange={v => isStock(v)} |
80 | - style={{ width: 150, marginRight: 10 }} | 80 | + style={{ width: 180, marginRight: 10, marginBottom: 10 }} |
81 | options={[ | 81 | options={[ |
82 | {value: 1, label: "有库存"}, | 82 | {value: 1, label: "有库存"}, |
83 | {value: 0, label: "无库存"}, | 83 | {value: 0, label: "无库存"}, |
@@ -87,7 +87,7 @@ export default function Filter() { | @@ -87,7 +87,7 @@ export default function Filter() { | ||
87 | placeholder="排序方式" | 87 | placeholder="排序方式" |
88 | defaultValue={18} | 88 | defaultValue={18} |
89 | onChange={v => isSorter(v)} | 89 | onChange={v => isSorter(v)} |
90 | - style={{ width: 150 }} | 90 | + style={{ width: 180 }} |
91 | options={[ | 91 | options={[ |
92 | {value: 18, label: "总库存降序"}, | 92 | {value: 18, label: "总库存降序"}, |
93 | {value: 21, label: "锁定库存降序"}, | 93 | {value: 21, label: "锁定库存降序"}, |
src/pages/pms/storage/partShop/components/List.tsx
@@ -4,6 +4,7 @@ import { useStore } from '../index'; | @@ -4,6 +4,7 @@ import { useStore } from '../index'; | ||
4 | import LockDetailModal from './LockDetailModal'; | 4 | import LockDetailModal from './LockDetailModal'; |
5 | import FlowDetailModal from './FlowDetailModal'; | 5 | import FlowDetailModal from './FlowDetailModal'; |
6 | import PartShopModal from './PartShopModal'; | 6 | import PartShopModal from './PartShopModal'; |
7 | +import LockFlowModal from './LockFlowModal'; | ||
7 | 8 | ||
8 | const { Column } = Table; | 9 | const { Column } = Table; |
9 | 10 | ||
@@ -11,6 +12,7 @@ export default function Filter() { | @@ -11,6 +12,7 @@ export default function Filter() { | ||
11 | const { setParams, loading, paginationConfig, list, setVisible, setItem, item, fw, setIsprice} = useStore(); | 12 | const { setParams, loading, paginationConfig, list, setVisible, setItem, item, fw, setIsprice} = useStore(); |
12 | const [visibleLockDetail, setVisibleLockDetail] = useState(false); | 13 | const [visibleLockDetail, setVisibleLockDetail] = useState(false); |
13 | const [visibleFlowDetail, setVisibleFlowDetail] = useState(false); | 14 | const [visibleFlowDetail, setVisibleFlowDetail] = useState(false); |
15 | + const [visibleLockFlow, setVisibleLockFlow] = useState(false); | ||
14 | 16 | ||
15 | return ( | 17 | return ( |
16 | <div> | 18 | <div> |
@@ -43,6 +45,14 @@ export default function Filter() { | @@ -43,6 +45,14 @@ export default function Filter() { | ||
43 | title="入库流水" | 45 | title="入库流水" |
44 | render={(t, it: PartRepertorySpace.Item) => <a onClick={() => { setVisibleFlowDetail(true); setItem({...it, isOut: false}); }}>查看</a>} | 46 | render={(t, it: PartRepertorySpace.Item) => <a onClick={() => { setVisibleFlowDetail(true); setItem({...it, isOut: false}); }}>查看</a>} |
45 | /> | 47 | /> |
48 | + <Column | ||
49 | + title="锁库流水" | ||
50 | + render={(t, it: PartRepertorySpace.Item) => <a onClick={() => { setVisibleLockFlow(true); setItem({...it, isLock: true}); }}>查看</a>} | ||
51 | + /> | ||
52 | + <Column | ||
53 | + title="释放流水" | ||
54 | + render={(t, it: PartRepertorySpace.Item) => <a onClick={() => { setVisibleLockFlow(true); setItem({...it, isLock: false}); }}>查看</a>} | ||
55 | + /> | ||
46 | {fw ? ( | 56 | {fw ? ( |
47 | <Column | 57 | <Column |
48 | title="操作" | 58 | title="操作" |
@@ -65,6 +75,7 @@ export default function Filter() { | @@ -65,6 +75,7 @@ export default function Filter() { | ||
65 | </Table> | 75 | </Table> |
66 | <LockDetailModal item={item} visible={visibleLockDetail} onCancel={() => setVisibleLockDetail(false)} /> | 76 | <LockDetailModal item={item} visible={visibleLockDetail} onCancel={() => setVisibleLockDetail(false)} /> |
67 | <FlowDetailModal item={item} visible={visibleFlowDetail} onCancel={() => setVisibleFlowDetail(false)} /> | 77 | <FlowDetailModal item={item} visible={visibleFlowDetail} onCancel={() => setVisibleFlowDetail(false)} /> |
78 | + <LockFlowModal item={item} visible={visibleLockFlow} onCancel={() => setVisibleLockFlow(false)} /> | ||
68 | <PartShopModal /> | 79 | <PartShopModal /> |
69 | </div> | 80 | </div> |
70 | ); | 81 | ); |
src/pages/pms/storage/partShop/components/LockFlowModal.tsx
0 → 100644
1 | +import React, {useEffect, useState} from 'react'; | ||
2 | +import {Modal, Table, Button} from 'antd'; | ||
3 | +import { getLockFlowDetail } from '@/pages/pms/storage/partShop/api'; | ||
4 | +import usePagination from '@/hooks/usePagination'; | ||
5 | + | ||
6 | +interface Props { | ||
7 | + item?: any | ||
8 | + visible: boolean | ||
9 | + onCancel: () => any | ||
10 | +} | ||
11 | +const {Column} = Table; | ||
12 | +export default function Index(props: Props) { | ||
13 | + const {item, visible, onCancel} = props; | ||
14 | + const [delay, setDelay] = useState(true); | ||
15 | + const { list, loading, setParams, paginationConfig, setList } = usePagination<PmsStoragePartShop.FlowVO>(getLockFlowDetail, {}, { delay }); | ||
16 | + | ||
17 | + useEffect(() => { | ||
18 | + if (item.shopId && item.partId && visible) { | ||
19 | + setParams({ partId: item.partId, shopId: item.shopId, isLock: item.isLock }, true); | ||
20 | + setDelay(false); | ||
21 | + } else { | ||
22 | + setList([]); | ||
23 | + } | ||
24 | + }, [visible, item.partId]); | ||
25 | + | ||
26 | + return ( | ||
27 | + <Modal | ||
28 | + title={`${item.isLock ? '锁定库存' : '释放库存'}流水`} | ||
29 | + width={1000} | ||
30 | + visible={visible} | ||
31 | + maskClosable={false} | ||
32 | + onCancel={onCancel} | ||
33 | + footer={[ | ||
34 | + <Button key="1" onClick={onCancel}>取消</Button>, | ||
35 | + ]} | ||
36 | + > | ||
37 | + <Table | ||
38 | + loading={loading} | ||
39 | + dataSource={list} | ||
40 | + rowKey={(v: PmsStoragePartShop.FlowVO) => `${v.type}_${v.typeId}`} | ||
41 | + pagination={paginationConfig} | ||
42 | + > | ||
43 | + <Column title="配件数量" dataIndex="partCnt" /> | ||
44 | + <Column title="单号" dataIndex="remark" render={t => t || "--"} /> | ||
45 | + <Column | ||
46 | + title="详情" | ||
47 | + dataIndex="text" | ||
48 | + width={350} | ||
49 | + render={(t: string, it: PmsStoragePartShop.FlowVO) => { | ||
50 | + const obj = JSON.parse(t || '{}'); | ||
51 | + return ( | ||
52 | + <div> | ||
53 | + {!!obj.type && <div>{`类型: ${obj.type}`}</div>} | ||
54 | + {!!obj.serviceCatName && <div>{`进站类型: ${obj.serviceCatName}`}</div>} | ||
55 | + {!!obj.exclusiveAdviser && <div>{`专属顾问: ${obj.exclusiveAdviser}`}</div>} | ||
56 | + {!!obj.shopLinkmanName && <div>{`服务顾问: ${obj.shopLinkmanName}`}</div>} | ||
57 | + {!!obj.receiverName && <div>{`服务顾问: ${obj.receiverName}`}</div>} | ||
58 | + {!!obj.plateNo && <div>{`车牌号: ${obj.plateNo}`}</div>} | ||
59 | + {!!obj.ownerName && <div>{`车主: ${obj.ownerName}`}</div>} | ||
60 | + {!!obj.vin && <div>{`VIN: ${obj.vin}`}</div>} | ||
61 | + {!!obj.userName && <div>{`操作账号: ${obj.userName}`}</div>} | ||
62 | + {!!obj.fixRemark && <div>{`备注: ${obj.fixRemark}`}</div>} | ||
63 | + </div> | ||
64 | + ); | ||
65 | + }} | ||
66 | + /> | ||
67 | + <Column title={`${item.isLock ? '锁库' : '释放'}时间`} dataIndex="recordTime" /> | ||
68 | + </Table> | ||
69 | + </Modal> | ||
70 | + ); | ||
71 | +} | ||
0 | \ No newline at end of file | 72 | \ No newline at end of file |
src/pages/pms/storage/partShop/index.tsx
1 | import React, {useState} from 'react'; | 1 | import React, {useState} from 'react'; |
2 | -import { PlusOutlined, VerticalAlignBottomOutlined } from '@ant-design/icons'; | 2 | +import { PlusOutlined, DownloadOutlined, UploadOutlined } from '@ant-design/icons'; |
3 | import { Card, Button } from 'antd'; | 3 | import { Card, Button } from 'antd'; |
4 | import { PageHeaderWrapper } from '@ant-design/pro-layout'; | 4 | import { PageHeaderWrapper } from '@ant-design/pro-layout'; |
5 | import Filter from './components/Filter'; | 5 | import Filter from './components/Filter'; |
@@ -20,53 +20,51 @@ function PartShop() { | @@ -20,53 +20,51 @@ function PartShop() { | ||
20 | return ( | 20 | return ( |
21 | <PageHeaderWrapper title={`服务站配件${fw ? '(霏微)': ''}`}> | 21 | <PageHeaderWrapper title={`服务站配件${fw ? '(霏微)': ''}`}> |
22 | <Card> | 22 | <Card> |
23 | - <div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}> | 23 | + <div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 20 }}> |
24 | <Filter /> | 24 | <Filter /> |
25 | - <div style={{display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center'}}> | 25 | + <div style={{ display: 'flex', alignItems: 'center'}}> |
26 | + <Button | ||
27 | + type="primary" | ||
28 | + icon={<PlusOutlined />} | ||
29 | + onClick={() => { setVisible(true); setIsadd(true); }} | ||
30 | + > | ||
31 | + 新增 | ||
32 | + </Button> | ||
26 | {fw && ( | 33 | {fw && ( |
27 | - <> | ||
28 | - <Button | ||
29 | - icon={(<PlusOutlined />)} | ||
30 | - type="primary" | ||
31 | - onClick={() => setImportVisible(true)} | ||
32 | - > | ||
33 | - 导入 | ||
34 | - </Button> | ||
35 | - <Button | ||
36 | - icon={(<PlusOutlined />)} | ||
37 | - type="primary" | ||
38 | - onClick={() => { setImportVisible(true); setStock(true); }} | ||
39 | - style={{marginLeft: 10}} | ||
40 | - > | ||
41 | - 调运库存导入 | ||
42 | - </Button> | ||
43 | - </> | ||
44 | - )} | ||
45 | - {/* {!fw && ( */} | ||
46 | <Button | 34 | <Button |
35 | + icon={<UploadOutlined />} | ||
47 | type="primary" | 36 | type="primary" |
48 | - icon={<VerticalAlignBottomOutlined />} | ||
49 | - onClick={() => { setMore(true); setIslock(true); }} | 37 | + onClick={() => setImportVisible(true)} |
38 | + style={{ marginLeft: 10 }} | ||
39 | + > | ||
40 | + 导入 | ||
41 | + </Button> | ||
42 | + )} | ||
43 | + {fw && ( | ||
44 | + <Button | ||
45 | + icon={<UploadOutlined />} | ||
46 | + type="primary" | ||
47 | + onClick={() => { setImportVisible(true); setStock(true); }} | ||
50 | style={{marginLeft: 10}} | 48 | style={{marginLeft: 10}} |
51 | > | 49 | > |
52 | - 锁件批量导出 | 50 | + 调运库存导入 |
53 | </Button> | 51 | </Button> |
54 | - {/* )} */} | 52 | + )} |
55 | <Button | 53 | <Button |
56 | type="primary" | 54 | type="primary" |
57 | - icon={<VerticalAlignBottomOutlined />} | ||
58 | - onClick={() => setMore(true)} | 55 | + icon={<DownloadOutlined />} |
56 | + onClick={() => { setMore(true); setIslock(true); }} | ||
59 | style={{marginLeft: 10}} | 57 | style={{marginLeft: 10}} |
60 | > | 58 | > |
61 | - 库存批量导出 | 59 | + 锁件批量导出 |
62 | </Button> | 60 | </Button> |
63 | <Button | 61 | <Button |
64 | type="primary" | 62 | type="primary" |
65 | - icon={<PlusOutlined />} | ||
66 | - onClick={() => { setVisible(true); setIsadd(true); }} | ||
67 | - style={{ marginLeft: 10}} | 63 | + icon={<DownloadOutlined />} |
64 | + onClick={() => setMore(true)} | ||
65 | + style={{marginLeft: 10}} | ||
68 | > | 66 | > |
69 | - 新增 | 67 | + 库存批量导出 |
70 | </Button> | 68 | </Button> |
71 | </div> | 69 | </div> |
72 | </div> | 70 | </div> |
src/pages/pms/storage/partShop/interface.d.ts
@@ -21,7 +21,8 @@ declare namespace PmsStoragePartShop { | @@ -21,7 +21,8 @@ declare namespace PmsStoragePartShop { | ||
21 | actualStock?: number, | 21 | actualStock?: number, |
22 | shopId?: number, // 服务站ID | 22 | shopId?: number, // 服务站ID |
23 | shopName?: string // 服务站名称 | 23 | shopName?: string // 服务站名称 |
24 | - isOut?: boolean | 24 | + isOut?: boolean, |
25 | + isLock?:boolean | ||
25 | } | 26 | } |
26 | 27 | ||
27 | interface Params { | 28 | interface Params { |
@@ -77,6 +78,7 @@ declare namespace PmsStoragePartShop { | @@ -77,6 +78,7 @@ declare namespace PmsStoragePartShop { | ||
77 | isOut?: boolean, // 出入库 | 78 | isOut?: boolean, // 出入库 |
78 | current?: number | 79 | current?: number |
79 | pageSize?:number | 80 | pageSize?:number |
81 | + isLock?:boolean // 锁库 ?释放 | ||
80 | } | 82 | } |
81 | 83 | ||
82 | /** | 84 | /** |
src/pages/pms/transfer/HuolalaSetting/api.ts
0 → 100644
1 | +import { http } from '@/typing/http'; | ||
2 | +import request from '@/utils/request'; | ||
3 | +import { PMS_HOST, HOST } from '@/utils/host'; | ||
4 | + | ||
5 | +export interface ListVO{ | ||
6 | + /** | ||
7 | + * 财务账户信息id | ||
8 | + */ | ||
9 | + id?:number | ||
10 | + /** | ||
11 | + * 往来单位id | ||
12 | + */ | ||
13 | + supplierId?:number | ||
14 | + /** | ||
15 | + * 往来单位名称 | ||
16 | + */ | ||
17 | + supplierName?:string | ||
18 | + /** | ||
19 | + * 签约门店id | ||
20 | + */ | ||
21 | + shopId?:number | ||
22 | + /** | ||
23 | + * 签约门店名称 | ||
24 | + */ | ||
25 | + shopName?:string; | ||
26 | + /** | ||
27 | + * 当前余额 | ||
28 | + */ | ||
29 | + amount?:number; | ||
30 | + /** | ||
31 | + * 待到账金额 | ||
32 | + */ | ||
33 | + awaitAmount?:number; | ||
34 | + /** | ||
35 | + * 低余额推待办 | ||
36 | + */ | ||
37 | + minAmount?:number; | ||
38 | + /** | ||
39 | + * 推待办角色编码 | ||
40 | + */ | ||
41 | + roleCode?:string; | ||
42 | + /** | ||
43 | + * 推待办角色名称 | ||
44 | + */ | ||
45 | + roleName?:string; | ||
46 | + /** | ||
47 | + * 发单账号 | ||
48 | + */ | ||
49 | + account?:string; | ||
50 | + /** | ||
51 | + * 集团id | ||
52 | + */ | ||
53 | + groupId?:number; | ||
54 | + /** | ||
55 | + * 创建时间 | ||
56 | + */ | ||
57 | + time?:string; | ||
58 | +} | ||
59 | +interface Params{ | ||
60 | + current?:number, | ||
61 | + pageSize?:number | ||
62 | +} | ||
63 | +export interface saveParams{ | ||
64 | + //财务账户信息id | ||
65 | + id?:number; | ||
66 | + /** | ||
67 | + * 往来单位id | ||
68 | + */ | ||
69 | + supplierId?:number; | ||
70 | + /** | ||
71 | + * 往来单位名称 | ||
72 | + */ | ||
73 | + supplierName?:string; | ||
74 | + /** | ||
75 | + * 签约门店id | ||
76 | + */ | ||
77 | + shopId?:number; | ||
78 | + /** | ||
79 | + * 低余额推待办 | ||
80 | + */ | ||
81 | + minAmount?:number; | ||
82 | + /** | ||
83 | + * 推待办角色编码 | ||
84 | + */ | ||
85 | + roleCode?:string; | ||
86 | + /** | ||
87 | + * 推待办角色名称 | ||
88 | + */ | ||
89 | + roleName?:string; | ||
90 | + /** | ||
91 | + * 发单账号 | ||
92 | + */ | ||
93 | + // @NotBlank(message = "发单账号不能为空") | ||
94 | + account?:string; | ||
95 | +} | ||
96 | +interface queryList { | ||
97 | + current?:number | ||
98 | + pageSize?:number | ||
99 | + sysId?:number | ||
100 | +} | ||
101 | +// 查询财务账户信息列表 | ||
102 | +export function getList(params: Params):http.PromisePageResp<ListVO> { | ||
103 | + return request.get(`${PMS_HOST}/erp/finance/account/get/page`, {params}); | ||
104 | +} | ||
105 | +// 新增/编辑API | ||
106 | +export function saveApi(params: saveParams) { | ||
107 | + return request.post(`${PMS_HOST}/erp/finance/account/exit`, {...params}); | ||
108 | +} | ||
109 | +// 推待办角色列表 | ||
110 | +export function roleListApi(params: queryList): http.PromisePageResp<Role.Info> { | ||
111 | + return request.get(`${HOST}/role/list`, { params }); | ||
112 | +} | ||
113 | +// 删除API | ||
114 | +export function deleteApi(params: {id: number}) { | ||
115 | + return request.post(`${PMS_HOST}/erp/finance/account/delete`, {...params}); | ||
116 | +} | ||
0 | \ No newline at end of file | 117 | \ No newline at end of file |
src/pages/pms/transfer/HuolalaSetting/components/AddModal.tsx
0 → 100644
1 | +import React, { useEffect, useState } from 'react'; | ||
2 | +import {Form, Button, InputNumber, Modal, message, Input } from 'antd'; | ||
3 | +import PmsSelect from '@/pages/pms/comonents/PmsSelect'; | ||
4 | +import { ListVO, saveApi, roleListApi } from '../api'; | ||
5 | +import { getPageListApi, Item as item } from "@/pages/pms/partPlan/PlanSupplier/api"; | ||
6 | +import {getShopApi} from '@/pages/pms/storage/partShop/api'; | ||
7 | +import usePagination from '@/hooks/usePagination'; | ||
8 | +import useInitail from '@/hooks/useInitail'; | ||
9 | + | ||
10 | +const Item = Form.Item; | ||
11 | + | ||
12 | +interface Props{ | ||
13 | + visible?:boolean, | ||
14 | + onCancel: Function, | ||
15 | + item?:ListVO | ||
16 | +} | ||
17 | + | ||
18 | +export default function Index(props:Props) { | ||
19 | + const { list: suppliers } = usePagination<item>(getPageListApi, { supplierType: 40, pageSize: 500 }); | ||
20 | + const { data: shops } = useInitail<PmsStoragePartShop.Option[], {}>(getShopApi, [], {}); | ||
21 | + const { list } = usePagination<Role.Info>(roleListApi, { pageSize: 500, sysId: 229 }); | ||
22 | + const [loading, setLoading] = useState(false); | ||
23 | + const { visible, onCancel, item } = props; | ||
24 | + const [form] = Form.useForm(); | ||
25 | + | ||
26 | + useEffect(() => { | ||
27 | + if (visible && item?.id) { | ||
28 | + form.setFieldsValue({ | ||
29 | + supplierId: item.supplierId, | ||
30 | + shopId: item.shopId, | ||
31 | + minAmount: item.minAmount, | ||
32 | + roleCode: item.roleCode, | ||
33 | + account: item.account | ||
34 | + }); | ||
35 | + } | ||
36 | + if (!visible) { | ||
37 | + form.resetFields(); | ||
38 | + } | ||
39 | + }, [visible]); | ||
40 | + | ||
41 | + const onSave = () => { | ||
42 | + form.validateFields().then(files => { | ||
43 | + const params = { | ||
44 | + id: item?.id, | ||
45 | + supplierId: files.supplierId, | ||
46 | + supplierName: suppliers.find(i => i.supplierId == files.supplierId)?.supplierName, | ||
47 | + shopId: files.shopId, | ||
48 | + minAmount: files.minAmount, | ||
49 | + roleCode: files.roleCode, | ||
50 | + roleName: list.find(i => i.roleCode == files.roleCode)?.roleName, | ||
51 | + account: files.account | ||
52 | + }; | ||
53 | + setLoading(true); | ||
54 | + saveApi(params).then(res => { | ||
55 | + message.success("保存成功"); | ||
56 | + setLoading(false); | ||
57 | + onCancel(); | ||
58 | + }).catch(e => { | ||
59 | + message.error(e.message); | ||
60 | + setLoading(false); | ||
61 | + }); | ||
62 | + }); | ||
63 | + }; | ||
64 | + | ||
65 | + return ( | ||
66 | + <Modal | ||
67 | + title={item?.id ? "编辑货拉拉账户配置" : "新增货拉拉账户配置"} | ||
68 | + visible={visible} | ||
69 | + maskClosable={false} | ||
70 | + onCancel={() => onCancel()} | ||
71 | + footer={[ | ||
72 | + <Button loading={loading} onClick={() => onCancel()}>取消</Button>, | ||
73 | + <Button loading={loading} type="primary" htmlType="submit" onClick={() => onSave()}>保存</Button> | ||
74 | + ]} | ||
75 | + > | ||
76 | + <Form | ||
77 | + form={form} | ||
78 | + labelCol={{span: 5}} | ||
79 | + wrapperCol={{span: 12}} | ||
80 | + > | ||
81 | + <Item label="往来单位" name="supplierId" rules={[{required: true, message: "请选择往来单位"}]}> | ||
82 | + <PmsSelect | ||
83 | + placeholder="选择往来单位" | ||
84 | + options={suppliers.filter((item, index, self) => { | ||
85 | + return self.findIndex(el => el.supplierId == item.supplierId) === index; | ||
86 | + }).map((item) => ({ value: item.supplierId, label: item.supplierName }))} | ||
87 | + /> | ||
88 | + </Item> | ||
89 | + <Item label="签约门店" name="shopId" rules={[{ required: true, message: "请选择签约门店" }]}> | ||
90 | + <PmsSelect | ||
91 | + placeholder="选择签约门店" | ||
92 | + options={shops.map((item: PmsStoragePartShop.Option) => ({ value: item.id, label: item.name }))} | ||
93 | + /> | ||
94 | + </Item> | ||
95 | + <Item label="推待办余额" name="minAmount" rules={[{ required: true, message: "请填写金额" }]}> | ||
96 | + <InputNumber style={{width: '100%'}} addonAfter="元" /> | ||
97 | + </Item> | ||
98 | + <Item label="推待办角色" name="roleCode" rules={[{ required: true, message: "请选择推办角色" }]}> | ||
99 | + <PmsSelect | ||
100 | + placeholder="选择待办角色" | ||
101 | + options={list.map(item => ({value: item.roleCode, label: item.roleName}))} | ||
102 | + /> | ||
103 | + </Item> | ||
104 | + <Item label="发单账号" name="account" rules={[{ required: true, message: "请填写发单账号" }]}> | ||
105 | + <Input /> | ||
106 | + </Item> | ||
107 | + </Form> | ||
108 | + </Modal> | ||
109 | + ); | ||
110 | +} |
src/pages/pms/transfer/HuolalaSetting/components/ChargeModal.tsx
0 → 100644
1 | +import React from 'react'; | ||
2 | +import { Form, Button, InputNumber, Modal } from 'antd'; | ||
3 | +import PmsSelect from '@/pages/pms/comonents/PmsSelect'; | ||
4 | + | ||
5 | +const Item = Form.Item; | ||
6 | + | ||
7 | +interface Props { | ||
8 | + visible?: boolean, | ||
9 | + onCancel: Function, | ||
10 | + item?: any | ||
11 | +} | ||
12 | +export default function Index(props: Props) { | ||
13 | + const { visible, onCancel, item } = props; | ||
14 | + const [form] = Form.useForm(); | ||
15 | + | ||
16 | + const onSave = () => { | ||
17 | + const params = {id: item.id}; | ||
18 | + console.log(params); | ||
19 | + }; | ||
20 | + | ||
21 | + return ( | ||
22 | + <Modal | ||
23 | + title="预付款充值申请" | ||
24 | + visible={visible} | ||
25 | + maskClosable={false} | ||
26 | + onCancel={() => onCancel()} | ||
27 | + footer={[ | ||
28 | + <Button onClick={() => onCancel()}>取消</Button>, | ||
29 | + <Button type="primary" htmlType="submit" onClick={() => onSave()}>提交申请</Button> | ||
30 | + ]} | ||
31 | + > | ||
32 | + <Form | ||
33 | + form={form} | ||
34 | + labelCol={{ span: 7 }} | ||
35 | + wrapperCol={{ span: 12 }} | ||
36 | + > | ||
37 | + <Item label="往来单位" name="supplierName" rules={[{ required: true, message: "请选择往来单位" }]}> | ||
38 | + <PmsSelect /> | ||
39 | + </Item> | ||
40 | + <Item label="往来单位类型" name="shopName" rules={[{ required: true, message: "请选择签约门店" }]}> | ||
41 | + <PmsSelect /> | ||
42 | + </Item> | ||
43 | + <Item label="账户余额" name="amount" rules={[{ required: true, message: "请填写金额" }]}> | ||
44 | + <InputNumber style={{ width: '100%' }} addonAfter="元" disabled /> | ||
45 | + </Item> | ||
46 | + <Item label="充值金额" name="awaitAmount" rules={[{ required: true, message: "请填写金额" }]}> | ||
47 | + <InputNumber style={{ width: '100%' }} addonAfter="元" /> | ||
48 | + </Item> | ||
49 | + <Item label="账户到账金额" name="awaitAmount" rules={[{ required: true, message: "请填写金额" }]}> | ||
50 | + <InputNumber style={{ width: '100%' }} addonAfter="元" disabled /> | ||
51 | + </Item> | ||
52 | + <Item label="结算门店" name="shopName" rules={[{ required: true, message: "请选择推办角色" }]}> | ||
53 | + <PmsSelect /> | ||
54 | + </Item> | ||
55 | + <Item label="发票金额要求比例" name="role" rules={[{ required: true, message: "请选择推办角色" }]}> | ||
56 | + <PmsSelect /> | ||
57 | + </Item> | ||
58 | + <Item label="结算方式" name="role" rules={[{ required: true, message: "请选择推办角色" }]}> | ||
59 | + <PmsSelect /> | ||
60 | + </Item> | ||
61 | + <Item label="附件" name="files"> | ||
62 | + <PmsSelect /> | ||
63 | + </Item> | ||
64 | + </Form> | ||
65 | + </Modal> | ||
66 | + ); | ||
67 | +} |
src/pages/pms/transfer/HuolalaSetting/index.tsx
0 → 100644
1 | +import React, { useState } from 'react'; | ||
2 | +import { Card, Button, Table, Divider, Popconfirm, message } from 'antd'; | ||
3 | +import { PageHeaderWrapper } from '@ant-design/pro-layout'; | ||
4 | +import AddModal from './components/AddModal'; | ||
5 | +import ChargeModal from './components/ChargeModal'; | ||
6 | +import {getList, ListVO, deleteApi} from './api'; | ||
7 | +import usePagination from '@/hooks/usePagination'; | ||
8 | + | ||
9 | +const Column = Table.Column; | ||
10 | +export default function Index() { | ||
11 | + const {list, loading, paginationConfig, setParams} = usePagination<ListVO>(getList, [], {}); | ||
12 | + const [current, setCurrent] = useState<{ visible: boolean, item: ListVO }>({visible: false, item: {}}); | ||
13 | + const [chargeInfo, setChargeInfo] = useState<{ visible: boolean, item: ListVO }>({visible: false, item: {}}); | ||
14 | + const data = [{id: 1, supplierName: "货拉拉", shopName: "不过承诺书可能单纯迪士尼才", amount: 3000, minAmount: 1500, roleName: "计划制定员", account: "15725173,16638183"}]; | ||
15 | + return ( | ||
16 | + <PageHeaderWrapper title="货拉拉账户配置"> | ||
17 | + <Card | ||
18 | + extra={<Button type="primary" onClick={() => setCurrent({visible: true, item: {}})}>新增</Button>} | ||
19 | + > | ||
20 | + <Table dataSource={data} rowKey="id" loading={loading} pagination={paginationConfig}> | ||
21 | + <Column title="往来单位" dataIndex="supplierName" /> | ||
22 | + <Column title="签约门店" dataIndex="shopName" /> | ||
23 | + <Column title="当前余额(元)" dataIndex="amount" /> | ||
24 | + <Column title="低余额推待办(元)" dataIndex="minAmount" /> | ||
25 | + <Column title="推待办角色" dataIndex="roleName" /> | ||
26 | + <Column title="发单账号" dataIndex="account" /> | ||
27 | + <Column | ||
28 | + title="操作" | ||
29 | + render={r => ( | ||
30 | + <div style={{display: 'flex', flexWrap: 'wrap', alignItems: 'center'}}> | ||
31 | + <a onClick={() => setChargeInfo({visible: true, item: r})}>预付款充值申请</a> | ||
32 | + <Divider type="vertical" /> | ||
33 | + <a onClick={() => setCurrent({visible: true, item: r})}>编辑</a> | ||
34 | + <Divider type="vertical" /> | ||
35 | + <Popconfirm | ||
36 | + title="确认删除" | ||
37 | + onConfirm={() => { | ||
38 | + deleteApi({id: r.id}).then(res => { | ||
39 | + message.success('操作成功'); | ||
40 | + setParams({}, true); | ||
41 | + }).catch(e => message.error(e.message)); | ||
42 | + }} | ||
43 | + > | ||
44 | + <a>删除</a> | ||
45 | + </Popconfirm> | ||
46 | + </div> | ||
47 | + )} | ||
48 | + /> | ||
49 | + </Table> | ||
50 | + <AddModal visible={current.visible} item={current.item} onCancel={() => setCurrent({ visible: false, item: {} })} /> | ||
51 | + <ChargeModal visible={chargeInfo.visible} item={chargeInfo.item} onCancel={() => setChargeInfo({ visible: false, item: {} })} /> | ||
52 | + </Card> | ||
53 | + </PageHeaderWrapper> | ||
54 | + ); | ||
55 | +} |
src/pages/pms/transfer/transferPool/comonents/Filiter.tsx
@@ -26,9 +26,9 @@ export default function Index() { | @@ -26,9 +26,9 @@ export default function Index() { | ||
26 | <Input.Search | 26 | <Input.Search |
27 | allowClear | 27 | allowClear |
28 | enterButton | 28 | enterButton |
29 | - placeholder="输入关键词进行搜索" | 29 | + placeholder="输入关键词搜索" |
30 | onSearch={(value, event) => setParams({keywords: value}, true)} | 30 | onSearch={(value, event) => setParams({keywords: value}, true)} |
31 | - style={{ width: 220, marginRight: 10 }} | 31 | + style={{ width: 200, marginRight: 10, marginBottom: 10 }} |
32 | /> | 32 | /> |
33 | <PmsSelect | 33 | <PmsSelect |
34 | style={{width: 200, marginRight: 10}} | 34 | style={{width: 200, marginRight: 10}} |