Commit 576a38ce95fa74baff8d977d2480d9d06bbdfffd
Merge remote-tracking branch 'origin/IntegralRecord'
# Conflicts: # src/pages/ResearchGroup/constant.tsx
Showing
12 changed files
with
1554 additions
and
1211 deletions
src/pages/Order/FeedBack/OrderDrawer copy.tsx deleted
100644 → 0
1 | -import { RESPONSE_CODE } from '@/constants/enum'; | ||
2 | -import { | ||
3 | - postKingdeeRepCustomer, | ||
4 | - postKingdeeRepCustomerDetail, | ||
5 | - postKingdeeRepMaterial, | ||
6 | - postKingdeeRepMaterialUnit, | ||
7 | - postKingdeeRepMeasureUnit, | ||
8 | - postServiceOrderAddOrder, | ||
9 | - postServiceOrderQuerySalesCode, | ||
10 | - postServiceOrderUpdateOrder, | ||
11 | -} from '@/services'; | ||
12 | -import { | ||
13 | - enumToSelect, | ||
14 | - getAliYunOSSFileNameFromUrl, | ||
15 | - getUserInfo, | ||
16 | -} from '@/utils'; | ||
17 | -import { getTeacherCustomFieldNumber } from '@/utils/kingdee'; | ||
18 | -import { | ||
19 | - DrawerForm, | ||
20 | - FormListActionType, | ||
21 | - ProCard, | ||
22 | - ProFormDateTimePicker, | ||
23 | - ProFormDigit, | ||
24 | - ProFormList, | ||
25 | - ProFormSelect, | ||
26 | - ProFormText, | ||
27 | - ProFormTextArea, | ||
28 | - ProFormUploadDragger, | ||
29 | -} from '@ant-design/pro-components'; | ||
30 | -import { Button, Form, message } from 'antd'; | ||
31 | -import { cloneDeep } from 'lodash'; | ||
32 | -import { useEffect, useRef, useState } from 'react'; | ||
33 | -import KingdeeCustomerModal from './KingdeeCustomerModal'; | ||
34 | -import { | ||
35 | - INVOCING_STATUS_OPTIONS, | ||
36 | - INVOCING_STATUS_OPTIONS_OLD, | ||
37 | - PAYMENT_CHANNEL_OPTIONS, | ||
38 | - PAYMENT_METHOD_OPTIONS, | ||
39 | - PRODUCT_BELONG_DEPARTMENT_OPTIONS, | ||
40 | -} from './constant'; | ||
41 | - | ||
42 | -export default ({ onClose, data, subOrders, orderOptType }) => { | ||
43 | - const [invoicingStatus, setInvoicingStatus] = useState(''); | ||
44 | - const [salesCodeOptions, setSalesCodeOptions] = useState([]); | ||
45 | - const [customer, setCustomer] = useState({}); | ||
46 | - const [kingdeeCstomerModalVisible, setKingdeeCstomerModalVisible] = | ||
47 | - useState(false); | ||
48 | - const [ | ||
49 | - productParametersDisabledFlagList, | ||
50 | - setProductParametersDisabledFlagList, | ||
51 | - ] = useState([]); | ||
52 | - // const [productInvStockOptionsList, setProductInvStockOptionsList] = useState( | ||
53 | - // [], | ||
54 | - // ); //商品的仓库选项 | ||
55 | - const [productUnitOptionsList, setProductUnitOptionsList] = useState([]); //商品的单位选项 | ||
56 | - const [productCustomerContactOptions, setProductCustomerContactOptions] = | ||
57 | - useState([]); //客户的收货人选项 | ||
58 | - const [form] = Form.useForm<{ | ||
59 | - salesCode: ''; | ||
60 | - customerName: ''; | ||
61 | - customerContactNumber: ''; | ||
62 | - institution: ''; | ||
63 | - institutionContactName: ''; | ||
64 | - customerShippingAddress: ''; | ||
65 | - totalPayment: ''; | ||
66 | - paymentChannel: ''; | ||
67 | - paymentMethod: ''; | ||
68 | - productBelongBusiness: ''; | ||
69 | - invoicingStatus: ''; | ||
70 | - invoiceIdentificationNumber: ''; | ||
71 | - invoicingTime: ''; | ||
72 | - bank: ''; | ||
73 | - bankAccountNumber: ''; | ||
74 | - deleteSubOrderLists: []; | ||
75 | - notes: ''; | ||
76 | - list: [ | ||
77 | - { | ||
78 | - productCode: ''; | ||
79 | - productName: ''; | ||
80 | - quantity: ''; | ||
81 | - productPrice: ''; | ||
82 | - parameters: ''; | ||
83 | - subOrderPayment: ''; | ||
84 | - unit: ''; | ||
85 | - serialNumber: ''; | ||
86 | - notes: ''; | ||
87 | - }, | ||
88 | - ]; | ||
89 | - }>(); | ||
90 | - | ||
91 | - let originSubOrders = cloneDeep(subOrders); | ||
92 | - /** | ||
93 | - * 获取当前的操作类型boolean值 | ||
94 | - * @param type 操作类型,如果与当前匹配返回true | ||
95 | - */ | ||
96 | - function optType(type: string) { | ||
97 | - return orderOptType === type; | ||
98 | - } | ||
99 | - | ||
100 | - /** | ||
101 | - * | ||
102 | - * @returns 获取开票选项 | ||
103 | - */ | ||
104 | - function getInvoicingSelect() { | ||
105 | - if (optType('edit')) { | ||
106 | - return enumToSelect(INVOCING_STATUS_OPTIONS_OLD); | ||
107 | - } | ||
108 | - return enumToSelect(INVOCING_STATUS_OPTIONS); | ||
109 | - } | ||
110 | - | ||
111 | - const fileList: any = []; | ||
112 | - | ||
113 | - const getSalesCodeOptions = async () => { | ||
114 | - const res = await postServiceOrderQuerySalesCode(); | ||
115 | - let options = res.data?.map((item) => { | ||
116 | - return { | ||
117 | - label: item.userName, | ||
118 | - value: item.userName, | ||
119 | - number: item.number, | ||
120 | - }; | ||
121 | - }); | ||
122 | - setSalesCodeOptions(options); | ||
123 | - | ||
124 | - if (optType('copy') || optType('edit')) { | ||
125 | - let includeFlag = false; | ||
126 | - //销售代码校验,如果是旧的销售代码,则提示并清空 | ||
127 | - for (let option of options) { | ||
128 | - if (option.value === data.salesCode) { | ||
129 | - includeFlag = true; | ||
130 | - } | ||
131 | - } | ||
132 | - if (!includeFlag) { | ||
133 | - form.resetFields(['salesCode']); | ||
134 | - message.warning('检测到销售代码为旧的,已清空,请重新选择'); | ||
135 | - } | ||
136 | - } | ||
137 | - }; | ||
138 | - | ||
139 | - //复制的时候,如果是不需要开票,要把开票信息清空 | ||
140 | - if (optType('copy') && data.invoicingStatus === 'UN_INVOICE') { | ||
141 | - data.invoiceIdentificationNumber = undefined; | ||
142 | - } | ||
143 | - | ||
144 | - if (subOrders !== undefined && subOrders.length > 0) { | ||
145 | - data.list = subOrders; | ||
146 | - } | ||
147 | - | ||
148 | - const actionRef = useRef< | ||
149 | - FormListActionType<{ | ||
150 | - name: string; | ||
151 | - }> | ||
152 | - >(); | ||
153 | - | ||
154 | - useEffect(() => { | ||
155 | - form.setFieldsValue({ ...data }); | ||
156 | - //如果是新建,需要清空list | ||
157 | - if (optType('add')) { | ||
158 | - form.resetFields(['list']); | ||
159 | - } | ||
160 | - }, [data]); | ||
161 | - | ||
162 | - /** | ||
163 | - * 选择客户后自动为收货人Select添加选项,填充课题组和单位信息 | ||
164 | - * @param option 客户选项 | ||
165 | - */ | ||
166 | - async function autoFillCustomerContactSelectOptions(customerId: any) { | ||
167 | - //查询单位详细信息 | ||
168 | - let res = await postKingdeeRepCustomerDetail({ | ||
169 | - data: { | ||
170 | - id: customerId, | ||
171 | - }, | ||
172 | - }); | ||
173 | - | ||
174 | - //erp客户名称 | ||
175 | - form.setFieldValue('erpCustomerName', res?.name); | ||
176 | - | ||
177 | - //重新设置当前option | ||
178 | - form.setFieldValue('erpCustomerId', { | ||
179 | - label: res?.name, | ||
180 | - value: res?.id, | ||
181 | - id: res?.id, | ||
182 | - }); | ||
183 | - | ||
184 | - //查询客户自定义字段,课题组 | ||
185 | - let entity_number = await getTeacherCustomFieldNumber(); | ||
186 | - | ||
187 | - //在单位详细信息中拿到自定义字段的值 | ||
188 | - let customField = res?.custom_field; | ||
189 | - if (customField) { | ||
190 | - let teacherName = customField[entity_number]; | ||
191 | - //填充到课题组老师表单字段中 | ||
192 | - form.setFieldValue('institutionContactName', teacherName); | ||
193 | - } | ||
194 | - | ||
195 | - //单位名称,从客户名称中获取,客户名称规则<单位名称>-<联系人名称和电话> | ||
196 | - let namePortions = res?.name?.split('-'); | ||
197 | - if (namePortions && namePortions.length >= 2) { | ||
198 | - form.setFieldValue('institution', namePortions[0]); | ||
199 | - } | ||
200 | - | ||
201 | - //如果原来的收货信息没有包含在这次查询出来的收货人选项中,那么清除原来的收货人信息 | ||
202 | - let existFlag = false; | ||
203 | - | ||
204 | - //填充收货人选项 | ||
205 | - let newProductCustomerContactOptions = res?.bomentity?.map((item) => { | ||
206 | - let address = | ||
207 | - item.contact_person + ',' + item.mobile + ',' + item.contact_address; | ||
208 | - if (address === data.contactAddress) { | ||
209 | - existFlag = true; | ||
210 | - } | ||
211 | - return { ...item, label: address, value: address }; | ||
212 | - }); | ||
213 | - | ||
214 | - setProductCustomerContactOptions(newProductCustomerContactOptions); | ||
215 | - | ||
216 | - if (!existFlag) { | ||
217 | - //清空原来的收货人信息 | ||
218 | - form.setFieldValue('customerShippingAddress', undefined); | ||
219 | - form.setFieldValue('customerContactNumber', undefined); | ||
220 | - form.setFieldValue('customerName', undefined); | ||
221 | - form.setFieldValue('erpCustomerAddress', undefined); | ||
222 | - } | ||
223 | - } | ||
224 | - | ||
225 | - /** | ||
226 | - * 回显金蝶信息 | ||
227 | - */ | ||
228 | - async function showKindeeInfo() { | ||
229 | - //客户信息 | ||
230 | - if (data.customerId) { | ||
231 | - //客户回显 | ||
232 | - autoFillCustomerContactSelectOptions(data.customerId); | ||
233 | - } | ||
234 | - | ||
235 | - //商品单位回显 | ||
236 | - let list = data?.subOrderInformationLists; | ||
237 | - if (list) { | ||
238 | - let newProductUnitOptionsList = [...productUnitOptionsList]; | ||
239 | - for (let i = 0; i < list.length; i++) { | ||
240 | - newProductUnitOptionsList[i] = [ | ||
241 | - { label: list[i].unit, value: list[i].unitId }, | ||
242 | - ]; | ||
243 | - } | ||
244 | - setProductUnitOptionsList(newProductUnitOptionsList); | ||
245 | - } | ||
246 | - } | ||
247 | - | ||
248 | - /** | ||
249 | - * | ||
250 | - * @param option 商品名称所对应的商品数据 | ||
251 | - * @param currentRowData list中当前行的数据 | ||
252 | - */ | ||
253 | - async function autoFillProductInfo( | ||
254 | - option: any, | ||
255 | - currentRowData: any, | ||
256 | - index: any, | ||
257 | - ) { | ||
258 | - let newProductParametersDisabledFlagList = [ | ||
259 | - ...productParametersDisabledFlagList, | ||
260 | - ]; | ||
261 | - let newProductUnitOptionsList = [...productUnitOptionsList]; | ||
262 | - newProductUnitOptionsList[index] = []; | ||
263 | - | ||
264 | - //是新增商品 | ||
265 | - if (option.type === 'add') { | ||
266 | - //商品参数开放权限可以编辑 | ||
267 | - newProductParametersDisabledFlagList[index] = false; | ||
268 | - | ||
269 | - //清空商品信息 | ||
270 | - let copyList = form.getFieldValue('list'); | ||
271 | - let currentData = copyList[index]; | ||
272 | - currentData.productCode = undefined; | ||
273 | - currentData.parameters = undefined; | ||
274 | - currentData.unit = undefined; | ||
275 | - currentData.subOrderPayment = undefined; | ||
276 | - currentData.quantity = undefined; | ||
277 | - currentData.notes = undefined; | ||
278 | - currentData.productPrice = undefined; | ||
279 | - form.setFieldValue('list', copyList); | ||
280 | - | ||
281 | - //查询计量单价列表 | ||
282 | - let res = await postKingdeeRepMeasureUnit({ data: {} }); | ||
283 | - if (res && res?.rows) { | ||
284 | - for (let row of res?.rows) { | ||
285 | - newProductUnitOptionsList[index].push({ | ||
286 | - label: row.name, | ||
287 | - value: row.id, | ||
288 | - }); | ||
289 | - } | ||
290 | - } | ||
291 | - } else { | ||
292 | - //选择的是已有的商品,进行内容自动填充 | ||
293 | - let copyList = form.getFieldValue('list'); | ||
294 | - let currentData = copyList[index]; | ||
295 | - currentData.productCode = option?.number; | ||
296 | - currentData.parameters = option?.model; | ||
297 | - currentData.unit = option?.base_unit_name; | ||
298 | - | ||
299 | - //商品id | ||
300 | - currentData.materialId = option?.id; | ||
301 | - | ||
302 | - //单位 | ||
303 | - currentData.unit = option.base_unit_name; | ||
304 | - currentData.unitId = option.base_unit_id; | ||
305 | - | ||
306 | - form.setFieldValue('list', copyList); | ||
307 | - | ||
308 | - //商品所在的仓库选项填充 | ||
309 | - // let res = await postKingdeeRepMaterialStock({ | ||
310 | - // data: { | ||
311 | - // material_id: option.id, | ||
312 | - // }, | ||
313 | - // }); | ||
314 | - // let newProductInvStockOptionsList = [...productInvStockOptionsList]; | ||
315 | - // newProductInvStockOptionsList[index] = res?.rows?.map((item) => { | ||
316 | - // return { label: item.inv_stock, value: item.inv_stock_id }; | ||
317 | - // }); | ||
318 | - // setProductInvStockOptionsList(newProductInvStockOptionsList); | ||
319 | - | ||
320 | - //商品单位填充,查询商品单位列表 | ||
321 | - let res = await postKingdeeRepMaterialUnit({ | ||
322 | - data: { material_id: option.id }, | ||
323 | - }); | ||
324 | - if (res && res.rows) { | ||
325 | - for (let row of res.rows) { | ||
326 | - newProductUnitOptionsList[index].push({ | ||
327 | - label: row.unit_name, | ||
328 | - value: row.unit_id, | ||
329 | - }); | ||
330 | - } | ||
331 | - } | ||
332 | - //商品参数不允许编辑 | ||
333 | - newProductParametersDisabledFlagList[index] = true; | ||
334 | - } | ||
335 | - | ||
336 | - setProductParametersDisabledFlagList(newProductParametersDisabledFlagList); | ||
337 | - setProductUnitOptionsList(newProductUnitOptionsList); | ||
338 | - } | ||
339 | - | ||
340 | - /** | ||
341 | - * 选择收货人后自动填充信息 | ||
342 | - * @param option 收货人信息 | ||
343 | - */ | ||
344 | - async function autoFillCustomerInfo(option: any) { | ||
345 | - form.setFieldValue('customerShippingAddress', option.contact_address); | ||
346 | - form.setFieldValue('customerContactNumber', option.mobile); | ||
347 | - form.setFieldValue('customerName', option.contact_person); | ||
348 | - | ||
349 | - //erp收货地址:需要与客户联系人中的地址一样:姓名,手机号,地址 | ||
350 | - form.setFieldValue('contactAddress', option.value); | ||
351 | - } | ||
352 | - | ||
353 | - /** | ||
354 | - * 填充销售代表的信息 | ||
355 | - * @param option | ||
356 | - */ | ||
357 | - function autoFillSalesInfo(option: any) { | ||
358 | - console.log(option); | ||
359 | - //销售代表对应职员编码填充 | ||
360 | - form.setFieldValue('empNumber', option.number); | ||
361 | - } | ||
362 | - | ||
363 | - /** | ||
364 | - * 选择商品单位后自动填充 | ||
365 | - * @param option | ||
366 | - * @param index | ||
367 | - */ | ||
368 | - function autoFillUnit(option: any, index: any) { | ||
369 | - let copyList = form.getFieldValue('list'); | ||
370 | - let currentData = copyList[index]; | ||
371 | - currentData.unit = option?.label; | ||
372 | - form.setFieldValue('list', copyList); | ||
373 | - } | ||
374 | - | ||
375 | - /** | ||
376 | - * 计算子订单金额 | ||
377 | - * @param listMeta 当前商品信息 | ||
378 | - */ | ||
379 | - function computeSubOrderPayment(listMeta: any) { | ||
380 | - let quantity = listMeta?.record?.quantity; | ||
381 | - let productPrice = listMeta?.record?.productPrice; | ||
382 | - quantity = quantity === '' || quantity === undefined ? 0 : quantity; | ||
383 | - productPrice = | ||
384 | - productPrice === '' || productPrice === undefined ? 0 : productPrice; | ||
385 | - | ||
386 | - listMeta.subOrderPayment = quantity * productPrice; | ||
387 | - let list = form.getFieldValue('list'); | ||
388 | - list[listMeta?.index].subOrderPayment = quantity * productPrice; | ||
389 | - form.setFieldValue('list', list); | ||
390 | - } | ||
391 | - | ||
392 | - /** | ||
393 | - * 计算支付总额 | ||
394 | - */ | ||
395 | - function computeTotalPayment() { | ||
396 | - let list = form.getFieldValue('list'); | ||
397 | - let totalPayment = 0; | ||
398 | - list?.forEach((subOrder: any) => { | ||
399 | - let subOrderPayment = subOrder?.subOrderPayment; | ||
400 | - if (subOrderPayment === '' || subOrderPayment === undefined) { | ||
401 | - totalPayment += 0; | ||
402 | - } else { | ||
403 | - totalPayment += subOrderPayment; | ||
404 | - } | ||
405 | - }); | ||
406 | - form.setFieldValue('totalPayment', totalPayment); | ||
407 | - } | ||
408 | - | ||
409 | - useEffect(() => { | ||
410 | - getSalesCodeOptions(); | ||
411 | - showKindeeInfo(); | ||
412 | - }, []); | ||
413 | - | ||
414 | - useEffect(() => { | ||
415 | - // 在组件挂载或数据变化时,更新组件状态 | ||
416 | - if (data) { | ||
417 | - setInvoicingStatus(data.invoicingStatus); | ||
418 | - } | ||
419 | - }, [data]); | ||
420 | - | ||
421 | - // let mainInfoDisbled = optType('edit'); | ||
422 | - if (optType('edit') || optType('copy')) { | ||
423 | - //如果是复制,需要开票,不回显是否需要开票字段 | ||
424 | - if (optType('copy')) { | ||
425 | - if (data.invoicingStatus === 'INVOICED') { | ||
426 | - data.invoicingStatus = undefined; | ||
427 | - } | ||
428 | - } | ||
429 | - //订单修改和新增的子订单列表命名是list | ||
430 | - data.list = data.subOrderInformationLists; | ||
431 | - //主订单事业部默认显示子订单第一条的事业部 | ||
432 | - data.productBelongBusiness = data.list[0].productBelongBusiness; | ||
433 | - data.paymentMethod = data.list[0].paymentMethod; | ||
434 | - data.paymentChannel = data.list[0].paymentChannel; | ||
435 | - data.invoicingStatus = data.list[0].invoicingStatus; | ||
436 | - | ||
437 | - data.list = data.list?.map((item) => { | ||
438 | - item.filePaths = item.listAnnex?.map((path) => { | ||
439 | - let i = 0; | ||
440 | - return { | ||
441 | - uid: i++, | ||
442 | - name: getAliYunOSSFileNameFromUrl(path), | ||
443 | - status: 'uploaded', | ||
444 | - url: path, | ||
445 | - response: { data: [path] }, | ||
446 | - }; | ||
447 | - }); | ||
448 | - return item; | ||
449 | - }); | ||
450 | - } | ||
451 | - | ||
452 | - return ( | ||
453 | - <> | ||
454 | - <DrawerForm<{ | ||
455 | - deleteSubOrderLists: any; | ||
456 | - name: string; | ||
457 | - company: string; | ||
458 | - }> | ||
459 | - open | ||
460 | - width="35%" | ||
461 | - title={optType('add') || optType('copy') ? '新建订单' : '修改订单'} | ||
462 | - resize={{ | ||
463 | - onResize() { | ||
464 | - console.log('resize!'); | ||
465 | - }, | ||
466 | - maxWidth: window.innerWidth * 0.8, | ||
467 | - minWidth: 400, | ||
468 | - }} | ||
469 | - // layout="horizontal" | ||
470 | - // labelCol={{ span: 8 }} | ||
471 | - form={form} | ||
472 | - autoFocusFirstInput | ||
473 | - drawerProps={{ | ||
474 | - destroyOnClose: true, | ||
475 | - maskClosable: false, | ||
476 | - }} | ||
477 | - submitTimeout={2000} | ||
478 | - onFinish={async (values) => { | ||
479 | - let res = {}; | ||
480 | - //附件处理 | ||
481 | - let list = values.list; | ||
482 | - // console.log(list); | ||
483 | - list = list.map((item) => { | ||
484 | - item.filePaths = item.filePaths?.map((file) => { | ||
485 | - console.log(file); | ||
486 | - return { url: file.response.data[0] }; | ||
487 | - }); | ||
488 | - return item; | ||
489 | - }); | ||
490 | - | ||
491 | - values.list = list; | ||
492 | - values.institution = values.institution?.trim(); | ||
493 | - values.institutionContactName = values.institutionContactName?.trim(); | ||
494 | - | ||
495 | - if (typeof values.erpCustomerId !== 'string') { | ||
496 | - values.erpCustomerId = values.erpCustomerId?.id; | ||
497 | - } | ||
498 | - | ||
499 | - if (optType('add') || optType('copy')) { | ||
500 | - res = await postServiceOrderAddOrder({ data: values }); | ||
501 | - } else { | ||
502 | - //计算已删除的子订单id | ||
503 | - const originIds = originSubOrders.map((item) => { | ||
504 | - return item.id; | ||
505 | - }); | ||
506 | - const curIds = form.getFieldValue('list')?.map((item) => { | ||
507 | - return item.id; | ||
508 | - }); | ||
509 | - let diff = originIds.filter((item) => !curIds.includes(item)); | ||
510 | - values.deleteSubOrderLists = diff; | ||
511 | - res = await postServiceOrderUpdateOrder({ data: values }); | ||
512 | - } | ||
513 | - | ||
514 | - if (res.result === RESPONSE_CODE.SUCCESS) { | ||
515 | - message.success(res.message); | ||
516 | - // 不返回不会关闭弹框 | ||
517 | - onClose(true); | ||
518 | - return true; | ||
519 | - } | ||
520 | - }} | ||
521 | - onOpenChange={(val) => { | ||
522 | - return !val && onClose(); | ||
523 | - }} | ||
524 | - > | ||
525 | - <h2>订单基本信息</h2> | ||
526 | - <ProFormText | ||
527 | - key="id" | ||
528 | - name="id" | ||
529 | - width="lg" | ||
530 | - disabled | ||
531 | - label="id" | ||
532 | - placeholder="id" | ||
533 | - hidden | ||
534 | - /> | ||
535 | - | ||
536 | - <ProFormText | ||
537 | - key="empNumber" | ||
538 | - name="empNumber" | ||
539 | - width="lg" | ||
540 | - label="销售职员编码" | ||
541 | - placeholder="销售职员编码" | ||
542 | - hidden | ||
543 | - /> | ||
544 | - | ||
545 | - <ProFormSelect | ||
546 | - name="salesCode" | ||
547 | - key="salesCode" | ||
548 | - width="lg" | ||
549 | - showSearch | ||
550 | - label="销售代表" | ||
551 | - placeholder="请输入销售代表" | ||
552 | - rules={[{ required: true, message: '销售代表必填' }]} | ||
553 | - options={salesCodeOptions} | ||
554 | - onChange={(_, option) => { | ||
555 | - autoFillSalesInfo(option); | ||
556 | - }} | ||
557 | - // disabled={mainInfoDisbled} | ||
558 | - /> | ||
559 | - | ||
560 | - <ProFormText | ||
561 | - key="erpCustomerName" | ||
562 | - name="erpCustomerName" | ||
563 | - hidden | ||
564 | - ></ProFormText> | ||
565 | - | ||
566 | - <ProFormText | ||
567 | - key="contactAddress" | ||
568 | - name="contactAddress" | ||
569 | - hidden | ||
570 | - ></ProFormText> | ||
571 | - | ||
572 | - <ProFormSelect | ||
573 | - name="erpCustomerId" | ||
574 | - key="erpCustomerId" | ||
575 | - width="lg" | ||
576 | - showSearch | ||
577 | - label={ | ||
578 | - <> | ||
579 | - <span>客户</span> | ||
580 | - <span | ||
581 | - className="pl-2 text-xs text-[#1677ff] cursor-pointer" | ||
582 | - onClick={() => { | ||
583 | - let customerId = form.getFieldValue('erpCustomerId'); | ||
584 | - if (typeof customerId === 'string') { | ||
585 | - setCustomer({ ...customer, id: customerId }); | ||
586 | - } else { | ||
587 | - setCustomer({ ...customer, id: customerId.id }); | ||
588 | - } | ||
589 | - setKingdeeCstomerModalVisible(true); | ||
590 | - }} | ||
591 | - > | ||
592 | - 编辑客户信息 | ||
593 | - </span> | ||
594 | - </> | ||
595 | - } | ||
596 | - placeholder="请选择客户" | ||
597 | - rules={[{ required: true, message: '客户必填' }]} | ||
598 | - onChange={(_, option) => { | ||
599 | - //新增客户 | ||
600 | - if (option.type === 'add') { | ||
601 | - setCustomer({ name: option.name }); | ||
602 | - setKingdeeCstomerModalVisible(true); | ||
603 | - return; | ||
604 | - } | ||
605 | - autoFillCustomerContactSelectOptions(option.id); | ||
606 | - }} | ||
607 | - initialValue={{ | ||
608 | - label: data?.erpCustomerName, | ||
609 | - value: data?.customerId, | ||
610 | - id: data?.customerId, | ||
611 | - }} | ||
612 | - fieldProps={{ | ||
613 | - optionItemRender(item) { | ||
614 | - if (item.type === 'add') { | ||
615 | - return ( | ||
616 | - <div title={item.name + '(新增客户)'}> | ||
617 | - <span style={{ color: '#333333' }}>{item.name}</span> | ||
618 | - {' | '} | ||
619 | - <span style={{ color: 'orange' }}>自定义</span> | ||
620 | - </div> | ||
621 | - ); | ||
622 | - } | ||
623 | - return ( | ||
624 | - <div | ||
625 | - title={ | ||
626 | - item.name + | ||
627 | - ' | ' + | ||
628 | - item.customerContactNumber + | ||
629 | - ' | ' + | ||
630 | - (item.customerShippingAddress === undefined | ||
631 | - ? '无地址' | ||
632 | - : item.customerShippingAddress) + | ||
633 | - ' | ' + | ||
634 | - item.institutionContactName + | ||
635 | - ' | ' + | ||
636 | - item.institution | ||
637 | - } | ||
638 | - > | ||
639 | - <span style={{ color: '#333333' }}>{item.name}</span> | ||
640 | - </div> | ||
641 | - ); | ||
642 | - }, | ||
643 | - }} | ||
644 | - debounceTime={1000} | ||
645 | - request={async (value, {}) => { | ||
646 | - const keywords = value.keyWords; | ||
647 | - const res = await postKingdeeRepCustomer({ | ||
648 | - data: { search: keywords }, | ||
649 | - }); | ||
650 | - console.log(res); | ||
651 | - | ||
652 | - let options = res?.rows?.map((c: any) => { | ||
653 | - return { | ||
654 | - ...c, | ||
655 | - label: c.name, | ||
656 | - value: c.id, | ||
657 | - key: c.id, | ||
658 | - }; | ||
659 | - }); | ||
660 | - | ||
661 | - //第一个商品默认为要新增客户 | ||
662 | - if (keywords.trim() !== '') { | ||
663 | - options.unshift({ | ||
664 | - name: keywords, | ||
665 | - type: 'add', | ||
666 | - label: keywords, | ||
667 | - value: 3.1415926, | ||
668 | - key: keywords, | ||
669 | - }); | ||
670 | - } | ||
671 | - return options; | ||
672 | - }} | ||
673 | - /> | ||
674 | - <ProFormSelect | ||
675 | - key="customerName" | ||
676 | - label="收货人" | ||
677 | - width="lg" | ||
678 | - showSearch | ||
679 | - name="customerName" | ||
680 | - placeholder="请选择收货人" | ||
681 | - rules={[{ required: true, message: '收货人必填' }]} | ||
682 | - onChange={(_, option) => { | ||
683 | - autoFillCustomerInfo(option); | ||
684 | - }} | ||
685 | - initialValue={data.contactAddress} | ||
686 | - options={productCustomerContactOptions} | ||
687 | - /> | ||
688 | - <ProFormText | ||
689 | - width="lg" | ||
690 | - key="customerContactNumber" | ||
691 | - name="customerContactNumber" | ||
692 | - label="联系方式" | ||
693 | - placeholder="请输入联系方式" | ||
694 | - rules={[{ required: true, message: '联系方式必填' }]} | ||
695 | - disabled | ||
696 | - /> | ||
697 | - <ProFormText | ||
698 | - width="lg" | ||
699 | - key="institution" | ||
700 | - name="institution" | ||
701 | - label="单位" | ||
702 | - placeholder="请输入单位" | ||
703 | - rules={[{ required: true, message: '单位必填' }]} | ||
704 | - disabled | ||
705 | - /> | ||
706 | - <ProFormText | ||
707 | - width="lg" | ||
708 | - key="institutionContactName" | ||
709 | - name="institutionContactName" | ||
710 | - label="课题组" | ||
711 | - placeholder="请输入课题组" | ||
712 | - rules={[{ required: true, message: '课题组必填' }]} | ||
713 | - disabled | ||
714 | - /> | ||
715 | - <ProFormTextArea | ||
716 | - width="lg" | ||
717 | - key="customerShippingAddress" | ||
718 | - name="customerShippingAddress" | ||
719 | - label="收货地址" | ||
720 | - placeholder="请输入收货地址" | ||
721 | - rules={[{ required: true, message: '收货地址必填' }]} | ||
722 | - disabled | ||
723 | - /> | ||
724 | - <div id="total-payment"> | ||
725 | - <ProFormDigit | ||
726 | - name="totalPayment" | ||
727 | - width="lg" | ||
728 | - key="totalPayment" | ||
729 | - label="支付总额(¥)" | ||
730 | - rules={[{ required: true, message: '支付总额必填' }]} | ||
731 | - tooltip="点击计算,合计所有子订单金额" | ||
732 | - fieldProps={{ | ||
733 | - addonAfter: ( | ||
734 | - <Button | ||
735 | - className="rounded-l-none" | ||
736 | - type="primary" | ||
737 | - onClick={computeTotalPayment} | ||
738 | - > | ||
739 | - 计算 | ||
740 | - </Button> | ||
741 | - ), | ||
742 | - }} | ||
743 | - // disabled={mainInfoDisbled} | ||
744 | - /> | ||
745 | - </div> | ||
746 | - | ||
747 | - <ProFormSelect | ||
748 | - placeholder="请输入支付渠道" | ||
749 | - name="paymentChannel" | ||
750 | - width="lg" | ||
751 | - key="paymentChannel" | ||
752 | - label="支付渠道" | ||
753 | - options={enumToSelect(PAYMENT_CHANNEL_OPTIONS)} | ||
754 | - rules={[{ required: true, message: '支付渠道必填' }]} | ||
755 | - // disabled={mainInfoDisbled} | ||
756 | - /> | ||
757 | - <ProFormSelect | ||
758 | - placeholder="请输入支付方式" | ||
759 | - name="paymentMethod" | ||
760 | - width="lg" | ||
761 | - key="paymentMethod" | ||
762 | - label="支付方式" | ||
763 | - options={enumToSelect(PAYMENT_METHOD_OPTIONS)} | ||
764 | - rules={[{ required: true, message: '支付方式必填' }]} | ||
765 | - // disabled={mainInfoDisbled} | ||
766 | - /> | ||
767 | - <ProFormSelect | ||
768 | - placeholder="选择是否需要开票" | ||
769 | - name="invoicingStatus" | ||
770 | - width="lg" | ||
771 | - key="invoicingStatus" | ||
772 | - label="是否需要开票" | ||
773 | - options={getInvoicingSelect()} | ||
774 | - // disabled={mainInfoDisbled} | ||
775 | - onChange={(_, option) => { | ||
776 | - setInvoicingStatus(option.value); | ||
777 | - if (option.value === 'UN_INVOICE') { | ||
778 | - form.setFieldValue('invoiceIdentificationNumber', undefined); | ||
779 | - form.setFieldValue('bank', undefined); | ||
780 | - form.setFieldValue('bankAccountNumber', undefined); | ||
781 | - } | ||
782 | - }} | ||
783 | - rules={[{ required: true, message: '是否需要开票必填' }]} | ||
784 | - /> | ||
785 | - <ProFormText | ||
786 | - width="lg" | ||
787 | - name="invoiceIdentificationNumber" | ||
788 | - label="开票信息" | ||
789 | - key="invoiceIdentificationNumber" | ||
790 | - // disabled={mainInfoDisbled} | ||
791 | - hidden={invoicingStatus === 'UN_INVOICE'} | ||
792 | - placeholder="请输入开票信息" | ||
793 | - rules={[ | ||
794 | - { | ||
795 | - required: invoicingStatus === 'UN_INVOICE' ? false : true, | ||
796 | - message: '开票信息必填', | ||
797 | - }, | ||
798 | - ]} | ||
799 | - /> | ||
800 | - | ||
801 | - {getUserInfo().roleSmallVO?.code === 'admin' ? ( | ||
802 | - <ProFormDateTimePicker | ||
803 | - width="lg" | ||
804 | - key="invoicingTime" | ||
805 | - name="invoicingTime" | ||
806 | - // disabled={mainInfoDisbled} | ||
807 | - hidden={invoicingStatus === 'UN_INVOICE'} | ||
808 | - label="开票时间" | ||
809 | - placeholder="请输入开票时间" | ||
810 | - /> | ||
811 | - ) : ( | ||
812 | - '' | ||
813 | - )} | ||
814 | - <ProFormText | ||
815 | - width="lg" | ||
816 | - name="bank" | ||
817 | - key="bank" | ||
818 | - label="开户银行" | ||
819 | - // disabled={mainInfoDisbled} | ||
820 | - hidden={invoicingStatus === 'UN_INVOICE'} | ||
821 | - placeholder="请输入开户银行" | ||
822 | - /> | ||
823 | - <ProFormText | ||
824 | - width="lg" | ||
825 | - key="bankAccountNumber" | ||
826 | - name="bankAccountNumber" | ||
827 | - hidden={invoicingStatus === 'UN_INVOICE'} | ||
828 | - label="银行账号" | ||
829 | - // disabled={mainInfoDisbled} | ||
830 | - placeholder="请输入银行账号" | ||
831 | - /> | ||
832 | - <ProFormTextArea | ||
833 | - width="lg" | ||
834 | - name="notes" | ||
835 | - label="备注" | ||
836 | - key="notes" | ||
837 | - // disabled={mainInfoDisbled} | ||
838 | - placeholder="请输入备注" | ||
839 | - rules={[ | ||
840 | - { | ||
841 | - max: 120, // 最大长度为120个字符 | ||
842 | - message: '备注不能超过120个字符', | ||
843 | - }, | ||
844 | - ]} | ||
845 | - /> | ||
846 | - | ||
847 | - <h2>商品信息</h2> | ||
848 | - <ProFormList | ||
849 | - creatorButtonProps={{ disabled: false }} | ||
850 | - name="list" | ||
851 | - label="" | ||
852 | - copyIconProps={false} //复制按钮不显示 | ||
853 | - initialValue={[ | ||
854 | - { | ||
855 | - productCode: '', | ||
856 | - productName: '', | ||
857 | - quantity: '', | ||
858 | - productPrice: '', | ||
859 | - parameters: '', | ||
860 | - subOrderPayment: '', | ||
861 | - }, | ||
862 | - ]} | ||
863 | - actionGuard={{ | ||
864 | - beforeRemoveRow: async (index) => { | ||
865 | - return new Promise((resolve) => { | ||
866 | - if (index === 0) { | ||
867 | - message.error('第一行数据不能删除'); | ||
868 | - resolve(false); | ||
869 | - return; | ||
870 | - } | ||
871 | - resolve(true); | ||
872 | - }); | ||
873 | - }, | ||
874 | - }} | ||
875 | - itemRender={(doms, listMeta) => { | ||
876 | - if (optType('edit')) { | ||
877 | - let i = 0; | ||
878 | - let defaultFileList = listMeta.record?.listAnnex?.map((annex) => { | ||
879 | - return { | ||
880 | - uid: i++, | ||
881 | - name: annex, | ||
882 | - status: 'uploaded', | ||
883 | - url: annex, | ||
884 | - response: { data: [annex] }, | ||
885 | - }; | ||
886 | - }); | ||
887 | - fileList[listMeta.index] = defaultFileList; | ||
888 | - } | ||
889 | - let itemFileList = fileList[listMeta.index]; | ||
890 | - return ( | ||
891 | - <ProCard | ||
892 | - bordered | ||
893 | - extra={doms.action} | ||
894 | - title={'商品' + (listMeta.index + 1)} | ||
895 | - style={{ | ||
896 | - marginBlockEnd: 8, | ||
897 | - }} | ||
898 | - > | ||
899 | - {[ | ||
900 | - <ProFormText | ||
901 | - key={'material' + listMeta.index} | ||
902 | - name="materialId" | ||
903 | - hidden | ||
904 | - ></ProFormText>, | ||
905 | - <ProFormSelect | ||
906 | - key="key" | ||
907 | - label="商品名称" | ||
908 | - width="lg" | ||
909 | - showSearch | ||
910 | - name="productName" | ||
911 | - // options={options} | ||
912 | - placeholder="请搜索商品" | ||
913 | - rules={[{ required: true, message: '商品名称必填' }]} | ||
914 | - onChange={(_, option) => { | ||
915 | - autoFillProductInfo(option, listMeta, listMeta.index); | ||
916 | - }} | ||
917 | - initialValue={{ | ||
918 | - label: listMeta?.record?.productName, | ||
919 | - value: listMeta?.record?.materialId, | ||
920 | - }} | ||
921 | - fieldProps={{ | ||
922 | - optionItemRender(item) { | ||
923 | - if (item.type === 'add') { | ||
924 | - return ( | ||
925 | - <div title={item.name + '(新增商品信息)'}> | ||
926 | - <span style={{ color: '#333333' }}> | ||
927 | - {item.label} | ||
928 | - </span> | ||
929 | - {' | '} | ||
930 | - <span style={{ color: 'orange' }}>新增商品</span> | ||
931 | - </div> | ||
932 | - ); | ||
933 | - } | ||
934 | - return ( | ||
935 | - <div | ||
936 | - title={ | ||
937 | - item.label + | ||
938 | - ' | ' + | ||
939 | - (item.model === undefined | ||
940 | - ? '无参数' | ||
941 | - : item.model) + | ||
942 | - ' | ' + | ||
943 | - item.base_unit_name | ||
944 | - } | ||
945 | - > | ||
946 | - <span style={{ color: '#333333' }}> | ||
947 | - {item.label} | ||
948 | - </span> | ||
949 | - {' | '} | ||
950 | - <span style={{ color: '#339999' }}> | ||
951 | - {item.model === undefined ? '无参数' : item.model} | ||
952 | - </span> | ||
953 | - {' | '} | ||
954 | - <span style={{ color: '#666666' }}> | ||
955 | - {item.base_unit_name === undefined | ||
956 | - ? '无单位' | ||
957 | - : item.base_unit_name} | ||
958 | - </span> | ||
959 | - </div> | ||
960 | - ); | ||
961 | - }, | ||
962 | - }} | ||
963 | - debounceTime={1000} | ||
964 | - request={async (value) => { | ||
965 | - const keywords = value.keyWords; | ||
966 | - const res = await postKingdeeRepMaterial({ | ||
967 | - data: { search: keywords }, | ||
968 | - }); | ||
969 | - let options = res?.rows?.map((p: any) => { | ||
970 | - return { | ||
971 | - ...p, | ||
972 | - label: p.name, | ||
973 | - value: p.id + '|' + p.name, | ||
974 | - key: p.id, | ||
975 | - }; | ||
976 | - }); | ||
977 | - | ||
978 | - //第一个商品默认为要新增的商品 | ||
979 | - if (keywords.trim() !== '') { | ||
980 | - options.unshift({ | ||
981 | - productName: keywords, | ||
982 | - type: 'add', | ||
983 | - label: keywords, | ||
984 | - value: 13 + '|' + keywords, | ||
985 | - key: keywords, | ||
986 | - }); | ||
987 | - } | ||
988 | - return options; | ||
989 | - }} | ||
990 | - />, | ||
991 | - <ProFormText | ||
992 | - key={'productCode' + listMeta.index} | ||
993 | - width="lg" | ||
994 | - name="productCode" | ||
995 | - disabled | ||
996 | - label={ | ||
997 | - <> | ||
998 | - <span>商品编码</span> | ||
999 | - <span className="pl-2 text-xs text-gray-400"> | ||
1000 | - 新增商品时,商品编码由系统自动生成 | ||
1001 | - </span> | ||
1002 | - </> | ||
1003 | - } | ||
1004 | - placeholder="商品编码" | ||
1005 | - />, | ||
1006 | - // <ProFormSelect | ||
1007 | - // key="inv_stock" | ||
1008 | - // placeholder="请选择仓库" | ||
1009 | - // name="invStockId" | ||
1010 | - // width="lg" | ||
1011 | - // label="仓库" | ||
1012 | - // options={productInvStockOptionsList[listMeta.index]} | ||
1013 | - // />, | ||
1014 | - <ProFormText | ||
1015 | - key={'parameters' + listMeta.index} | ||
1016 | - width="lg" | ||
1017 | - name="parameters" | ||
1018 | - label="商品参数" | ||
1019 | - placeholder="请输入商品参数" | ||
1020 | - rules={[{ required: true, message: '商品参数必填' }]} | ||
1021 | - disabled={ | ||
1022 | - productParametersDisabledFlagList[listMeta.index] !== | ||
1023 | - false | ||
1024 | - } | ||
1025 | - />, | ||
1026 | - <ProFormDigit | ||
1027 | - key={'quantity' + listMeta.index} | ||
1028 | - width="lg" | ||
1029 | - name="quantity" | ||
1030 | - label="商品数量" | ||
1031 | - fieldProps={{ | ||
1032 | - onChange: (value) => { | ||
1033 | - listMeta.record.quantity = value; | ||
1034 | - computeSubOrderPayment(listMeta); | ||
1035 | - }, | ||
1036 | - }} | ||
1037 | - placeholder="请输入商品数量" | ||
1038 | - rules={[{ required: true, message: '商品数量必填' }]} | ||
1039 | - />, | ||
1040 | - | ||
1041 | - <ProFormDigit | ||
1042 | - key={'productPrice' + listMeta.index} | ||
1043 | - width="lg" | ||
1044 | - name="productPrice" | ||
1045 | - label="商品单价" | ||
1046 | - fieldProps={{ | ||
1047 | - onChange: (value) => { | ||
1048 | - listMeta.record.productPrice = value; | ||
1049 | - computeSubOrderPayment(listMeta); | ||
1050 | - }, | ||
1051 | - }} | ||
1052 | - placeholder="请输入商品单价" | ||
1053 | - rules={[{ required: true, message: '商品单价必填' }]} | ||
1054 | - />, | ||
1055 | - | ||
1056 | - <ProFormSelect | ||
1057 | - key="unitId" | ||
1058 | - placeholder="请选择单位" | ||
1059 | - name="unitId" | ||
1060 | - width="lg" | ||
1061 | - label="单位" | ||
1062 | - showSearch | ||
1063 | - onChange={(_, option) => { | ||
1064 | - autoFillUnit(option, listMeta.index); | ||
1065 | - }} | ||
1066 | - options={productUnitOptionsList[listMeta.index]} | ||
1067 | - rules={[{ required: true, message: '商品单位必填' }]} | ||
1068 | - />, | ||
1069 | - <ProFormText | ||
1070 | - key={'unit' + listMeta.index} | ||
1071 | - width="lg" | ||
1072 | - name="unit" | ||
1073 | - label="商品单位" | ||
1074 | - placeholder="请输入商品单位" | ||
1075 | - rules={[{ required: true, message: '商品单位必填' }]} | ||
1076 | - hidden | ||
1077 | - />, | ||
1078 | - | ||
1079 | - <ProFormDigit | ||
1080 | - width="lg" | ||
1081 | - key={'subOrderPayment' + listMeta.index} | ||
1082 | - name="subOrderPayment" | ||
1083 | - label="子订单金额" | ||
1084 | - placeholder="请输入子订单金额" | ||
1085 | - tooltip="商品数量和单价变化后会自动计算子订单金额" | ||
1086 | - rules={[{ required: true, message: '子订单金额必填' }]} | ||
1087 | - />, | ||
1088 | - <ProFormSelect | ||
1089 | - key={'productBelongBusiness' + listMeta.index} | ||
1090 | - placeholder="请输入所属事业部" | ||
1091 | - name="productBelongBusiness" | ||
1092 | - width="lg" | ||
1093 | - label="所属事业部" | ||
1094 | - options={enumToSelect(PRODUCT_BELONG_DEPARTMENT_OPTIONS)} | ||
1095 | - initialValue={'EXPERIMENTAL_CONSUMABLES'} | ||
1096 | - rules={[{ required: true, message: '所属事业部必填' }]} | ||
1097 | - // disabled={mainInfoDisbled} | ||
1098 | - />, | ||
1099 | - <ProFormTextArea | ||
1100 | - key={'notes' + listMeta.index} | ||
1101 | - width="lg" | ||
1102 | - name="notes" | ||
1103 | - label={ | ||
1104 | - <div> | ||
1105 | - <span>备注</span> | ||
1106 | - <span className="pl-2 text-xs text-gray-400"> | ||
1107 | - 备注将体现在出货单上,请将需要仓管看见的信息写在备注上,例如需要开收据等信息。 | ||
1108 | - </span> | ||
1109 | - </div> | ||
1110 | - } | ||
1111 | - placeholder="请输入备注" | ||
1112 | - rules={[ | ||
1113 | - { | ||
1114 | - max: 120, // 最大长度为120个字符 | ||
1115 | - message: '备注不能超过120个字符', | ||
1116 | - }, | ||
1117 | - ]} | ||
1118 | - />, | ||
1119 | - <> | ||
1120 | - <ProFormUploadDragger | ||
1121 | - key={'filePaths' + listMeta.index} | ||
1122 | - label="附件" | ||
1123 | - name="filePaths" | ||
1124 | - action="/api/service/order/fileProcess" | ||
1125 | - fieldProps={{ | ||
1126 | - headers: { | ||
1127 | - Authorization: localStorage.getItem('token'), | ||
1128 | - }, | ||
1129 | - itemFileList, | ||
1130 | - }} | ||
1131 | - /> | ||
1132 | - </>, | ||
1133 | - ]} | ||
1134 | - </ProCard> | ||
1135 | - ); | ||
1136 | - }} | ||
1137 | - actionRef={actionRef} | ||
1138 | - ></ProFormList> | ||
1139 | - </DrawerForm> | ||
1140 | - | ||
1141 | - {kingdeeCstomerModalVisible && ( | ||
1142 | - <KingdeeCustomerModal | ||
1143 | - setVisible={setKingdeeCstomerModalVisible} | ||
1144 | - data={customer} | ||
1145 | - onClose={(customerId: any) => { | ||
1146 | - setKingdeeCstomerModalVisible(false); | ||
1147 | - //回显已经新建好的客户 | ||
1148 | - autoFillCustomerContactSelectOptions(customerId); | ||
1149 | - }} | ||
1150 | - /> | ||
1151 | - )} | ||
1152 | - </> | ||
1153 | - ); | ||
1154 | -}; |
src/pages/Order/OrderList/OrderDrawer.tsx
@@ -32,8 +32,8 @@ import { getTeacherCustomFieldNumber } from '@/utils/kingdee'; | @@ -32,8 +32,8 @@ import { getTeacherCustomFieldNumber } from '@/utils/kingdee'; | ||
32 | import { getSalesCodeOptions } from '@/utils/order'; | 32 | import { getSalesCodeOptions } from '@/utils/order'; |
33 | import { getDefaultString } from '@/utils/StringUtil'; | 33 | import { getDefaultString } from '@/utils/StringUtil'; |
34 | import { | 34 | import { |
35 | - DrawerForm, | ||
36 | FormListActionType, | 35 | FormListActionType, |
36 | + ModalForm, | ||
37 | ProCard, | 37 | ProCard, |
38 | ProFormDatePicker, | 38 | ProFormDatePicker, |
39 | ProFormDateTimePicker, | 39 | ProFormDateTimePicker, |
@@ -760,14 +760,14 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | @@ -760,14 +760,14 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | ||
760 | 760 | ||
761 | return ( | 761 | return ( |
762 | <> | 762 | <> |
763 | - <DrawerForm<{ | 763 | + <ModalForm<{ |
764 | isLocalData: any; | 764 | isLocalData: any; |
765 | deleteSubOrderLists: any; | 765 | deleteSubOrderLists: any; |
766 | name: string; | 766 | name: string; |
767 | company: string; | 767 | company: string; |
768 | }> | 768 | }> |
769 | open | 769 | open |
770 | - width="35%" | 770 | + width={1000} |
771 | title={drawerTitle} | 771 | title={drawerTitle} |
772 | resize={{ | 772 | resize={{ |
773 | onResize() { | 773 | onResize() { |
@@ -1913,6 +1913,9 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | @@ -1913,6 +1913,9 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | ||
1913 | value: listMeta?.record?.materialId, | 1913 | value: listMeta?.record?.materialId, |
1914 | }} | 1914 | }} |
1915 | fieldProps={{ | 1915 | fieldProps={{ |
1916 | + popupMatchSelectWidth: false, | ||
1917 | + listHeight: 400, | ||
1918 | + dropdownStyle: { width: '55%' }, | ||
1916 | filterOption() { | 1919 | filterOption() { |
1917 | return true; | 1920 | return true; |
1918 | }, | 1921 | }, |
@@ -2230,7 +2233,7 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | @@ -2230,7 +2233,7 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | ||
2230 | }} | 2233 | }} |
2231 | actionRef={actionRef} | 2234 | actionRef={actionRef} |
2232 | ></ProFormList> | 2235 | ></ProFormList> |
2233 | - </DrawerForm> | 2236 | + </ModalForm> |
2234 | {kingdeeCstomerModalVisible && ( | 2237 | {kingdeeCstomerModalVisible && ( |
2235 | <KingdeeCustomerModal | 2238 | <KingdeeCustomerModal |
2236 | setVisible={setKingdeeCstomerModalVisible} | 2239 | setVisible={setKingdeeCstomerModalVisible} |
src/pages/Prepaid/components/PointsExchangeModal.tsx
0 → 100644
1 | +import { postIntegralExchangeIntegral } from '@/services/request'; | ||
2 | +import { | ||
3 | + ModalForm, | ||
4 | + ProFormInstance, | ||
5 | + ProFormTextArea, | ||
6 | +} from '@ant-design/pro-components'; | ||
7 | +import { Form, Input, message } from 'antd'; | ||
8 | +import React, { useEffect, useRef, useState } from 'react'; | ||
9 | +import '../index.less'; | ||
10 | + | ||
11 | +interface PointsExchangeModalProps { | ||
12 | + setVisible: (visible: boolean) => void; | ||
13 | + userInfoObj: { | ||
14 | + uid: string; | ||
15 | + nickname?: string; | ||
16 | + realName?: string; | ||
17 | + [key: string]: any; | ||
18 | + }; | ||
19 | + onClose: () => void; | ||
20 | +} | ||
21 | + | ||
22 | +const PointsExchangeModal: React.FC<PointsExchangeModalProps> = ({ | ||
23 | + setVisible, | ||
24 | + userInfoObj, | ||
25 | + onClose, | ||
26 | +}) => { | ||
27 | + const [form] = Form.useForm<{ delta: string; remark: string }>(); | ||
28 | + const formRef = useRef<ProFormInstance>(); | ||
29 | + const uid = userInfoObj?.uid; | ||
30 | + const userName = userInfoObj?.nickname || userInfoObj?.realName || ''; | ||
31 | + const [accountPoints, setAccountPoints] = useState<number>(0); | ||
32 | + | ||
33 | + useEffect(() => { | ||
34 | + if (userInfoObj && userInfoObj.delta) { | ||
35 | + setAccountPoints(Number(userInfoObj.delta) || 0); | ||
36 | + } | ||
37 | + }, [userInfoObj]); | ||
38 | + | ||
39 | + // Validate that delta is not greater than available points | ||
40 | + const validateDelta = (rule: any, value: string) => { | ||
41 | + const deltaValue = Number(value); | ||
42 | + if (isNaN(deltaValue)) { | ||
43 | + return Promise.reject('请输入有效的积分数值'); | ||
44 | + } | ||
45 | + if (deltaValue <= 0) { | ||
46 | + return Promise.reject('兑换积分必须大于0'); | ||
47 | + } | ||
48 | + if (deltaValue > accountPoints) { | ||
49 | + return Promise.reject('兑换积分不能大于账户积分'); | ||
50 | + } | ||
51 | + return Promise.resolve(); | ||
52 | + }; | ||
53 | + | ||
54 | + return ( | ||
55 | + <div className="prepaid-index"> | ||
56 | + <ModalForm<{ | ||
57 | + delta: string; | ||
58 | + remark: string; | ||
59 | + }> | ||
60 | + width={600} | ||
61 | + open | ||
62 | + title="积分兑换" | ||
63 | + form={form} | ||
64 | + formRef={formRef} | ||
65 | + autoFocusFirstInput | ||
66 | + submitter={{ | ||
67 | + searchConfig: { | ||
68 | + submitText: '确认兑换', | ||
69 | + resetText: '取消', | ||
70 | + }, | ||
71 | + }} | ||
72 | + modalProps={{ | ||
73 | + destroyOnClose: true, | ||
74 | + onCancel: () => { | ||
75 | + setVisible(false); | ||
76 | + }, | ||
77 | + }} | ||
78 | + onFinish={async (values) => { | ||
79 | + try { | ||
80 | + // 调用积分兑换API | ||
81 | + await postIntegralExchangeIntegral({ | ||
82 | + data: { | ||
83 | + id: Number(uid), // 使用用户的uid作为id参数 | ||
84 | + delta: values.delta, // 将delta设为负数 | ||
85 | + remark: values.remark, // 兑换说明 | ||
86 | + relationEntityType: 'USER', // 关联实体类型 | ||
87 | + createByName: userName, // 使用昵称或真实姓名作为createByName | ||
88 | + }, | ||
89 | + }); | ||
90 | + | ||
91 | + message.success('积分兑换成功'); | ||
92 | + setVisible(false); | ||
93 | + onClose(); | ||
94 | + return true; | ||
95 | + } catch (error) { | ||
96 | + console.error(error); | ||
97 | + return false; | ||
98 | + } | ||
99 | + }} | ||
100 | + onOpenChange={setVisible} | ||
101 | + > | ||
102 | + <Form.Item | ||
103 | + label="兑换积分" | ||
104 | + name="delta" | ||
105 | + rules={[ | ||
106 | + { required: true, message: '请输入兑换积分' }, | ||
107 | + { validator: validateDelta }, | ||
108 | + ]} | ||
109 | + > | ||
110 | + <Input style={{ height: '30px' }} placeholder="请输入兑换积分数量" /> | ||
111 | + </Form.Item> | ||
112 | + | ||
113 | + <Form.Item | ||
114 | + label="兑换说明" | ||
115 | + name="remark" | ||
116 | + rules={[{ required: true, message: '请输入兑换说明' }]} | ||
117 | + > | ||
118 | + <ProFormTextArea | ||
119 | + style={{ height: '100px' }} | ||
120 | + placeholder="请输入兑换说明" | ||
121 | + /> | ||
122 | + </Form.Item> | ||
123 | + </ModalForm> | ||
124 | + </div> | ||
125 | + ); | ||
126 | +}; | ||
127 | + | ||
128 | +export default PointsExchangeModal; |
src/pages/Prepaid/components/PointsExchangeRecordsModal.tsx
0 → 100644
1 | +import { postIntegralUserExchangeRecords } from '@/services'; | ||
2 | +import { formatDateTime } from '@/utils'; | ||
3 | +import { Button, DatePicker, Empty, Modal, Space, Table, Tabs } from 'antd'; | ||
4 | +import React, { useEffect, useState } from 'react'; | ||
5 | +import '../index.less'; | ||
6 | + | ||
7 | +interface PointsExchangeRecordsModalProps { | ||
8 | + setVisible: (visible: boolean) => void; | ||
9 | + userInfoObj: { | ||
10 | + uid: string; | ||
11 | + phone?: string; | ||
12 | + nickname?: string; | ||
13 | + realName?: string; | ||
14 | + [key: string]: any; | ||
15 | + }; | ||
16 | + onClose: () => void; | ||
17 | +} | ||
18 | + | ||
19 | +interface RecordItem { | ||
20 | + createByName: string | null; | ||
21 | + createTime: string; | ||
22 | + delta: number; | ||
23 | + remark: string | null; | ||
24 | + sourceId: string | null; | ||
25 | +} | ||
26 | + | ||
27 | +interface RecordsData { | ||
28 | + exchangeRecords: RecordItem[]; | ||
29 | + collectedRecords: RecordItem[]; | ||
30 | + pendingRecords: RecordItem[]; | ||
31 | +} | ||
32 | + | ||
33 | +const PointsExchangeRecordsModal: React.FC<PointsExchangeRecordsModalProps> = ({ | ||
34 | + setVisible, | ||
35 | + userInfoObj, | ||
36 | + onClose, | ||
37 | +}) => { | ||
38 | + const [activeTab, setActiveTab] = useState<string>('1'); | ||
39 | + const [loading, setLoading] = useState<boolean>(false); | ||
40 | + const [recordsData, setRecordsData] = useState<RecordsData>({ | ||
41 | + exchangeRecords: [], | ||
42 | + collectedRecords: [], | ||
43 | + pendingRecords: [], | ||
44 | + }); | ||
45 | + | ||
46 | + // Add date range state for each tab | ||
47 | + const [exchangeStartTime, setExchangeStartTime] = useState<string | null>( | ||
48 | + null, | ||
49 | + ); | ||
50 | + const [exchangeEndTime, setExchangeEndTime] = useState<string | null>(null); | ||
51 | + const [collectedStartTime, setCollectedStartTime] = useState<string | null>( | ||
52 | + null, | ||
53 | + ); | ||
54 | + const [collectedEndTime, setCollectedEndTime] = useState<string | null>(null); | ||
55 | + const [pendingStartTime, setPendingStartTime] = useState<string | null>(null); | ||
56 | + const [pendingEndTime, setPendingEndTime] = useState<string | null>(null); | ||
57 | + | ||
58 | + const uid = userInfoObj?.uid; | ||
59 | + const phone = userInfoObj?.phone; | ||
60 | + | ||
61 | + // Function to fetch records data from API with date parameters | ||
62 | + const fetchRecordsData = async ( | ||
63 | + params: { | ||
64 | + startTime?: string | null; | ||
65 | + endTime?: string | null; | ||
66 | + tabKey?: string; | ||
67 | + } = {}, | ||
68 | + ) => { | ||
69 | + try { | ||
70 | + setLoading(true); | ||
71 | + const { startTime, endTime, tabKey } = params; | ||
72 | + | ||
73 | + // Prepare API request data | ||
74 | + const requestData: any = { | ||
75 | + id: Number(uid), | ||
76 | + phone: phone, | ||
77 | + }; | ||
78 | + | ||
79 | + // Add date range if provided | ||
80 | + if (startTime) requestData.startTime = startTime; | ||
81 | + if (endTime) requestData.endTime = endTime; | ||
82 | + | ||
83 | + const response = await postIntegralUserExchangeRecords({ | ||
84 | + data: requestData, | ||
85 | + }); | ||
86 | + | ||
87 | + if (response && response.data) { | ||
88 | + // Update only the data for the active tab if tabKey is provided | ||
89 | + if (tabKey) { | ||
90 | + setRecordsData((prevData) => { | ||
91 | + const newData = { ...prevData }; | ||
92 | + | ||
93 | + if (tabKey === '1') { | ||
94 | + newData.exchangeRecords = response.data.exchangeRecords || []; | ||
95 | + } else if (tabKey === '2') { | ||
96 | + newData.collectedRecords = response.data.collectedRecords || []; | ||
97 | + } else if (tabKey === '3') { | ||
98 | + newData.pendingRecords = response.data.pendingRecords || []; | ||
99 | + } | ||
100 | + | ||
101 | + return newData; | ||
102 | + }); | ||
103 | + } else { | ||
104 | + // Update all data if no specific tab is targeted | ||
105 | + setRecordsData({ | ||
106 | + exchangeRecords: response.data.exchangeRecords || [], | ||
107 | + collectedRecords: response.data.collectedRecords || [], | ||
108 | + pendingRecords: response.data.pendingRecords || [], | ||
109 | + }); | ||
110 | + } | ||
111 | + } | ||
112 | + } catch (error) { | ||
113 | + console.error('Failed to fetch exchange records:', error); | ||
114 | + } finally { | ||
115 | + setLoading(false); | ||
116 | + } | ||
117 | + }; | ||
118 | + | ||
119 | + // Fetch records data when component mounts | ||
120 | + useEffect(() => { | ||
121 | + if (uid || phone) { | ||
122 | + fetchRecordsData(); | ||
123 | + } | ||
124 | + }, [uid, phone]); | ||
125 | + | ||
126 | + // Exchange records columns | ||
127 | + const exchangeRecordsColumns = [ | ||
128 | + { | ||
129 | + title: '兑换日期', | ||
130 | + dataIndex: 'createTime', | ||
131 | + key: 'createTime', | ||
132 | + width: 160, | ||
133 | + render: (text: string) => formatDateTime(text), | ||
134 | + }, | ||
135 | + { | ||
136 | + title: '扣除积分', | ||
137 | + dataIndex: 'delta', | ||
138 | + key: 'delta', | ||
139 | + width: 100, | ||
140 | + render: (delta: number) => ( | ||
141 | + <span style={{ color: delta < 0 ? 'green' : 'red' }}>{delta}</span> | ||
142 | + ), | ||
143 | + }, | ||
144 | + { | ||
145 | + title: '操作人', | ||
146 | + dataIndex: 'createByName', | ||
147 | + key: 'createByName', | ||
148 | + width: 100, | ||
149 | + render: (text: string | null) => text || '-', | ||
150 | + }, | ||
151 | + { | ||
152 | + title: '积分用途', | ||
153 | + dataIndex: 'remark', | ||
154 | + key: 'remark', | ||
155 | + render: (text: string | null) => text || '-', | ||
156 | + }, | ||
157 | + ]; | ||
158 | + | ||
159 | + // Collected records columns | ||
160 | + const collectedRecordsColumns = [ | ||
161 | + { | ||
162 | + title: '订单号', | ||
163 | + dataIndex: 'sourceId', | ||
164 | + key: 'sourceId', | ||
165 | + render: (text: string | null) => text || '-', | ||
166 | + }, | ||
167 | + { | ||
168 | + title: '领取积分', | ||
169 | + dataIndex: 'delta', | ||
170 | + key: 'delta', | ||
171 | + render: (delta: number) => ( | ||
172 | + <span style={{ color: delta > 0 ? 'green' : 'red' }}>{delta}</span> | ||
173 | + ), | ||
174 | + }, | ||
175 | + { | ||
176 | + title: '领取日期', | ||
177 | + dataIndex: 'createTime', | ||
178 | + key: 'createTime', | ||
179 | + render: (text: string) => formatDateTime(text), | ||
180 | + }, | ||
181 | + ]; | ||
182 | + | ||
183 | + // Pending records columns | ||
184 | + const pendingRecordsColumns = [ | ||
185 | + { | ||
186 | + title: '订单号', | ||
187 | + dataIndex: 'sourceId', | ||
188 | + key: 'sourceId', | ||
189 | + render: (text: string | null) => text || '-', | ||
190 | + }, | ||
191 | + { | ||
192 | + title: '领取积分', | ||
193 | + dataIndex: 'delta', | ||
194 | + key: 'delta', | ||
195 | + render: (delta: number) => ( | ||
196 | + <span style={{ color: delta > 0 ? 'green' : 'red' }}>{delta}</span> | ||
197 | + ), | ||
198 | + }, | ||
199 | + { | ||
200 | + title: '过期日期', | ||
201 | + dataIndex: 'createTime', | ||
202 | + key: 'createTime', | ||
203 | + render: (text: string) => formatDateTime(text), | ||
204 | + }, | ||
205 | + ]; | ||
206 | + | ||
207 | + // Tab items | ||
208 | + const tabItems = [ | ||
209 | + { | ||
210 | + key: '1', | ||
211 | + label: '兑换记录', | ||
212 | + children: ( | ||
213 | + <> | ||
214 | + <div | ||
215 | + style={{ marginBottom: 16, display: 'flex', alignItems: 'center' }} | ||
216 | + > | ||
217 | + <span>兑换日期:</span> | ||
218 | + <Space> | ||
219 | + <DatePicker | ||
220 | + placeholder="开始日期" | ||
221 | + onChange={(date, dateString) => | ||
222 | + setExchangeStartTime(dateString) | ||
223 | + } | ||
224 | + style={{ width: 150 }} | ||
225 | + /> | ||
226 | + <DatePicker | ||
227 | + placeholder="结束日期" | ||
228 | + onChange={(date, dateString) => setExchangeEndTime(dateString)} | ||
229 | + style={{ width: 150 }} | ||
230 | + /> | ||
231 | + <Button | ||
232 | + type="primary" | ||
233 | + onClick={() => | ||
234 | + fetchRecordsData({ | ||
235 | + startTime: exchangeStartTime, | ||
236 | + endTime: exchangeEndTime, | ||
237 | + tabKey: '1', | ||
238 | + }) | ||
239 | + } | ||
240 | + > | ||
241 | + 查询 | ||
242 | + </Button> | ||
243 | + </Space> | ||
244 | + </div> | ||
245 | + <Table | ||
246 | + columns={exchangeRecordsColumns} | ||
247 | + dataSource={recordsData.exchangeRecords.map((item, index) => ({ | ||
248 | + ...item, | ||
249 | + key: `exchange-${index}`, | ||
250 | + }))} | ||
251 | + pagination={{ pageSize: 5 }} | ||
252 | + loading={loading && activeTab === '1'} | ||
253 | + locale={{ | ||
254 | + emptyText: <Empty description="暂无兑换记录" />, | ||
255 | + }} | ||
256 | + /> | ||
257 | + </> | ||
258 | + ), | ||
259 | + }, | ||
260 | + { | ||
261 | + key: '2', | ||
262 | + label: '已领取积分', | ||
263 | + children: ( | ||
264 | + <> | ||
265 | + <div | ||
266 | + style={{ marginBottom: 16, display: 'flex', alignItems: 'center' }} | ||
267 | + > | ||
268 | + <span>领取日期:</span> | ||
269 | + <Space> | ||
270 | + <DatePicker | ||
271 | + placeholder="开始日期" | ||
272 | + onChange={(date, dateString) => | ||
273 | + setCollectedStartTime(dateString) | ||
274 | + } | ||
275 | + style={{ width: 150 }} | ||
276 | + /> | ||
277 | + <DatePicker | ||
278 | + placeholder="结束日期" | ||
279 | + onChange={(date, dateString) => setCollectedEndTime(dateString)} | ||
280 | + style={{ width: 150 }} | ||
281 | + /> | ||
282 | + <Button | ||
283 | + type="primary" | ||
284 | + onClick={() => | ||
285 | + fetchRecordsData({ | ||
286 | + startTime: collectedStartTime, | ||
287 | + endTime: collectedEndTime, | ||
288 | + tabKey: '2', | ||
289 | + }) | ||
290 | + } | ||
291 | + > | ||
292 | + 查询 | ||
293 | + </Button> | ||
294 | + </Space> | ||
295 | + </div> | ||
296 | + <Table | ||
297 | + columns={collectedRecordsColumns} | ||
298 | + dataSource={recordsData.collectedRecords.map((item, index) => ({ | ||
299 | + ...item, | ||
300 | + key: `collected-${index}`, | ||
301 | + }))} | ||
302 | + pagination={{ pageSize: 5 }} | ||
303 | + loading={loading && activeTab === '2'} | ||
304 | + locale={{ | ||
305 | + emptyText: <Empty description="暂无已领取积分记录" />, | ||
306 | + }} | ||
307 | + /> | ||
308 | + </> | ||
309 | + ), | ||
310 | + }, | ||
311 | + { | ||
312 | + key: '3', | ||
313 | + label: '待领取积分', | ||
314 | + children: ( | ||
315 | + <> | ||
316 | + <div | ||
317 | + style={{ marginBottom: 16, display: 'flex', alignItems: 'center' }} | ||
318 | + > | ||
319 | + <span>过期日期:</span> | ||
320 | + <Space> | ||
321 | + <DatePicker | ||
322 | + placeholder="开始日期" | ||
323 | + onChange={(date, dateString) => setPendingStartTime(dateString)} | ||
324 | + style={{ width: 150 }} | ||
325 | + /> | ||
326 | + <DatePicker | ||
327 | + placeholder="结束日期" | ||
328 | + onChange={(date, dateString) => setPendingEndTime(dateString)} | ||
329 | + style={{ width: 150 }} | ||
330 | + /> | ||
331 | + <Button | ||
332 | + type="primary" | ||
333 | + onClick={() => | ||
334 | + fetchRecordsData({ | ||
335 | + startTime: pendingStartTime, | ||
336 | + endTime: pendingEndTime, | ||
337 | + tabKey: '3', | ||
338 | + }) | ||
339 | + } | ||
340 | + > | ||
341 | + 查询 | ||
342 | + </Button> | ||
343 | + </Space> | ||
344 | + </div> | ||
345 | + <Table | ||
346 | + columns={pendingRecordsColumns} | ||
347 | + dataSource={recordsData.pendingRecords.map((item, index) => ({ | ||
348 | + ...item, | ||
349 | + key: `pending-${index}`, | ||
350 | + }))} | ||
351 | + pagination={{ pageSize: 5 }} | ||
352 | + loading={loading && activeTab === '3'} | ||
353 | + locale={{ | ||
354 | + emptyText: <Empty description="暂无待领取积分记录" />, | ||
355 | + }} | ||
356 | + /> | ||
357 | + </> | ||
358 | + ), | ||
359 | + }, | ||
360 | + ]; | ||
361 | + | ||
362 | + return ( | ||
363 | + <Modal | ||
364 | + open={true} | ||
365 | + title="积分兑换记录" | ||
366 | + width={1000} | ||
367 | + onCancel={() => { | ||
368 | + setVisible(false); | ||
369 | + onClose(); | ||
370 | + }} | ||
371 | + footer={null} | ||
372 | + destroyOnClose | ||
373 | + > | ||
374 | + <Tabs | ||
375 | + activeKey={activeTab} | ||
376 | + onChange={(key) => setActiveTab(key)} | ||
377 | + items={tabItems} | ||
378 | + /> | ||
379 | + </Modal> | ||
380 | + ); | ||
381 | +}; | ||
382 | + | ||
383 | +export default PointsExchangeRecordsModal; |
src/pages/Prepaid/constant.tsx
@@ -187,6 +187,27 @@ export const ACCOUNT_COLUMNS = [ | @@ -187,6 +187,27 @@ export const ACCOUNT_COLUMNS = [ | ||
187 | hideInSearch: true, | 187 | hideInSearch: true, |
188 | }, | 188 | }, |
189 | { | 189 | { |
190 | + title: '账户积分', | ||
191 | + dataIndex: 'delta', | ||
192 | + key: 'delta', | ||
193 | + valueType: 'number', | ||
194 | + hideInSearch: true, | ||
195 | + }, | ||
196 | + { | ||
197 | + title: '待领取积分', | ||
198 | + dataIndex: 'pendingDelta', | ||
199 | + key: 'pendingDelta', | ||
200 | + valueType: 'number', | ||
201 | + hideInSearch: true, | ||
202 | + }, | ||
203 | + { | ||
204 | + title: '已扣除积分', | ||
205 | + dataIndex: 'deleteDelta', | ||
206 | + key: 'deleteDelta', | ||
207 | + valueType: 'number', | ||
208 | + hideInSearch: true, | ||
209 | + }, | ||
210 | + { | ||
190 | title: '账号', | 211 | title: '账号', |
191 | dataIndex: 'account', | 212 | dataIndex: 'account', |
192 | key: 'account', | 213 | key: 'account', |
src/pages/Prepaid/index.tsx
@@ -16,6 +16,8 @@ import React, { useRef, useState } from 'react'; | @@ -16,6 +16,8 @@ import React, { useRef, useState } from 'react'; | ||
16 | import CheckModal from '../Order/Order/components/CheckModal'; | 16 | import CheckModal from '../Order/Order/components/CheckModal'; |
17 | import { CHECK_TYPE } from '../Order/constant'; | 17 | import { CHECK_TYPE } from '../Order/constant'; |
18 | import BalanceChangeRecordsModal from './components/BalanceChangeRecordsModal'; | 18 | import BalanceChangeRecordsModal from './components/BalanceChangeRecordsModal'; |
19 | +import PointsExchangeModal from './components/PointsExchangeModal'; | ||
20 | +import PointsExchangeRecordsModal from './components/PointsExchangeRecordsModal'; | ||
19 | import RechargePrepaymentModal from './components/RechargePrepaymentModal'; | 21 | import RechargePrepaymentModal from './components/RechargePrepaymentModal'; |
20 | import { | 22 | import { |
21 | ACCOUNT_COLUMNS, | 23 | ACCOUNT_COLUMNS, |
@@ -23,18 +25,25 @@ import { | @@ -23,18 +25,25 @@ import { | ||
23 | SALES_RECHARGE_PREPAYMENT_COLUMNS, | 25 | SALES_RECHARGE_PREPAYMENT_COLUMNS, |
24 | } from './constant'; | 26 | } from './constant'; |
25 | import './index.less'; | 27 | import './index.less'; |
28 | + | ||
26 | const PrepaidPage = () => { | 29 | const PrepaidPage = () => { |
27 | const prepaidActionRef = useRef<ActionType>(); | 30 | const prepaidActionRef = useRef<ActionType>(); |
28 | const accountActionRef = useRef<ActionType>(); | 31 | const accountActionRef = useRef<ActionType>(); |
29 | const [rechargePrepaymentModalVisible, setRechargePrepaymentModalVisible] = | 32 | const [rechargePrepaymentModalVisible, setRechargePrepaymentModalVisible] = |
30 | - useState(false); | 33 | + useState<boolean>(false); |
31 | const [currentOptPrepaymentObj, setCurrentOptPrepaymentObj] = useState(null); | 34 | const [currentOptPrepaymentObj, setCurrentOptPrepaymentObj] = useState(null); |
32 | const [currentOptUserObj, setCurrentOptUserObj] = useState(null); | 35 | const [currentOptUserObj, setCurrentOptUserObj] = useState(null); |
33 | - const [checkVisible, setCheckVisible] = useState(false); | 36 | + const [checkVisible, setCheckVisible] = useState<boolean>(false); |
34 | const [ | 37 | const [ |
35 | balanceChangeRecordsModalVisible, | 38 | balanceChangeRecordsModalVisible, |
36 | setBalanceChangeRecordsModalVisible, | 39 | setBalanceChangeRecordsModalVisible, |
37 | - ] = useState(false); | 40 | + ] = useState<boolean>(false); |
41 | + const [pointsExchangeModalVisible, setPointsExchangeModalVisible] = | ||
42 | + useState<boolean>(false); | ||
43 | + const [ | ||
44 | + pointsExchangeRecordsModalVisible, | ||
45 | + setPointsExchangeRecordsModalVisible, | ||
46 | + ] = useState<boolean>(false); | ||
38 | 47 | ||
39 | const reloadPrepaidTable = () => { | 48 | const reloadPrepaidTable = () => { |
40 | prepaidActionRef.current?.reload(); | 49 | prepaidActionRef.current?.reload(); |
@@ -194,11 +203,24 @@ const PrepaidPage = () => { | @@ -194,11 +203,24 @@ const PrepaidPage = () => { | ||
194 | valueType: 'option', | 203 | valueType: 'option', |
195 | key: 'option', | 204 | key: 'option', |
196 | fixed: 'right', | 205 | fixed: 'right', |
197 | - width: 120, | 206 | + width: 240, |
198 | render: (text, record) => { | 207 | render: (text, record) => { |
199 | let btns = []; | 208 | let btns = []; |
200 | btns.push( | 209 | btns.push( |
201 | <Button | 210 | <Button |
211 | + className="p-0 ml-2" | ||
212 | + key="points" | ||
213 | + type="link" | ||
214 | + onClick={() => { | ||
215 | + setCurrentOptUserObj(record); | ||
216 | + setPointsExchangeModalVisible(true); | ||
217 | + }} | ||
218 | + > | ||
219 | + 积分兑换 | ||
220 | + </Button>, | ||
221 | + ); | ||
222 | + btns.push( | ||
223 | + <Button | ||
202 | className="p-0" | 224 | className="p-0" |
203 | key="view" | 225 | key="view" |
204 | type="link" | 226 | type="link" |
@@ -210,6 +232,19 @@ const PrepaidPage = () => { | @@ -210,6 +232,19 @@ const PrepaidPage = () => { | ||
210 | 消费记录 | 232 | 消费记录 |
211 | </Button>, | 233 | </Button>, |
212 | ); | 234 | ); |
235 | + btns.push( | ||
236 | + <Button | ||
237 | + className="p-0 ml-2" | ||
238 | + key="pointsRecords" | ||
239 | + type="link" | ||
240 | + onClick={() => { | ||
241 | + setCurrentOptUserObj(record); | ||
242 | + setPointsExchangeRecordsModalVisible(true); | ||
243 | + }} | ||
244 | + > | ||
245 | + 积分兑换记录 | ||
246 | + </Button>, | ||
247 | + ); | ||
213 | return btns; | 248 | return btns; |
214 | }, | 249 | }, |
215 | }); | 250 | }); |
@@ -377,6 +412,31 @@ const PrepaidPage = () => { | @@ -377,6 +412,31 @@ const PrepaidPage = () => { | ||
377 | }} | 412 | }} |
378 | /> | 413 | /> |
379 | )} | 414 | )} |
415 | + | ||
416 | + {pointsExchangeModalVisible && currentOptUserObj && ( | ||
417 | + <PointsExchangeModal | ||
418 | + setVisible={(val: boolean) => { | ||
419 | + setPointsExchangeModalVisible(val); | ||
420 | + }} | ||
421 | + userInfoObj={currentOptUserObj} | ||
422 | + onClose={() => { | ||
423 | + setPointsExchangeModalVisible(false); | ||
424 | + reloadAccountTable(); | ||
425 | + }} | ||
426 | + /> | ||
427 | + )} | ||
428 | + | ||
429 | + {pointsExchangeRecordsModalVisible && currentOptUserObj && ( | ||
430 | + <PointsExchangeRecordsModal | ||
431 | + setVisible={(val: boolean) => { | ||
432 | + setPointsExchangeRecordsModalVisible(val); | ||
433 | + }} | ||
434 | + userInfoObj={currentOptUserObj} | ||
435 | + onClose={() => { | ||
436 | + setPointsExchangeRecordsModalVisible(false); | ||
437 | + }} | ||
438 | + /> | ||
439 | + )} | ||
380 | </div> | 440 | </div> |
381 | ); | 441 | ); |
382 | }; | 442 | }; |
src/pages/ResearchGroup/components/PointsExchangeModal.tsx
0 → 100644
1 | +import { postIntegralExchangeIntegral } from '@/services/request'; | ||
2 | +import { getUserInfo } from '@/utils'; | ||
3 | +import { | ||
4 | + ModalForm, | ||
5 | + ProFormInstance, | ||
6 | + ProFormTextArea, | ||
7 | +} from '@ant-design/pro-components'; | ||
8 | +import { Form, Input, message } from 'antd'; | ||
9 | +import React, { useEffect, useRef, useState } from 'react'; | ||
10 | +import '../index.less'; | ||
11 | + | ||
12 | +interface PointsExchangeModalProps { | ||
13 | + setVisible: (visible: boolean) => void; | ||
14 | + record: any; | ||
15 | + onClose: () => void; | ||
16 | +} | ||
17 | +const userInfo = getUserInfo(); | ||
18 | +const PointsExchangeModal: React.FC<PointsExchangeModalProps> = ({ | ||
19 | + setVisible, | ||
20 | + record, | ||
21 | + onClose, | ||
22 | +}) => { | ||
23 | + const [form] = Form.useForm<{ delta: string; remark: string }>(); | ||
24 | + const formRef = useRef<ProFormInstance>(); | ||
25 | + const [accountPoints, setAccountPoints] = useState<number>(0); | ||
26 | + | ||
27 | + // Get account points from record | ||
28 | + useEffect(() => { | ||
29 | + if (record && record.delta) { | ||
30 | + setAccountPoints(Number(record.delta) || 0); | ||
31 | + } | ||
32 | + }, [record]); | ||
33 | + | ||
34 | + // Validate that delta is not greater than available points | ||
35 | + const validateDelta = (rule: any, value: string) => { | ||
36 | + const deltaValue = Number(value); | ||
37 | + if (isNaN(deltaValue)) { | ||
38 | + return Promise.reject('请输入有效的积分数值'); | ||
39 | + } | ||
40 | + if (deltaValue <= 0) { | ||
41 | + return Promise.reject('兑换积分必须大于0'); | ||
42 | + } | ||
43 | + if (deltaValue > accountPoints) { | ||
44 | + return Promise.reject('兑换积分不能大于账户积分'); | ||
45 | + } | ||
46 | + return Promise.resolve(); | ||
47 | + }; | ||
48 | + | ||
49 | + return ( | ||
50 | + <div className="prepaid-index"> | ||
51 | + <ModalForm<{ | ||
52 | + delta: string; | ||
53 | + remark: string; | ||
54 | + }> | ||
55 | + width={600} | ||
56 | + open | ||
57 | + title="确认兑换" | ||
58 | + form={form} | ||
59 | + formRef={formRef} | ||
60 | + autoFocusFirstInput | ||
61 | + submitter={{ | ||
62 | + searchConfig: { | ||
63 | + submitText: '确认兑换', | ||
64 | + resetText: '取消', | ||
65 | + }, | ||
66 | + }} | ||
67 | + modalProps={{ | ||
68 | + destroyOnClose: true, | ||
69 | + onCancel: () => { | ||
70 | + setVisible(false); | ||
71 | + }, | ||
72 | + }} | ||
73 | + onFinish={async (values) => { | ||
74 | + try { | ||
75 | + // 调用积分兑换API | ||
76 | + await postIntegralExchangeIntegral({ | ||
77 | + data: { | ||
78 | + id: Number(record.id), | ||
79 | + delta: Number(values.delta), | ||
80 | + remark: values.remark, | ||
81 | + relationEntityType: 'RESEARCH_GROUP', | ||
82 | + createByName: userInfo?.username, | ||
83 | + }, | ||
84 | + }); | ||
85 | + | ||
86 | + message.success('积分兑换成功'); | ||
87 | + setVisible(false); | ||
88 | + onClose(); | ||
89 | + return true; | ||
90 | + } catch (error) { | ||
91 | + console.error(error); | ||
92 | + return false; | ||
93 | + } | ||
94 | + }} | ||
95 | + onOpenChange={setVisible} | ||
96 | + > | ||
97 | + <Form.Item | ||
98 | + label="兑换积分" | ||
99 | + name="delta" | ||
100 | + rules={[ | ||
101 | + { required: true, message: '请输入兑换积分' }, | ||
102 | + { validator: validateDelta }, | ||
103 | + ]} | ||
104 | + > | ||
105 | + <Input style={{ height: '30px' }} placeholder="请输入兑换积分数量" /> | ||
106 | + </Form.Item> | ||
107 | + | ||
108 | + <Form.Item | ||
109 | + label="兑换说明" | ||
110 | + name="remark" | ||
111 | + rules={[{ required: true, message: '请输入兑换说明' }]} | ||
112 | + > | ||
113 | + <ProFormTextArea | ||
114 | + style={{ height: '100px' }} | ||
115 | + placeholder="请输入兑换说明" | ||
116 | + /> | ||
117 | + </Form.Item> | ||
118 | + </ModalForm> | ||
119 | + </div> | ||
120 | + ); | ||
121 | +}; | ||
122 | + | ||
123 | +export default PointsExchangeModal; |
src/pages/ResearchGroup/components/PointsExchangeRecordsModal.tsx
0 → 100644
1 | +import { postIntegralGroupExchangeRecords } from '@/services/request'; | ||
2 | +import { ModalForm, ProTable } from '@ant-design/pro-components'; | ||
3 | +import { Button, DatePicker, Space, Tabs, message } from 'antd'; | ||
4 | +import dayjs from 'dayjs'; | ||
5 | +import React, { useState } from 'react'; | ||
6 | +import '../index.less'; | ||
7 | + | ||
8 | +interface PointsExchangeRecordsModalProps { | ||
9 | + setVisible: (visible: boolean) => void; | ||
10 | + record: any; | ||
11 | +} | ||
12 | + | ||
13 | +// Define a type for the records data | ||
14 | +type RecordsDataType = { | ||
15 | + exchangeRecords: any[]; | ||
16 | + collectedRecords: any[]; | ||
17 | + pendingRecords: any[]; | ||
18 | +}; | ||
19 | + | ||
20 | +const PointsExchangeRecordsModal: React.FC<PointsExchangeRecordsModalProps> = ({ | ||
21 | + setVisible, | ||
22 | + record, | ||
23 | +}) => { | ||
24 | + const [activeTab, setActiveTab] = useState('1'); | ||
25 | + | ||
26 | + // Separate date ranges for each tab | ||
27 | + const [exchangeDateRange, setExchangeDateRange] = useState<any[]>([]); | ||
28 | + const [collectedDateRange, setCollectedDateRange] = useState<any[]>([]); | ||
29 | + const [pendingDateRange, setPendingDateRange] = useState<any[]>([]); | ||
30 | + | ||
31 | + const [loading, setLoading] = useState(false); | ||
32 | + const [recordsData, setRecordsData] = useState<RecordsDataType>({ | ||
33 | + exchangeRecords: [], // 兑换记录 | ||
34 | + collectedRecords: [], // 已领取积分 | ||
35 | + pendingRecords: [], // 待领取积分 | ||
36 | + }); | ||
37 | + | ||
38 | + // Function to fetch records data from API with date parameters | ||
39 | + const fetchRecordsData = async (params: { | ||
40 | + startTime?: string | null; | ||
41 | + endTime?: string | null; | ||
42 | + tabKey: string; | ||
43 | + }) => { | ||
44 | + try { | ||
45 | + setLoading(true); | ||
46 | + const { startTime, endTime, tabKey } = params; | ||
47 | + | ||
48 | + // Prepare API request data | ||
49 | + const requestDto: any = { | ||
50 | + id: Number(record.id), | ||
51 | + }; | ||
52 | + | ||
53 | + // Add date range if provided | ||
54 | + if (startTime) requestDto.startTime = startTime; | ||
55 | + if (endTime) requestDto.endTime = endTime; | ||
56 | + | ||
57 | + console.log(`Fetching data for tab: ${tabKey}`); | ||
58 | + | ||
59 | + // Use postIntegralGroupExchangeRecords instead of postIntegralUserExchangeRecords | ||
60 | + const response = await postIntegralGroupExchangeRecords({ | ||
61 | + data: requestDto, | ||
62 | + }); | ||
63 | + | ||
64 | + if (response && response.data) { | ||
65 | + // Update only the data for the active tab | ||
66 | + setRecordsData((prevData: RecordsDataType) => { | ||
67 | + const newData = { ...prevData }; | ||
68 | + | ||
69 | + switch (tabKey) { | ||
70 | + case '1': // 兑换记录 | ||
71 | + newData.exchangeRecords = response.data.exchangeRecords || []; | ||
72 | + break; | ||
73 | + case '2': // 已领取积分 | ||
74 | + newData.collectedRecords = response.data.collectedRecords || []; | ||
75 | + break; | ||
76 | + case '3': // 待领取积分 | ||
77 | + newData.pendingRecords = response.data.pendingRecords || []; | ||
78 | + break; | ||
79 | + } | ||
80 | + | ||
81 | + return newData; | ||
82 | + }); | ||
83 | + } else { | ||
84 | + message.error('获取积分记录失败'); | ||
85 | + } | ||
86 | + } catch (error) { | ||
87 | + console.error(error); | ||
88 | + message.error('获取积分记录失败'); | ||
89 | + } finally { | ||
90 | + setLoading(false); | ||
91 | + } | ||
92 | + }; | ||
93 | + | ||
94 | + // Initial data fetch for all tabs | ||
95 | + React.useEffect(() => { | ||
96 | + const loadAllTabs = async () => { | ||
97 | + try { | ||
98 | + setLoading(true); | ||
99 | + const requestDto = { | ||
100 | + id: Number(record.id), | ||
101 | + }; | ||
102 | + | ||
103 | + const response = await postIntegralGroupExchangeRecords({ | ||
104 | + data: requestDto, | ||
105 | + }); | ||
106 | + | ||
107 | + if (response && response.data) { | ||
108 | + setRecordsData({ | ||
109 | + exchangeRecords: response.data.exchangeRecords || [], | ||
110 | + collectedRecords: response.data.collectedRecords || [], | ||
111 | + pendingRecords: response.data.pendingRecords || [], | ||
112 | + }); | ||
113 | + } else { | ||
114 | + message.error('获取积分记录失败'); | ||
115 | + } | ||
116 | + } catch (error) { | ||
117 | + console.error(error); | ||
118 | + message.error('获取积分记录失败'); | ||
119 | + } finally { | ||
120 | + setLoading(false); | ||
121 | + } | ||
122 | + }; | ||
123 | + | ||
124 | + loadAllTabs(); | ||
125 | + }, [record.id]); | ||
126 | + | ||
127 | + const handleTabChange = (key: string) => { | ||
128 | + setActiveTab(key); | ||
129 | + }; | ||
130 | + | ||
131 | + // Get current date range based on active tab | ||
132 | + const getCurrentDateRange = () => { | ||
133 | + switch (activeTab) { | ||
134 | + case '1': | ||
135 | + return exchangeDateRange; | ||
136 | + case '2': | ||
137 | + return collectedDateRange; | ||
138 | + case '3': | ||
139 | + return pendingDateRange; | ||
140 | + default: | ||
141 | + return []; | ||
142 | + } | ||
143 | + }; | ||
144 | + | ||
145 | + // Set date range for current tab | ||
146 | + const handleDateRangeChange = (dates: any) => { | ||
147 | + switch (activeTab) { | ||
148 | + case '1': | ||
149 | + setExchangeDateRange(dates); | ||
150 | + break; | ||
151 | + case '2': | ||
152 | + setCollectedDateRange(dates); | ||
153 | + break; | ||
154 | + case '3': | ||
155 | + setPendingDateRange(dates); | ||
156 | + break; | ||
157 | + } | ||
158 | + }; | ||
159 | + | ||
160 | + const handleSearchClick = () => { | ||
161 | + const dateRange = getCurrentDateRange(); | ||
162 | + // Only get the dates that are actually selected | ||
163 | + const startTime = dateRange?.[0] | ||
164 | + ? dayjs(dateRange[0]).format('YYYY-MM-DD') | ||
165 | + : null; | ||
166 | + const endTime = dateRange?.[1] | ||
167 | + ? dayjs(dateRange[1]).format('YYYY-MM-DD') | ||
168 | + : null; | ||
169 | + | ||
170 | + fetchRecordsData({ | ||
171 | + startTime, | ||
172 | + endTime, | ||
173 | + tabKey: activeTab, | ||
174 | + }); | ||
175 | + }; | ||
176 | + | ||
177 | + const handleClearClick = () => { | ||
178 | + // Clear date range for current tab | ||
179 | + switch (activeTab) { | ||
180 | + case '1': | ||
181 | + setExchangeDateRange([]); | ||
182 | + break; | ||
183 | + case '2': | ||
184 | + setCollectedDateRange([]); | ||
185 | + break; | ||
186 | + case '3': | ||
187 | + setPendingDateRange([]); | ||
188 | + break; | ||
189 | + } | ||
190 | + | ||
191 | + // Fetch data without date filters | ||
192 | + fetchRecordsData({ | ||
193 | + startTime: null, | ||
194 | + endTime: null, | ||
195 | + tabKey: activeTab, | ||
196 | + }); | ||
197 | + }; | ||
198 | + | ||
199 | + // 兑换记录表格列定义 | ||
200 | + const exchangeColumns = [ | ||
201 | + { | ||
202 | + title: '兑换日期', | ||
203 | + dataIndex: 'createTime', | ||
204 | + key: 'createTime', | ||
205 | + width: 30, | ||
206 | + }, | ||
207 | + { | ||
208 | + title: '扣除积分', | ||
209 | + dataIndex: 'delta', | ||
210 | + key: 'delta', | ||
211 | + width: 20, | ||
212 | + }, | ||
213 | + { | ||
214 | + title: '操作人', | ||
215 | + dataIndex: 'createByName', | ||
216 | + key: 'createByName', | ||
217 | + width: 20, | ||
218 | + }, | ||
219 | + { | ||
220 | + title: '积分用途', | ||
221 | + dataIndex: 'remark', | ||
222 | + key: 'remark', | ||
223 | + width: 100, | ||
224 | + }, | ||
225 | + ]; | ||
226 | + | ||
227 | + // 已领取积分表格列定义 | ||
228 | + const collectedColumns = [ | ||
229 | + { | ||
230 | + title: '订单号', | ||
231 | + dataIndex: 'sourceId', | ||
232 | + key: 'sourceId', | ||
233 | + }, | ||
234 | + { | ||
235 | + title: '领取积分', | ||
236 | + dataIndex: 'delta', | ||
237 | + key: 'delta', | ||
238 | + }, | ||
239 | + { | ||
240 | + title: '领取日期', | ||
241 | + dataIndex: 'createTime', | ||
242 | + key: 'createTime', | ||
243 | + }, | ||
244 | + ]; | ||
245 | + | ||
246 | + // 待领取积分表格列定义 | ||
247 | + const pendingColumns = [ | ||
248 | + { | ||
249 | + title: '订单号', | ||
250 | + dataIndex: 'sourceId', | ||
251 | + key: 'sourceId', | ||
252 | + }, | ||
253 | + { | ||
254 | + title: '领取积分', | ||
255 | + dataIndex: 'delta', | ||
256 | + key: 'delta', | ||
257 | + }, | ||
258 | + { | ||
259 | + title: '过期日期', | ||
260 | + dataIndex: 'createTime', | ||
261 | + key: 'createTime', | ||
262 | + }, | ||
263 | + ]; | ||
264 | + | ||
265 | + // Render date picker and search buttons for current tab | ||
266 | + const renderDateRangePicker = () => { | ||
267 | + return ( | ||
268 | + <Space style={{ marginBottom: 16 }}> | ||
269 | + <DatePicker.RangePicker | ||
270 | + value={getCurrentDateRange()} | ||
271 | + onChange={handleDateRangeChange} | ||
272 | + allowEmpty={[true, true]} | ||
273 | + /> | ||
274 | + <Button type="primary" onClick={handleSearchClick}> | ||
275 | + 搜索 | ||
276 | + </Button> | ||
277 | + <Button onClick={handleClearClick}>重置</Button> | ||
278 | + </Space> | ||
279 | + ); | ||
280 | + }; | ||
281 | + | ||
282 | + return ( | ||
283 | + <div className="prepaid-index"> | ||
284 | + <ModalForm | ||
285 | + width={1000} | ||
286 | + open | ||
287 | + title="积分兑换记录" | ||
288 | + submitter={false} | ||
289 | + modalProps={{ | ||
290 | + destroyOnClose: true, | ||
291 | + onCancel: () => { | ||
292 | + setVisible(false); | ||
293 | + }, | ||
294 | + }} | ||
295 | + > | ||
296 | + <Tabs activeKey={activeTab} onChange={handleTabChange}> | ||
297 | + <Tabs.TabPane tab="兑换记录" key="1"> | ||
298 | + {renderDateRangePicker()} | ||
299 | + <ProTable | ||
300 | + headerTitle={false} | ||
301 | + search={false} | ||
302 | + options={false} | ||
303 | + pagination={{ | ||
304 | + pageSize: 10, | ||
305 | + }} | ||
306 | + loading={loading && activeTab === '1'} | ||
307 | + dataSource={recordsData.exchangeRecords} | ||
308 | + columns={exchangeColumns} | ||
309 | + rowKey="id" | ||
310 | + /> | ||
311 | + </Tabs.TabPane> | ||
312 | + <Tabs.TabPane tab="已领取积分" key="2"> | ||
313 | + {renderDateRangePicker()} | ||
314 | + <ProTable | ||
315 | + headerTitle={false} | ||
316 | + search={false} | ||
317 | + options={false} | ||
318 | + pagination={{ | ||
319 | + pageSize: 10, | ||
320 | + }} | ||
321 | + loading={loading && activeTab === '2'} | ||
322 | + dataSource={recordsData.collectedRecords} | ||
323 | + columns={collectedColumns} | ||
324 | + rowKey="id" | ||
325 | + /> | ||
326 | + </Tabs.TabPane> | ||
327 | + <Tabs.TabPane tab="待领取积分" key="3"> | ||
328 | + {renderDateRangePicker()} | ||
329 | + <ProTable | ||
330 | + headerTitle={false} | ||
331 | + search={false} | ||
332 | + options={false} | ||
333 | + pagination={{ | ||
334 | + pageSize: 10, | ||
335 | + }} | ||
336 | + loading={loading && activeTab === '3'} | ||
337 | + dataSource={recordsData.pendingRecords} | ||
338 | + columns={pendingColumns} | ||
339 | + rowKey="id" | ||
340 | + /> | ||
341 | + </Tabs.TabPane> | ||
342 | + </Tabs> | ||
343 | + </ModalForm> | ||
344 | + </div> | ||
345 | + ); | ||
346 | +}; | ||
347 | + | ||
348 | +export default PointsExchangeRecordsModal; |
src/pages/ResearchGroup/constant.tsx
1 | -import { enumToProTableEnumValue } from '@/utils'; | ||
2 | - | 1 | +import { postServiceConstListResearchGroupsStatus } from '@/services'; |
2 | +import { enumToProTableEnumValue, enumToSelect } from '@/utils'; | ||
3 | +import { MessageTwoTone } from '@ant-design/icons'; | ||
4 | +import { Space, Tooltip } from 'antd'; | ||
3 | export const AUDIT_STATUS_OPTIONS = { | 5 | export const AUDIT_STATUS_OPTIONS = { |
4 | CREATED: '未审核', | 6 | CREATED: '未审核', |
5 | AUDIT_PASS: '审核通过', | 7 | AUDIT_PASS: '审核通过', |
@@ -53,6 +55,59 @@ export const RESEARCH_GROUP_COLUMNS = [ | @@ -53,6 +55,59 @@ export const RESEARCH_GROUP_COLUMNS = [ | ||
53 | hideInSearch: true, | 55 | hideInSearch: true, |
54 | }, | 56 | }, |
55 | { | 57 | { |
58 | + title: '账户积分', | ||
59 | + dataIndex: 'delta', | ||
60 | + key: 'delta', | ||
61 | + valueType: 'number', | ||
62 | + hideInSearch: true, | ||
63 | + }, | ||
64 | + { | ||
65 | + title: '待领取积分', | ||
66 | + dataIndex: 'pendingDelta', | ||
67 | + key: 'pendingDelta', | ||
68 | + valueType: 'number', | ||
69 | + hideInSearch: true, | ||
70 | + }, | ||
71 | + { | ||
72 | + title: '已扣除积分', | ||
73 | + dataIndex: 'deleteDelta', | ||
74 | + key: 'deleteDelta', | ||
75 | + valueType: 'number', | ||
76 | + hideInSearch: true, | ||
77 | + }, | ||
78 | + { | ||
79 | + title: '状态', | ||
80 | + dataIndex: 'statusText', | ||
81 | + key: 'statusText', | ||
82 | + hideInSearch: true, | ||
83 | + render: (_, record) => { | ||
84 | + console.log('1111' + JSON.stringify(record)); | ||
85 | + return ( | ||
86 | + <> | ||
87 | + <Space> | ||
88 | + {record.statusText} | ||
89 | + {record.statusNotes && ( | ||
90 | + <Tooltip title={record.statusNotes}> | ||
91 | + <MessageTwoTone /> | ||
92 | + </Tooltip> | ||
93 | + )} | ||
94 | + </Space> | ||
95 | + </> | ||
96 | + ); | ||
97 | + }, | ||
98 | + }, | ||
99 | + { | ||
100 | + title: '状态', | ||
101 | + dataIndex: 'status', | ||
102 | + key: 'status', | ||
103 | + valueType: 'select', | ||
104 | + request: async () => { | ||
105 | + const groupStatus = await postServiceConstListResearchGroupsStatus(); | ||
106 | + return enumToSelect(groupStatus.data); | ||
107 | + }, | ||
108 | + hideInTable: true, | ||
109 | + }, | ||
110 | + { | ||
56 | title: '预存手机号', | 111 | title: '预存手机号', |
57 | dataIndex: 'accountPhone', | 112 | dataIndex: 'accountPhone', |
58 | key: 'accountPhone', | 113 | key: 'accountPhone', |
src/pages/ResearchGroup/index.tsx
@@ -29,6 +29,8 @@ import { | @@ -29,6 +29,8 @@ import { | ||
29 | import React, { useRef, useState } from 'react'; | 29 | import React, { useRef, useState } from 'react'; |
30 | import AuditModal from './components/AuditModal'; | 30 | import AuditModal from './components/AuditModal'; |
31 | import ImportModal from './components/ImportModal'; | 31 | import ImportModal from './components/ImportModal'; |
32 | +import PointsExchangeModal from './components/PointsExchangeModal'; | ||
33 | +import PointsExchangeRecordsModal from './components/PointsExchangeRecordsModal'; | ||
32 | import ResearchGroupAddModal from './components/ResearchGroupAddModal'; | 34 | import ResearchGroupAddModal from './components/ResearchGroupAddModal'; |
33 | import ResearchGroupMemberRequestAddModal from './components/ResearchGroupMemberRequestAddModal'; | 35 | import ResearchGroupMemberRequestAddModal from './components/ResearchGroupMemberRequestAddModal'; |
34 | import { | 36 | import { |
@@ -60,6 +62,13 @@ const PrepaidPage = () => { | @@ -60,6 +62,13 @@ const PrepaidPage = () => { | ||
60 | const [accountInfoLoading, setAccountInfoLoading] = useState(false); | 62 | const [accountInfoLoading, setAccountInfoLoading] = useState(false); |
61 | const [perms, setPerms] = useState<string[]>([]); | 63 | const [perms, setPerms] = useState<string[]>([]); |
62 | const [optRecordId, setOptRecordId] = useState<any>(null); | 64 | const [optRecordId, setOptRecordId] = useState<any>(null); |
65 | + const [pointsExchangeModalVisible, setPointsExchangeModalVisible] = | ||
66 | + useState<boolean>(false); | ||
67 | + const [ | ||
68 | + pointsExchangeRecordsModalVisible, | ||
69 | + setPointsExchangeRecordsModalVisible, | ||
70 | + ] = useState<boolean>(false); | ||
71 | + const [currentRecord, setCurrentRecord] = useState<any>(null); | ||
63 | 72 | ||
64 | const reloadResearchGroupTable = () => { | 73 | const reloadResearchGroupTable = () => { |
65 | researchGroupActionRef.current?.reload(); | 74 | researchGroupActionRef.current?.reload(); |
@@ -306,9 +315,39 @@ const PrepaidPage = () => { | @@ -306,9 +315,39 @@ const PrepaidPage = () => { | ||
306 | valueType: 'option', | 315 | valueType: 'option', |
307 | key: 'option', | 316 | key: 'option', |
308 | fixed: 'right', | 317 | fixed: 'right', |
309 | - width: 120, | 318 | + width: 240, |
310 | render: (text, record) => { | 319 | render: (text, record) => { |
311 | let btns = []; | 320 | let btns = []; |
321 | + | ||
322 | + // Add Points Exchange button if there are accounts | ||
323 | + btns.push( | ||
324 | + <Button | ||
325 | + className="p-0" | ||
326 | + key="points-exchange" | ||
327 | + type="link" | ||
328 | + onClick={() => { | ||
329 | + setCurrentRecord(record); | ||
330 | + setPointsExchangeModalVisible(true); | ||
331 | + }} | ||
332 | + > | ||
333 | + 积分兑换 | ||
334 | + </Button>, | ||
335 | + ); | ||
336 | + | ||
337 | + btns.push( | ||
338 | + <Button | ||
339 | + className="p-0" | ||
340 | + key="points-records" | ||
341 | + type="link" | ||
342 | + onClick={() => { | ||
343 | + setCurrentRecord(record); | ||
344 | + setPointsExchangeRecordsModalVisible(true); | ||
345 | + }} | ||
346 | + > | ||
347 | + 积分兑换记录 | ||
348 | + </Button>, | ||
349 | + ); | ||
350 | + | ||
312 | if (perms?.includes('modify')) { | 351 | if (perms?.includes('modify')) { |
313 | btns.push( | 352 | btns.push( |
314 | <Button | 353 | <Button |
@@ -794,6 +833,24 @@ const PrepaidPage = () => { | @@ -794,6 +833,24 @@ const PrepaidPage = () => { | ||
794 | }} | 833 | }} |
795 | /> | 834 | /> |
796 | )} | 835 | )} |
836 | + | ||
837 | + {pointsExchangeModalVisible && currentRecord && ( | ||
838 | + <PointsExchangeModal | ||
839 | + setVisible={setPointsExchangeModalVisible} | ||
840 | + record={currentRecord} | ||
841 | + onClose={() => { | ||
842 | + reloadResearchGroupTable(); | ||
843 | + }} | ||
844 | + /> | ||
845 | + )} | ||
846 | + | ||
847 | + {pointsExchangeRecordsModalVisible && currentRecord && ( | ||
848 | + <PointsExchangeRecordsModal | ||
849 | + setVisible={setPointsExchangeRecordsModalVisible} | ||
850 | + record={currentRecord} | ||
851 | + onClose={() => {}} | ||
852 | + /> | ||
853 | + )} | ||
797 | </div> | 854 | </div> |
798 | ); | 855 | ); |
799 | }; | 856 | }; |
src/services/definition.ts
@@ -1521,36 +1521,70 @@ export interface Entry { | @@ -1521,36 +1521,70 @@ export interface Entry { | ||
1521 | unEmpInsuranceC?: string; | 1521 | unEmpInsuranceC?: string; |
1522 | } | 1522 | } |
1523 | 1523 | ||
1524 | -export interface File { | ||
1525 | - absolute?: boolean; | ||
1526 | - absoluteFile?: File; | ||
1527 | - absolutePath?: string; | ||
1528 | - canonicalFile?: File; | ||
1529 | - canonicalPath?: string; | ||
1530 | - directory?: boolean; | ||
1531 | - executable?: boolean; | ||
1532 | - file?: boolean; | ||
1533 | - /** @format int64 */ | ||
1534 | - freeSpace?: number; | ||
1535 | - hidden?: boolean; | ||
1536 | - /** @format int64 */ | ||
1537 | - lastModified?: number; | ||
1538 | - name?: string; | ||
1539 | - parent?: string; | ||
1540 | - parentFile?: File; | ||
1541 | - path?: string; | ||
1542 | - readable?: boolean; | ||
1543 | - /** @format int64 */ | ||
1544 | - totalSpace?: number; | 1524 | +export interface ExchangeIntegralDto { |
1525 | + createByName?: string; | ||
1526 | + delta?: number; | ||
1545 | /** @format int64 */ | 1527 | /** @format int64 */ |
1546 | - usableSpace?: number; | ||
1547 | - writable?: boolean; | 1528 | + id?: number; |
1529 | + relationEntityType?: string; | ||
1530 | + remark?: string; | ||
1531 | +} | ||
1532 | + | ||
1533 | +export interface ExchangeRecordsRequestDto { | ||
1534 | + createByName?: string; | ||
1535 | + createByNameLike?: string; | ||
1536 | + /** @format date-time */ | ||
1537 | + createTimeGe?: string; | ||
1538 | + /** @format date-time */ | ||
1539 | + createTimeLe?: string; | ||
1540 | + /** @format int32 */ | ||
1541 | + current?: number; | ||
1542 | + /** @format int32 */ | ||
1543 | + end?: number; | ||
1544 | + /** @format date-time */ | ||
1545 | + endTime?: string; | ||
1546 | + /** @format int32 */ | ||
1547 | + id?: number; | ||
1548 | + /** @format int32 */ | ||
1549 | + pageSize?: number; | ||
1550 | + phone?: string; | ||
1551 | + /** @format int32 */ | ||
1552 | + start?: number; | ||
1553 | + /** @format date-time */ | ||
1554 | + startTime?: string; | ||
1555 | + /** @format int32 */ | ||
1556 | + total?: number; | ||
1548 | } | 1557 | } |
1549 | 1558 | ||
1550 | export interface FilePathDto { | 1559 | export interface FilePathDto { |
1551 | url?: string; | 1560 | url?: string; |
1552 | } | 1561 | } |
1553 | 1562 | ||
1563 | +export interface GroupExchangeRecordsRequestDto { | ||
1564 | + createByName?: string; | ||
1565 | + createByNameLike?: string; | ||
1566 | + /** @format date-time */ | ||
1567 | + createTimeGe?: string; | ||
1568 | + /** @format date-time */ | ||
1569 | + createTimeLe?: string; | ||
1570 | + /** @format int32 */ | ||
1571 | + current?: number; | ||
1572 | + /** @format int32 */ | ||
1573 | + end?: number; | ||
1574 | + /** @format date-time */ | ||
1575 | + endTime?: string; | ||
1576 | + /** @format int64 */ | ||
1577 | + id?: number; | ||
1578 | + /** @format int32 */ | ||
1579 | + pageSize?: number; | ||
1580 | + /** @format int32 */ | ||
1581 | + start?: number; | ||
1582 | + /** @format date-time */ | ||
1583 | + startTime?: string; | ||
1584 | + /** @format int32 */ | ||
1585 | + total?: number; | ||
1586 | +} | ||
1587 | + | ||
1554 | export type InputStream = any; | 1588 | export type InputStream = any; |
1555 | 1589 | ||
1556 | export interface InventoryMaterialStockReq { | 1590 | export interface InventoryMaterialStockReq { |
@@ -3727,6 +3761,16 @@ export interface ResearchGroupEditRequest { | @@ -3727,6 +3761,16 @@ export interface ResearchGroupEditRequest { | ||
3727 | createTime?: string; | 3761 | createTime?: string; |
3728 | /** | 3762 | /** |
3729 | * @description | 3763 | * @description |
3764 | + * 已扣除积分 | ||
3765 | + */ | ||
3766 | + deleteDelta?: number; | ||
3767 | + /** | ||
3768 | + * @description | ||
3769 | + * 账户积分 | ||
3770 | + */ | ||
3771 | + delta?: number; | ||
3772 | + /** | ||
3773 | + * @description | ||
3730 | * 课题组名称 | 3774 | * 课题组名称 |
3731 | */ | 3775 | */ |
3732 | groupName?: string; | 3776 | groupName?: string; |
@@ -3744,6 +3788,11 @@ export interface ResearchGroupEditRequest { | @@ -3744,6 +3788,11 @@ export interface ResearchGroupEditRequest { | ||
3744 | logicDelete?: boolean; | 3788 | logicDelete?: boolean; |
3745 | members?: Array<ResearchGroupMembers>; | 3789 | members?: Array<ResearchGroupMembers>; |
3746 | paths?: Array<string>; | 3790 | paths?: Array<string>; |
3791 | + /** | ||
3792 | + * @description | ||
3793 | + * 待领取积分 | ||
3794 | + */ | ||
3795 | + pendingDelta?: number; | ||
3747 | requestStatus?: string; | 3796 | requestStatus?: string; |
3748 | /** | 3797 | /** |
3749 | * @description | 3798 | * @description |
@@ -4062,6 +4111,16 @@ export interface ResearchGroupsDTO { | @@ -4062,6 +4111,16 @@ export interface ResearchGroupsDTO { | ||
4062 | createTime?: string; | 4111 | createTime?: string; |
4063 | /** | 4112 | /** |
4064 | * @description | 4113 | * @description |
4114 | + * 已扣除积分 | ||
4115 | + */ | ||
4116 | + deleteDelta?: number; | ||
4117 | + /** | ||
4118 | + * @description | ||
4119 | + * 账户积分 | ||
4120 | + */ | ||
4121 | + delta?: number; | ||
4122 | + /** | ||
4123 | + * @description | ||
4065 | * 课题组名称 | 4124 | * 课题组名称 |
4066 | */ | 4125 | */ |
4067 | groupName?: string; | 4126 | groupName?: string; |
@@ -4079,6 +4138,11 @@ export interface ResearchGroupsDTO { | @@ -4079,6 +4138,11 @@ export interface ResearchGroupsDTO { | ||
4079 | logicDelete?: boolean; | 4138 | logicDelete?: boolean; |
4080 | members?: Array<ResearchGroupMembers>; | 4139 | members?: Array<ResearchGroupMembers>; |
4081 | paths?: Array<string>; | 4140 | paths?: Array<string>; |
4141 | + /** | ||
4142 | + * @description | ||
4143 | + * 待领取积分 | ||
4144 | + */ | ||
4145 | + pendingDelta?: number; | ||
4082 | requestStatus?: string; | 4146 | requestStatus?: string; |
4083 | /** | 4147 | /** |
4084 | * @description | 4148 | * @description |
@@ -4107,7 +4171,7 @@ export interface ResetPwdVO { | @@ -4107,7 +4171,7 @@ export interface ResetPwdVO { | ||
4107 | 4171 | ||
4108 | export interface Resource { | 4172 | export interface Resource { |
4109 | description?: string; | 4173 | description?: string; |
4110 | - file?: File; | 4174 | + file?: TsgFile; |
4111 | filename?: string; | 4175 | filename?: string; |
4112 | inputStream?: InputStream; | 4176 | inputStream?: InputStream; |
4113 | open?: boolean; | 4177 | open?: boolean; |
@@ -4815,6 +4879,32 @@ export interface CompanyInfo { | @@ -4815,6 +4879,32 @@ export interface CompanyInfo { | ||
4815 | taxIdIsNotNull?: boolean; | 4879 | taxIdIsNotNull?: boolean; |
4816 | } | 4880 | } |
4817 | 4881 | ||
4882 | +export interface TsgFile { | ||
4883 | + absolute?: boolean; | ||
4884 | + absoluteFile?: TsgFile; | ||
4885 | + absolutePath?: string; | ||
4886 | + canonicalFile?: TsgFile; | ||
4887 | + canonicalPath?: string; | ||
4888 | + directory?: boolean; | ||
4889 | + executable?: boolean; | ||
4890 | + file?: boolean; | ||
4891 | + /** @format int64 */ | ||
4892 | + freeSpace?: number; | ||
4893 | + hidden?: boolean; | ||
4894 | + /** @format int64 */ | ||
4895 | + lastModified?: number; | ||
4896 | + name?: string; | ||
4897 | + parent?: string; | ||
4898 | + parentFile?: TsgFile; | ||
4899 | + path?: string; | ||
4900 | + readable?: boolean; | ||
4901 | + /** @format int64 */ | ||
4902 | + totalSpace?: number; | ||
4903 | + /** @format int64 */ | ||
4904 | + usableSpace?: number; | ||
4905 | + writable?: boolean; | ||
4906 | +} | ||
4907 | + | ||
4818 | export interface InvoiceDetail { | 4908 | export interface InvoiceDetail { |
4819 | createByName?: string; | 4909 | createByName?: string; |
4820 | /** @format date-time */ | 4910 | /** @format date-time */ |
src/services/request.ts
@@ -56,7 +56,10 @@ import type { | @@ -56,7 +56,10 @@ import type { | ||
56 | DistrictDo, | 56 | DistrictDo, |
57 | DistrictSearchDo, | 57 | DistrictSearchDo, |
58 | Dto, | 58 | Dto, |
59 | + ExchangeIntegralDto, | ||
60 | + ExchangeRecordsRequestDto, | ||
59 | FeedbackRegistrationDTO, | 61 | FeedbackRegistrationDTO, |
62 | + GroupExchangeRecordsRequestDto, | ||
60 | InventoryMaterialStockReq, | 63 | InventoryMaterialStockReq, |
61 | InvoiceBatchDownloadDto, | 64 | InvoiceBatchDownloadDto, |
62 | InvoiceDto, | 65 | InvoiceDto, |
@@ -71,7 +74,6 @@ import type { | @@ -71,7 +74,6 @@ import type { | ||
71 | MeasureUnitListRes, | 74 | MeasureUnitListRes, |
72 | MergeIntegralDto, | 75 | MergeIntegralDto, |
73 | MessageQueryDTO, | 76 | MessageQueryDTO, |
74 | - ModelAndView, | ||
75 | OrderAddVO, | 77 | OrderAddVO, |
76 | OrderAuditLogQueryVO, | 78 | OrderAuditLogQueryVO, |
77 | OrderBaseInfoQueryVO, | 79 | OrderBaseInfoQueryVO, |
@@ -3830,7 +3832,9 @@ export interface GetErrorResponse { | @@ -3830,7 +3832,9 @@ export interface GetErrorResponse { | ||
3830 | * @description | 3832 | * @description |
3831 | * OK | 3833 | * OK |
3832 | */ | 3834 | */ |
3833 | - 200: ModelAndView; | 3835 | + 200: { |
3836 | + [propertyName: string]: any; | ||
3837 | + }; | ||
3834 | /** | 3838 | /** |
3835 | * @description | 3839 | * @description |
3836 | * Unauthorized | 3840 | * Unauthorized |
@@ -3851,9 +3855,9 @@ export interface GetErrorResponse { | @@ -3851,9 +3855,9 @@ export interface GetErrorResponse { | ||
3851 | export type GetErrorResponseSuccess = GetErrorResponse[200]; | 3855 | export type GetErrorResponseSuccess = GetErrorResponse[200]; |
3852 | /** | 3856 | /** |
3853 | * @description | 3857 | * @description |
3854 | - * errorHtml | 3858 | + * error |
3855 | * @tags basic-error-controller | 3859 | * @tags basic-error-controller |
3856 | - * @produces text/html | 3860 | + * @produces * |
3857 | */ | 3861 | */ |
3858 | export const getError = /* #__PURE__ */ (() => { | 3862 | export const getError = /* #__PURE__ */ (() => { |
3859 | const method = 'get'; | 3863 | const method = 'get'; |
@@ -3877,7 +3881,9 @@ export interface PutErrorResponse { | @@ -3877,7 +3881,9 @@ export interface PutErrorResponse { | ||
3877 | * @description | 3881 | * @description |
3878 | * OK | 3882 | * OK |
3879 | */ | 3883 | */ |
3880 | - 200: ModelAndView; | 3884 | + 200: { |
3885 | + [propertyName: string]: any; | ||
3886 | + }; | ||
3881 | /** | 3887 | /** |
3882 | * @description | 3888 | * @description |
3883 | * Created | 3889 | * Created |
@@ -3903,9 +3909,9 @@ export interface PutErrorResponse { | @@ -3903,9 +3909,9 @@ export interface PutErrorResponse { | ||
3903 | export type PutErrorResponseSuccess = PutErrorResponse[200]; | 3909 | export type PutErrorResponseSuccess = PutErrorResponse[200]; |
3904 | /** | 3910 | /** |
3905 | * @description | 3911 | * @description |
3906 | - * errorHtml | 3912 | + * error |
3907 | * @tags basic-error-controller | 3913 | * @tags basic-error-controller |
3908 | - * @produces text/html | 3914 | + * @produces * |
3909 | * @consumes application/json | 3915 | * @consumes application/json |
3910 | */ | 3916 | */ |
3911 | export const putError = /* #__PURE__ */ (() => { | 3917 | export const putError = /* #__PURE__ */ (() => { |
@@ -3930,7 +3936,9 @@ export interface PostErrorResponse { | @@ -3930,7 +3936,9 @@ export interface PostErrorResponse { | ||
3930 | * @description | 3936 | * @description |
3931 | * OK | 3937 | * OK |
3932 | */ | 3938 | */ |
3933 | - 200: ModelAndView; | 3939 | + 200: { |
3940 | + [propertyName: string]: any; | ||
3941 | + }; | ||
3934 | /** | 3942 | /** |
3935 | * @description | 3943 | * @description |
3936 | * Created | 3944 | * Created |
@@ -3956,9 +3964,9 @@ export interface PostErrorResponse { | @@ -3956,9 +3964,9 @@ export interface PostErrorResponse { | ||
3956 | export type PostErrorResponseSuccess = PostErrorResponse[200]; | 3964 | export type PostErrorResponseSuccess = PostErrorResponse[200]; |
3957 | /** | 3965 | /** |
3958 | * @description | 3966 | * @description |
3959 | - * errorHtml | 3967 | + * error |
3960 | * @tags basic-error-controller | 3968 | * @tags basic-error-controller |
3961 | - * @produces text/html | 3969 | + * @produces * |
3962 | * @consumes application/json | 3970 | * @consumes application/json |
3963 | */ | 3971 | */ |
3964 | export const postError = /* #__PURE__ */ (() => { | 3972 | export const postError = /* #__PURE__ */ (() => { |
@@ -3983,7 +3991,9 @@ export interface DeleteErrorResponse { | @@ -3983,7 +3991,9 @@ export interface DeleteErrorResponse { | ||
3983 | * @description | 3991 | * @description |
3984 | * OK | 3992 | * OK |
3985 | */ | 3993 | */ |
3986 | - 200: ModelAndView; | 3994 | + 200: { |
3995 | + [propertyName: string]: any; | ||
3996 | + }; | ||
3987 | /** | 3997 | /** |
3988 | * @description | 3998 | * @description |
3989 | * No Content | 3999 | * No Content |
@@ -4004,9 +4014,9 @@ export interface DeleteErrorResponse { | @@ -4004,9 +4014,9 @@ export interface DeleteErrorResponse { | ||
4004 | export type DeleteErrorResponseSuccess = DeleteErrorResponse[200]; | 4014 | export type DeleteErrorResponseSuccess = DeleteErrorResponse[200]; |
4005 | /** | 4015 | /** |
4006 | * @description | 4016 | * @description |
4007 | - * errorHtml | 4017 | + * error |
4008 | * @tags basic-error-controller | 4018 | * @tags basic-error-controller |
4009 | - * @produces text/html | 4019 | + * @produces * |
4010 | */ | 4020 | */ |
4011 | export const deleteError = /* #__PURE__ */ (() => { | 4021 | export const deleteError = /* #__PURE__ */ (() => { |
4012 | const method = 'delete'; | 4022 | const method = 'delete'; |
@@ -4030,7 +4040,9 @@ export interface OptionsErrorResponse { | @@ -4030,7 +4040,9 @@ export interface OptionsErrorResponse { | ||
4030 | * @description | 4040 | * @description |
4031 | * OK | 4041 | * OK |
4032 | */ | 4042 | */ |
4033 | - 200: ModelAndView; | 4043 | + 200: { |
4044 | + [propertyName: string]: any; | ||
4045 | + }; | ||
4034 | /** | 4046 | /** |
4035 | * @description | 4047 | * @description |
4036 | * No Content | 4048 | * No Content |
@@ -4051,9 +4063,9 @@ export interface OptionsErrorResponse { | @@ -4051,9 +4063,9 @@ export interface OptionsErrorResponse { | ||
4051 | export type OptionsErrorResponseSuccess = OptionsErrorResponse[200]; | 4063 | export type OptionsErrorResponseSuccess = OptionsErrorResponse[200]; |
4052 | /** | 4064 | /** |
4053 | * @description | 4065 | * @description |
4054 | - * errorHtml | 4066 | + * error |
4055 | * @tags basic-error-controller | 4067 | * @tags basic-error-controller |
4056 | - * @produces text/html | 4068 | + * @produces * |
4057 | * @consumes application/json | 4069 | * @consumes application/json |
4058 | */ | 4070 | */ |
4059 | export const optionsError = /* #__PURE__ */ (() => { | 4071 | export const optionsError = /* #__PURE__ */ (() => { |
@@ -4078,7 +4090,9 @@ export interface HeadErrorResponse { | @@ -4078,7 +4090,9 @@ export interface HeadErrorResponse { | ||
4078 | * @description | 4090 | * @description |
4079 | * OK | 4091 | * OK |
4080 | */ | 4092 | */ |
4081 | - 200: ModelAndView; | 4093 | + 200: { |
4094 | + [propertyName: string]: any; | ||
4095 | + }; | ||
4082 | /** | 4096 | /** |
4083 | * @description | 4097 | * @description |
4084 | * No Content | 4098 | * No Content |
@@ -4099,9 +4113,9 @@ export interface HeadErrorResponse { | @@ -4099,9 +4113,9 @@ export interface HeadErrorResponse { | ||
4099 | export type HeadErrorResponseSuccess = HeadErrorResponse[200]; | 4113 | export type HeadErrorResponseSuccess = HeadErrorResponse[200]; |
4100 | /** | 4114 | /** |
4101 | * @description | 4115 | * @description |
4102 | - * errorHtml | 4116 | + * error |
4103 | * @tags basic-error-controller | 4117 | * @tags basic-error-controller |
4104 | - * @produces text/html | 4118 | + * @produces * |
4105 | * @consumes application/json | 4119 | * @consumes application/json |
4106 | */ | 4120 | */ |
4107 | export const headError = /* #__PURE__ */ (() => { | 4121 | export const headError = /* #__PURE__ */ (() => { |
@@ -4126,7 +4140,9 @@ export interface PatchErrorResponse { | @@ -4126,7 +4140,9 @@ export interface PatchErrorResponse { | ||
4126 | * @description | 4140 | * @description |
4127 | * OK | 4141 | * OK |
4128 | */ | 4142 | */ |
4129 | - 200: ModelAndView; | 4143 | + 200: { |
4144 | + [propertyName: string]: any; | ||
4145 | + }; | ||
4130 | /** | 4146 | /** |
4131 | * @description | 4147 | * @description |
4132 | * No Content | 4148 | * No Content |
@@ -4147,9 +4163,9 @@ export interface PatchErrorResponse { | @@ -4147,9 +4163,9 @@ export interface PatchErrorResponse { | ||
4147 | export type PatchErrorResponseSuccess = PatchErrorResponse[200]; | 4163 | export type PatchErrorResponseSuccess = PatchErrorResponse[200]; |
4148 | /** | 4164 | /** |
4149 | * @description | 4165 | * @description |
4150 | - * errorHtml | 4166 | + * error |
4151 | * @tags basic-error-controller | 4167 | * @tags basic-error-controller |
4152 | - * @produces text/html | 4168 | + * @produces * |
4153 | * @consumes application/json | 4169 | * @consumes application/json |
4154 | */ | 4170 | */ |
4155 | export const patchError = /* #__PURE__ */ (() => { | 4171 | export const patchError = /* #__PURE__ */ (() => { |
@@ -4238,6 +4254,77 @@ export const postFileDirectDown = /* #__PURE__ */ (() => { | @@ -4238,6 +4254,77 @@ export const postFileDirectDown = /* #__PURE__ */ (() => { | ||
4238 | return request; | 4254 | return request; |
4239 | })(); | 4255 | })(); |
4240 | 4256 | ||
4257 | +/** @description request parameter type for postIntegralExchangeIntegral */ | ||
4258 | +export interface PostIntegralExchangeIntegralOption { | ||
4259 | + /** | ||
4260 | + * @description | ||
4261 | + * dto | ||
4262 | + */ | ||
4263 | + body: { | ||
4264 | + /** | ||
4265 | + @description | ||
4266 | + dto */ | ||
4267 | + dto: ExchangeIntegralDto; | ||
4268 | + }; | ||
4269 | +} | ||
4270 | + | ||
4271 | +/** @description response type for postIntegralExchangeIntegral */ | ||
4272 | +export interface PostIntegralExchangeIntegralResponse { | ||
4273 | + /** | ||
4274 | + * @description | ||
4275 | + * OK | ||
4276 | + */ | ||
4277 | + 200: ServerResult; | ||
4278 | + /** | ||
4279 | + * @description | ||
4280 | + * Created | ||
4281 | + */ | ||
4282 | + 201: any; | ||
4283 | + /** | ||
4284 | + * @description | ||
4285 | + * Unauthorized | ||
4286 | + */ | ||
4287 | + 401: any; | ||
4288 | + /** | ||
4289 | + * @description | ||
4290 | + * Forbidden | ||
4291 | + */ | ||
4292 | + 403: any; | ||
4293 | + /** | ||
4294 | + * @description | ||
4295 | + * Not Found | ||
4296 | + */ | ||
4297 | + 404: any; | ||
4298 | +} | ||
4299 | + | ||
4300 | +export type PostIntegralExchangeIntegralResponseSuccess = | ||
4301 | + PostIntegralExchangeIntegralResponse[200]; | ||
4302 | +/** | ||
4303 | + * @description | ||
4304 | + * 积分兑换 | ||
4305 | + * @tags 积分接口 | ||
4306 | + * @produces * | ||
4307 | + * @consumes application/json | ||
4308 | + */ | ||
4309 | +export const postIntegralExchangeIntegral = /* #__PURE__ */ (() => { | ||
4310 | + const method = 'post'; | ||
4311 | + const url = '/integral/exchangeIntegral'; | ||
4312 | + function request( | ||
4313 | + option: PostIntegralExchangeIntegralOption, | ||
4314 | + ): Promise<PostIntegralExchangeIntegralResponseSuccess> { | ||
4315 | + return requester(request.url, { | ||
4316 | + method: request.method, | ||
4317 | + ...option, | ||
4318 | + }) as unknown as Promise<PostIntegralExchangeIntegralResponseSuccess>; | ||
4319 | + } | ||
4320 | + | ||
4321 | + /** http method */ | ||
4322 | + request.method = method; | ||
4323 | + /** request url */ | ||
4324 | + request.url = url; | ||
4325 | + return request; | ||
4326 | +})(); | ||
4327 | + | ||
4241 | /** @description response type for postIntegralGetIntegralRecordTypes */ | 4328 | /** @description response type for postIntegralGetIntegralRecordTypes */ |
4242 | export interface PostIntegralGetIntegralRecordTypesResponse { | 4329 | export interface PostIntegralGetIntegralRecordTypesResponse { |
4243 | /** | 4330 | /** |
@@ -4292,6 +4379,77 @@ export const postIntegralGetIntegralRecordTypes = /* #__PURE__ */ (() => { | @@ -4292,6 +4379,77 @@ export const postIntegralGetIntegralRecordTypes = /* #__PURE__ */ (() => { | ||
4292 | return request; | 4379 | return request; |
4293 | })(); | 4380 | })(); |
4294 | 4381 | ||
4382 | +/** @description request parameter type for postIntegralGroupExchangeRecords */ | ||
4383 | +export interface PostIntegralGroupExchangeRecordsOption { | ||
4384 | + /** | ||
4385 | + * @description | ||
4386 | + * dto | ||
4387 | + */ | ||
4388 | + body: { | ||
4389 | + /** | ||
4390 | + @description | ||
4391 | + dto */ | ||
4392 | + dto: GroupExchangeRecordsRequestDto; | ||
4393 | + }; | ||
4394 | +} | ||
4395 | + | ||
4396 | +/** @description response type for postIntegralGroupExchangeRecords */ | ||
4397 | +export interface PostIntegralGroupExchangeRecordsResponse { | ||
4398 | + /** | ||
4399 | + * @description | ||
4400 | + * OK | ||
4401 | + */ | ||
4402 | + 200: ServerResult; | ||
4403 | + /** | ||
4404 | + * @description | ||
4405 | + * Created | ||
4406 | + */ | ||
4407 | + 201: any; | ||
4408 | + /** | ||
4409 | + * @description | ||
4410 | + * Unauthorized | ||
4411 | + */ | ||
4412 | + 401: any; | ||
4413 | + /** | ||
4414 | + * @description | ||
4415 | + * Forbidden | ||
4416 | + */ | ||
4417 | + 403: any; | ||
4418 | + /** | ||
4419 | + * @description | ||
4420 | + * Not Found | ||
4421 | + */ | ||
4422 | + 404: any; | ||
4423 | +} | ||
4424 | + | ||
4425 | +export type PostIntegralGroupExchangeRecordsResponseSuccess = | ||
4426 | + PostIntegralGroupExchangeRecordsResponse[200]; | ||
4427 | +/** | ||
4428 | + * @description | ||
4429 | + * 课题组积分兑换记录 | ||
4430 | + * @tags 积分接口 | ||
4431 | + * @produces * | ||
4432 | + * @consumes application/json | ||
4433 | + */ | ||
4434 | +export const postIntegralGroupExchangeRecords = /* #__PURE__ */ (() => { | ||
4435 | + const method = 'post'; | ||
4436 | + const url = '/integral/groupExchangeRecords'; | ||
4437 | + function request( | ||
4438 | + option: PostIntegralGroupExchangeRecordsOption, | ||
4439 | + ): Promise<PostIntegralGroupExchangeRecordsResponseSuccess> { | ||
4440 | + return requester(request.url, { | ||
4441 | + method: request.method, | ||
4442 | + ...option, | ||
4443 | + }) as unknown as Promise<PostIntegralGroupExchangeRecordsResponseSuccess>; | ||
4444 | + } | ||
4445 | + | ||
4446 | + /** http method */ | ||
4447 | + request.method = method; | ||
4448 | + /** request url */ | ||
4449 | + request.url = url; | ||
4450 | + return request; | ||
4451 | +})(); | ||
4452 | + | ||
4295 | /** @description request parameter type for postIntegralMergeUserIntegralToGroup */ | 4453 | /** @description request parameter type for postIntegralMergeUserIntegralToGroup */ |
4296 | export interface PostIntegralMergeUserIntegralToGroupOption { | 4454 | export interface PostIntegralMergeUserIntegralToGroupOption { |
4297 | /** | 4455 | /** |
@@ -4647,6 +4805,77 @@ export const postIntegralQuerySumByUser = /* #__PURE__ */ (() => { | @@ -4647,6 +4805,77 @@ export const postIntegralQuerySumByUser = /* #__PURE__ */ (() => { | ||
4647 | return request; | 4805 | return request; |
4648 | })(); | 4806 | })(); |
4649 | 4807 | ||
4808 | +/** @description request parameter type for postIntegralUserExchangeRecords */ | ||
4809 | +export interface PostIntegralUserExchangeRecordsOption { | ||
4810 | + /** | ||
4811 | + * @description | ||
4812 | + * dto | ||
4813 | + */ | ||
4814 | + body: { | ||
4815 | + /** | ||
4816 | + @description | ||
4817 | + dto */ | ||
4818 | + dto: ExchangeRecordsRequestDto; | ||
4819 | + }; | ||
4820 | +} | ||
4821 | + | ||
4822 | +/** @description response type for postIntegralUserExchangeRecords */ | ||
4823 | +export interface PostIntegralUserExchangeRecordsResponse { | ||
4824 | + /** | ||
4825 | + * @description | ||
4826 | + * OK | ||
4827 | + */ | ||
4828 | + 200: ServerResult; | ||
4829 | + /** | ||
4830 | + * @description | ||
4831 | + * Created | ||
4832 | + */ | ||
4833 | + 201: any; | ||
4834 | + /** | ||
4835 | + * @description | ||
4836 | + * Unauthorized | ||
4837 | + */ | ||
4838 | + 401: any; | ||
4839 | + /** | ||
4840 | + * @description | ||
4841 | + * Forbidden | ||
4842 | + */ | ||
4843 | + 403: any; | ||
4844 | + /** | ||
4845 | + * @description | ||
4846 | + * Not Found | ||
4847 | + */ | ||
4848 | + 404: any; | ||
4849 | +} | ||
4850 | + | ||
4851 | +export type PostIntegralUserExchangeRecordsResponseSuccess = | ||
4852 | + PostIntegralUserExchangeRecordsResponse[200]; | ||
4853 | +/** | ||
4854 | + * @description | ||
4855 | + * 用户积分兑换记录 | ||
4856 | + * @tags 积分接口 | ||
4857 | + * @produces * | ||
4858 | + * @consumes application/json | ||
4859 | + */ | ||
4860 | +export const postIntegralUserExchangeRecords = /* #__PURE__ */ (() => { | ||
4861 | + const method = 'post'; | ||
4862 | + const url = '/integral/userExchangeRecords'; | ||
4863 | + function request( | ||
4864 | + option: PostIntegralUserExchangeRecordsOption, | ||
4865 | + ): Promise<PostIntegralUserExchangeRecordsResponseSuccess> { | ||
4866 | + return requester(request.url, { | ||
4867 | + method: request.method, | ||
4868 | + ...option, | ||
4869 | + }) as unknown as Promise<PostIntegralUserExchangeRecordsResponseSuccess>; | ||
4870 | + } | ||
4871 | + | ||
4872 | + /** http method */ | ||
4873 | + request.method = method; | ||
4874 | + /** request url */ | ||
4875 | + request.url = url; | ||
4876 | + return request; | ||
4877 | +})(); | ||
4878 | + | ||
4650 | /** @description request parameter type for postKingdeeRepCustomer */ | 4879 | /** @description request parameter type for postKingdeeRepCustomer */ |
4651 | export interface PostKingdeeRepCustomerOption { | 4880 | export interface PostKingdeeRepCustomerOption { |
4652 | /** | 4881 | /** |