Commit 72c2c6d7 authored by XieZhiXiong's avatar XieZhiXiong

feat: 调整会员模块相关路由

parent ff78a5b3
/**
* @description 路由配置页, 更多配置可查看 https://umijs.org/zh-CN/docs/routing#routes
*/
const router = [
{
path: '/login',
component: '@/pages/user/login',
},
{
path: '/mall/template/edit',
component: '@/pages/pageCustomized/mallEdit',
},
{
path: '/mall/template/preview',
component: '@/pages/pageCustomized/preview/mallPreview',
},
{
path: '/',
component: '@/layouts/index',
routes: [
{
path: '/',
redirect: '/home',
},
{
path: '/home',
name: 'home',
component: '@/pages/home',
icon: 'BarChartOutlined',
},
{
path: '/pageCustomized',
name: 'pageCustomized',
icon: 'SmileOutlined',
routes: [
{
path: '/pageCustomized/shopCenterTemplate',
name: 'shopCenterTemplate',
component: '@/pages/pageCustomized/shopCenterTemplate',
},
{
path: '/pageCustomized/shopTemplate',
name: 'shopTemplate',
component: '@/pages/pageCustomized/shopTemplate',
},
{
path: '/pageCustomized/template/detail',
name: 'templateDetail',
component: '@/pages/pageCustomized/templateDetail',
hideInMenu: true,
hidePageHeader: true,
},
],
},
{
path: '/memberAbility',
name: 'memberAbility',
icon: 'SmileOutlined',
routes: [
{
path: '/memberAbility/manage/maintian',
name: 'memberMaintain',
component: '@/pages/member/memberMaintain/index',
},
{
path: '/memberAbility/manage/addMember',
name: 'addMember',
hideInMenu: true,
hidePageHeader: true,
component: '@/pages/member/memberMaintain/addMember',
},
{
path: '/memberAbility/manage/memberPrSubmit',
name: 'memberPrSubmit',
component: '@/pages/member/memberPrSubmit/index',
},
{
path: '/memberAbility/manage/auditPrSubmit',
name: 'auditPrSubmit',
hideInMenu: true,
hidePageHeader: true,
component: '@/pages/member/memberPrSubmit/auditPrSubmit',
},
{
path: '/memberAbility/manage/memberPr1',
name: 'memberPr1',
component: '@/pages/member/memberPr1/index',
},
{
path: '/memberAbility/manage/auditPr1',
name: 'memberPr1',
hideInMenu: true,
hidePageHeader: true,
component: '@/pages/member/memberPr1/auditPr1',
},
{
path: '/memberAbility/manage/memberPr2',
name: 'memberPr2',
component: '@/pages/member/memberPr2/index',
},
{
path: '/memberAbility/manage/auditPr2',
name: 'memberPr2',
hideInMenu: true,
hidePageHeader: true,
component: '@/pages/member/memberPr2/auditPr2',
},
{
path: '/memberAbility/manage/memberPrConfirm',
name: 'memberPrConfirm',
component: '@/pages/member/memberPrConfirm/index',
},
{
path: '/memberAbility/manage/auditPrComfirm',
name: 'auditPrComfirm',
hideInMenu: true,
hidePageHeader: true,
component: '@/pages/member/memberPrConfirm/auditPrComfirm',
},
{
path: '/memberAbility/manage/memberUpgradeRule',
name: 'memberUpgradeRule',
component: '@/pages/member/memberUpgradeRule/index',
},
{
path: '/memberAbility/manage/level',
name: 'memberLevel',
component: '@/pages/member/memberLevel/index',
},
{
path: '/memberAbility/manage/addEquity',
name: 'addEquity',
hideInMenu: true,
hidePageHeader: true,
component: '@/pages/member/memberLevel/addEquity',
},
],
}
],
},
];
export default router;
/*
* @Author: XieZhiXiong
* @Date: 2020-07-29 10:21:49
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-01-26 17:36:39
* @Description:
*/
/**
* @description 路由配置页, 更多配置可查看 https://umijs.org/zh-CN/docs/routing#routes
*/
const router = [
{
path: '/login',
component: '@/pages/user/login',
},
{
path: '/mall/template/edit',
component: '@/pages/pageCustomized/mallEdit',
},
{
path: '/mall/template/preview',
component: '@/pages/pageCustomized/preview/mallPreview',
},
{
path: '/',
component: '@/layouts/index',
routes: [
{
path: '/',
redirect: '/home',
},
{
path: '/home',
name: 'home',
component: '@/pages/home',
icon: 'BarChartOutlined',
},
{
path: '/pageCustomized',
name: 'pageCustomized',
icon: 'SmileOutlined',
routes: [
{
path: '/pageCustomized/shopCenterTemplate',
name: 'shopCenterTemplate',
component: '@/pages/pageCustomized/shopCenterTemplate',
},
{
path: '/pageCustomized/shopTemplate',
name: 'shopTemplate',
component: '@/pages/pageCustomized/shopTemplate',
},
{
path: '/pageCustomized/template/detail',
name: 'templateDetail',
component: '@/pages/pageCustomized/templateDetail',
hideInMenu: true,
hidePageHeader: true,
},
],
},
],
},
];
export default router;
This diff is collapsed.
......@@ -2,7 +2,7 @@
* @Author: XieZhiXiong
* @Date: 2020-08-20 16:15:59
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-08-21 17:08:26
* @LastEditTime: 2021-01-26 17:26:44
* @Description: 基于 NormalTable 简单的可编辑列 Table
*/
import React, { useContext, useState, useEffect, useRef } from 'react';
......@@ -20,12 +20,24 @@ const EditableContext = React.createContext<any>({});
interface EditableRowProps {
index: number;
onFieldsChange: (changedFields: []) => {};
}
const EditableRow: React.FC<EditableRowProps> = ({ index, ...props }) => {
const EditableRow: React.FC<EditableRowProps> = ({
index,
onFieldsChange,
...props
}) => {
const [form] = Form.useForm();
const handleFieldsChange = (changedFields, allFields) => {
if (onFieldsChange) {
onFieldsChange(changedFields);
}
};
return (
<Form form={form} component={false}>
<Form form={form} component={false} onFieldsChange={handleFieldsChange}>
<EditableContext.Provider value={form}>
<tr {...props} />
</EditableContext.Provider>
......
/*
* @Author: XieZhiXiong
* @Date: 2020-08-20 16:15:59
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-12-21 13:57:49
* @Description: 简单封装了分页事件的 Table
*/
import React from 'react';
import { Table } from 'antd';
import classNames from 'classnames';
import { StandardTableProps } from './interface';
import styles from './index.less';
export default class NormalTable extends React.PureComponent<StandardTableProps> {
state = {
page: 1,
size: 10,
};
handlePaginationChange = (page: number, size: number) => {
const { pagination = {}, onPaginationChange } = this.props;
const { current, pageSize } = pagination;
// 内部自己维护 page、size, 单独控制当前页 或 当前页数
if (!('current' in pagination)) {
this.setState({ page: current });
}
if (!('pageSize' in pagination)) {
this.setState({ size: pageSize });
}
if (onPaginationChange) {
onPaginationChange(page, size);
}
};
render() {
const { page, size } = this.state;
const {
columns,
dataSource,
rowKey = 'id',
pagination = {},
loading,
className,
onPaginationChange,
...restProps
} = this.props;
const newPagination: any = pagination ? {
current: page,
pageSize: size,
showSizeChanger: true,
showQuickJumper: true,
onChange: this.handlePaginationChange,
size: 'small',
showTotal: () => `共 ${pagination.total || 0} 条`,
...pagination,
} : false;
return (
<div className={classNames(className)}>
<Table
rowKey={rowKey}
columns={columns}
dataSource={dataSource}
loading={loading}
pagination={newPagination}
{...restProps}
/>
</div>
)
}
/*
* @Author: XieZhiXiong
* @Date: 2020-08-20 16:15:59
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-12-21 13:57:12
* @Description: 简单封装了分页事件的 Table
*/
import React from 'react';
import { Table } from 'antd';
import classNames from 'classnames';
import { StandardTableProps } from './interface';
import styles from './index.less';
export default class NormalTable extends React.PureComponent<StandardTableProps> {
state = {
page: 1,
size: 10,
};
handlePaginationChange = (page: number, size: number) => {
const { pagination = {}, onPaginationChange } = this.props;
const { current, pageSize } = pagination;
// 内部自己维护 page、size, 单独控制当前页 或 当前页数
if (!('current' in pagination)) {
this.setState({ page: current });
}
if (!('pageSize' in pagination)) {
this.setState({ size: pageSize });
}
if (onPaginationChange) {
onPaginationChange(page, size);
}
};
render() {
const { page, size } = this.state;
const {
columns,
dataSource,
rowKey = 'id',
pagination = {},
loading,
className,
onPaginationChange,
...restProps
} = this.props;
const newPagination: any = pagination ? {
current: page,
pageSize: size,
showSizeChanger: true,
showQuickJumper: true,
onChange: this.handlePaginationChange,
size: 'small',
showTotal: () => `共 ${pagination.total || 0} 条`,
...pagination,
} : false;
return (
<div className={classNames(className)}>
<Table
rowKey={rowKey}
columns={columns}
dataSource={dataSource}
loading={loading}
pagination={newPagination}
{...restProps}
/>
</div>
)
}
}
\ No newline at end of file
......@@ -2,13 +2,13 @@
* @Author: XieZhiXiong
* @Date: 2020-08-21 11:13:55
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-10-21 16:39:54
* @LastEditTime: 2020-08-25 10:05:19
* @Description:
*/
import { TableProps, TablePaginationConfig, ColumnType } from 'antd/lib/table';
export interface StandardTableProps extends TableProps<any> {
pagination?: TablePaginationConfig | false;
pagination?: TablePaginationConfig;
onPaginationChange?: (page: number, size: number) => void;
}
......@@ -25,6 +25,18 @@ export interface EditableCellProps {
addonAfter?: React.ReactNode;
}
export interface ChangedFieldsItem {
errors: string[],
name: string[],
touched: boolean,
validating: boolean,
value: string,
};
export interface EditableRowProps extends React.HTMLAttributes<HTMLElement> {
onFieldsChange?: (changedFields: ChangedFieldsItem[]) => void,
}
interface EditableColumns extends ColumnType<any> {
dataIndex?: string | number;
editable?: boolean;
......
......@@ -2,7 +2,7 @@
* @Author: LeeJiancong
* @Date: 2020-08-04 15:05:52
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-01-22 13:45:50
* @LastEditTime: 2021-01-26 16:46:00
*/
import utils from '@/utils'
import menu from '../en-US/menu'
......@@ -57,10 +57,12 @@ export default {
'menu.authConfig.memberDetail': '角色详情',
'menu.authConfig.userSystem': '用户管理',
'menu.authConfig.userDetail': '用户详情',
// 会员能力
'menu.memberAbility': '会员管理',
'menu.memberAbility.memberMaintain': '会员维护',
'menu.memberAbility.addMember': '新增会员',
'menu.memberAbility.editMember': '编辑会员',
'menu.memberAbility.maintainDetail': '会员详情',
'menu.memberAbility.maintainDetail.basicInfo': '会员基本信息',
'menu.memberAbility.maintainDetail.levelInfo': '会员等级信息',
......@@ -69,16 +71,17 @@ export default {
'menu.memberAbility.maintainDetail.powerInfo': '权限信息',
'menu.memberAbility.maintainFrozen': '会员冻结',
'menu.memberAbility.memberPrSubmit': '待提交审核',
'menu.memberAbility.auditPrSubmit': '待提交审核详情',
'menu.memberAbility.memberPrSubmitDetail': '待提交审核详情',
'menu.memberAbility.memberPr1': '待审核(一级)',
'menu.memberAbility.memberPr2': '待审核(二级)',
'menu.memberAbility.auditPr1': '待审核详情(一级)',
'menu.memberAbility.auditPr2': '待审核详情(二级)',
'menu.memberAbility.memberPr1Detail': '待审核详情(一级)',
'menu.memberAbility.memberPr2Detail': '待审核详情(二级)',
'menu.memberAbility.memberPrConfirm': '待确认审核',
'menu.memberAbility.auditPrComfirm': '待确认审核详情',
'menu.memberAbility.memberPrConfirmDetail': '待确认审核详情',
'menu.memberAbility.memberUpgradeRule': '会员升级规则',
'menu.memberAbility.memberLevel': '会员等级',
'menu.memberAbility.addEquity': '会员权益设置',
'menu.memberAbility.editMemberLevel': '会员权益设置',
'menu.memberAbility.memberLevelDetail': '查看会员权益',
//需求单 2020-11-17
'menu.demandOrder': '需求单审核',
......
.headerTop {
display: flex;
align-items: center;
font-size: 18px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
&-icon {
width: 48px;
height: 48px;
line-height: 48px;
border-radius: 4px;
border: 1px solid #DFE1E6;
color: #fff;
text-align: center;
background-color: #8777D9;
}
&-level {
color: #303133;
margin: 0 8px 0 12px;
}
&-identity {
width: 72px;
height: 24px;
line-height: 24px;
background-color: #FFEBE6;
border-radius: 4px;
color: #E63F3B;
font-size: 12px;
font-weight: 400;
text-align: center;
}
}
.headerMain {
display: flex;
&-left {
flex: 6;
display: flex;
flex-wrap: wrap;
padding-left: 90px;
&-option {
display: flex;
width: calc(100% / 3);
margin-bottom: 17px;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #909399;
padding-right: 20px;
&:nth-of-type(n + 4) {
margin: 0;
}
div {
flex: 1;
&:nth-last-of-type(1) {
flex: 2;
}
}
}
}
&-right {
flex: 1;
text-align: right;
}
}
.extra {
&-main {
display: flex;
&-content {
position: relative;
flex: 1;
&:nth-last-of-type(1) {
flex: 2.5;
}
}
.left {
display: flex;
align-items: center;
padding: 35px 0 28px 8%;
background: rgba(250, 251, 252, 1);
border-radius: 4px;
.icon {
position: absolute;
left: 0;
top: 0;
width: 72px;
height: 24px;
color: #fff;
background-color: #606266;
border-radius: 4px 0px 4px 0px;
text-align: center;
}
.input {
display: flex;
justify-content: center;
&-main {
position: relative;
width: 328px;
height: 38px;
padding-bottom: 8px;
&::after {
content: '';
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 1px;
background-color: #DFE1E6;
}
// :global {
// .ant-input {
// border: none;
// box-shadow: none;
// background-color: transparent;
// }
// }
&-com {
width: 100%;
height: 100%;
border: 0;
outline: none;
background-color: rgba(0, 0, 0, 0);
font-size: 32px;
font-weight: 500;
color: #303133;
&:focus {
border: none;
box-shadow: none;
background-color: transparent;
}
}
}
}
}
.right {
padding: 27px 40px;
}
}
}
import React, { useState, useEffect } from 'react';
import { history } from 'umi';
import {
Button,
Popconfirm,
Card,
Input,
Slider,
Spin,
message,
} from 'antd';
import classNames from 'classnames';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { ContainerOutlined } from '@ant-design/icons';
import React from 'react';
import { usePageStatus } from '@/hooks/usePageStatus';
import { PublicApi } from '@/services/api';
import { PATTERN_MAPS } from '@/constants/regExp';
import StatusSwitch from '@/components/StatusSwitch';
import { EditableCellTable } from '@/components/PolymericTable';
import { EditableCellProps, EditableColumns } from '@/components/PolymericTable/interface';
import { GetMemberManageLevelGetResponse } from '@/services/MemberApi';
import styles from './addEquity.less';
import DetailInfo from './components/DetailInfo';
const addEquity: React.FC<[]> = () => {
const AddEquity: React.FC = () => {
const { id } = usePageStatus();
const [levelInfo, setLevelInfo] = useState<GetMemberManageLevelGetResponse>(null);
const [thresholdValue, setThresholdValue] = useState(100);
const [infoLoading, setInfoLoading] = useState(true);
const [submitLoading, setSubmitLoading] = useState(false);
const marks = {
0: '0',
5000: '5000',
10000: '10000',
15000: '15000',
20000: '20000',
50000: '50000',
};
const getMemberLevelInfo = () => {
setInfoLoading(true);
PublicApi.getMemberManageLevelGet({
id,
}).then(res => {
if (res.code === 1000) {
const { point = 0 } = res.data;
setLevelInfo(res.data);
setThresholdValue(point);
}
}).finally(() => {
setInfoLoading(false);
});
};
const handleChangeStatus = record => {
const disabled = record.status === 0;
PublicApi.postMemberManageRightUpdatestatus({
id: record.id,
status: disabled ? 1 : 0,
}).then(res => {
if (res.code === 1000) {
getMemberLevelInfo();
}
});
};
const columns: EditableColumns[] = [
{
title: 'ID',
dataIndex: 'id',
align: 'center',
},
{
title: '会员权益名称',
dataIndex: 'name',
align: 'center',
},
{
title: '会员权益说明',
dataIndex: 'remark',
align: 'center',
},
{
title: '权益获取方式',
dataIndex: 'acquireWay',
align: 'center',
},
{
title: '参数设置方式',
dataIndex: 'paramWay',
align: 'center',
},
{
title: '参数',
dataIndex: 'param',
align: 'center',
width: '20%',
editable: true,
},
{
title: '状态',
dataIndex: 'status',
align: 'center',
render: (_, record: any) => (
<StatusSwitch
handleConfirm={() => handleChangeStatus(record)}
record={record}
fieldNames="status"
/>
)
}
];
useEffect(() => {
getMemberLevelInfo();
}, []);
const handleThresholdChange = e => {
const { value } = e.target;
setThresholdValue(+value);
};
// 重新保存 dataSource
const handleSave = row => {
const { rights = [] } = levelInfo;
const newData = [...rights];
const index = newData.findIndex(item => item.id === row.id);
const item = newData[index];
newData.splice(index, 1, {
...item,
...row,
param: +row.param,
});
setLevelInfo({
...levelInfo,
rights: newData,
});
};
const updateThreshold = () => {
return PublicApi.postMemberManageLevelUpdatepoint({
id,
point: thresholdValue,
}, {
ctlType: 'none',
});
};
const updateRightsParam = () => {
if (!levelInfo.rights || !levelInfo.rights.length) {
return;
}
const payload = levelInfo.rights.map(item => ({
id: item.id,
param: item.param,
}));
return PublicApi.postMemberManageRightUpdateparam({
items: payload,
}, {
ctlType: 'none',
});
};
const handleSubmit = async () => {
const promises = [updateThreshold(), updateRightsParam()];
setSubmitLoading(true);
try {
const resArr = await Promise.all(promises);
if (resArr.every(item => item && item.code === 1000)) {
message.success('保存成功');
getMemberLevelInfo();
}
const errorItem = resArr.find((item: any) => item.code !== 1000);
if (errorItem) {
message.error(errorItem.message);
}
} catch (errInfo) {
}
setSubmitLoading(false);
};
const newColumns: any = columns.map(col => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record, index): EditableCellProps => ({
onSave: handleSave,
record,
index,
dataIndex: col.dataIndex,
title: col.title,
editable: col.editable || false,
rules: [
{
required: true,
message: '请输入相应值',
},
{
pattern: PATTERN_MAPS.money,
message: '请输入整数或小数位不超过两位的小数',
},
],
addonAfter: '%',
}),
};
});
return (
<Spin spinning={infoLoading}>
<PageHeaderWrapper
onBack={() => history.goBack()}
title={
<>
<div className={styles.headerTop}>
<div className={styles['headerTop-icon']}>
{ levelInfo && levelInfo.levelTag.length ? levelInfo.levelTag[0] : '' }
</div>
<div className={styles['headerTop-level']}>{ levelInfo?.levelTag }</div>
<div className={styles['headerTop-identity']}>{ levelInfo?.memberLevelTypeName }</div>
</div>
</>
}
content={
<div className={styles.headerMain}>
<div className={styles['headerMain-left']}>
<div className={styles['headerMain-left-option']}>
<div>会员等级:</div>
<div>{ levelInfo?.level }</div>
</div>
<div className={styles['headerMain-left-option']}>
<div>升级分值标签:</div>
<div>{ levelInfo?.scoreTag }</div>
</div>
<div className={styles['headerMain-left-option']}>
<div>角色类型:</div>
<div>{ levelInfo?.roleTypeName }</div>
</div>
<div className={styles['headerMain-left-option']}>
<div>会员等级说明:</div>
<div>{ levelInfo?.levelRemark }</div>
</div>
<div className={styles['headerMain-left-option']}>
<div>会员角色名称:</div>
<div>{ levelInfo?.roleName }</div>
</div>
<div className={styles['headerMain-left-option']}>
<div>会员类型:</div>
<div>{ levelInfo?.memberTypeName }</div>
</div>
</div>
<div className={styles['headerMain-right']}>
<Button
type="primary"
icon={<ContainerOutlined />}
loading={submitLoading}
onClick={handleSubmit}
>
保存
</Button>
</div>
</div>
}
>
<Card
title="升级阀值"
headStyle={{
borderBottom: 'none',
}}
bordered={false}
>
<div className={styles.extra}>
<div className={styles['extra-main']}>
<div className={classNames(styles['extra-main-content'], styles.left)}>
<div className={styles.icon}>当前阀值</div>
<div className={styles.input}>
<div className={styles['input-main']}>
<Input
className={styles['input-main-com']}
value={`${thresholdValue}`}
onChange={handleThresholdChange}
/>
</div>
</div>
</div>
{/* <div className={classNames(styles['extra-main-content'], styles.right)}>
<Slider
marks={marks}
max={50000}
value={thresholdValue}
disabled
/>
</div> */}
</div>
</div>
</Card>
<Card
title="会员权益"
headStyle={{
borderBottom: 'none',
}}
style={{
marginTop: 24,
}}
bordered={false}
>
<EditableCellTable
dataSource={levelInfo?.rights}
columns={newColumns}
loading={false}
pagination={null}
/>
</Card>
</PageHeaderWrapper>
</Spin>
)
}
<DetailInfo id={id} isEdit />
);
};
export default addEquity
\ No newline at end of file
export default AddEquity;
\ No newline at end of file
.headerTop {
display: flex;
align-items: center;
font-size: 18px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
&-icon {
width: 48px;
height: 48px;
line-height: 48px;
border-radius: 4px;
border: 1px solid #DFE1E6;
color: #fff;
text-align: center;
background-color: #8777D9;
}
&-level {
color: #303133;
margin: 0 8px 0 12px;
}
&-identity {
width: 72px;
height: 24px;
line-height: 24px;
background-color: #FFEBE6;
border-radius: 4px;
color: #E63F3B;
font-size: 12px;
font-weight: 400;
text-align: center;
}
}
.headerMain {
display: flex;
&-left {
flex: 6;
display: flex;
flex-wrap: wrap;
padding-left: 90px;
&-option {
display: flex;
width: calc(100% / 3);
margin-bottom: 17px;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #909399;
padding-right: 20px;
&:nth-of-type(n + 4) {
margin: 0;
}
div {
flex: 1;
&:nth-last-of-type(1) {
flex: 2;
}
}
}
}
&-right {
flex: 1;
text-align: right;
}
}
.extra {
&-main {
display: flex;
&-content {
position: relative;
flex: 1;
&:nth-last-of-type(1) {
flex: 2.5;
}
}
.left {
display: flex;
align-items: center;
padding: 35px 0 28px 8%;
background: rgba(250, 251, 252, 1);
border-radius: 4px;
.icon {
position: absolute;
left: 0;
top: 0;
width: 72px;
height: 24px;
color: #fff;
background-color: #606266;
border-radius: 4px 0px 4px 0px;
text-align: center;
}
.input {
display: flex;
justify-content: center;
&-main {
position: relative;
width: 328px;
height: 38px;
padding-bottom: 8px;
&::after {
content: '';
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 1px;
background-color: #DFE1E6;
}
// :global {
// .ant-input {
// border: none;
// box-shadow: none;
// background-color: transparent;
// }
// }
&-com {
width: 100%;
height: 100%;
border: 0;
outline: none;
background-color: rgba(0, 0, 0, 0);
font-size: 32px;
font-weight: 500;
color: #303133;
&:focus {
border: none;
box-shadow: none;
background-color: transparent;
}
}
}
}
}
.right {
padding: 27px 40px;
}
}
}
This diff is collapsed.
/*
* @Author: XieZhiXiong
* @Date: 2021-01-26 17:27:30
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-01-26 17:27:31
* @Description:
*/
import React from 'react';
import { usePageStatus } from '@/hooks/usePageStatus';
import DetailInfo from './components/DetailInfo';
const EquityDetail: React.FC = () => {
const { id } = usePageStatus();
return (
<DetailInfo id={id} />
);
};
export default EquityDetail;
\ No newline at end of file
......@@ -49,7 +49,7 @@ const MemberLevel: React.FC<[]> = () => {
key: 'levelTag',
render: (text: any, record: any) => (
<EyePreview
url={`/memberAbility/manage/level/addEquity?id=${record.id}&preview=1`}
url={`/memberAbility/manage/level/detail?id=${record.id}`}
>
{text}
</EyePreview>
......@@ -105,7 +105,7 @@ const MemberLevel: React.FC<[]> = () => {
<Button
type="link"
onClick={() =>
history.push(`/memberAbility/manage/level/addEquity?id=${record.id}`)
history.push(`/memberAbility/manage/level/edit?id=${record.id}`)
}
>
设置
......
import React, { useState, useEffect, useRef, ReactNode } 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 { merge } from 'rxjs';
import { usePageStatus } from '@/hooks/usePageStatus';
import ReutrnEle from '@/components/ReturnEle';
import NiceForm from '@/components/NiceForm';
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect';
import { useLinkageUtils } from '@/utils/formEffectUtils';
import { PublicApi } from '@/services/api';
import { GetMemberAbilitySubGetResponse } from '@/services/MemberApi';
import { initDetailSchema } from './schema';
const formActions = createFormActions();
const {
onFieldValueChange$,
onFieldInputChange$,
onFormInputChange$,
} = FormEffectHooks;
const AddMember: React.FC<any> = props => {
const { id, validateId } = usePageStatus();
const [memberItems, setMemberItems] = useState<any>({});
const [memberInfo, setMemberInfo] = useState<GetMemberAbilitySubGetResponse>(null);
const [submitLoading, setSubmitLoading] = useState(false);
const [infoLoading, setInfoLoading] = useState(false);
const [unsaved, setUnsaved] = useState(false);
const getDetailedInfo = async () => {
if (id && validateId) {
setInfoLoading(true);
const infoRes = await PublicApi.getMemberMaintenanceGetmember({
memberId: id,
validateId,
});
if (infoRes.code !== 1000) {
return;
}
const {
memberTypeEnum,
groups = [],
account,
countryCode,
createTime,
currentStep,
levelTag,
memberId,
memberTypeName,
name,
outerHistory,
outerStatusName,
roleName,
verifySteps,
...rest
}: any = infoRes.data;
// 注册资料处理
const detail = {};
for (let i = 0; i < groups.length; i++) {
const item = groups[i];
if (item.elements) {
for (let j = 0; j < item.elements.length; j++) {
const ele = item.elements[j];
detail[ele.fieldName] = ele.fieldValue;
}
}
}
setMemberInfo({
memberTypeId: memberTypeEnum,
...rest,
...detail,
});
setInfoLoading(false);
}
};
useEffect(() => {
getDetailedInfo();
}, []);
const handleSubmit = (values: any) => {
const {
memberTypeId,
roleId,
level,
countryCodeId,
phone,
email,
outerStatus,
status,
statusName,
currentOuterStep,
outerVerifySteps,
validateId,
...rest
} = values;
if (!id) {
setSubmitLoading(true);
const msg = message.loading({
content: '正在添加,请稍候...',
duration: 0,
});
PublicApi.postMemberMaintenanceAddmember({
memberTypeId,
roleId,
level,
countryCodeId,
phone,
email,
detail: rest,
}).then(res => {
if (res.code !== 1000) {
return;
}
setUnsaved(false);
setTimeout(() => {
history.goBack();
}, 800);
}).finally(() => {
msg();
setSubmitLoading(false);
});
} else {
setSubmitLoading(true);
const msg = message.loading({
content: '正在保存,请稍候...',
duration: 0,
});
PublicApi.postMemberMaintenanceUpdatemember({
memberId: id,
validateId,
memberTypeId,
roleId,
level,
countryCodeId,
phone,
email,
detail: rest,
}).then(res => {
if (res.code !== 1000) {
return;
}
setUnsaved(false);
setTimeout(() => {
history.goBack();
}, 800);
}).finally(() => {
msg();
setSubmitLoading(false);
});
}
};
// 会员类型、注册手机下拉框
const getPageitemsBasic = async () => {
const res = await PublicApi.getMemberMaintenanceAddpageitems();
if (res.code === 1000) {
const { data = {} }: any = res;
const {
memberTypes = [],
countryCodes = [],
} = data;
return {
memberTypeId: memberTypes.map(item => ({ label: item.memberTypeName, value: item.memberTypeId })),
countryCodeId: countryCodes.map(item => ({ label: item.text, value: item.id })),
};
}
return {};
};
const useAsyncLinkageEffect = () => {
const linkage = useLinkageUtils();
// 间接触发根据会员类型
onFieldValueChange$('memberTypeId').subscribe(fieldState => {
if (!fieldState.value) {
return;
}
// 查询角色下拉
linkage.loading('roleId');
PublicApi.getMemberMaintenanceAddpageitemsRole({
memberTypeId: fieldState.value,
}).then(res => {
if (res.code === 1000) {
const { data = [] } = res;
const options = data.map(item => ({ label: item.roleName, value: item.roleId }));
linkage.enum('roleId', options);
}
}).finally(() => {
linkage.loaded('roleId');
});
});
// 根据会员类型
onFieldInputChange$('memberTypeId').subscribe(fieldState => {
if (!fieldState.value) {
return;
}
linkage.value('roleId', undefined);
linkage.enum('roleId', []);
linkage.value('level', undefined);
linkage.enum('level', []);
});
// 根据会员角色,查询其他注册资料
onFieldValueChange$('roleId').subscribe(fieldState => {
if (!fieldState.value) {
return;
}
PublicApi.getMemberMaintenanceAddpageitemsDetail({
roleId: fieldState.value,
}).then(res => {
if (res.code === 1000) {
const { data = [] } = res;
setMemberItems(data);
}
});
});
// 手动触发改变的话重置等级下拉框
onFieldInputChange$('*(memberTypeId,roleId)').subscribe(() => {
linkage.value('level', undefined);
linkage.enum('level', []);
});
// 根据会员类型和角色,查询等级下拉
onFieldValueChange$('*(memberTypeId,roleId)').subscribe(fieldState => {
const selfName = fieldState.name;
const selfValue = fieldState.value;
const otherName = selfName == 'memberTypeId' ? 'roleId' : 'memberTypeId';
setTimeout(() => {
const otherValue = formActions.getFieldState(otherName, state => state.value);
if (selfValue && otherValue) {
linkage.loading('level');
PublicApi.getMemberMaintenanceAddpageitemsLevel({
memberTypeId: selfName == 'memberTypeId' ? selfValue : otherValue,
roleId: selfName == 'memberTypeId' ? otherValue : selfValue,
}, {
useCache: true,
}).then(res => {
if (res.code === 1000) {
const { data = [] } = res;
const options = data.map(item => ({ label: item.levelTag, value: item.level }));
linkage.enum('level', options);
}
}).finally(() => {
linkage.loaded('level');
});
}
}, 0);
});
}
return (
<Spin spinning={infoLoading}>
<PageHeaderWrapper
onBack={() => history.goBack()}
backIcon={<ReutrnEle description="返回" />}
title={!id ? '新建会员' : '编辑会员'}
extra={[
<Button
key="1"
type="primary"
icon={<SaveOutlined />}
loading={submitLoading}
onClick={() => formActions.submit()}
>
保存
</Button>,
]}
>
<Card>
<NiceForm
onSubmit={handleSubmit}
actions={formActions}
initialValues={memberInfo || {}}
effects={($, actions) => {
useAsyncInitSelect(
['memberTypeId', 'countryCodeId'],
getPageitemsBasic,
);
useAsyncLinkageEffect();
onFormInputChange$().subscribe(() => {
if (!unsaved) {
setUnsaved(true);
}
});
}}
schema={initDetailSchema(memberItems)}
/>
</Card>
</PageHeaderWrapper>
<Prompt when={unsaved} message="您还有未保存的内容,是否确定要离开?" />
</Spin>
);
};
export default AddMember;
/*
* @Author: XieZhiXiong
* @Date: 2020-07-29 10:44:34
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-01-26 15:50:44
* @Description: 新增会员
*/
import React from 'react';
import MemberForm from './components/MemberForm';
const AddMember: React.FC = () => {
return (
<MemberForm />
);
};
export default AddMember;
/*
* @Author: XieZhiXiong
* @Date: 2021-01-26 15:45:24
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-01-26 16:48:08
* @Description:
*/
import React, { useState, useEffect } from 'react';
import { history, Prompt } from 'umi';
import { 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 ReutrnEle from '@/components/ReturnEle';
import NiceForm from '@/components/NiceForm';
import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect';
import { useLinkageUtils } from '@/utils/formEffectUtils';
import { PublicApi } from '@/services/api';
import { GetMemberAbilitySubGetResponse } from '@/services/MemberApi';
import { initDetailSchema } from './schema';
const formActions = createFormActions();
const {
onFieldValueChange$,
onFieldInputChange$,
onFormInputChange$,
} = FormEffectHooks;
interface MemberFormProps {
/**
* 数据id
*/
id?: string;
/**
* 记录id
*/
validateId?: string;
/**
* 是否是编辑的
*/
isEdit?: boolean,
};
const MemberForm: React.FC<MemberFormProps> = ({
id,
validateId,
isEdit = false,
}) => {
const [memberItems, setMemberItems] = useState<any>({});
const [memberInfo, setMemberInfo] = useState<GetMemberAbilitySubGetResponse>(null);
const [submitLoading, setSubmitLoading] = useState(false);
const [infoLoading, setInfoLoading] = useState(false);
const [unsaved, setUnsaved] = useState(false);
const getDetailedInfo = async () => {
if (id && validateId) {
setInfoLoading(true);
const infoRes = await PublicApi.getMemberMaintenanceGetmember({
memberId: id,
validateId,
});
if (infoRes.code !== 1000) {
return;
}
const {
memberTypeEnum,
groups = [],
account,
countryCode,
createTime,
currentStep,
levelTag,
memberId,
memberTypeName,
name,
outerHistory,
outerStatusName,
roleName,
verifySteps,
...rest
}: any = infoRes.data;
// 注册资料处理
const detail = {};
for (let i = 0; i < groups.length; i++) {
const item = groups[i];
if (item.elements) {
for (let j = 0; j < item.elements.length; j++) {
const ele = item.elements[j];
detail[ele.fieldName] = ele.fieldValue;
}
}
}
setMemberInfo({
memberTypeId: memberTypeEnum,
...rest,
...detail,
});
setInfoLoading(false);
}
};
useEffect(() => {
getDetailedInfo();
}, []);
const handleSubmit = (values: any) => {
const {
memberTypeId,
roleId,
level,
countryCodeId,
phone,
email,
outerStatus,
status,
statusName,
currentOuterStep,
outerVerifySteps,
validateId,
...rest
} = values;
if (!id) {
if (isEdit) {
return;
}
setSubmitLoading(true);
const msg = message.loading({
content: '正在添加,请稍候...',
duration: 0,
});
PublicApi.postMemberMaintenanceAddmember({
memberTypeId,
roleId,
level,
countryCodeId,
phone,
email,
detail: rest,
}).then(res => {
if (res.code !== 1000) {
return;
}
setUnsaved(false);
setTimeout(() => {
history.goBack();
}, 800);
}).finally(() => {
msg();
setSubmitLoading(false);
});
} else {
if (!isEdit) {
return;
}
setSubmitLoading(true);
const msg = message.loading({
content: '正在保存,请稍候...',
duration: 0,
});
PublicApi.postMemberMaintenanceUpdatemember({
memberId: +id,
validateId,
memberTypeId,
roleId,
level,
countryCodeId,
phone,
email,
detail: rest,
}).then(res => {
if (res.code !== 1000) {
return;
}
setUnsaved(false);
setTimeout(() => {
history.goBack();
}, 800);
}).finally(() => {
msg();
setSubmitLoading(false);
});
}
};
// 会员类型、注册手机下拉框
const getPageitemsBasic = async () => {
const res = await PublicApi.getMemberMaintenanceAddpageitems();
if (res.code === 1000) {
const { data = {} }: any = res;
const {
memberTypes = [],
countryCodes = [],
} = data;
return {
memberTypeId: memberTypes.map(item => ({ label: item.memberTypeName, value: item.memberTypeId })),
countryCodeId: countryCodes.map(item => ({ label: item.text, value: item.id })),
};
}
return {};
};
const useAsyncLinkageEffect = () => {
const linkage = useLinkageUtils();
// 间接触发根据会员类型
onFieldValueChange$('memberTypeId').subscribe(fieldState => {
if (!fieldState.value) {
return;
}
// 查询角色下拉
linkage.loading('roleId');
PublicApi.getMemberMaintenanceAddpageitemsRole({
memberTypeId: fieldState.value,
}).then(res => {
if (res.code === 1000) {
const { data = [] } = res;
const options = data.map(item => ({ label: item.roleName, value: item.roleId }));
linkage.enum('roleId', options);
}
}).finally(() => {
linkage.loaded('roleId');
});
});
// 根据会员类型
onFieldInputChange$('memberTypeId').subscribe(fieldState => {
if (!fieldState.value) {
return;
}
linkage.value('roleId', undefined);
linkage.enum('roleId', []);
linkage.value('level', undefined);
linkage.enum('level', []);
});
// 根据会员角色,查询其他注册资料
onFieldValueChange$('roleId').subscribe(fieldState => {
if (!fieldState.value) {
return;
}
PublicApi.getMemberMaintenanceAddpageitemsDetail({
roleId: fieldState.value,
}).then(res => {
if (res.code === 1000) {
const { data = [] } = res;
setMemberItems(data);
}
});
});
// 手动触发改变的话重置等级下拉框
onFieldInputChange$('*(memberTypeId,roleId)').subscribe(() => {
linkage.value('level', undefined);
linkage.enum('level', []);
});
// 根据会员类型和角色,查询等级下拉
onFieldValueChange$('*(memberTypeId,roleId)').subscribe(fieldState => {
const selfName = fieldState.name;
const selfValue = fieldState.value;
const otherName = selfName == 'memberTypeId' ? 'roleId' : 'memberTypeId';
setTimeout(() => {
const otherValue = formActions.getFieldState(otherName, state => state.value);
if (selfValue && otherValue) {
linkage.loading('level');
PublicApi.getMemberMaintenanceAddpageitemsLevel({
memberTypeId: selfName == 'memberTypeId' ? selfValue : otherValue,
roleId: selfName == 'memberTypeId' ? otherValue : selfValue,
}, {
useCache: true,
}).then(res => {
if (res.code === 1000) {
const { data = [] } = res;
const options = data.map(item => ({ label: item.levelTag, value: item.level }));
linkage.enum('level', options);
}
}).finally(() => {
linkage.loaded('level');
});
}
}, 0);
});
}
return (
<Spin spinning={infoLoading}>
<PageHeaderWrapper
onBack={() => history.goBack()}
backIcon={<ReutrnEle description="返回" />}
title={!id ? '新建会员' : '编辑会员'}
extra={[
<Button
key="1"
type="primary"
icon={<SaveOutlined />}
loading={submitLoading}
onClick={() => formActions.submit()}
>
保存
</Button>,
]}
>
<Card>
<NiceForm
onSubmit={handleSubmit}
actions={formActions}
initialValues={memberInfo || {}}
effects={($, actions) => {
useAsyncInitSelect(
['memberTypeId', 'countryCodeId'],
getPageitemsBasic,
);
useAsyncLinkageEffect();
onFormInputChange$().subscribe(() => {
if (!unsaved) {
setUnsaved(true);
}
});
}}
schema={initDetailSchema(memberItems)}
/>
</Card>
</PageHeaderWrapper>
<Prompt when={unsaved} message="您还有未保存的内容,是否确定要离开?" />
</Spin>
);
};
export default MemberForm;
/*
* @Author: XieZhiXiong
* @Date: 2021-01-26 15:51:08
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-01-26 15:51:09
* @Description: 编辑会员
*/
import React from 'react';
import { usePageStatus } from '@/hooks/usePageStatus';
import MemberForm from './components/MemberForm';
const EditMember: React.FC = () => {
const { id, validateId } = usePageStatus();
return (
<MemberForm id={id} validateId={validateId} isEdit={true} />
);
};
export default EditMember;
\ No newline at end of file
......@@ -103,7 +103,7 @@ const memberMaintain: React.FC<[]> = () => {
render: (text: any, record: any) => (
<>
<EyePreview
url={`/memberAbility/manage/maintainDetail/basicInfo?id=${record.memberId}&validateId=${record.validateId}`}
url={`/memberAbility/manage/maintian/detail/basicInfo?id=${record.memberId}&validateId=${record.validateId}`}
>
{text}
</EyePreview>
......@@ -200,7 +200,7 @@ const memberMaintain: React.FC<[]> = () => {
<Button
type="link"
onClick={() =>
history.push(`/memberAbility/manage/addMember?id=${record.memberId}&validateId=${record.validateId}`)
history.push(`/memberAbility/manage/maintian/edit?id=${record.memberId}&validateId=${record.validateId}`)
}
>
编辑
......@@ -293,7 +293,7 @@ const memberMaintain: React.FC<[]> = () => {
<Space>
<Button
type="primary"
onClick={() => history.push(`/memberAbility/manage/addMember`)}
onClick={() => history.push(`/memberAbility/manage/maintian/add`)}
>
<PlusOutlined />
新建
......
This diff is collapsed.
This diff is collapsed.
......@@ -32,7 +32,7 @@ const MemberPr1: React.FC<{}> = props => {
const [selectedList, setSelectList] = useState<any>([]);
const handleJumpAudit = record => {
history.push(`/memberAbility/manage/auditPr1?id=${record.memberId}&validateId=${record.validateId}`);
history.push(`/memberAbility/manage/memberPr1/verify?id=${record.memberId}&validateId=${record.validateId}`);
};
const defaultColumns: ColumnType<any>[] = [
......@@ -48,7 +48,7 @@ const MemberPr1: React.FC<{}> = props => {
render: (text: any, record: any) => (
<>
<EyePreview
url={`/memberAbility/manage/auditPr1?id=${record.memberId}&validateId=${record.validateId}&preview=1`}
url={`/memberAbility/manage/memberPr1/detail?id=${record.memberId}&validateId=${record.validateId}`}
>
{text}
</EyePreview>
......
/*
* @Author: XieZhiXiong
* @Date: 2021-01-26 16:55:17
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-01-26 16:55:18
* @Description:
*/
import React from 'react';
import { usePageStatus } from '@/hooks/usePageStatus';
import DetailInfo from './components/DetailInfo';
const Pr1Detail: React.FC = () => {
const { id, validateId, pageStatus } = usePageStatus();
return (
<DetailInfo id={id} validateId={validateId} />
);
};
export default Pr1Detail;
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
......@@ -32,7 +32,7 @@ const MemberPr2: React.FC<{}> = props => {
const [selectedList, setSelectList] = useState<any>([]);
const handleJumpAudit = record => {
history.push(`/memberAbility/manage/auditPr2?id=${record.memberId}&validateId=${record.validateId}`);
history.push(`/memberAbility/manage/memberPr2/verify?id=${record.memberId}&validateId=${record.validateId}`);
};
const defaultColumns: ColumnType<any>[] = [
......@@ -48,7 +48,7 @@ const MemberPr2: React.FC<{}> = props => {
render: (text: any, record: any) => (
<>
<EyePreview
url={`/memberAbility/manage/auditPr2?id=${record.memberId}&validateId=${record.validateId}&preview=1`}
url={`/memberAbility/manage/memberPr2/detail?id=${record.memberId}&validateId=${record.validateId}`}
>
{text}
</EyePreview>
......
/*
* @Author: XieZhiXiong
* @Date: 2021-01-26 17:03:51
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-01-26 17:03:51
* @Description:
*/
import React from 'react';
import { usePageStatus } from '@/hooks/usePageStatus';
import DetailInfo from './components/DetailInfo';
const Pr2Detail: React.FC = () => {
const { id, validateId, pageStatus } = usePageStatus();
return (
<DetailInfo id={id} validateId={validateId} />
);
};
export default Pr2Detail;
\ No newline at end of file
......@@ -33,7 +33,7 @@ const MemberPrConfirm: React.FC<{}> = props => {
const [selectedList, setSelectList] = useState<any>([]);
const handleJumpAudit = record => {
history.push(`/memberAbility/manage/auditPrComfirm?id=${record.memberId}&validateId=${record.validateId}`);
history.push(`/memberAbility/manage/memberPrConfirm/verify?id=${record.memberId}&validateId=${record.validateId}`);
};
const defaultColumns: ColumnType<any>[] = [
......@@ -49,7 +49,7 @@ const MemberPrConfirm: React.FC<{}> = props => {
render: (text: any, record: any) => (
<>
<EyePreview
url={`/memberAbility/manage/auditPrComfirm?id=${record.memberId}&validateId=${record.validateId}&preview=1`}
url={`/memberAbility/manage/memberPrConfirm/detail?id=${record.memberId}&validateId=${record.validateId}`}
>
{text}
</EyePreview>
......
/*
* @Author: XieZhiXiong
* @Date: 2021-01-26 17:10:09
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-01-26 17:10:09
* @Description:
*/
import React from 'react';
import { usePageStatus } from '@/hooks/usePageStatus';
import DetailInfo from './components/DetailInfo';
const PrComfirmDetail: React.FC = () => {
const { id, validateId, pageStatus } = usePageStatus();
return (
<DetailInfo id={id} validateId={validateId} />
);
};
export default PrComfirmDetail;
\ No newline at end of file
......@@ -32,7 +32,7 @@ const MemberPrSubmit: React.FC<{}> = props => {
const [selectedList, setSelectList] = useState<any>([]);
const handleJumpAudit = record => {
history.push(`/memberAbility/manage/auditPrSubmit?id=${record.memberId}&validateId=${record.validateId}`);
history.push(`/memberAbility/manage/memberPrSubmit/verify?id=${record.memberId}&validateId=${record.validateId}`);
};
const defaultColumns: ColumnType<any>[] = [
......@@ -48,7 +48,7 @@ const MemberPrSubmit: React.FC<{}> = props => {
render: (text: any, record: any) => (
<>
<EyePreview
url={`/memberAbility/manage/auditPrSubmit?id=${record.memberId}&validateId=${record.validateId}&preview=1`}
url={`/memberAbility/manage/memberPrSubmit/detail?id=${record.memberId}&validateId=${record.validateId}`}
>
{text}
</EyePreview>
......
/*
* @Author: XieZhiXiong
* @Date: 2021-01-26 16:43:44
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-01-26 16:43:45
* @Description:
*/
import React from 'react';
import { usePageStatus } from '@/hooks/usePageStatus';
import DetailInfo from './components/DetailInfo';
const PrSubmitDetail: React.FC = () => {
const { id, validateId, pageStatus } = usePageStatus();
return (
<DetailInfo id={id} validateId={validateId} />
);
};
export default PrSubmitDetail;
\ No newline at end of file
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