Commit af3fccf0 authored by Bill's avatar Bill

Merge branch 'dev-srm' of 10.0.0.22:lingxi/lingxi-business-paltform into dev-srm

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