Commit 0e55a8c79b76af6eb19adc2ba293edc03ce6a58f

Authored by 曾国涛
1 parent 9eb4ffda

feat(ResearchGroup): 新增预存账号申请功能

- 在成员申请弹窗中添加预存账号选择功能
- 新增申请类型字段,区分新增成员和新增预存账号
- 修改弹窗显示逻辑,根据申请类型显示不同表单内容
- 优化成员选择和客户信息搜索功能
src/pages/ResearchGroup/components/ResearchGroupMemberRequestAddModal.tsx
1 1 import { RESPONSE_CODE } from '@/constants/enum';
2 2 import {
3   - postCanrdApiUserAddressList,
  3 + postCanrdApiUserAddressList, postCanrdApiUserList,
4 4 postResearchGroupMemberRequestsAdd,
5 5 postResearchGroupMemberRequestsDetail,
6 6 postResearchGroupMemberRequestsEdit,
... ... @@ -25,15 +25,39 @@ import { useEffect, useState } from 'react';
25 25 import '../index.less';
26 26  
27 27 // import { cloneDeep } from 'lodash';
28   -export default ({ setVisible, requestId, onClose }) => {
  28 +export default ({ setVisible, requestId, onClose,type }) => {
29 29 const [form] = Form.useForm();
30 30 const [memberOptions, setMemberOptions] = useState<any[]>([]);
31 31 const [requestInfo, setRequestInfo] = useState<any>(null);
32 32 const [modalLoading, setModalLoading] = useState(false);
33 33 const [groupOption, setGroupOption] = useState<any>(null);
34 34 const copyRequestId = cloneDeep(requestId);
  35 + const [requestCount, setRequestCount] = useState(1);
  36 + const [accountOptions, setAccountOptions] = useState<any[]>([]);
35 37  
36 38 /**
  39 + * 保存account的options
  40 + * @param option
  41 + * @returns
  42 + */
  43 + function autoAccountSelectOptions(option: any) {
  44 + if (!option) {
  45 + return;
  46 + }
  47 + let id = option.value;
  48 + //判断当前客户信息是否已添加过:id匹配或者option的phone匹配说明添加过了
  49 + let accountIds = form.getFieldValue('accounts');
  50 + if (!accountIds) {
  51 + //表单项没值的时候默认是undefined。初始化为数组
  52 + accountIds = [];
  53 + }
  54 + if (accountIds.includes(id)) {
  55 + return;
  56 + }
  57 + //option添加到accountOptions中
  58 + setAccountOptions(option);
  59 + }
  60 + /**
37 61 * 获取课题组信息
38 62 * @returns
39 63 */
... ... @@ -177,7 +201,23 @@ export default ({ setVisible, requestId, onClose }) =&gt; {
177 201 }
178 202 values.members = memberObjs;
179 203 }
180   -
  204 +//预存账号对象封装
  205 + if (values.accounts) {
  206 + let accountObjs: any[] = [];
  207 + for (let accountOption of accountOptions) {
  208 + if (values.accounts.includes(accountOption.uid)) {
  209 + accountObjs.push({
  210 + accountPhone: accountOption.phone,
  211 + accountId: accountOption.uid,
  212 + accountName: accountOption.realName,
  213 + id: accountOption.id,
  214 + groupId: accountOption.groupId,
  215 + });
  216 + }
  217 + }
  218 + values.accounts = accountObjs;
  219 + }
  220 + values.requestType = type;
181 221 //课题组信息封装
182 222 if (groupOption) {
183 223 values.groupName = groupOption.groupName;
... ... @@ -309,145 +349,214 @@ export default ({ setVisible, requestId, onClose }) =&gt; {
309 349 }}
310 350 />
311 351 </ProForm.Group>
312   -
313   - <ProFormSelect
314   - name="members"
315   - key="members"
316   - width="lg"
317   - showSearch
318   - label="课题组成员"
319   - placeholder="请添加课题组成员"
320   - rules={[{ required: true, message: '请至少添加一个成员' }]}
321   - fieldProps={{
322   - mode: 'multiple',
323   - filterOption() {
324   - return true;
325   - },
326   - optionItemRender(item: any) {
327   - let name = item.realName + ' | ' + item.phone;
328   - return (
329   - <div title={name}>
330   - <span style={{ color: '#333333' }}>{name}</span>
331   - </div>
332   - );
333   - },
334   - }}
335   - options={memberOptions}
336   - />
337   -
338   - <ProCard
339   - title="选择或自定义课题组成员信息"
340   - bordered
341   - tooltip="从【客户信息】选择框中可以直接搜索客户,选中后自动添加到【课题组成员】中。也可以自定义输入【客户名称】和【手机号】,点击添加按钮手动添加到【课题组成员】中。"
342   - >
343   - <ProForm.Group>
  352 + {type==='ADD_ACCOUNT'&&
344 353 <ProFormSelect
345   - key="customerName"
346   - label="客户信息(选择)"
347   - width="lg"
348   - showSearch
349   - name="customerName"
350   - placeholder="请选择客户信息"
351   - onChange={(_, option) => {
352   - autoFillCustomerInfo(option);
353   - }}
354   - fieldProps={{
355   - filterOption() {
356   - return true;
357   - },
358   - optionItemRender(item: any) {
359   - if (item.type === 'add') {
  354 + name="accounts"
  355 + key="accounts"
  356 + width="lg"
  357 + showSearch
  358 + label="绑定预存账号(可多选)"
  359 + placeholder="请选择预存账号"
  360 + onChange={(_, option) => {
  361 + autoAccountSelectOptions(option);
  362 + }}
  363 + //rules={[{ required: true, message: '请至少选择绑定一个预存账号' }]}
  364 + fieldProps={{
  365 + mode: 'multiple',
  366 + filterOption() {
  367 + return true;
  368 + },
  369 + optionItemRender(item: any) {
  370 + let name =
  371 + item.label +
  372 + ' | ' +
  373 + item.institution +
  374 + ' | ' +
  375 + item.nowMoney +
  376 + '¥' +
  377 + ' | ' +
  378 + item.phone;
360 379 return (
361   - <div title={item.name + '(新增客户)'}>
362   - <span style={{ color: '#333333' }}>{item.name}</span>
363   - {' | '}
364   - <span style={{ color: 'orange' }}>自定义</span>
365   - </div>
  380 + <div title={name}>
  381 + <span style={{ color: '#333333' }}>{name}</span>
  382 + </div>
366 383 );
  384 + },
  385 + }}
  386 + rules={[{ required: true, message: '请至少添加一个账号' }]}
  387 + debounceTime={1000}
  388 + request={async (value, {}) => {
  389 + const keywords = value.keyWords;
  390 + let body = {
  391 + keywords: keywords,
  392 + pageSize: 20,
  393 + researchGroupId: undefined,
  394 + };
  395 +
  396 + if (requestCount === 1) {
  397 + body.researchGroupId = form.getFieldValue('groupId');
367 398 }
368 399  
369   - let title = '';
370   - let spanText = '';
371   - let realName = item.realName;
372   - let phone = item.phone;
373   -
374   - title =
375   - getDefaultString(realName) +
376   - '|' +
377   - getDefaultString(phone);
378   -
379   - spanText =
380   - getDefaultString(realName) +
381   - '|' +
382   - getDefaultString(phone);
383   - return (
384   - <div title={title}>
385   - <span style={{ color: '#333333' }}>{spanText}</span>
386   - </div>
387   - );
388   - },
389   - }}
390   - debounceTime={1000}
391   - request={async (value, {}) => {
392   - const keywords = value.keyWords;
393   - if (keywords === '') {
394   - return [];
395   - }
396   - const res = await postCanrdApiUserAddressList({
397   - data: { keywords: keywords },
398   - });
399   - let options = res?.data?.map((c: any) => {
400   - return {
401   - ...c,
402   - label: c.name,
403   - value: c.id,
404   - key: c.id,
405   - };
406   - });
407   -
408   - //对options去重,realName和phone唯一
409   - options = deduplicateOptions(options);
410   -
411   - //第一个商品默认为要新增客户
412   - if (keywords.trim() !== '') {
413   - options.unshift({
414   - name: keywords,
415   - type: 'add',
416   - label: keywords,
417   - value: 3.1415926,
418   - key: keywords,
  400 + const res = await postCanrdApiUserList({
  401 + data: body,
  402 + });
  403 + let options = res?.data?.data?.map((c: any) => {
  404 + return {
  405 + ...c,
  406 + label: c.realName,
  407 + value: c.uid,
  408 + key: c.uid,
  409 + };
419 410 });
420   - }
421 411  
422   - return options;
423   - }}
424   - />
425   - </ProForm.Group>
426   -
427   - <ProForm.Group>
428   - <ProFormText
429   - name="realName"
430   - label="客户名称(自定义)"
431   - placeholder="请输入客户名称"
432   - rules={[{ required: false, message: '请输入客户名称' }]}
  412 + setRequestCount(requestCount + 1);
  413 + return options;
  414 + }}
433 415 />
434   - <ProFormText
435   - name="phone"
436   - label="手机号(自定义)"
437   - width="md"
438   - placeholder="请输入手机号"
439   - rules={[{ required: false, message: '请输入手机号' }]}
440   - />
441   - </ProForm.Group>
442   - <Button
443   - type="primary"
444   - onClick={() => {
445   - addCustomMember();
446   - }}
447   - >
448   - 添加
449   - </Button>
450   - </ProCard>
  416 + }
  417 + {
  418 + type!=='ADD_ACCOUNT'&&
  419 + <>
  420 + <ProFormSelect
  421 + name="members"
  422 + key="members"
  423 + width="lg"
  424 + showSearch
  425 + label="课题组成员"
  426 + placeholder="请添加课题组成员"
  427 + rules={[{ required: true, message: '请至少添加一个成员' }]}
  428 + fieldProps={{
  429 + mode: 'multiple',
  430 + filterOption() {
  431 + return true;
  432 + },
  433 + optionItemRender(item: any) {
  434 + let name = item.realName + ' | ' + item.phone;
  435 + return (
  436 + <div title={name}>
  437 + <span style={{ color: '#333333' }}>{name}</span>
  438 + </div>
  439 + );
  440 + },
  441 + }}
  442 + options={memberOptions}
  443 + />
  444 +
  445 + <ProCard
  446 + title="选择或自定义课题组成员信息"
  447 + bordered
  448 + tooltip="从【客户信息】选择框中可以直接搜索客户,选中后自动添加到【课题组成员】中。也可以自定义输入【客户名称】和【手机号】,点击添加按钮手动添加到【课题组成员】中。"
  449 + >
  450 + <ProForm.Group>
  451 + <ProFormSelect
  452 + key="customerName"
  453 + label="客户信息(选择)"
  454 + width="lg"
  455 + showSearch
  456 + name="customerName"
  457 + placeholder="请选择客户信息"
  458 + onChange={(_, option) => {
  459 + autoFillCustomerInfo(option);
  460 + }}
  461 + fieldProps={{
  462 + filterOption() {
  463 + return true;
  464 + },
  465 + optionItemRender(item: any) {
  466 + if (item.type === 'add') {
  467 + return (
  468 + <div title={item.name + '(新增客户)'}>
  469 + <span style={{ color: '#333333' }}>{item.name}</span>
  470 + {' | '}
  471 + <span style={{ color: 'orange' }}>自定义</span>
  472 + </div>
  473 + );
  474 + }
  475 +
  476 + let title = '';
  477 + let spanText = '';
  478 + let realName = item.realName;
  479 + let phone = item.phone;
  480 +
  481 + title =
  482 + getDefaultString(realName) +
  483 + '|' +
  484 + getDefaultString(phone);
  485 +
  486 + spanText =
  487 + getDefaultString(realName) +
  488 + '|' +
  489 + getDefaultString(phone);
  490 + return (
  491 + <div title={title}>
  492 + <span style={{ color: '#333333' }}>{spanText}</span>
  493 + </div>
  494 + );
  495 + },
  496 + }}
  497 + debounceTime={1000}
  498 + request={async (value, {}) => {
  499 + const keywords = value.keyWords;
  500 + if (keywords === '') {
  501 + return [];
  502 + }
  503 + const res = await postCanrdApiUserAddressList({
  504 + data: { keywords: keywords },
  505 + });
  506 + let options = res?.data?.map((c: any) => {
  507 + return {
  508 + ...c,
  509 + label: c.name,
  510 + value: c.id,
  511 + key: c.id,
  512 + };
  513 + });
  514 +
  515 + //对options去重,realName和phone唯一
  516 + options = deduplicateOptions(options);
  517 +
  518 + //第一个商品默认为要新增客户
  519 + if (keywords.trim() !== '') {
  520 + options.unshift({
  521 + name: keywords,
  522 + type: 'add',
  523 + label: keywords,
  524 + value: 3.1415926,
  525 + key: keywords,
  526 + });
  527 + }
  528 +
  529 + return options;
  530 + }}
  531 + />
  532 + </ProForm.Group>
  533 +
  534 + <ProForm.Group>
  535 + <ProFormText
  536 + name="realName"
  537 + label="客户名称(自定义)"
  538 + placeholder="请输入客户名称"
  539 + rules={[{ required: false, message: '请输入客户名称' }]}
  540 + />
  541 + <ProFormText
  542 + name="phone"
  543 + label="手机号(自定义)"
  544 + width="md"
  545 + placeholder="请输入手机号"
  546 + rules={[{ required: false, message: '请输入手机号' }]}
  547 + />
  548 + </ProForm.Group>
  549 + <Button
  550 + type="primary"
  551 + onClick={() => {
  552 + addCustomMember();
  553 + }}
  554 + >
  555 + 添加
  556 + </Button>
  557 + </ProCard>
  558 + </>
  559 + }
451 560  
452 561 <ProFormTextArea
453 562 name="requestNotes"
... ...
src/pages/ResearchGroup/constant.tsx
... ... @@ -162,6 +162,12 @@ export const RESEARCH_GROUP_MEMBER_REQUEST_COLUMNS = [
162 162 hideInTable: true,
163 163 },
164 164 {
  165 + title: '申请类型',
  166 + dataIndex: 'requestTypeText',
  167 + key: 'requestTypeText',
  168 + hideInSearch: true,
  169 + },
  170 + {
165 171 title: '课题组名称',
166 172 dataIndex: 'groupName',
167 173 key: 'groupName',
... ... @@ -211,6 +217,23 @@ export const RESEARCH_GROUP_MEMBER_REQUEST_COLUMNS = [
211 217 hideInTable: true,
212 218 },
213 219 {
  220 + title: '申请类型',
  221 + dataIndex: 'requestType',
  222 + key: 'requestType',
  223 + valueType: 'select',
  224 + valueEnum: {
  225 + ADD_MEMBER: {
  226 + text: '新增成员',
  227 + status: 'ADD_MEMBER'
  228 + },
  229 + ADD_ACCOUNT: {
  230 + text: '新增课题组',
  231 + status: 'ADD_ACCOUNT'
  232 + },
  233 + },
  234 + hideInTable: true,
  235 + },
  236 + {
214 237 title: '申请备注',
215 238 dataIndex: 'requestNotes',
216 239 key: 'requestNotes',
... ...
src/pages/ResearchGroup/index.tsx
... ... @@ -44,6 +44,7 @@ const PrepaidPage = () =&gt; {
44 44 const [importModalVisible, setImportModalVisible] = useState(false);
45 45 const [auditIds, setAuditIds] = useState<any[]>([]);
46 46 const [auditModalVisible, setAuditModalVisible] = useState(false);
  47 + const [requestType, setRequestType] = useState(null);
47 48 const [
48 49 researchGroupMemberRequestAddModalVisible,
49 50 setResearchGroupMemberRequestAddModalVisible,
... ... @@ -436,6 +437,7 @@ const PrepaidPage = () =&gt; {
436 437 type="link"
437 438 onClick={() => {
438 439 setResearchGroupMemberRequestAddModalVisible(true);
  440 + setRequestType(record?.requestType)
439 441 setOptRecordId(record?.id);
440 442 }}
441 443 >
... ... @@ -659,16 +661,31 @@ const PrepaidPage = () =&gt; {
659 661 let btns = [];
660 662 btns.push(
661 663 <Button
662   - key="button"
  664 + key="abutton"
663 665 icon={<PlusOutlined />}
664 666 onClick={() => {
  667 + setRequestType('ADD_ACCOUNT');
665 668 setResearchGroupMemberRequestAddModalVisible(true);
666 669 }}
667 670 type="primary"
668 671 >
669   - 新
  672 + 新增预存账号申请
670 673 </Button>,
671 674 );
  675 + btns.push(
  676 + <Button
  677 + key="button"
  678 + icon={<PlusOutlined />}
  679 + onClick={() => {
  680 + setRequestType(null);
  681 + setResearchGroupMemberRequestAddModalVisible(true);
  682 + }}
  683 + type="primary"
  684 + >
  685 + 新增成员申请
  686 + </Button>,
  687 + );
  688 +
672 689 return btns;
673 690 }}
674 691 rowSelection={{
... ... @@ -753,6 +770,7 @@ const PrepaidPage = () =&gt; {
753 770  
754 771 {researchGroupMemberRequestAddModalVisible && (
755 772 <ResearchGroupMemberRequestAddModal
  773 +
756 774 setVisible={(val: boolean) => {
757 775 setResearchGroupMemberRequestAddModalVisible(val);
758 776 if (!val) {
... ... @@ -761,10 +779,12 @@ const PrepaidPage = () =&gt; {
761 779 }}
762 780 requestId={optRecordId}
763 781 onClose={() => {
  782 + setRequestType(null)
764 783 setResearchGroupMemberRequestAddModalVisible(false);
765 784 setOptRecordId(null);
766 785 reloadMemberApplyTable();
767 786 }}
  787 + type={requestType}
768 788 />
769 789 )}
770 790  
... ...