Commit 5e1adeb7 authored by XieZhiXiong's avatar XieZhiXiong

feat: 对接 会员导入 新增

parent aa412753
/*
* @Author: LeeJiancong
* @Date: 2020-07-22 09:54:50
* @LastEditors: LeeJiancong
* @LastEditTime: 2020-10-12 18:13:49
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-05-28 18:33:56
*/
/**
* 正则表达式集合
......@@ -19,4 +19,5 @@ export const PATTERN_MAPS = {
money:/^\d*(?:\.\d{0,2})?$/,
weight:/^\d*(?:\.\d{0,3})?$/,
quantity: /^[1-9]+[0-9]*$/, // 数量,大于等于1的正整数
identity: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/, // 数量,大于等于1的正整数
}
\ No newline at end of file
......@@ -3,7 +3,7 @@ import MemberForm from './components/MemberForm';
const AddMember: React.FC = () => {
return (
<MemberForm />
<MemberForm isEdit />
);
};
......
import React, { useState, useEffect, useRef, ReactNode } from 'react';
import React, { useState, useEffect } from 'react';
import { history, Prompt } from 'umi';
import { Badge, Button, Card, Spin, message } from 'antd';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { SaveOutlined } from '@ant-design/icons';
import { createFormActions, FormEffectHooks, FormPath } from '@formily/antd';
import { Select, Input } from '@formily/antd-components'
import { Radio, Checkbox } from '@formily/antd-components'
import { merge } from 'rxjs';
import { usePageStatus } from '@/hooks/usePageStatus';
import ReutrnEle from '@/components/ReturnEle';
......@@ -25,9 +25,17 @@ const {
} = FormEffectHooks;
interface MemberFormProps {
/**
* 数据id
*/
id?: number;
/**
* 数据审核id
*/
validateId?: number;
// 是否是编辑的
/**
* 是否是可编辑的
*/
isEdit?: boolean,
mode?: 'myself' | "any"
};
......@@ -38,7 +46,6 @@ const MemberForm: React.FC<MemberFormProps> = ({
mode,
isEdit = false,
}) => {
const areaRef = useRef<any[]>([])
const [memberItems, setMemberItems] = useState<any>({});
const [memberInfo, setMemberInfo] = useState<GetMemberAbilitySubGetResponse>(null);
const [submitLoading, setSubmitLoading] = useState(false);
......@@ -120,19 +127,19 @@ const MemberForm: React.FC<MemberFormProps> = ({
const channelType = channelTypes.map(item => ({ label: item.channelTypeName, value: item.channelTypeId }));
if (areasOptions.length) {
formActions.setFieldState('areas.*.pcode', state => {
formActions.setFieldState('areas.*.provinceCode', state => {
FormPath.setIn(state, 'props.enum', areasOptions);
});
areaCodes && areaCodes.forEach((area, index) => {
const { pcode, ccode } = area;
const province = areas.find(item => item.code === pcode);
const { provinceCode, cityCode } = area;
const province = areas.find(item => item.code === provinceCode);
if (province && province.children) {
const citys =
province.children.map((item: { code: string, name: string }) => ({ label: item.name, value: item.code }));
formActions.setFieldState(
`areas.${index}.ccode`,
`areas.${index}.cityCode`,
state => {
FormPath.setIn(state, 'props.enum', citys);
}
......@@ -145,8 +152,6 @@ const MemberForm: React.FC<MemberFormProps> = ({
FormPath.setIn(state, 'props.enum', channelType);
});
areaRef.current = areas;
setMemberInfo({
memberTypeId: memberTypeEnum,
...rest,
......@@ -183,6 +188,7 @@ const MemberForm: React.FC<MemberFormProps> = ({
channelTypeId,
areas = [],
remark,
upperRelationId,
outerStatus,
status,
......@@ -190,26 +196,29 @@ const MemberForm: React.FC<MemberFormProps> = ({
...rest
} = values;
const filtered = areas.filter(item => item.pcode || item.ccode);
const filtered = areas.filter(item => item.provinceCode || item.cityCode);
const payload = {
memberTypeId,
roleId,
level,
countryCodeId,
phone,
email,
channelTypeId,
areas: filtered,
remark,
upperRelationId: upperRelationId || 0,
detail: rest,
};
if (!id && !isEdit) {
if (!id && isEdit) {
setSubmitLoading(true);
const msg = message.loading({
content: '正在添加,请稍候...',
duration: 0,
});
PublicApi.postMemberAbilitySubAdd({
memberTypeId,
roleId,
level,
countryCodeId,
phone,
email,
channelTypeId,
areas: filtered,
remark,
detail: rest,
}, {
PublicApi.postMemberAbilitySubAdd(payload, {
timeout: 0,
}).then(res => {
if (res.code !== 1000) {
......@@ -223,7 +232,6 @@ const MemberForm: React.FC<MemberFormProps> = ({
msg();
setSubmitLoading(false);
});
return;
}
if (id && validateId && isEdit) {
......@@ -351,6 +359,7 @@ const MemberForm: React.FC<MemberFormProps> = ({
linkage.value('channelTypeId', undefined);
linkage.value('areas', []);
linkage.value('remark', '');
linkage.value('upperRelationId', undefined);
// 获取渠道信息
PublicApi.getMemberAbilitySubPageitemsChannel({
......@@ -361,33 +370,36 @@ const MemberForm: React.FC<MemberFormProps> = ({
}
const {
channelLevelTag = '',
areas = [],
channelTypes = [],
upperMembers = [],
} = res.data;
formActions.setFieldState('tabs', state => {
state.props['x-component-props'] =
state.props['x-component-props'] || {};
const { hiddenKeys } = state.props['x-component-props'];
state.props['x-component-props'].hiddenKeys =
!channelLevelTag ? ['tab-2'] : [];
});
areaRef.current = areas;
const areasOptions = areas.map(item => ({ label: item.name, value: item.code }));
const channelType = channelTypes.map(item => ({ label: item.channelTypeName, value: item.channelTypeId }));
if (areasOptions.length) {
formActions.setFieldState('areas.*.pcode', state => {
FormPath.setIn(state, 'props.enum', areasOptions);
// 渠道上级id,如果没有也是返回只有一项的数组
if (upperMembers.length === 1 && !upperMembers[0].upperRelationId) {
linkage.hide('upperRelationId');
// set 一下值,触发 valueChange 事件
linkage.value('upperRelationId', 0);
} else {
const upperMembersOptions = upperMembers.map(item => ({ label: item.name, value: item.upperRelationId }));
formActions.setFieldState('upperRelationId', state => {
FormPath.setIn(state, 'props.enum', upperMembersOptions);
});
}
formActions.setFieldState('channelLevel', state => {
FormPath.setIn(state, 'value', channelLevelTag);
});
formActions.setFieldState('channelTypeId', state => {
FormPath.setIn(state, 'props.enum', channelType);
});
});
});
......@@ -443,20 +455,59 @@ const MemberForm: React.FC<MemberFormProps> = ({
}, 0);
});
// 渠道信息省级变化,筛选出对应的市级数据
onFieldInputChange$('areas.*.pcode').subscribe(fieldState => {
const province = areaRef.current.find(item => item.code === fieldState.value);
if (!province) {
// 渠道上级改变时,请求出对应的省级数据
onFieldValueChange$('upperRelationId').subscribe(fieldState => {
if (fieldState.value === undefined) {
return;
}
// 清空渠道原来数据
linkage.value('areas', []);
PublicApi.getMemberAbilitySubPageitemsProvince({
upperRelationId: fieldState.value,
}).then(res => {
if (res.code === 1000) {
const { data = [] } = res;
const options = data.map(item => ({ label: item.name, value: item.code }));
formActions.setFieldState('areas.*.provinceCode', state => {
FormPath.setIn(state, 'props.enum', options);
});
}
});
});
// 省级改变时,,请求出对应的市级数据
onFieldInputChange$('areas.*.provinceCode').subscribe(fieldState => {
if (fieldState.value === undefined) {
return;
}
const city = (province.children || []).map(item => ({ label: item.name, value: item.code }));
const upperRelationValue = formActions.getFieldValue('upperRelationId');
formActions.setFieldState(
FormPath.transform(fieldState.name, /\d/, $1 => `areas.${$1}.ccode`),
FormPath.transform(fieldState.name, /\d/, $1 => `areas.${$1}.cityCode`),
state => {
FormPath.setIn(state, 'value', undefined);
FormPath.setIn(state, 'props.enum', city);
FormPath.setIn(state, 'props.x-props.hasFeedback', true);
FormPath.setIn(state, 'loading', true);
}
);
PublicApi.getMemberAbilitySubPageitemsCity({
upperRelationId: upperRelationValue,
provinceCode: fieldState.value,
}).then(res => {
if (res.code === 1000) {
const { data = [] } = res;
const options = data.map(item => ({ label: item.name, value: item.code }));
formActions.setFieldState(
FormPath.transform(fieldState.name, /\d/, $1 => `areas.${$1}.cityCode`),
state => {
FormPath.setIn(state, 'value', undefined);
FormPath.setIn(state, 'props.enum', options);
FormPath.setIn(state, 'loading', false);
}
);
}
});
});
}
......@@ -486,6 +537,10 @@ const MemberForm: React.FC<MemberFormProps> = ({
onSubmit={handleSubmit}
actions={formActions}
initialValues={memberInfo || {}}
components={{
RadioGroup: Radio.Group,
CheckboxGroup: Checkbox.Group,
}}
effects={($, actions) => {
useAsyncInitSelect(
['memberTypeId', 'countryCodeId'],
......@@ -501,6 +556,7 @@ const MemberForm: React.FC<MemberFormProps> = ({
});
}}
schema={initDetailSchema(memberItems)}
editable={isEdit}
/>
</Card>
</PageHeaderWrapper>
......
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { UPLOAD_TYPE } from '@/constants';
import { PATTERN_MAPS } from '@/constants/regExp';
const FIELD_TYPE_MAP = {
'string': 'string',
'long': 'string',
'upload': 'customUpload',
type FieldType = 'string' | 'long' | 'upload' | 'radio' | 'select' | 'checkbox';
// 字段校验规则枚举:0-无校验规则,1-邮箱规则,2-手机号码规则,3-身份证规则,4-电话号码规则
const RULE_REG_MAP = {
1: PATTERN_MAPS.email,
2: PATTERN_MAPS.phone,
3: PATTERN_MAPS.identity,
4: PATTERN_MAPS.tel,
};
const getXComponentProps = (type, item) => {
const MAP = {
'string': {
placeholder: item.fieldRemark,
},
'upload': {
listType: 'card',
action: '/api/file/file/upload',
data: { fileType: UPLOAD_TYPE },
fileList: [],
onChange: file => console.log(file),
},
const getFieldType = (field) => {
// 默认是 输入框
let description: { [key: string]: any } = {
type: 'string',
required: field.fieldEmpty === 0,
title: field.fieldLocalName,
default: field.fieldValue,
'x-component-props': {
placeholder: field.fieldRemark,
disabled: field.disabled,
},
};
return MAP[type];
// 公共的属性
const common = {
type: 'string',
required: field.fieldEmpty === 0,
title: field.fieldLocalName,
default: field.fieldValue,
'x-rules': [
(
field.ruleEnum
? {
pattern: RULE_REG_MAP[field.ruleEnum],
message: field.msg,
}
: null
),
(
field.pattern
? {
pattern: field.pattern,
message: field.msg,
}
: null
),
].filter(Boolean),
};
switch (field.fieldType as FieldType) {
case 'upload': {
description = {
'x-component': 'CustomUpload',
'x-component-props': {
showDesc: false,
disabled: field.disabled,
},
};
break;
}
case 'radio': {
description = {
'x-component': 'RadioGroup',
enum: field.fieldEnum,
'x-component-props': {
showDesc: false,
disabled: field.disabled,
},
};
break;
}
case 'select': {
description = {
enum: field.fieldEnum,
};
break;
}
case 'checkbox': {
description = {
'x-component': 'CheckboxGroup',
enum: field.fieldEnum,
};
break;
}
default:
break;
}
return Object.assign({}, description, common);
};
const getCompnentValue = (elements: any) => {
const getComponentValue = (elements: any) => {
const components = {};
for (let item of elements) {
// 先判断是否存在 type,防止不存在的 type 报错
const realType = FIELD_TYPE_MAP[item.fieldType];
if (realType) {
components[item.fieldName] = {
type: FIELD_TYPE_MAP[item.fieldType],
required: item.fieldEmpty === 0,
title: item.fieldCNName,
'x-component-props': getXComponentProps(realType, item),
};
}
for (let item of elements) {
components[item.fieldName] = getFieldType(item);
}
return components;
};
......@@ -173,6 +229,15 @@ export const initDetailSchema = (props: any) => {
full: true,
},
properties: {
upperRelationId: {
type: 'string',
enum: [],
title: '上级渠道',
required: true,
'x-component-props': {
},
},
channelLevel: {
type: 'text',
title: '渠道级别',
......@@ -194,14 +259,14 @@ export const initDetailSchema = (props: any) => {
items: {
type: 'object',
properties: {
pcode: {
provinceCode: {
type: 'string',
enum: [],
'x-component-props': {
allowClear: true,
},
},
ccode: {
cityCode: {
type: 'string',
enum: [],
'x-component-props': {
......@@ -251,7 +316,7 @@ export const initDetailSchema = (props: any) => {
wrapperCol: 8,
labelAlign: 'left',
},
properties: getCompnentValue(item.elements),
properties: getComponentValue(item.elements),
},
},
};
......
......@@ -108,13 +108,12 @@ const getFieldType = (field) => {
};
};
const getCompnentValue = (elements: any) => {
const getComponentValue = (elements: any) => {
const components = {};
for (let item of elements) {
components[item.fieldName] = getFieldType(item);
}
console.log('components', components)
return components;
};
......@@ -140,7 +139,7 @@ export const initDetailSchema = (props: any) => {
wrapperCol: 8,
labelAlign: 'left',
},
properties: getCompnentValue(item.elements),
properties: getComponentValue(item.elements),
},
},
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment