Commit 8dfcfb06ed42a14a85db990446df1d12ebef61a3
1 parent
7043c73b
加装车配置新增联调
Showing
6 changed files
with
698 additions
and
0 deletions
config/routers/fvm.ts
src/pages/stock/VehicleAdditional/api.ts
0 → 100644
1 | +import { http } from '@/typing/http'; | |
2 | +import request from '@/utils/request'; | |
3 | +import { FVM_HOST } from '@/utils/host'; | |
4 | + | |
5 | +/** | |
6 | + * 查询列表 | |
7 | + */ | |
8 | +export function getPageListApi(params?: AdditionalCarSpace.QueryParams): http.PromisePageResp<AdditionalCarSpace.Item> { | |
9 | + return request.get(`${FVM_HOST}/erp/vehicle/optional/list`, { params }); | |
10 | +} | |
11 | + | |
12 | +/** | |
13 | + * 保存 | |
14 | + */ | |
15 | +export function saveApi(params: AdditionalCarSpace.Item): http.PromiseResp<void> { | |
16 | + return request.post(`${FVM_HOST}/erp/vehicle/optional/save`, params); | |
17 | +} | |
18 | +/** 启用禁用 */ | |
19 | +export function changeStatusApi(params: { id: number, status: number }): http.PromiseResp<string> { | |
20 | + return request.get<string>(`${FVM_HOST}/erp/vehicle/optional/enable`, { params }); | |
21 | +} | |
22 | + | |
23 | +/** | |
24 | + * 查询库房列表 | |
25 | + */ | |
26 | +export function getDeatilListApi(params: AdditionalCarSpace.StorageParams): http.PromiseResp<AdditionalCarSpace.Item> { | |
27 | + return request.get(`${FVM_HOST}/erp/vehicle/optional/Detail`, { params }); | |
28 | +} | |
0 | 29 | \ No newline at end of file | ... | ... |
src/pages/stock/VehicleAdditional/components/CarSelect.tsx
0 → 100644
1 | +import React, { useEffect, useState } from "react"; | |
2 | +import { | |
3 | + Button, | |
4 | + Popconfirm, | |
5 | + Card, | |
6 | + Table, | |
7 | + Modal, | |
8 | + Form, | |
9 | + Select, | |
10 | + Space, | |
11 | +} from "antd"; | |
12 | +import useInitial from "@/hooks/useInitail"; | |
13 | +import { | |
14 | + getOnsaleBrandApi, | |
15 | + getOnsaleSeriesApi, | |
16 | + getOnsaleSpecApi, | |
17 | +} from "@/pages/stock/Components/api"; | |
18 | + | |
19 | +interface Props { | |
20 | + onChange?: (pa: any) => void; | |
21 | + value?: any[]; | |
22 | + disabled?: boolean; | |
23 | + level?: number; //1品牌,2车系,3车型 | |
24 | +} | |
25 | + | |
26 | +interface Item { | |
27 | + label: string; | |
28 | + value: number; | |
29 | + key?: number; | |
30 | +} | |
31 | +const { Column } = Table; | |
32 | +const { Option } = Select; | |
33 | + | |
34 | +export default function index({ onChange, value, disabled }: Props) { | |
35 | + console.log("🚀 ~ file: CarSelect.tsx:34 ~ index ~ value", value) | |
36 | + const [form] = Form.useForm(); | |
37 | + const { data: brandList } = useInitial(getOnsaleBrandApi, [], {}); | |
38 | + // 控制Modal是否可见 | |
39 | + const [visible, setVisible] = useState<boolean>(false); | |
40 | + // 控制是否可见车型下拉框 | |
41 | + const [specVisible, setSpecVisible] = useState<boolean>(false); | |
42 | + const [level, setLevel] = useState<number>(1); | |
43 | + //存储表格当前车系 | |
44 | + const [currentItem, setCurrentItem] = useState<any>(); | |
45 | + //存储Modal中可选的车系 | |
46 | + const [series, setSeries] = useState<any>([]); | |
47 | + //存储接口返回的车型 | |
48 | + const [specList, setSpecList] = useState<any>([]); | |
49 | + //存储Modal选择的品牌和车系作为表格的数据源 | |
50 | + const [savaData, setSavadata] = useState<any>([]); | |
51 | + // 存储已经选中的车系 | |
52 | + const [selectedSeries, setSelectedSeries] = useState<any[]>([]); | |
53 | + | |
54 | + useEffect(() => { | |
55 | + if (value && value.length) { | |
56 | + setSelectedSeries([...value]); | |
57 | + setSavadata([...value]); | |
58 | + } | |
59 | + }, [value]); | |
60 | + | |
61 | + const _onOk = () => { | |
62 | + form | |
63 | + .validateFields() | |
64 | + .then((fileds) => { | |
65 | + if (level === 2) { | |
66 | + const { series } = fileds; | |
67 | + const _series = series.map((item: Item) => ({ | |
68 | + seriesId: item.value, | |
69 | + seriesName: item.label, | |
70 | + authType: 1, | |
71 | + })); | |
72 | + currentItem.children = _series; | |
73 | + // currentItem.authType = 2; | |
74 | + const tempData = savaData.map((item: any) => (item.brandId === currentItem.brandId ? currentItem : item) | |
75 | + ); | |
76 | + setSavadata([...tempData]); | |
77 | + onChange && onChange(tempData); | |
78 | + setVisible(false); | |
79 | + // setSpecVisible(false); | |
80 | + return; | |
81 | + } | |
82 | + if (level === 3) { | |
83 | + const { spec } = fileds; | |
84 | + console.log('savaData', savaData) | |
85 | + const _spec = spec.map((item: Item) => ({ | |
86 | + specId: item.value, | |
87 | + specName: item.label, | |
88 | + })); | |
89 | + currentItem.children = _spec; | |
90 | + currentItem.authType = 2; | |
91 | + const tempData = savaData.map((item: any) => { | |
92 | + if (item.children) { | |
93 | + const newChildren = item.children.map((i: any) => (i.seriesId === currentItem.seriesId ? currentItem : i)); | |
94 | + item.children = newChildren; | |
95 | + } | |
96 | + return item; | |
97 | + // item.children ? item.children.map((i: any) => (i.seriesId === currentItem.seriesId ? currentItem : i)) : item) | |
98 | + }); | |
99 | + console.log("🚀 ~ file: CarSelect.tsx:97 ~ tempData ~ tempData", tempData) | |
100 | + setSavadata([...tempData]); | |
101 | + onChange && onChange(tempData); | |
102 | + setVisible(false); | |
103 | + // setSpecVisible(false); | |
104 | + return; | |
105 | + } | |
106 | + const { brand } = fileds; | |
107 | + const tempArray = brand.map((item: any) => ({ | |
108 | + brandName: item.label, | |
109 | + brandId: item.value, | |
110 | + // seriesName: item.label, | |
111 | + // seriesId: Number(item.key), | |
112 | + authType: 1, //1全部2部分 | |
113 | + })); | |
114 | + | |
115 | + selectedSeries.push(...tempArray); | |
116 | + | |
117 | + savaData.push(...tempArray); | |
118 | + onChange && onChange(selectedSeries); | |
119 | + setVisible(false); | |
120 | + }) | |
121 | + .catch((err) => console.log(err.message)); | |
122 | + }; | |
123 | + | |
124 | + // 选择部分车辆表格==》删除车系 | |
125 | + const onDelete = (record: any) => { | |
126 | + const _savaData = savaData.filter( | |
127 | + (item: any) => item.seriesId != record.seriesId | |
128 | + ); | |
129 | + const _selectedSeries = selectedSeries.filter( | |
130 | + (item) => item.seriesId != record.seriesId | |
131 | + ); | |
132 | + setSavadata([..._savaData]); | |
133 | + onChange && onChange(_savaData); | |
134 | + setSelectedSeries([..._selectedSeries]); | |
135 | + }; | |
136 | + | |
137 | + // 选择部分车辆表格==》编辑选择部分车型 | |
138 | + const onSelectSpec = async (record: any) => { | |
139 | + console.log("🚀 ~ file: CarSelect.tsx:114 ~ onSelectSpec ~ record", record) | |
140 | + if (record.brandId) { | |
141 | + const { data } = await getOnsaleSeriesApi(record.brandId); | |
142 | + setSeries(data); | |
143 | + setLevel(2); | |
144 | + } | |
145 | + if (record.seriesId) { | |
146 | + const { data } = await getOnsaleSpecApi(record.seriesId); | |
147 | + setSpecList(data); | |
148 | + setLevel(3); | |
149 | + } | |
150 | + setCurrentItem(record); | |
151 | + setSpecVisible(true); | |
152 | + setVisible(true); | |
153 | + }; | |
154 | + | |
155 | + return ( | |
156 | + <> | |
157 | + <Card> | |
158 | + <div style={{ display: "flex", justifyContent: "flex-end" }}> | |
159 | + <Button | |
160 | + type="link" | |
161 | + disabled={disabled} | |
162 | + onClick={() => { | |
163 | + setVisible(true); | |
164 | + form.resetFields(); | |
165 | + }} | |
166 | + > | |
167 | + 新增 | |
168 | + </Button> | |
169 | + </div> | |
170 | + | |
171 | + <Table | |
172 | + dataSource={value} | |
173 | + rowKey={(record) => String(record.id)} | |
174 | + > | |
175 | + <Column | |
176 | + title="品牌" | |
177 | + dataIndex="brandName" | |
178 | + key="brandId" | |
179 | + /> | |
180 | + <Column title="车系" dataIndex="seriesName" key="seriesId" /> | |
181 | + <Column | |
182 | + title="车型" | |
183 | + dataIndex="specName" | |
184 | + key="specId" | |
185 | + render={(text, record: any) => { | |
186 | + console.log("车型", text, record) | |
187 | + return (text || (record.children && record.children.length !== 0) ? ( | |
188 | + <span> | |
189 | + {text} | |
190 | + </span> | |
191 | + ) : ( | |
192 | + <span style={{ color: "#999" }}>全部车型</span> | |
193 | + )) | |
194 | + }} | |
195 | + /> | |
196 | + {!disabled && ( | |
197 | + <Column | |
198 | + title="操作" | |
199 | + // key="operation" | |
200 | + render={(_, record: any, index) => { | |
201 | + console.log("操作", _, record, index); | |
202 | + return ( | |
203 | + <Space> | |
204 | + <Button | |
205 | + type="link" | |
206 | + style={{ padding: 0 }} | |
207 | + onClick={() => onSelectSpec(record)} | |
208 | + disabled={disabled} | |
209 | + > | |
210 | + {record.brandId ? "编辑车系" : (record.seriesId ? "编辑车型" : "")} | |
211 | + </Button> | |
212 | + | |
213 | + <Popconfirm | |
214 | + title="确定删除?" | |
215 | + okText="确定" | |
216 | + style={{ padding: 0 }} | |
217 | + cancelText="取消" | |
218 | + onConfirm={() => onDelete(record)} | |
219 | + > | |
220 | + <Button type="link" danger disabled={disabled}> | |
221 | + 删除 | |
222 | + </Button> | |
223 | + </Popconfirm> | |
224 | + </Space> | |
225 | + ) | |
226 | + }} | |
227 | + /> | |
228 | + )} | |
229 | + </Table> | |
230 | + </Card> | |
231 | + | |
232 | + {/* 选择品牌和车系 */} | |
233 | + <Modal | |
234 | + title="选择车辆信息" | |
235 | + visible={visible} | |
236 | + onOk={() => form.submit()} | |
237 | + onCancel={() => { | |
238 | + setVisible(false); | |
239 | + setSpecVisible(false); | |
240 | + }} | |
241 | + afterClose={() => { | |
242 | + form.resetFields(); | |
243 | + setCurrentItem({}); | |
244 | + }} | |
245 | + > | |
246 | + <Form onFinish={_onOk} form={form}> | |
247 | + {level === 1 ? ( | |
248 | + <Form.Item | |
249 | + label="品牌" | |
250 | + name="brand" | |
251 | + rules={[{ required: true, message: "请选择品牌:" }]} | |
252 | + > | |
253 | + <Select | |
254 | + labelInValue | |
255 | + mode="multiple" | |
256 | + // onChange={async (value) => { | |
257 | + // form.resetFields(["series"]); | |
258 | + // const { data: seriesList } = await getOnsaleSeriesApi( | |
259 | + // value?.key | |
260 | + // ); | |
261 | + // let tempArray = selectedSeries.map((item) => item.seriesId); | |
262 | + // const tempData = seriesList?.filter( | |
263 | + // (value) => !tempArray.includes(value.id) | |
264 | + // ); | |
265 | + // setSeries(tempData); | |
266 | + // }} | |
267 | + > | |
268 | + {brandList.map((item) => ( | |
269 | + <Option value={item.id} key={item.id}> | |
270 | + {item.name} | |
271 | + </Option> | |
272 | + ))} | |
273 | + </Select> | |
274 | + </Form.Item> | |
275 | + ) : null} | |
276 | + | |
277 | + {/* 车系 */} | |
278 | + {level === 2 && ( | |
279 | + <Form.Item | |
280 | + label="车系" | |
281 | + name="series" | |
282 | + rules={[{ required: true, message: "请选择车系" }]} | |
283 | + > | |
284 | + <Select labelInValue mode="multiple" allowClear> | |
285 | + {series.map((item: any) => ( | |
286 | + <Option value={item.id} key={item.id}> | |
287 | + {item.name} | |
288 | + </Option> | |
289 | + ))} | |
290 | + </Select> | |
291 | + </Form.Item> | |
292 | + )} | |
293 | + {level === 3 ? ( | |
294 | + <Form.Item | |
295 | + label="车型" | |
296 | + name="spec" | |
297 | + rules={[{ required: true, message: "请选择车型" }]} | |
298 | + > | |
299 | + <Select labelInValue mode="multiple" allowClear> | |
300 | + {specList.map((item: any) => ( | |
301 | + <Option value={item.id} key={item.id}> | |
302 | + {item.name} | |
303 | + </Option> | |
304 | + ))} | |
305 | + </Select> | |
306 | + </Form.Item> | |
307 | + ) : null} | |
308 | + </Form> | |
309 | + </Modal> | |
310 | + </> | |
311 | + ); | |
312 | +} | ... | ... |
src/pages/stock/VehicleAdditional/components/EditModal.tsx
0 → 100644
1 | +import React, { useState, useEffect } from 'react'; | |
2 | +import '@ant-design/compatible/assets/index.css'; | |
3 | +import { message, Modal, Select, Form, Input, InputNumber, Radio, Button } from 'antd'; | |
4 | +import { saveApi } from '../api'; | |
5 | +import { UploadOutlined } from '@ant-design/icons'; | |
6 | +import PositionSelector from "@/components/PositionSelector"; | |
7 | +import _ from 'lodash'; | |
8 | +import FeeweeUploadAttachment from '@/components/FeeweeUploadAttachment'; | |
9 | +import useInitial from '@/hooks/useInitail'; | |
10 | +import CarSelect from './CarSelect'; | |
11 | + | |
12 | +const Item = Form.Item; | |
13 | +const Option = Select.Option; | |
14 | +interface Props { | |
15 | + visible: boolean, | |
16 | + onCancel: Function, | |
17 | + item: AdditionalCarSpace.Item, | |
18 | + brands: CommonApi.OptionVO[], | |
19 | + fetchList: () => any, | |
20 | + | |
21 | +} | |
22 | + | |
23 | +function EditModal(props: Props) { | |
24 | + const { item, onCancel, fetchList, brands, visible } = props; | |
25 | + const [delay, setDelay] = useState<boolean | undefined>(true); | |
26 | + const [loading, setLoading] = useState(false); | |
27 | + const [brandId, setBrandId] = useState<number>(); | |
28 | + const [storageList, setStorageList] = useState<any[]>([]); | |
29 | + const [form] = Form.useForm(); | |
30 | + | |
31 | + useEffect(() => { | |
32 | + if (visible && item != null) { | |
33 | + const a = item.optionalAuth.map((brand: any) => { | |
34 | + if (brand.authSeries) { | |
35 | + const newItem = brand.authSeries.map((child: any) => (child.authSpec ? { ...child, children: child.authSpec, authSpec: undefined } : child)); | |
36 | + return { ...brand, children: newItem, authSeries: undefined }; | |
37 | + } | |
38 | + return brand; | |
39 | + }); | |
40 | + form.setFieldsValue({ | |
41 | + ...item, | |
42 | + image: item.image.split(','), | |
43 | + optionalAuth: a | |
44 | + }); | |
45 | + } else { | |
46 | + form.resetFields(); | |
47 | + setBrandId(undefined); | |
48 | + } | |
49 | + }, [visible]); | |
50 | + | |
51 | + function submit() { | |
52 | + form.validateFields().then(values => { | |
53 | + const params = { | |
54 | + id: item && item.id, | |
55 | + ...values, | |
56 | + image: values.image.join(','), | |
57 | + optionalAuth: values.optionalAuth.map((item: any) => { | |
58 | + if (item.children) { | |
59 | + item.authSeries = item.children.map((child: any) => (child.children ? { ...child, authSpec: child.children } : child)); | |
60 | + } | |
61 | + return item; | |
62 | + }) | |
63 | + }; | |
64 | + setLoading(true); | |
65 | + saveApi(params).then(() => { | |
66 | + message.success('保存成功'); | |
67 | + fetchList(); | |
68 | + onCancel(); | |
69 | + setLoading(false); | |
70 | + }).catch(e => { | |
71 | + setLoading(false); | |
72 | + message.error(e.message); | |
73 | + }); | |
74 | + }); | |
75 | + } | |
76 | + | |
77 | + /**获取授权库 */ | |
78 | + function onChange(values: any, option: any) { | |
79 | + setStorageList(option.map((i: any) => ({ type: i.type, storageId: i.value, storageName: i.children }))); | |
80 | + } | |
81 | + return ( | |
82 | + <Modal | |
83 | + title={item ? '编辑' : '新增'} | |
84 | + visible={visible} | |
85 | + maskClosable={false} | |
86 | + onCancel={() => onCancel()} | |
87 | + onOk={form.submit} | |
88 | + confirmLoading={loading} | |
89 | + width="60%" | |
90 | + > | |
91 | + <Form onFinish={submit} form={form} labelWrap labelCol={{ span: 5 }} wrapperCol={{ span: 15 }}> | |
92 | + <Item label="加装项目" name="name" rules={[{ required: true, message: '请输入' }]}> | |
93 | + <Input allowClear placeholder="加装项目" /> | |
94 | + </Item> | |
95 | + {!item ? ( | |
96 | + <> | |
97 | + <Item name="image" label="图片" rules={[{ required: true, message: '请上传' }]}> | |
98 | + <FeeweeUploadAttachment useCos maxCount={1} listType="picture"> | |
99 | + <Button icon={<UploadOutlined />}>上传图片</Button> | |
100 | + </FeeweeUploadAttachment> | |
101 | + </Item> | |
102 | + <Item label="商家零售价格" name="dealerPrice" rules={[{ required: true, message: '请输入' }]}> | |
103 | + <InputNumber style={{ width: '100%' }} addonAfter="元" placeholder="请输入" /> | |
104 | + </Item> | |
105 | + <Item label="厂家定制价格" name="factoryPrice" rules={[{ required: true, message: '请输入' }]}> | |
106 | + <InputNumber style={{ width: '100%' }} addonAfter="元" placeholder="请输入" /> | |
107 | + </Item> | |
108 | + <Item label="返利金额" name="rebatePrice" rules={[{ required: true, message: '请输入' }]}> | |
109 | + <InputNumber style={{ width: '100%' }} addonAfter="(元/台)" placeholder="请输入" /> | |
110 | + </Item> | |
111 | + <Item label="内部提成方式" name="rewardType" rules={[{ required: true, message: '该选项为必填项' }]}> | |
112 | + <Radio.Group> | |
113 | + <Radio value={1}>无提成</Radio> | |
114 | + <Radio value={2}>单独提成</Radio> | |
115 | + </Radio.Group> | |
116 | + </Item> | |
117 | + <Item | |
118 | + noStyle | |
119 | + shouldUpdate={(prevValues, curValues) => prevValues.rewardType !== curValues.rewardType} | |
120 | + > | |
121 | + {({ getFieldValue }) => { | |
122 | + const type = getFieldValue('rewardType'); | |
123 | + return type == 2 ? ( | |
124 | + <> | |
125 | + <Form.Item label="单独提成金额" name="rewardAmount" rules={[{ required: true, message: '该选项为必填项' }]}> | |
126 | + <InputNumber style={{ width: '100%' }} addonAfter="元" placeholder="请输入" /> | |
127 | + </Form.Item> | |
128 | + </> | |
129 | + ) : null; | |
130 | + }} | |
131 | + </Item> | |
132 | + </> | |
133 | + ) : null} | |
134 | + <Item | |
135 | + name="optionalAuth" | |
136 | + label="授权车辆范围" | |
137 | + wrapperCol={{ span: 20 }} | |
138 | + labelCol={{ span: 3 }} | |
139 | + rules={[{ required: true, message: "选择车辆" }]} | |
140 | + > | |
141 | + <CarSelect disabled={!!item} /> | |
142 | + </Item> | |
143 | + </Form> | |
144 | + </Modal> | |
145 | + ); | |
146 | +} | |
147 | + | |
148 | +export default EditModal; | |
0 | 149 | \ No newline at end of file | ... | ... |
src/pages/stock/VehicleAdditional/index.tsx
0 → 100644
1 | +import React, { useState, useEffect } from "react"; | |
2 | +import { Button, Card, Divider, message, Popconfirm, Table, Select, Switch } from "antd"; | |
3 | +import { PageHeaderWrapper } from "@ant-design/pro-layout"; | |
4 | +import usePagination from "@/hooks/usePagination"; | |
5 | +import SaveModal from "./components/EditModal"; | |
6 | +import { changeStatusApi, getPageListApi } from "./api"; | |
7 | +import useInitial from "@/hooks/useInitail"; | |
8 | +import { getBrandFilterApi } from "@/common/api"; | |
9 | +import { IMGURL } from '@/utils'; | |
10 | +// import defaultThum from "@/assets/defaultThum.png"; | |
11 | + | |
12 | +const Column = Table.Column; | |
13 | +const defaultImg = require('@/assets/defaultThum.png'); | |
14 | + | |
15 | +export default function StorageList() { | |
16 | + const [delay, setDelay] = useState(true); | |
17 | + const { list, paginationConfig, loading, setParams, setLoading, innerParams } = usePagination<AdditionalCarSpace.Item>(getPageListApi, { enable: 1 }, { delay }); | |
18 | + const { data: brandList } = useInitial(getBrandFilterApi, [], {}); | |
19 | + const [visible, setVisible] = useState(false); | |
20 | + const [item, setItem] = useState<AdditionalCarSpace.Item>({}); | |
21 | + | |
22 | + useEffect(() => { | |
23 | + if (brandList.length) { | |
24 | + setParams({ ...innerParams, brandId: brandList[0].id }, true); | |
25 | + setDelay(false); | |
26 | + } | |
27 | + }, [brandList]); | |
28 | + /**启用禁用 */ | |
29 | + function handleChangeStatus(item: AdditionalCarSpace.Item) { | |
30 | + const pa = { | |
31 | + id: item.id, | |
32 | + status: item.status === 0 ? 1 : 0, | |
33 | + }; | |
34 | + changeStatusApi(pa) | |
35 | + .then((res) => { | |
36 | + setLoading(true); | |
37 | + message.success("操作成功"); | |
38 | + }) | |
39 | + .catch((e) => { | |
40 | + message.error(e.message); | |
41 | + }); | |
42 | + } | |
43 | + | |
44 | + return ( | |
45 | + <PageHeaderWrapper title="车辆加装配置"> | |
46 | + <Card> | |
47 | + <div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between", marginBottom: 20 }}> | |
48 | + <div style={{ display: "flex", flexDirection: "row" }}> | |
49 | + <Select style={{ width: 250 }} placeholder="请选择品牌" allowClear onChange={(v) => setParams({ brandId: v }, true)} value={innerParams.brandId}> | |
50 | + {brandList.map((item: { id: number; name: string }) => ( | |
51 | + <Select.Option value={item.id} key={item.id}> | |
52 | + {item.name} | |
53 | + </Select.Option> | |
54 | + ))} | |
55 | + </Select> | |
56 | + <Select style={{ width: 150, marginLeft: 20 }} placeholder="状态" value={innerParams.enable} onChange={(v) => setParams({ ...innerParams, enable: v }, true)} allowClear> | |
57 | + <Select.Option value={0} key={0}> | |
58 | + 禁用 | |
59 | + </Select.Option> | |
60 | + <Select.Option value={1} key={1}> | |
61 | + 启用 | |
62 | + </Select.Option> | |
63 | + </Select> | |
64 | + </div> | |
65 | + <Button | |
66 | + type="primary" | |
67 | + onClick={() => { | |
68 | + setVisible(true); | |
69 | + setItem({}); | |
70 | + }} | |
71 | + > | |
72 | + 新增 | |
73 | + </Button> | |
74 | + </div> | |
75 | + <Table size="small" loading={loading} pagination={paginationConfig} rowKey={(item) => String(item.id)} dataSource={list} onChange={(_pagination) => setParams({ ..._pagination }, true)}> | |
76 | + <Column title="加装项目" dataIndex="name" /> | |
77 | + <Column | |
78 | + title="图片" | |
79 | + dataIndex="image" | |
80 | + render={(image, record: AdditionalCarSpace.Item) => ( | |
81 | + <> | |
82 | + <div style={{ width: 40, height: 50 }}> | |
83 | + <img src={IMGURL.showImage(image)} alt="" /> | |
84 | + </div> | |
85 | + </> | |
86 | + )} | |
87 | + /> | |
88 | + <Column title="商家零售价格(元)" dataIndex="dealerPrice" /> | |
89 | + <Column title="厂家定制价格(元)" dataIndex="factoryPrice" /> | |
90 | + <Column title="返利金额(元/台)" dataIndex="rebatePrice" /> | |
91 | + <Column title="内部提成方式" dataIndex="rewardType" render={(t) => (t == 1 ? "无提成" : "单独提成")} /> | |
92 | + <Column title="单独提成金额(元)" dataIndex="rewardAmount" /> | |
93 | + <Column | |
94 | + title="适用范围" | |
95 | + dataIndex="optionalAuth" | |
96 | + render={(t, _item) => <Button type="link" onClick={() => { setVisible(true); setItem(_item); }}>查看</Button>} | |
97 | + /> | |
98 | + <Column | |
99 | + title="操作" | |
100 | + render={(text, _item: AdditionalCarSpace.Item) => ( | |
101 | + <> | |
102 | + <Popconfirm placement="top" title={`确认${_item.status == 1 ? "禁用" : "启用"}?`} onConfirm={(v) => handleChangeStatus(_item)}> | |
103 | + <Switch defaultChecked={text} checkedChildren="启用" unCheckedChildren="禁用" /> | |
104 | + </Popconfirm> | |
105 | + </> | |
106 | + )} | |
107 | + /> | |
108 | + </Table> | |
109 | + <SaveModal visible={visible} brands={brandList} item={item} fetchList={() => setParams({ ...innerParams, current: 1 }, true)} onCancel={() => setVisible(false)} /> | |
110 | + </Card> | |
111 | + </PageHeaderWrapper> | |
112 | + ); | |
113 | +} | ... | ... |
src/pages/stock/VehicleAdditional/interface.d.ts
0 → 100644
1 | +declare namespace AdditionalCarSpace { | |
2 | + | |
3 | + /** | |
4 | + * 查询参数 | |
5 | + */ | |
6 | + interface QueryParams { | |
7 | + current?: number, | |
8 | + pageSize?: number, | |
9 | + } | |
10 | + | |
11 | + /** | |
12 | + * 列表项 | |
13 | + */ | |
14 | + interface Item { | |
15 | + id: number; | |
16 | + groupId: number; | |
17 | + name: string; | |
18 | + dealerPrice: number; | |
19 | + factoryPrice: number; | |
20 | + /**返利价格 */ | |
21 | + rebatePrice: number; | |
22 | + /**内部提成方式 1无提成 2单独提成 */ | |
23 | + rewardType: number; | |
24 | + /**单独提成金额 */ | |
25 | + rewardAmount: number; | |
26 | + image: string; | |
27 | + status: number; | |
28 | + createTime: number; | |
29 | + optionalAuth: AuthCarItem[] | |
30 | + } | |
31 | + | |
32 | + interface AuthCarItem { | |
33 | + optionalId: number; | |
34 | + authType: number; | |
35 | + brandId: number; | |
36 | + brandName: string; | |
37 | + authSeries: [ | |
38 | + { | |
39 | + optionalId: number; | |
40 | + brandId: number; | |
41 | + authType: number; | |
42 | + seriesId: number; | |
43 | + seriesName: string; | |
44 | + authSpec: [ | |
45 | + { | |
46 | + optionalId: number; | |
47 | + seriesId: number; | |
48 | + specId: number; | |
49 | + specName: string | |
50 | + } | |
51 | + ] | |
52 | + } | |
53 | + ] | |
54 | + } | |
55 | + /** | |
56 | + * 保存参数 | |
57 | + */ | |
58 | + interface SaveParam { | |
59 | + id?: number, // 库位ID | |
60 | + name?: string, // 名称 | |
61 | + regionName?: string, // 地区名称 | |
62 | + regionBh?: string, // 地区编号 | |
63 | + lng?: number, // 经度 | |
64 | + lat?: number, // 纬度 | |
65 | + acreage?: number, // 面积 | |
66 | + parkCount?: number, // 车位数 | |
67 | + maxParkCount?: number, //最大车位数 | |
68 | + type?: number, // 库位类型1区域库3展厅库 | |
69 | + } | |
70 | + | |
71 | + /** | |
72 | + * 整车库集合 | |
73 | + */ | |
74 | + interface Storage { | |
75 | + storageId: number, //库房id | |
76 | + storageName: string, //库房名称 | |
77 | + type: number //1-普通库,2-门店库 | |
78 | + } | |
79 | + | |
80 | + interface StorageParams { | |
81 | + brandId?: number, // 品牌id | |
82 | + areaId?: number, //区域库id, | |
83 | + } | |
84 | + /** | |
85 | + * 选项 | |
86 | + */ | |
87 | + interface StorageVo { | |
88 | + id: number, | |
89 | + name: string, | |
90 | + type: number | |
91 | + } | |
92 | +} | |
0 | 93 | \ No newline at end of file | ... | ... |