Commit 9a37442171e0a692f5f720efa992cfef901177cf
Merge remote-tracking branch 'origin/pms'
Showing
8 changed files
with
330 additions
and
7 deletions
config/routers/pms.ts
@@ -191,4 +191,12 @@ export default [ | @@ -191,4 +191,12 @@ export default [ | ||
191 | path: '/pms/setting/performanceSetting', // 绩效设置 | 191 | path: '/pms/setting/performanceSetting', // 绩效设置 |
192 | component: './pms/setting/PerformanceSetting' | 192 | component: './pms/setting/PerformanceSetting' |
193 | }, | 193 | }, |
194 | + { | ||
195 | + path: '/pms/setting/perTarget', // 绩效目标设置 | ||
196 | + component: './pms/setting/PerTarget' | ||
197 | + }, | ||
198 | + { | ||
199 | + path: '/pms/setting/freightTarget', // 运费目标设置 | ||
200 | + component: './pms/setting/FreightTarget' | ||
201 | + }, | ||
194 | ]; | 202 | ]; |
src/pages/pms/setting/FreightTarget/api.ts
0 → 100644
1 | +import { http } from '@/typing/http'; | ||
2 | +import request from '@/utils/request'; | ||
3 | +import { PMS_HOST } from '@/utils/host'; | ||
4 | + | ||
5 | +export interface Item { | ||
6 | + id?: number, | ||
7 | + index?:number | ||
8 | + amount?: any, // | ||
9 | + startDays?: any | ||
10 | + endDays?: any// | ||
11 | +} | ||
12 | +interface Params { | ||
13 | + shopId?: number | ||
14 | + keywords?: string | ||
15 | + storageId?: number | ||
16 | +} | ||
17 | +/** | ||
18 | + * 查询绩效--运费目标达成设置 | ||
19 | + */ | ||
20 | +export function getDetail(params: Params): http.PromiseResp<Item[]> { | ||
21 | + return request.get(`${PMS_HOST}/erp/target/amount/setting/get/list`, { params }); | ||
22 | +} | ||
23 | +/** | ||
24 | + * 新增或编辑绩效--运费目标设置 | ||
25 | + */ | ||
26 | +export function saveApi(params: {list: Item[]}) { | ||
27 | + return request.post(`${PMS_HOST}/erp/target/amount/setting/add/or/update`, params); | ||
28 | +} |
src/pages/pms/setting/FreightTarget/components/AddModal.tsx
0 → 100644
src/pages/pms/setting/FreightTarget/index.tsx
0 → 100644
1 | +import React, { useState } from 'react'; | ||
2 | +import { PageHeaderWrapper } from '@ant-design/pro-layout'; | ||
3 | +import { Card, InputNumber, Button, message } from 'antd'; | ||
4 | +import useInitial from '@/hooks/useInitail'; | ||
5 | +import { getDetail, saveApi, Item} from './api'; | ||
6 | +import ConfirmBnt from '../components/ConfirmBnt'; | ||
7 | +import { DeleteOutlined } from '@ant-design/icons'; | ||
8 | + | ||
9 | +const Index = () => { | ||
10 | + const [disable, setDisable] = useState(false); | ||
11 | + const { data, setData, loading, setLoading } = useInitial<Item[], object>(getDetail, [{ startDays: 1, endDays: null, amount: null }, { startDays: null, endDays: null, amount: null }], {}); | ||
12 | + | ||
13 | + const handleAdd = () => { | ||
14 | + setData([...data, { startDays: null, endDays: null, amount: null }]); | ||
15 | + }; | ||
16 | + | ||
17 | + const handleInputChange = (index: number, p: any) => { | ||
18 | + let arr = data; | ||
19 | + if (p.endDays) { | ||
20 | + arr[index + 1].startDays = p.endDays + 1; | ||
21 | + } | ||
22 | + setData(arr.map((it, i) => { | ||
23 | + if (index == i) { | ||
24 | + return { ...it, ...p}; | ||
25 | + } else { | ||
26 | + return it; | ||
27 | + } | ||
28 | + } | ||
29 | + )); | ||
30 | + }; | ||
31 | + | ||
32 | + const handleDel = (event: any, index: number) => { | ||
33 | + let arr = data; | ||
34 | + arr.splice(index, 1); | ||
35 | + arr[arr.length -1].startDays = arr[arr.length-2].endDays+1; | ||
36 | + setData(arr); | ||
37 | + }; | ||
38 | + | ||
39 | + const svae = () => { | ||
40 | + saveApi({list: data}).then(() => { | ||
41 | + message.success('保存成功'); | ||
42 | + setLoading(true); | ||
43 | + setDisable(false); | ||
44 | + }).catch(e => message.error(e.message)); | ||
45 | + }; | ||
46 | + | ||
47 | + return ( | ||
48 | + <PageHeaderWrapper title="运费目标设置"> | ||
49 | + <Card loading={loading}> | ||
50 | + {!!data?.length && data.map((it, index) => ( | ||
51 | + index < data.length-1 ? ( | ||
52 | + <div key={index} style={{ display: 'flex', alignItems: 'center', marginBottom: 10 }}> | ||
53 | + <span style={{ marginRight: 10 }}>{index + 1}、</span> | ||
54 | + <> | ||
55 | + 缺件起始天数 | ||
56 | + <InputNumber | ||
57 | + disabled | ||
58 | + min={index > 0 ? data[index - 1].endDays : 1} | ||
59 | + value={index > 0 ? data[index - 1].endDays+1 : 1} | ||
60 | + style={{ width: 100, marginLeft: 10, marginRight: 20 }} | ||
61 | + /> | ||
62 | + </> | ||
63 | + <> | ||
64 | + 缺件结束天数 | ||
65 | + <InputNumber | ||
66 | + disabled={!disable} | ||
67 | + min={0} | ||
68 | + value={it.endDays} | ||
69 | + onChange={value => { | ||
70 | + handleInputChange(index, { startDays: index > 0 ? data[index - 1].endDays + 1 : it.startDays, endDays: value }); | ||
71 | + }} | ||
72 | + style={{ width: 100, marginLeft: 10, marginRight: 20 }} | ||
73 | + /> | ||
74 | + </> | ||
75 | + <> | ||
76 | + 运费统计增加 | ||
77 | + <InputNumber | ||
78 | + disabled={!disable} | ||
79 | + addonAfter="元" | ||
80 | + value={it.amount} | ||
81 | + min={0} | ||
82 | + onChange={value => handleInputChange(index, { amount: value })} | ||
83 | + style={{ width: 100, marginLeft: 10, marginRight: 20 }} | ||
84 | + /> | ||
85 | + </> | ||
86 | + {(index == data.length - 2 && disable && index != 0) ? <Button onClick={(event: any) => handleDel(event, index)} shape="circle" icon={<DeleteOutlined />} /> : ''} | ||
87 | + </div> | ||
88 | + ) : | ||
89 | + ( | ||
90 | + <div style={{ display: 'flex', alignItems: 'center', marginBottom: 10 }}> | ||
91 | + <span style={{ marginRight: 10 }}>{data.length}、</span> | ||
92 | + <div style={{ marginRight: 20 }}> | ||
93 | + <InputNumber disabled min={0} value={data[data.length - 2].endDays + 1} style={{ width: 100, marginRight: 10 }} /> | ||
94 | + 天及以上 | ||
95 | + </div> | ||
96 | + <> | ||
97 | + 运费统计增加 | ||
98 | + <InputNumber | ||
99 | + disabled={!disable} | ||
100 | + addonAfter="元" | ||
101 | + value={it.amount} | ||
102 | + min={0} | ||
103 | + onChange={value => handleInputChange(data.length - 1, { startDays: index > 0 ? data[index - 1].endDays + 1 : it.startDays, endDays: null, amount: value })} | ||
104 | + style={{ width: 100, marginLeft: 10, marginRight: 20 }} | ||
105 | + /> | ||
106 | + </> | ||
107 | + </div> | ||
108 | + ) | ||
109 | + ))} | ||
110 | + <Button type="default" disabled={!disable} onClick={() => handleAdd()}>添加梯度</Button> | ||
111 | + <ConfirmBnt | ||
112 | + disable={disable} | ||
113 | + onOk={() => svae()} | ||
114 | + onCancel={() => { setDisable(false); setLoading(true); }} | ||
115 | + onEdit={() => { | ||
116 | + setDisable(true); | ||
117 | + setData(data); | ||
118 | + }} | ||
119 | + /> | ||
120 | + </Card> | ||
121 | + </PageHeaderWrapper> | ||
122 | + ); | ||
123 | +}; | ||
124 | +export default Index; | ||
0 | \ No newline at end of file | 125 | \ No newline at end of file |
src/pages/pms/setting/PerTarget/api.ts
0 → 100644
1 | +import { http } from '@/typing/http'; | ||
2 | +import request from '@/utils/request'; | ||
3 | +import { PMS_HOST } from '@/utils/host'; | ||
4 | + | ||
5 | +export interface Item { | ||
6 | + id?: number, | ||
7 | + amount?: number, // | ||
8 | + days?: number | ||
9 | + storageId?: number// 员工调运费用, 1.5元 / 公里 | ||
10 | + shopId?: number // 备料时效 | ||
11 | + storageName?: string | ||
12 | + shopName?: string | ||
13 | +} | ||
14 | +interface Params { | ||
15 | + shopId?:number | ||
16 | + keywords?:string | ||
17 | + storageId?:number | ||
18 | +} | ||
19 | +/** | ||
20 | + * 查询绩效--目标设置明细 | ||
21 | + */ | ||
22 | +export function getDetail(params: Params): http.PromiseResp<Item[]> { | ||
23 | + return request.get(`${PMS_HOST}/erp/target/setting/get/list`, { params }); | ||
24 | +} | ||
25 | +/** | ||
26 | + * 新增或编辑绩效--目标设置明细 | ||
27 | + */ | ||
28 | +export function saveApi(params: Item) { | ||
29 | + return request.post(`${PMS_HOST}/erp/target/setting/add/or/update`, params); | ||
30 | +} | ||
31 | +/** | ||
32 | + * 删除绩效--目标设置明细 | ||
33 | + */ | ||
34 | +export function DeleteApi(params: {id?: number}) { | ||
35 | + return request.post(`${PMS_HOST}/erp/target/setting/delete`, params, {contentType: 'form-urlencoded'}); | ||
36 | +} |
src/pages/pms/setting/PerTarget/components/AddModal.tsx
0 → 100644
1 | +import React, { useEffect } from 'react'; | ||
2 | +import {Modal, Form, InputNumber, message} from 'antd'; | ||
3 | +import PmsSelsct from '@/pages/pms/comonents/PmsSelect'; | ||
4 | +import { getStoragePage } from '@/pages/pms/storage/StorageManage/api'; | ||
5 | +import usePagination from '@/hooks/usePagination'; | ||
6 | +import { saveApi } from '../api'; | ||
7 | + | ||
8 | +const {Item} = Form; | ||
9 | + | ||
10 | +interface Props { | ||
11 | + item:any | ||
12 | + visible:boolean | ||
13 | + onCancel:Function | ||
14 | + refesh:Function | ||
15 | +} | ||
16 | + | ||
17 | +export default function Index(props: Props) { | ||
18 | + const { item, onCancel, visible, refesh } = props; | ||
19 | + const [form] = Form.useForm(); | ||
20 | + const { list: storages } = usePagination<PartStorageSpace.PageVO>(getStoragePage, { pageSize: 1000 }); | ||
21 | + | ||
22 | + const OK = () => { | ||
23 | + form.validateFields().then(fileds => { | ||
24 | + const params = { | ||
25 | + id: item?.id, | ||
26 | + storageId: fileds.storageId, | ||
27 | + days: fileds.days, | ||
28 | + amount: fileds.amount | ||
29 | + }; | ||
30 | + saveApi(params).then(res => { | ||
31 | + message.success("提交成功"); | ||
32 | + onCancel(); | ||
33 | + refesh(); | ||
34 | + }).catch(e => { | ||
35 | + message.error(e.message); | ||
36 | + }); | ||
37 | + }); | ||
38 | + }; | ||
39 | + | ||
40 | + useEffect(() => { | ||
41 | + if (visible && item.id) { | ||
42 | + form.setFieldsValue({ | ||
43 | + ...item | ||
44 | + }); | ||
45 | + } | ||
46 | + if (!visible) { | ||
47 | + form.resetFields(); | ||
48 | + } | ||
49 | + }, [visible]); | ||
50 | + | ||
51 | + return ( | ||
52 | + <Modal | ||
53 | + open={visible} | ||
54 | + maskClosable={false} | ||
55 | + onCancel={() => onCancel()} | ||
56 | + onOk={() => OK()} | ||
57 | + title={item.id ? '编辑' : '新增'} | ||
58 | + > | ||
59 | + <Form form={form} labelCol={{span: 6}} wrapperCol={{span: 16}}> | ||
60 | + <Item name="storageId" label="库房" required rules={[{ required: true, message: '请选择库房' }]}> | ||
61 | + <PmsSelsct | ||
62 | + style={{width: 300}} | ||
63 | + options={storages.map((item: PartStorageSpace.PageVO) => ({ value: item.id, label: item.storageName }))} | ||
64 | + /> | ||
65 | + </Item> | ||
66 | + <Item name="days" label="订件时长目标" required rules={[{ required: true, message: '请输入' }]}> | ||
67 | + <InputNumber style={{ width: 300 }} addonAfter="天" /> | ||
68 | + </Item> | ||
69 | + <Item name="amount" label="运费目标" required rules={[{ required: true, message: '请输入' }]}> | ||
70 | + <InputNumber style={{ width: 300 }} addonAfter="元" /> | ||
71 | + </Item> | ||
72 | + </Form> | ||
73 | + </Modal> | ||
74 | + ); | ||
75 | +} | ||
0 | \ No newline at end of file | 76 | \ No newline at end of file |
src/pages/pms/setting/PerTarget/index.tsx
0 → 100644
1 | +import React, { useState } from 'react'; | ||
2 | +import { PageHeaderWrapper } from '@ant-design/pro-layout'; | ||
3 | +import { Table, Button, Card, Popconfirm, Divider, message } from 'antd'; | ||
4 | +import AddModal from './components/AddModal'; | ||
5 | +import {Item, getDetail, DeleteApi} from './api'; | ||
6 | +import useInitial from '@/hooks/useInitail'; | ||
7 | + | ||
8 | +const {Column} = Table; | ||
9 | + | ||
10 | +const Index = () => { | ||
11 | + const [current, setCurrent] = useState<{visible:boolean, item?:any}>({visible: false, item: {}}); | ||
12 | + const { data, loading, setParams } = useInitial<Item[], object>(getDetail, [], {}); | ||
13 | + | ||
14 | + const dele = (id?: number) => { | ||
15 | + DeleteApi({id}).then(res => { | ||
16 | + message.success('操作成功'); | ||
17 | + setParams({}, true); | ||
18 | + }).catch(e => message.error(e.message)); | ||
19 | + }; | ||
20 | + | ||
21 | + return ( | ||
22 | + <PageHeaderWrapper title="绩效目标设置"> | ||
23 | + <Card> | ||
24 | + <div style={{display: 'flex', justifyContent: 'flex-end', marginBottom: 20}}> | ||
25 | + <Button type="primary" onClick={() => setCurrent({visible: true, item: {}})}>新增</Button> | ||
26 | + </div> | ||
27 | + <Table | ||
28 | + dataSource={data} | ||
29 | + loading={loading} | ||
30 | + rowKey={r => `${r.id}`} | ||
31 | + pagination={false} | ||
32 | + > | ||
33 | + <Column title="库房" dataIndex="storageName" /> | ||
34 | + <Column title="门店" dataIndex="shopName" /> | ||
35 | + <Column title="订件时长目标(天)" dataIndex="days" /> | ||
36 | + <Column title="运费目标(元)" dataIndex="amount" /> | ||
37 | + <Column | ||
38 | + title="操作" | ||
39 | + render={(r:Item) => ( | ||
40 | + <> | ||
41 | + <a onClick={() => setCurrent({visible: true, item: r})}>编辑</a> | ||
42 | + <Divider type="vertical" /> | ||
43 | + <Popconfirm | ||
44 | + title="确认删除" | ||
45 | + onConfirm={() => dele(r.id)} | ||
46 | + > | ||
47 | + <a>删除</a> | ||
48 | + </Popconfirm> | ||
49 | + </> | ||
50 | + )} | ||
51 | + /> | ||
52 | + </Table> | ||
53 | + <AddModal item={current.item} visible={current.visible} onCancel={() => setCurrent({visible: false, item: {}})} refesh={() => setParams({}, true)} /> | ||
54 | + </Card> | ||
55 | + </PageHeaderWrapper> | ||
56 | + ); | ||
57 | +}; | ||
58 | +export default Index; | ||
0 | \ No newline at end of file | 59 | \ No newline at end of file |
src/pages/pms/setting/PlanSetting/index.tsx
1 | import React, { useState } from 'react'; | 1 | import React, { useState } from 'react'; |
2 | -import { Card, InputNumber, message, Radio } from 'antd'; | 2 | +import { Card, InputNumber, message } from 'antd'; |
3 | import { PageHeaderWrapper } from '@ant-design/pro-layout'; | 3 | import { PageHeaderWrapper } from '@ant-design/pro-layout'; |
4 | import useInitail from '@/hooks/useInitail'; | 4 | import useInitail from '@/hooks/useInitail'; |
5 | import ConfirmBnt from '../components/ConfirmBnt'; | 5 | import ConfirmBnt from '../components/ConfirmBnt'; |
@@ -65,12 +65,6 @@ export default function Index() { | @@ -65,12 +65,6 @@ export default function Index() { | ||
65 | /> | 65 | /> |
66 | ,配件计划不审批 | 66 | ,配件计划不审批 |
67 | </span> | 67 | </span> |
68 | - <span style={{ marginBottom: 20 }}>4、计划员能否修改订件的错误配件编码: | ||
69 | - <Radio.Group value={Number(data.editBuyPartCode)} disabled={!disable} onChange={v => setData({ ...data, editBuyPartCode: !!v.target.value})}> | ||
70 | - <Radio value={1}>是</Radio> | ||
71 | - <Radio value={0}>否</Radio> | ||
72 | - </Radio.Group> | ||
73 | - </span> | ||
74 | <ConfirmBnt | 68 | <ConfirmBnt |
75 | disable={disable} | 69 | disable={disable} |
76 | onOk={handleSave} | 70 | onOk={handleSave} |