Commit 842c269c authored by XieZhiXiong's avatar XieZhiXiong

feat: 添加会员等级管理模块相关

parent a3ef7a20
......@@ -202,6 +202,45 @@ const MemberManageRoute = {
hideInMenu: true,
hidePageHeader: true,
},
// 平台会员等级管理
{
path: '/memberManage/platformMemberLevel',
name: '平台会员等级管理',
component: '@/pages/memberManage/platformMemberLevel',
noMargin: true,
},
// 平台会员等级管理 - 新增
{
path: '/memberManage/platformMemberLevel/add',
name: '新增平台会员等级',
component: '@/pages/memberManage/platformMemberLevel/addMemberLevel',
hideInMenu: true,
hidePageHeader: true,
},
// 平台会员等级管理 - 修改
{
path: '/memberManage/platformMemberLevel/modify',
name: '修改平台会员等级',
component: '@/pages/memberManage/platformMemberLevel/modifyMemberLevel',
hideInMenu: true,
hidePageHeader: true,
},
// 平台会员等级管理 - 详情
{
path: '/memberManage/platformMemberLevel/details',
name: '查看规则会员等级',
component: '@/pages/memberManage/platformMemberLevel/memberLevelDetails',
hideInMenu: true,
hidePageHeader: true,
},
// 平台会员等级管理 - 平台会员权益设置
{
path: '/memberManage/platformMemberLevel/setMemberLevelRight',
name: '平台会员权益设置',
component: '@/pages/memberManage/platformMemberLevel/setMemberLevelRight',
hideInMenu: true,
hidePageHeader: true,
},
],
}
export default MemberManageRoute;
......@@ -90,8 +90,8 @@ export interface NormalTableProps<T> extends Omit<TableProps<T>, 'pagination'> {
}
export interface EditableCellProps {
onSave?: (row: {[key: string]: any}) => void,
onValidateError?: (error: {[key: string]: any}) => void,
onSave?: (row: any) => void,
onValidateError?: (error: any) => void,
record?: any;
index?: number;
dataIndex?: string | number;
......
......@@ -132,4 +132,51 @@ export const MEMBER_OUTER_STATUS_MODIFY_PASSED = 9;
/**
* 会员变更审核不通过
*/
export const MEMBER_OUTER_STATUS_MODIFY_NOT_PASSED = 10;
\ No newline at end of file
export const MEMBER_OUTER_STATUS_MODIFY_NOT_PASSED = 10;
/**
* 会员等级层级options
*/
export const MEMBER_LEVEL_ENUM = [
{
label: '1',
value: 1,
},
{
label: '2',
value: 2,
},
{
label: '3',
value: 3,
},
{
label: '4',
value: 4,
},
{
label: '5',
value: 5,
},
{
label: '6',
value: 6,
},
{
label: '7',
value: 7,
},
{
label: '8',
value: 8,
},
{
label: '9',
value: 9,
},
{
label: '10',
value: 10,
},
];
\ No newline at end of file
......@@ -3,16 +3,16 @@ export interface ShopInfo {
name: string;
type: number;
environment: number;
property?: any;
property: number;
self: number;
memberOperate: number;
openMro: number;
openMro?: any;
logoUrl: string;
describe: string;
state: number;
url: string;
isDefault: number;
createTime?: any;
createTime: number;
}
export interface OrderMode {
......@@ -33,8 +33,9 @@ export interface SiteInfo {
name: string;
logo: string;
siteUrl: string;
symbol?: any;
symbol: string;
language: string;
enableMultiTenancy: number;
}
export interface Global {
......
/**
* @Description 平台会员等级管理 - 新增
*/
import React from 'react';
import { message } from 'antd';
import { history } from 'umi';
import { postMemberManageLevelCreate } from '@/services/MemberV2Api';
import MemberLevelForm, { SubmitValue } from './components/MemberLevelForm';
const AddMemberLevel: React.FC<{}> = (props) => {
const handleRoleRuleConfigFormSubmit = (value: SubmitValue): Promise<void> => (
new Promise((resolve, reject) => {
const msg = message.loading({
content: '正在添加,请稍候...',
duration: 0,
});
const { memberApplicableRole, ...rest } = value;
postMemberManageLevelCreate({
...rest,
roleIds: memberApplicableRole.map((item) => item.roleId),
}).then((res) => {
if (res.code === 1000) {
resolve();
setTimeout(() => {
history.goBack();
}, 800);
} else {
reject();
}
}).finally(() => {
msg();
});
})
);
return (
<MemberLevelForm
title='新增平台会员等级'
onSubmit={handleRoleRuleConfigFormSubmit}
/>
);
};
export default AddMemberLevel;
/*
* @Description: 平台会员等级 - 适用会员角色FormField
*/
import React, { useState, useEffect } from 'react';
import { Button } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import { ColumnType } from 'antd/lib/table/interface';
import themeConfig from '@/../config/theme.config';
import PolymericTable from '@/components/PolymericTable';
import MemberRoleDrawer, { MemberRoleDrawerSubmitValue, MemberRoleDrawerProps } from '../MemberRoleDrawer';
export type MemberApplicableRoleType = MemberRoleDrawerSubmitValue[0] & {}
export interface MemberApplicableRoleProps {
value?: MemberApplicableRoleType[],
onChange?: (value: MemberApplicableRoleType[]) => void,
fetchDataSource: MemberRoleDrawerProps['fetchDataSource'],
editable: boolean,
}
const normalColumns: ColumnType<MemberApplicableRoleType>[] = [
{
title: '会员角色ID',
dataIndex: 'roleId',
},
{
title: '会员角色',
dataIndex: 'roleName',
},
{
title: '角色类型',
dataIndex: 'roleTypeName',
},
{
title: '会员类型',
dataIndex: 'memberTypeName',
},
];
const MemberApplicableRole = (props: MemberApplicableRoleProps) => {
const { value, onChange, fetchDataSource, editable } = props;
const [innerValue, setInnerValue] = useState<MemberApplicableRoleType[]>([]);
const [visibleDrawer, setVisibleDrawer] = useState(false);
useEffect(() => {
if ('value' in props) {
setInnerValue(value!);
}
}, [value]);
const triggerChange = (next: MemberRoleDrawerSubmitValue) => {
onChange?.(next);
};
// 删除项
const handleRemoveItem = (record: MemberApplicableRoleType) => {
const newData = [...innerValue];
const index = newData.findIndex((item) => item.roleId === record.roleId);
if (index !== -1) {
newData.splice(index, 1);
}
if (!('value' in props)) {
setInnerValue(newData);
}
triggerChange(newData);
};
const columns: ColumnType<MemberApplicableRoleType>[] = [
...normalColumns,
editable ? {
title: '操作',
dataIndex: 'option',
align: 'center',
render: (_, record) => (
<Button
type="link"
onClick={() => handleRemoveItem(record)}
>
删除
</Button>
),
} : null,
].filter(Boolean) as any;
const handleVisibleDrawer = (flag?: boolean) => {
setVisibleDrawer(!!flag);
};
const handleMemberRoleDrawerSubmit = (next: MemberRoleDrawerSubmitValue) => {
if (!('value' in props)) {
setInnerValue(next);
}
triggerChange(next);
handleVisibleDrawer(false);
};
return (
<div>
{editable && (
<Button
icon={<PlusOutlined />}
onClick={() => handleVisibleDrawer(true)}
style={{
marginBottom: themeConfig['@margin-md'],
}}
block
>
选择会员角色
</Button>
)}
<PolymericTable
rowKey="roleId"
columns={columns}
dataSource={innerValue}
pagination={null}
/>
<MemberRoleDrawer
visible={visibleDrawer}
onClose={() => handleVisibleDrawer(false)}
value={innerValue}
onSubmit={handleMemberRoleDrawerSubmit}
fetchDataSource={fetchDataSource}
/>
</div>
);
};
MemberApplicableRole.isVirtualFieldComponent = true;
export default MemberApplicableRole;
\ No newline at end of file
/*
* @Description: 会员角色规则 - 基础信息布局容器组件
*/
import React from 'react';
import AnchorPage from '@/components/AnchorPage';
import MellowCard from '@/components/MellowCard';
import { PLATFORM_MEMBER_LEVEL } from '../../config';
interface BasicInfoVirtualFieldItemProps {
children: React.ReactNode,
}
const BasicInfoVirtualFieldItem = (props: BasicInfoVirtualFieldItemProps) => {
const { children } = props;
return (
<AnchorPage.Item itemKey={PLATFORM_MEMBER_LEVEL}>
<MellowCard
title="平台会员等级"
bodyStyle={{
paddingBottom: 0,
}}
>
{children}
</MellowCard>
</AnchorPage.Item>
);
};
BasicInfoVirtualFieldItem.isVirtualFieldComponent = true;
export default BasicInfoVirtualFieldItem;
\ No newline at end of file
/*
* @Description: 平台会员等级 - 会员适用会员角色FormField
*/
import React from 'react';
import AnchorPage from '@/components/AnchorPage';
import MellowCard from '@/components/MellowCard';
import themeConfig from '@/../config/theme.config';
import { MEMBER_APPLICABLE_ROLE } from '../../config';
import MemberApplicableRole, { MemberApplicableRoleType } from '../../../MemberApplicableRole';
export type MemberApplicableRoleValue = MemberApplicableRoleType[]
const MemberApplicableRoleFormField = (props) => {
const componentProps = props.props['x-component-props'] || {};
return (
<AnchorPage.Item itemKey={MEMBER_APPLICABLE_ROLE}>
<MellowCard
title="适用会员角色"
style={{
marginTop: themeConfig['@margin-md'],
}}
bodyStyle={{
paddingBottom: 0,
}}
>
<MemberApplicableRole
value={props.value}
onChange={(next) => props.mutators.change(next)}
fetchDataSource={componentProps.fetchDataSource}
editable={props.editable}
/>
</MellowCard>
</AnchorPage.Item>
);
};
MemberApplicableRoleFormField.isFieldComponent = true;
export default MemberApplicableRoleFormField;
export * from '../../../MemberApplicableRole';
\ No newline at end of file
export const PLATFORM_MEMBER_LEVEL = 'PLATFORM_MEMBER_LEVEL';
export const MEMBER_APPLICABLE_ROLE = 'MEMBER_APPLICABLE_ROLE';
export const anchorsArr = [
{
key: PLATFORM_MEMBER_LEVEL,
name: '基本信息',
},
{
key: MEMBER_APPLICABLE_ROLE,
name: '适用会员角色',
},
];
\ No newline at end of file
/*
* @Description: 新增/修改 平台会员等级
*/
import React, { useState } from 'react';
import { Button } from 'antd';
import { SaveOutlined } from '@ant-design/icons';
import { createFormActions, FormEffectHooks } from '@formily/antd';
import { Input } from '@formily/antd-components';
import { Prompt } from 'umi';
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
import { getMemberManageLevelRolePage, getMemberManageLevelTypes } from '@/services/MemberV2Api';
import AnchorPage from '@/components/AnchorPage';
import NiceForm from '@/components/NiceForm';
import schema from './schema';
import { anchorsArr } from './config';
import BasicInfoVirtualFieldItem from './components/BasicInfoVirtualFieldItem';
import MemberApplicableRoleFormField, { MemberApplicableRoleValue, MemberApplicableRoleProps } from './components/MemberApplicableRoleFormField';
import styles from './index.less';
const formActions = createFormActions();
const {
onFormInit$,
onFormInputChange$,
} = FormEffectHooks;
export type SubmitValueType = {
/**
* 会员等级
*/
level: number,
/**
* 会员等级标签
*/
levelTag: string,
/**
* 会员等级类型
*/
levelType: number,
/**
* 升级分值标签
*/
scoreTag: string,
/**
* 会员等级说明
*/
remark: string,
/**
* 当前会员适用会员角色
*/
memberApplicableRole: MemberApplicableRoleValue,
}
// 暂定
export type SubmitValue = SubmitValueType & {}
interface MemberLevelFormProps {
/**
* title
*/
title: string,
/**
* 数据id
*/
value?: SubmitValueType,
/**
* 点击保存触发事件
*/
onSubmit?: (value: SubmitValue) => Promise<void>,
/**
* 是否可编辑的,默认 true
*/
editable?: boolean,
/**
* 是否禁用部分不可以编辑的表单项,默认 false
*/
cloudy?: boolean,
}
const MemberLevelForm: React.FC<MemberLevelFormProps> = (props) => {
const {
title,
value,
onSubmit,
editable = true,
cloudy = false,
} = props;
const [submitLoading, setSubmitLoading] = useState(false);
const [unsaved, setUnsaved] = useState(false);
const fetchMemberApplicableRole = (): MemberApplicableRoleProps['fetchDataSource'] => (async (params) => {
const res = await getMemberManageLevelRolePage({
...params,
current: `${params.current}`,
pageSize: `${params.pageSize}`,
});
return res.data;
});
const handleSubmit = (values: SubmitValueType) => {
if (onSubmit) {
setSubmitLoading(true);
onSubmit(values)
.then(() => {
setUnsaved(false);
})
.finally(() => {
setSubmitLoading(false);
});
}
};
return (
<div className={styles['role-rule-config-form']}>
<AnchorPage
title={title}
anchors={anchorsArr}
extra={[
(editable
? (
<Button
key="1"
type="primary"
icon={<SaveOutlined />}
loading={submitLoading}
onClick={() => formActions.submit()}
>
保存
</Button>
)
: null
),
]}
>
<NiceForm
previewPlaceholder=" "
onSubmit={handleSubmit}
actions={formActions}
initialValues={value}
components={{
TextArea: Input.TextArea,
BasicInfoVirtualFieldItem,
MemberApplicableRole: MemberApplicableRoleFormField,
}}
effects={($, actions) => {
const { setFieldState } = actions;
onFormInit$().subscribe(() => {
if (cloudy) {
actions.setFieldState(
'*(memberApplicableRole)',
(state) => {
state.editable = false;
}
);
}
// 初始会员角色列表请求接口方法
setFieldState('memberApplicableRole', (state) => {
state.props['x-component-props'] = state.props['x-component-props'] || {};
state.props['x-component-props'].fetchDataSource = fetchMemberApplicableRole();
});
});
onFormInputChange$().subscribe(() => {
if (!unsaved) {
setUnsaved(true);
}
});
useAsyncSelect(
'levelType',
async () => {
const { data, code } = await getMemberManageLevelTypes();
if (code === 1000) {
return data.map((item) => ({ label: item.levelTypeName, value: item.levelType }));
}
return [];
}
);
}}
schema={schema}
editable={!!editable}
/>
</AnchorPage>
<Prompt when={unsaved} message="您还有未保存的内容,是否确定要离开?" />
</div>
);
};
export default MemberLevelForm;
import { ISchema } from '@formily/antd';
import { MEMBER_LEVEL_ENUM } from '@/constants/const/member';
const schema: ISchema = {
type: 'object',
properties: {
BASIC_INFO: {
type: 'object',
'x-component': 'BasicInfoVirtualFieldItem',
properties: {
MEGA_LADYOUT_1: {
type: 'object',
'x-component': 'Mega-Layout',
'x-component-props': {
grid: true,
full: true,
columns: 2,
autoRow: true,
labelCol: 6,
labelAlign: 'left',
},
properties: {
level: {
title: '会员等级',
type: 'string',
enum: MEMBER_LEVEL_ENUM,
required: true,
'x-component-props': {
placeholder: '请选择',
},
},
levelTag: {
title: '会员等级标签',
type: 'string',
'x-component-props': {
placeholder: '请输入,最长16个字符,8个汉字',
},
'x-rules': [
{
required: true,
message: '请输入会员等级标签',
},
{
limitByte: true, // 自定义校验规则
maxByte: 16,
}
],
},
levelType: {
title: '会员等级类型',
type: 'string',
enum: [],
required: true,
'x-component-props': {
placeholder: '请选择',
},
},
scoreTag: {
title: '升级分值标签',
type: 'string',
'x-component-props': {
placeholder: '请输入,最长16个字符,8个汉字',
},
'x-rules': [
{
required: true,
message: '请输入升级分值标签',
},
{
limitByte: true, // 自定义校验规则
maxByte: 16,
},
],
},
remark: {
title: '会员等级说明',
type: 'string',
'x-component': 'TextArea',
'x-component-props': {
placeholder: '在此输入你的内容,最长80个字符,40个汉字',
rows: 5,
},
'x-rules': [
{
limitByte: true, // 自定义校验规则
maxByte: 80,
}
],
},
},
},
},
},
memberApplicableRole: {
title: '',
type: 'string',
enum: [],
required: true,
'x-component': 'MemberApplicableRole',
},
},
};
export default schema;
/*
* @Description: 会员角色规则 - 适用会员角色FormField
*/
import React, { useEffect } from 'react';
import { Drawer, Button, message } from 'antd';
import { ColumnType } from 'antd/lib/table/interface';
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable';
import PolymericTable, { FetchParamsType, FetchResponse } from '@/components/PolymericTable';
export type MemberRoleType = {
/**
* 角色id
*/
roleId: number
/**
* 角色名称
*/
roleName: string
/**
* 角色类型名称
*/
roleTypeName: string
/**
* 会员类型名称
*/
memberTypeName: string
}
export type MemberRoleDrawerSubmitValue = MemberRoleType[]
type ExtraFetchType = FetchParamsType & {}
export interface MemberRoleDrawerProps {
/**
* 是否可见
*/
visible: boolean,
/**
* 值
*/
value: MemberRoleType[],
/**
* Form 确认事件
*/
onSubmit: (values:MemberRoleDrawerSubmitValue) => void,
/**
* 抽屉关闭事件
*/
onClose: () => void,
/**
* 获取dataSource方法
*/
fetchDataSource: (params: ExtraFetchType) => Promise<FetchResponse<MemberRoleType>>,
}
const MemberRoleDrawer = (props: MemberRoleDrawerProps) => {
const {
visible,
value,
onSubmit,
onClose,
fetchDataSource,
} = props;
const [rowSelection, rowCtl] = useRowSelectionTable({ type: 'checkbox', customKey: 'roleId' });
useEffect(() => {
if (value) {
rowCtl.setSelectRow(value);
rowCtl.setSelectedRowKeys(value.map((item) => item.roleId));
}
}, [value]);
const columns: ColumnType<MemberRoleType>[] = [
{
title: '会员角色名称',
dataIndex: 'roleName',
},
{
title: '角色类型',
dataIndex: 'roleTypeName',
},
{
title: '会员类型',
dataIndex: 'memberTypeName',
},
];
const fetchMemberRoleList = async (params: ExtraFetchType) => {
if (!fetchDataSource) {
return { data: [], totalCount: 0 };
}
const mergeParams = {
...params,
checkRoleIdList: Array.isArray(value) ? value.map((item) => item.roleId) : [],
};
const res = await fetchDataSource(mergeParams);
return res;
};
const handleClose = () => {
if (onClose) {
onClose();
}
};
const handleConfirm = () => {
if (!rowCtl.selectRow.length) {
message.warning('请选择会员角色');
return;
}
if (onSubmit) {
onSubmit(rowCtl.selectRow);
}
};
return (
<Drawer
title="选择会员"
width={1000}
onClose={handleClose}
visible={visible}
footer={
<div
style={{
textAlign: 'right',
}}
>
<Button onClick={handleClose} style={{ marginRight: 16 }}>
取消
</Button>
<Button onClick={handleConfirm} type="primary">
确 定
</Button>
</div>
}
bodyStyle={{
paddingBottom: 0,
}}
destroyOnClose
>
<PolymericTable
rowKey="roleId"
columns={columns}
fetchDataSource={(params) => fetchMemberRoleList(params as ExtraFetchType)}
rowSelection={rowSelection}
defaultPageSize={20}
full
/>
</Drawer>
);
};
export default MemberRoleDrawer;
\ No newline at end of file
/**
* @Description 平台会员等级管理 - 列表
*/
import React, { useState, useRef } from 'react';
import { history } from 'umi';
import { Card, Button, Space, Popconfirm, Modal, message } from 'antd';
import { PlusOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
import { ColumnType } from 'antd/lib/table/interface';
import { createFormActions } from '@formily/antd';
import { getMemberManageLevelPage, GetMemberManageLevelPageResponseDetail, postMemberManageLevelDelete, postMemberManageLevelStatus } from '@/services/MemberV2Api';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import EyePreview from '@/components/EyePreview';
import PolymericTable, { FetchParamsType, NormalTableRefHandleType } from '@/components/PolymericTable';
import StatusSwitch from '@/components/StatusSwitch';
import { querySchema } from './querySchema';
const { confirm } = Modal;
const queryFormActions = createFormActions();
type GetMemberLevelListRequestParams = FetchParamsType & {
levelTag: string,
roleName: string,
}
type GetMemberLevelListRequestResponse = GetMemberManageLevelPageResponseDetail & {}
const PlatformMemberLevelIndexIndex: React.FC<{}> = props => {
const [statusLoadingKey, setStatusLoadingKey] = useState(0);
const [deleteLoadingKey, setDeleteLoadingKey] = useState(0);
const polymericRef = useRef<NormalTableRefHandleType | null>(null);
const handleJumpFormPage = (record?: GetMemberLevelListRequestResponse) => {
history.push(!record ? '/memberManage/platformMemberLevel/add' : `/memberManage/platformMemberLevel/modify?id=${record.levelId}`);
};
const handleJumpSetMemberLevelRight = (record: GetMemberLevelListRequestResponse) => {
history.push(`/memberManage/platformMemberLevel/setMemberLevelRight?id=${record.levelId}`);
};
const handleChangeMemberLevelStatus = (record: GetMemberLevelListRequestResponse) => {
if (record.levelId === statusLoadingKey) {
return;
}
const msg = message.loading({
content: '正在更改,请稍候...',
duration: 0,
});
setStatusLoadingKey(record.levelId);
postMemberManageLevelStatus({
status: record.status === 1 ? 0 : 1,
levelId: record.levelId,
}).then((res) => {
if (res.code === 1000) {
polymericRef.current?.reload();
}
}).finally(() => {
msg();
setStatusLoadingKey(0);
});
};
const handleDeleteMemberLevel = (record: GetMemberLevelListRequestResponse) => {
if (record.levelId === deleteLoadingKey) {
return;
}
const msg = message.loading({
content: '正在删除,请稍候...',
duration: 0,
});
setDeleteLoadingKey(record.levelId);
postMemberManageLevelDelete({
levelId: record.levelId,
}).then((res) => {
if (res.code === 1000) {
polymericRef.current?.reload();
}
}).finally(() => {
msg();
setStatusLoadingKey(0);
});
};
const columns: ColumnType<GetMemberLevelListRequestResponse>[] = [
{
title: '会员等级ID',
dataIndex: 'levelId',
width: '10%',
},
{
title: '会员等级',
dataIndex: 'level',
width: '10%',
},
{
title: '会员等级标签',
dataIndex: 'levelTag',
render: (text: any, record) => (
<>
<EyePreview
url={`/memberManage/platformMemberLevel/details?id=${record.levelId}`}
>
{text}
</EyePreview>
</>
),
width: '10%',
},
{
title: '会员等级类型',
dataIndex: 'levelTypeName',
width: '10%',
},
{
title: '升级分值标签',
dataIndex: 'scoreTag',
width: '10%',
},
{
title: '会员角色名称',
dataIndex: 'roleName',
width: '10%',
},
{
title: '角色类型',
dataIndex: 'roleTypeName',
width: '10%',
},
{
title: '会员类型',
dataIndex: 'memberTypeName',
width: '10%',
},
{
title: '升级阀值',
dataIndex: 'point',
width: '10%',
},
{
title: '状态',
dataIndex: 'statusName',
width: '15%',
render: (text, record) => (
<StatusSwitch
handleConfirm={() => handleChangeMemberLevelStatus(record)}
record={record}
/>
),
},
{
title: '操作',
dataIndex: 'actions',
align: 'center',
fixed: 'right',
width: 200,
render: (text: any, record) => (
<>
<Button
type="link"
onClick={() => handleJumpFormPage(record)}
>
编辑
</Button>
<Popconfirm
title="是否确认删除该会员等级?"
onConfirm={() => handleDeleteMemberLevel(record)}
okText="确认"
cancelText="取消"
>
<Button
type="link"
loading={record.levelId === deleteLoadingKey}
>
删除
</Button>
</Popconfirm>
<Button
type="link"
onClick={() => handleJumpSetMemberLevelRight(record)}
>
设置权益与升级阀值
</Button>
</>
),
},
];
const fetchMemberRoleRuleList = async (params: GetMemberLevelListRequestParams) => {
const res = await getMemberManageLevelPage({
...params,
current: `${params.current}`,
pageSize: `${params.pageSize}`,
});
if (res.code === 1000) {
return res.data;
}
return { data: [], totalCount: 0 };
};
const handleInitial = () => {
confirm({
title: '提示',
icon: <ExclamationCircleOutlined />,
content: '点击“确定”,会将所有平台会员的会员等级初始化为初始等级,并享有该等级的所有权益!',
cancelText: '取消',
okText: '确定',
onOk() {
return new Promise((resolve) => {
setTimeout(() => {
resolve('123');
}, 2000);
});
},
onCancel() {
console.log('Cancel');
},
});
};
const RoleRuleConfigCtl = () => (
<Space>
<Button
type="primary"
onClick={() => handleJumpFormPage()}
icon={<PlusOutlined />}
>
新增
</Button>
<Button
type="primary"
onClick={() => handleInitial()}
>
初始化会员等级与权益
</Button>
</Space>
);
return (
<Card>
<PolymericTable
rowKey="levelId"
columns={columns}
fetchDataSource={(params) => fetchMemberRoleRuleList(params as GetMemberLevelListRequestParams)}
defaultPageSize={10}
searchFormProps={{
actions: queryFormActions,
schema: querySchema,
components: {
RoleRuleConfigCtl,
},
effects: ($, actions) => {
useStateFilterSearchLinkageEffect(
$,
actions,
'roleName',
FORM_FILTER_PATH,
);
},
}}
scroll={{ x: 1200 }}
ref={polymericRef}
/>
</Card>
);
};
export default PlatformMemberLevelIndexIndex;
\ No newline at end of file
/**
* @Description 平台会员等级 - 明细
*/
import React, { useState, useEffect } from 'react';
import { Spin } from 'antd';
import { getMemberManageLevelGet } from '@/services/MemberV2Api';
import { usePageStatus } from '@/hooks/usePageStatus';
import MemberLevelForm, { SubmitValueType } from './components/MemberLevelForm';
const MemberLevelDetails: React.FC<{}> = props => {
const [memberLevelDetails, setMemberLevelDetails] = useState<SubmitValueType | undefined>(undefined);
const [detailsLoading, setDetailsLoading] = useState(false);
const { id } = usePageStatus();
const fetchMemberLevelDetails = () => {
setDetailsLoading(true);
getMemberManageLevelGet({
levelId: id,
}).then((res) => {
if (res.code === 1000) {
const { roles, ...rest } = res.data;
setMemberLevelDetails({
...rest,
memberApplicableRole: roles,
});
}
}).finally(() => {
setDetailsLoading(false);
});
};
useEffect(() => {
fetchMemberLevelDetails();
}, []);
return (
<Spin spinning={detailsLoading}>
<MemberLevelForm
title='查看平台会员等级'
value={memberLevelDetails}
editable={false}
/>
</Spin>
);
};
export default MemberLevelDetails;
\ No newline at end of file
/**
* @Description 平台会员等级 - 编辑
*/
import React, { useState, useEffect } from 'react';
import { Spin, message } from 'antd';
import { history } from 'umi';
import { getMemberManageLevelGet, postMemberManageLevelUpdate } from '@/services/MemberV2Api';
import { usePageStatus } from '@/hooks/usePageStatus';
import MemberLevelForm, { SubmitValue, SubmitValueType } from './components/MemberLevelForm';
const ModifyMemberLevel: React.FC<{}> = (props) => {
const [memberLevelDetails, setMemberLevelDetails] = useState<SubmitValueType | undefined>(undefined);
const [detailsLoading, setDetailsLoading] = useState(false);
const { id } = usePageStatus();
const fetchMemberLevelDetails = () => {
setDetailsLoading(true);
getMemberManageLevelGet({
levelId: id,
}).then((res) => {
if (res.code === 1000) {
const { roles, ...rest } = res.data;
setMemberLevelDetails({
...rest,
memberApplicableRole: roles,
});
}
}).finally(() => {
setDetailsLoading(false);
});
};
useEffect(() => {
fetchMemberLevelDetails();
}, []);
const handleRoleRuleConfigFormSubmit = (value: SubmitValue): Promise<void> => (
new Promise((resolve, reject) => {
const msg = message.loading({
content: '正在修改,请稍候...',
duration: 0,
});
const { memberApplicableRole, ...rest } = value;
postMemberManageLevelUpdate({
levelId: +id,
...rest,
}).then((res) => {
if (res.code === 1000) {
resolve();
setTimeout(() => {
history.goBack();
}, 800);
} else {
reject();
}
}).finally(() => {
msg();
});
})
);
return (
<Spin spinning={detailsLoading}>
<MemberLevelForm
title='编辑平台会员角色'
value={memberLevelDetails}
onSubmit={handleRoleRuleConfigFormSubmit}
cloudy
/>
</Spin>
);
};
export default ModifyMemberLevel;
\ No newline at end of file
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { ISchema } from '@formily/antd';
export const querySchema: ISchema = {
type: 'object',
properties: {
MEGA_LAYOUT: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
grid: true,
},
properties: {
ctl: {
type: 'object',
'x-component': 'RoleRuleConfigCtl',
},
levelTag: {
type: 'string',
'x-component': 'Search',
'x-component-props': {
placeholder: '搜索',
tip: '输入 会员等级标签 进行搜索',
},
},
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
colStyle: {
marginLeft: 20,
},
},
properties: {
roleName: {
type: 'string',
'x-component-props': {
placeholder: '会员角色名称',
allowClear: true,
},
},
submit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: '查询',
},
},
},
},
},
};
\ No newline at end of file
/*
* @Description: 会员角色规则 - 基础信息布局容器组件
*/
import React from 'react';
import AnchorPage from '@/components/AnchorPage';
import MellowCard from '@/components/MellowCard';
import { MEMBER_LEVEL_INFO } from '../../config';
interface BasicInfoVirtualFieldItemProps {
children: React.ReactNode,
}
const BasicInfoVirtualFieldItem = (props: BasicInfoVirtualFieldItemProps) => {
const { children } = props;
return (
<AnchorPage.Item itemKey={MEMBER_LEVEL_INFO}>
<MellowCard
title="会员等级信息"
bodyStyle={{
paddingBottom: 0,
}}
>
{children}
</MellowCard>
</AnchorPage.Item>
);
};
BasicInfoVirtualFieldItem.isVirtualFieldComponent = true;
export default BasicInfoVirtualFieldItem;
\ No newline at end of file
/*
* @Description: 会员角色规则 - 适用会员角色FormField
*/
import React, { useEffect, useRef } from 'react';
import { Drawer, Button, message } from 'antd';
import { ColumnType } from 'antd/lib/table/interface';
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable';
import PolymericTable, { FetchParamsType, FetchResponse } from '@/components/PolymericTable';
export type MemberRoleType = {
/**
* 权益id
*/
rightId: number,
/**
* 权益类型枚举,1-价格权益,2-返现权益,3-积分权益
*/
rightType: number
/**
* 权益名称
*/
name: string
/**
* 获取方式枚举
*/
acquireWay: number
/**
* 获取方式名称
*/
acquireWayName: string
/**
* 参数设置方式枚举,1-按交易金额比例设置
*/
paramWay: number
/**
* 参数设置方式枚举,1-按交易金额比例设置
*/
paramWayName: string
}
export type MemberRightDrawerSubmitValue = MemberRoleType[]
type ExtraFetchType = FetchParamsType & {}
export interface MemberRightDrawerProps {
/**
* 是否可见
*/
visible: boolean,
/**
* 值
*/
value: MemberRoleType[],
/**
* Form 确认事件
*/
onSubmit: (values: MemberRightDrawerSubmitValue) => void,
/**
* 抽屉关闭事件
*/
onClose: () => void,
/**
* 获取dataSource方法
*/
fetchDataSource: (params: ExtraFetchType) => Promise<FetchResponse<MemberRoleType>>,
}
const MemberRightDrawer = (props: MemberRightDrawerProps) => {
const {
visible,
value,
onSubmit,
onClose,
fetchDataSource,
} = props;
const [rowSelection, rowCtl] = useRowSelectionTable({ type: 'checkbox', customKey: 'rightId' });
useEffect(() => {
if (value) {
rowCtl.setSelectRow(value);
rowCtl.setSelectedRowKeys(value.map((item) => item.rightId));
}
}, [value]);
const columns: ColumnType<MemberRoleType>[] = [
{
title: '会员权益ID',
dataIndex: 'rightId',
},
{
title: '会员权益名称',
dataIndex: 'name',
},
{
title: '会员权益说明',
dataIndex: 'rightDescription',
},
{
title: '权益获取方式',
dataIndex: 'acquireWayName',
},
{
title: '参数设置方式',
dataIndex: 'paramWayName',
},
];
const fetchMemberRoleList = async (params: ExtraFetchType) => {
if (!fetchDataSource) {
return { data: [], totalCount: 0 };
}
const mergeParams = {
...params,
checkRoleIdList: Array.isArray(value) ? value.map((item) => item.rightId) : [],
};
const res = await fetchDataSource(mergeParams);
return res;
};
const handleClose = () => {
if (onClose) {
onClose();
}
};
const handleConfirm = () => {
if (!rowCtl.selectRow.length) {
message.warning('请选择会员权益');
return;
}
if (onSubmit) {
onSubmit(rowCtl.selectRow);
}
};
return (
<Drawer
title="会员权益设置"
width={1000}
onClose={handleClose}
visible={visible}
footer={
<div
style={{
textAlign: 'right',
}}
>
<Button onClick={handleClose} style={{ marginRight: 16 }}>
取消
</Button>
<Button onClick={handleConfirm} type="primary">
确 定
</Button>
</div>
}
bodyStyle={{
paddingBottom: 0,
}}
destroyOnClose
>
<PolymericTable
rowKey="rightId"
columns={columns}
fetchDataSource={(params) => fetchMemberRoleList(params as ExtraFetchType)}
rowSelection={rowSelection}
pagination={null}
full
/>
</Drawer>
);
};
export default MemberRightDrawer;
\ No newline at end of file
.member-rights {
&-editable {
:global {
.ant-form-item {
margin-bottom: 0;
}
}
}
}
\ No newline at end of file
/*
* @Description: 平台会员等级 - 适用会员角色FormField
*/
import React, { useState, useEffect } from 'react';
import { Button, message } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import { ColumnType } from 'antd/lib/table/interface';
import { Schema, SchemaField, SchemaMarkupField as Field } from '@formily/antd';
import { toArr, FormPath } from '@formily/shared';
import { PATTERN_MAPS } from '@/constants/regExp';
import AnchorPage from '@/components/AnchorPage';
import MellowCard from '@/components/MellowCard';
import PolymericTable from '@/components/PolymericTable';
import themeConfig from '@/../config/theme.config';
import { MEMBER_RIGHT_SETTING } from '../../config';
import MemberRightDrawer, { MemberRightDrawerSubmitValue, MemberRightDrawerProps } from '../MemberRightDrawer';
import styles from './index.less';
export type MemberRightFormFieldType = MemberRightDrawerSubmitValue[0] & {
/**
* 参数
*/
parameter?: number,
/**
* 状态
*/
status?: number,
/**
* 状态名称
*/
statusName?: string,
/**
* 是否是新添加的
*/
fresh?: boolean,
}
export interface MemberRightFormFieldProps {
// value?: MemberRightFormFieldType[],
// onChange?: (value: MemberRightFormFieldType[]) => void,
/**
* 请求权益列表数据方法
*/
fetchDataSource: MemberRightDrawerProps['fetchDataSource'],
/**
* 点击改变状态触发事件
* 直接传列表项会有闭包问题,可能拿不到最新值
*/
onStatusChange?: (index: number) => Promise<void>,
/**
* 点击修改参数触发事件
* 直接传列表项会有闭包问题,可能拿不到最新值
*/
onChangeParameter?: (index: number) => Promise<void>,
}
export type MemberRightSetttingValue = MemberRightFormFieldType[]
const MemberRightFormField = (props) => {
const {
value,
editable,
path,
mutators,
} = props;
const xComponentProps: MemberRightFormFieldProps = props.props['x-component-props'] || {};
const { fetchDataSource, onStatusChange, onChangeParameter } = xComponentProps;
const [innerValue, setInnerValue] = useState<MemberRightFormFieldType[]>([]);
const [visibleDrawer, setVisibleDrawer] = useState(false);
const [parameterLoadingKey, setParameterLoadingKey] = useState<number | undefined>(undefined);
const [statusLoadingKey, setStatusLoadingKey] = useState<number | undefined>(undefined);
useEffect(() => {
if ('value' in props) {
setInnerValue(value!);
}
}, [value]);
const triggerChange = (next: MemberRightFormFieldType[]) => {
mutators.change?.(next);
};
const handleVisibleDrawer = (flag?: boolean) => {
setVisibleDrawer(!!flag);
};
const handleMemberRightDrawerSubmit = (next: MemberRightDrawerSubmitValue) => {
const normalize = next.map((item) => ({
...item,
parameter: (item as MemberRightFormFieldType).parameter || 0,
fresh: /\d/.test(`${(item as MemberRightFormFieldType).status}`) ? false : true,
}));
if (!('value' in props)) {
setInnerValue(normalize);
}
triggerChange(normalize);
handleVisibleDrawer(false);
};
// 删除项
const handleRemoveItem = (record: MemberRightFormFieldType) => {
const newData = [...innerValue];
const index = newData.findIndex((item) => item.rightId === record.rightId);
if (index !== -1) {
newData.splice(index, 1);
}
if (!('value' in props)) {
setInnerValue(newData);
}
triggerChange(newData);
};
const handleChangeRightStatus = (index: number) => {
if (onStatusChange) {
const msg = message.loading({
content: '正在更改,请稍候...',
duration: 0,
});
setStatusLoadingKey(index);
onStatusChange(index).finally(() => {
msg();
setStatusLoadingKey(undefined);
});
}
};
const handleChangeParameter = (index: number) => {
if (onChangeParameter) {
const msg = message.loading({
content: '正在更改,请稍候...',
duration: 0,
});
setParameterLoadingKey(index);
onChangeParameter(index).finally(() => {
msg();
setParameterLoadingKey(undefined);
});
}
};
const normalColumns: ColumnType<MemberRightFormFieldType>[] = [
{
title: '会员权益ID',
dataIndex: 'rightId',
},
{
title: '会员权益名称',
dataIndex: 'name',
},
{
title: '会员权益说明',
dataIndex: 'roleTypeName',
},
{
title: '权益获取方式',
dataIndex: 'acquireWayName',
},
{
title: '参数设置方式',
dataIndex: 'paramWayName',
},
{
title: '参数',
dataIndex: 'parameter',
width: '15%',
render: (text, record, index) => editable ? (
<div className={styles['member-rights-editable']}>
<SchemaField
path={FormPath.parse(path).concat(index)}
schema={new Schema({
type: 'object',
properties: {
parameter: {
type: 'string',
'x-component-props': {
addonAfter: '%',
},
'x-rules': [
{
required: true,
message: '请输入参数',
},
{
pattern: PATTERN_MAPS.money,
message: '请输入整数或小数位不超过两位的小数',
},
],
},
},
})}
/>
</div>
) : `${text}%`,
},
{
title: '状态',
dataIndex: 'statusName',
},
];
const columns: ColumnType<MemberRightFormFieldType>[] = [
...normalColumns,
editable ? {
title: '操作',
dataIndex: 'option',
align: 'center',
render: (_, record, index) => (
<>
<Button
type="link"
onClick={() => handleRemoveItem(record)}
disabled={!editable}
>
删除
</Button>
{!record.fresh ? (
<>
{/\d/.test(record.status) ? (
<Button
type="link"
onClick={() => handleChangeRightStatus(index)}
disabled={!editable}
loading={index === statusLoadingKey}
>
{record.status === 1 ? '停用' : '启用'}
</Button>
) : null}
<Button
type="link"
onClick={() => handleChangeParameter(index)}
disabled={!editable}
loading={index === parameterLoadingKey}
>
修改参数
</Button>
</>
) : null}
</>
),
} : null,
].filter(Boolean) as any;
return (
<AnchorPage.Item itemKey={MEMBER_RIGHT_SETTING}>
<MellowCard
title="会员权益设置"
style={{
marginTop: themeConfig['@margin-md'],
}}
bodyStyle={{
paddingBottom: 0,
}}
>
{editable && (
<Button
icon={<PlusOutlined />}
onClick={() => handleVisibleDrawer(true)}
style={{
marginBottom: themeConfig['@margin-md'],
}}
block
>
选择会员权益
</Button>
)}
<PolymericTable
rowKey="rightId"
columns={columns}
dataSource={innerValue}
pagination={null}
/>
<MemberRightDrawer
visible={visibleDrawer}
onClose={() => handleVisibleDrawer(false)}
value={innerValue}
onSubmit={handleMemberRightDrawerSubmit}
fetchDataSource={fetchDataSource}
/>
</MellowCard>
</AnchorPage.Item>
);
};
MemberRightFormField.isFieldComponent = true;
export default MemberRightFormField;
\ No newline at end of file
export const MEMBER_LEVEL_INFO = 'MEMBER_LEVEL_INFO';
export const MEMBER_RIGHT_SETTING = 'MEMBER_RIGHT_SETTING';
export const anchorsArr = [
{
key: MEMBER_LEVEL_INFO,
name: '会员等级信息',
},
{
key: MEMBER_RIGHT_SETTING,
name: '会员权益设置',
},
];
\ No newline at end of file
/**
* @Description 会员角色规则配置 - 编辑
*/
import React, { useState, useEffect } from 'react';
import { Spin, message, Button } from 'antd';
import { SaveOutlined } from '@ant-design/icons';
import { createFormActions, FormEffectHooks } from '@formily/antd';
import { ArrayTable, Input } from '@formily/antd-components';
import { Prompt, history } from 'umi';
import { usePageStatus } from '@/hooks/usePageStatus';
import { getMemberManageRightDetail, getMemberManageRightFind, postMemberManageRightParameterUpdate, postMemberManageRightStatus, postMemberManageRightUpdate } from '@/services/MemberV2Api';
import AnchorPage from '@/components/AnchorPage';
import NiceForm from '@/components/NiceForm';
import { anchorsArr } from './config';
import BasicInfoVirtualFieldItem from './comonents/BasicInfoVirtualFieldItem';
import MemberRightSetttingFormField, { MemberRightSetttingValue, MemberRightFormFieldProps } from './comonents/MemberRightFormFieldPro';
import schema from './schema';
import styles from './index.less';
const formActions = createFormActions();
const {
onFormInit$,
onFormInputChange$,
} = FormEffectHooks;
type SubmitValueType = {
/**
* 会员等级
*/
level: number,
/**
* 会员等级标签
*/
levelTag: string,
/**
* 会员等级标签
*/
levelTypeName: string,
/**
* 升级分值标签
*/
scoreTag: string,
/**
* 会员等级说明
*/
remark: string,
/**
* 会员角色名称
*/
roleName: string,
/**
* 角色类型
*/
roleTypeName: string,
/**
* 会员类型
*/
memberTypeName: string,
/**
* 升级阀值
*/
point: string,
/**
* 会员权益
*/
memberRights: MemberRightSetttingValue,
}
const SetMemberLevelRight: React.FC<{}> = (props) => {
const [rightDetails, setRightDetails] = useState<SubmitValueType | undefined>(undefined);
const [detailsLoading, setDetailsLoading] = useState(false);
const [submitLoading, setSubmitLoading] = useState(false);
const [unsaved, setUnsaved] = useState(false);
const { id } = usePageStatus();
const fetchMemberLevelRightDetails = () => {
setDetailsLoading(true);
getMemberManageRightDetail({
levelId: id,
}).then((res) => {
if (res.code === 1000) {
const { rights, point, ...rest } = res.data;
setRightDetails({
...rest,
point: `${point}`,
memberRights: rights,
});
}
}).finally(() => {
setDetailsLoading(false);
});
};
useEffect(() => {
fetchMemberLevelRightDetails();
}, []);
const fetchMemberRightsList = (): MemberRightFormFieldProps['fetchDataSource'] => (async (params) => {
const res = await getMemberManageRightFind();
if (res.code === 1000) {
return {
totalCount: res.data.length,
data: res.data,
};
}
return { totalCount: 0, data: [] };
});
const handleSubmit = (values: SubmitValueType) => {
const msg = message.loading({
content: '正在修改,请稍候...',
duration: 0,
});
const { point, memberRights, ...rest } = values;
setSubmitLoading(true);
postMemberManageRightUpdate({
levelId: +id,
point: +point,
rights: memberRights.map((item) => ({
rightType: item.rightId,
parameter: +item.parameter!,
})),
}).then((res) => {
if (res.code === 1000) {
setUnsaved(false);
setTimeout(() => {
history.goBack();
}, 800);
} else {
}
}).finally(() => {
msg();
setSubmitLoading(false);
});
};
const handleRightStatusChange = (index: number): Promise<void> => (
new Promise((resolve, reject) => {
const rightsValue: MemberRightSetttingValue = formActions.getFieldValue('memberRights');
const record = rightsValue[index];
postMemberManageRightStatus({
rightId: record.rightId,
status: record.status === 1 ? 0 : 1,
}).then((res) => {
if (res.code === 1000) {
resolve();
} else {
reject();
}
}).catch((err) => {
reject(err);
});
})
);
const handleRightChangeParameter = (index: number): Promise<void> => (
new Promise((resolve, reject) => {
const rightsValue: MemberRightSetttingValue = formActions.getFieldValue('memberRights');
const record = rightsValue[index];
postMemberManageRightParameterUpdate({
rightId: record.rightId,
parameter: +record.parameter,
}).then((res) => {
if (res.code === 1000) {
resolve();
} else {
reject();
}
}).catch((err) => {
reject(err);
});
})
);
return (
<Spin spinning={detailsLoading}>
<div className={styles['role-rule-config-form']}>
<AnchorPage
title="平台会员权益设置"
anchors={anchorsArr}
extra={[
<Button
key="1"
type="primary"
icon={<SaveOutlined />}
loading={submitLoading}
onClick={() => formActions.submit()}
>
保存
</Button>,
]}
>
<NiceForm
previewPlaceholder=" "
onSubmit={handleSubmit}
actions={formActions}
initialValues={rightDetails}
components={{
BasicInfoVirtualFieldItem,
MemberRightSettting: MemberRightSetttingFormField,
}}
expressionScope={{
handleRightStatusChange,
handleRightChangeParameter,
}}
effects={($, actions) => {
const { setFieldState } = actions;
onFormInit$().subscribe(() => {
// 初始会员权益列表请求接口方法
setFieldState('memberRights', (state) => {
state.props['x-component-props'] = state.props['x-component-props'] || {};
state.props['x-component-props'].fetchDataSource = fetchMemberRightsList();
});
});
onFormInputChange$().subscribe(() => {
if (!unsaved) {
setUnsaved(true);
}
});
}}
schema={schema}
/>
</AnchorPage>
<Prompt when={unsaved} message="您还有未保存的内容,是否确定要离开?" />
</div>
</Spin>
);
};
export default SetMemberLevelRight;
\ No newline at end of file
import { ISchema } from '@formily/antd';
const schema: ISchema = {
type: 'object',
properties: {
BASIC_INFO: {
type: 'object',
'x-component': 'BasicInfoVirtualFieldItem',
properties: {
MEGA_LADYOUT_1: {
type: 'object',
'x-component': 'Mega-Layout',
'x-component-props': {
grid: true,
full: true,
columns: 2,
autoRow: true,
labelCol: 6,
labelAlign: 'left',
},
properties: {
level: {
title: '会员等级',
type: 'string',
editable: false,
},
levelTag: {
title: '会员等级标签',
type: 'string',
editable: false,
},
levelTypeName: {
title: '会员等级类型',
type: 'string',
editable: false,
},
scoreTag: {
title: '升级分值标签',
type: 'string',
editable: false,
},
remark: {
title: '会员等级说明',
type: 'string',
editable: false,
},
roleName: {
title: '会员角色名称',
type: 'string',
editable: false,
},
roleTypeName: {
title: '角色类型',
type: 'string',
editable: false,
},
memberTypeName: {
title: '会员类型',
type: 'string',
editable: false,
},
point: {
title: '升级阀值',
type: 'string',
'x-rules': [
{
required: true,
message: '请输入升级阀值',
},
{
pattern: /^[1-9]?[0-9]*$/,
message: '请输入整数',
},
]
},
},
},
},
},
memberRights: {
title: '',
type: 'array',
'x-component': 'MemberRightSettting',
'x-component-props': {
onStatusChange: '{{handleRightStatusChange}}',
onChangeParameter: '{{handleRightChangeParameter}}',
},
},
},
};
export default schema;
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