Commit 8b6ef593 authored by tjy's avatar tjy

完善会员模块页面

parent 5285045a
...@@ -74,16 +74,28 @@ const router = [ ...@@ -74,16 +74,28 @@ const router = [
component: '@/pages/member/memberPrSubmit/auditPrSubmit', component: '@/pages/member/memberPrSubmit/auditPrSubmit',
}, },
{ {
path: '/memberAbility/manage/memberPr', path: '/memberAbility/manage/memberPr1',
name: 'memberPr', name: 'memberPr1',
component: '@/pages/member/memberPr/index', component: '@/pages/member/memberPr1/index',
}, },
{ {
path: '/memberAbility/manage/auditPr', path: '/memberAbility/manage/auditPr1',
name: 'memberPr', name: 'memberPr1',
hideInMenu: true, hideInMenu: true,
hidePageHeader: true, hidePageHeader: true,
component: '@/pages/member/memberPr/auditPr', 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', path: '/memberAbility/manage/memberPrConfirm',
......
...@@ -23,14 +23,14 @@ ...@@ -23,14 +23,14 @@
"dependencies": { "dependencies": {
"@ant-design/icons": "^4.2.1", "@ant-design/icons": "^4.2.1",
"@ant-design/pro-layout": "^5.0.12", "@ant-design/pro-layout": "^5.0.12",
"@formily/antd": "^1.2.8", "@formily/antd": "1.2.10",
"@formily/antd-components": "^1.2.8", "@formily/antd-components": "1.2.10",
"@umijs/preset-react": "1.x", "@umijs/preset-react": "1.x",
"@umijs/test": "^3.2.0", "@umijs/test": "^3.2.0",
"braft-editor": "^2.3.9", "braft-editor": "^2.3.9",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"god": "0.1.15", "god": "0.1.17",
"lint-staged": "^10.0.7", "lint-staged": "^10.0.7",
"mobx": "^5.15.4", "mobx": "^5.15.4",
"mobx-react": "^6.2.2", "mobx-react": "^6.2.2",
......
...@@ -7,7 +7,9 @@ import '@/global/styles/reset.less'; // 重置antd样式 ...@@ -7,7 +7,9 @@ import '@/global/styles/reset.less'; // 重置antd样式
import '@/global/styles/global.less'; // 导入全局样式 import '@/global/styles/global.less'; // 导入全局样式
// 默认引入所有的ant样式, 不引入css因为无法做到变量覆盖 // 默认引入所有的ant样式, 不引入css因为无法做到变量覆盖
import 'antd/dist/antd.less'; import 'antd/dist/antd.less';
import { setup } from '@formily/antd-components';
setup();
let extraRoutes: never[] = []; let extraRoutes: never[] = [];
/** /**
......
import React from 'react'
import { Row, Col } from 'antd';
import styled from 'styled-components'
import { findItemAndDelete } from '@/utils'
import cx from 'classnames'
const RowStyleLayout = styled(props => <div {...props} />)`
.card-checkbox {
display: flex;
flex-wrap: wrap;
}
.card-checkbox-item {
width: 320px;
height: 48px;
margin-right: 32px;
margin-bottom: 16px;
border:1px solid rgba(235,236,240,1);
padding: 0 16px;
display: flex;
align-items: center;
cursor: pointer;
}
.card-checkbox-item.active {
border-color: #00B382;
position: relative;
}
.card-checkbox-item.active::after {
content: '';
position: absolute;
bottom: 0;
right: 0;
width: 0;
height: 0;
border: 6px solid transparent;
border-right: 6px solid #00B382;
border-bottom: 6px solid #00B382;
}
.card-logo {
display: block;
width: 32px;
height: 32px;
border-radius: 50%;
margin-right: 8px;
}
.card-logo.default {
background: #669EDE;
text-align: center;
line-height: 32px;
color: #fff;
font-size: 12px;
}
.card-checkbox-title {
font-size: 14px;
color: #42526E;
}
`
const CardCheckBox = (props) => {
const { dataSource = [] } = props.props['x-component-props']
const value: number[] = props.value || []
const handleChange = (id) => {
if (value.includes(id)) {
const newValue = findItemAndDelete(value, id)
props.mutators.change(newValue)
} else {
props.mutators.change([...value, id])
}
}
const isChecked = (id) => {
return value.includes(id)
}
return (
<RowStyleLayout>
<Row className='card-checkbox'>
{
dataSource.map((v, i) => {
return (
<Col key={v.id} className={cx('card-checkbox-item', isChecked(v.id) ? 'active' : '')} onClick={() => handleChange(v.id)}>
{ v.logo ? <img className='card-logo' src={v.logo}/> : <div className='card-logo default'>logo</div> }
<span className='card-checkbox-title'>{v.title}</span>
</Col>
)
})
}
</Row>
</RowStyleLayout>
)
}
CardCheckBox.defaultProps = {}
CardCheckBox.isFieldComponent = true;
export default CardCheckBox
\ No newline at end of file
import React from 'react'
import styled from 'styled-components'
import { toArr } from '@formily/shared';
import { SchemaField, FormPath } from '@formily/antd';
import { Button } from 'antd';
// 由于自增列表里 无法进行mega布局, 所以只能在该组件下 重写样式
const RowStyleLayout = styled(props => <div {...props} />)`
.ant-btn {
margin-right: 16px;
}
.ant-form-item {
display: inline-flex;
margin-right: 16px;
margin-bottom: 16px;
}
> .ant-form-item {
margin-bottom: 20px;
margin-right: 20px;
}
> .ant-form-item:last-child {
margin-right: 0;
}
.ant-form-item-control {
max-width: none;
}
`
// 自增组件
const CustomAddArray = (props) => {
const { value, schema, className, editable, path, mutators } = props
const componentProps = schema.getExtendsComponentProps() || {}
const onAdd = () => mutators.push(schema.items.getEmptyValue())
const onRemove = index => mutators.remove(index)
return <div>
{ toArr(value).map((item, index, arr) => {
return <RowStyleLayout {...componentProps} key={index}>
<SchemaField path={FormPath.parse(path).concat(index)} onlyRenderProperties/>
<Button onClick={onAdd.bind(null, index)} type='primary'>+</Button>
{ index !== 0 && <Button onClick={onRemove.bind(null, index)}>-</Button>}
</RowStyleLayout>
}) }
</div>
}
CustomAddArray.isFieldComponent = true
export default CustomAddArray
import React from 'react';
import { Row, Col, Select, Input } from 'antd';
import styled from 'styled-components';
import { findItemAndDelete } from '@/utils';
import cx from 'classnames';
const { Option } = Select;
const RowStyleLayout = styled(props => <div {...props} />)``;
const registryPhone = (props: any) => {
const { dataSource = [], selectPh, inputPh } = props.props[
'x-component-props'
];
const defaultValue: any = props.props.default || {};
const value: any = props.value || {};
const handleChange = (type, e) => {
if (type === 'select') {
props.mutators.change({ ...value, phone: e });
} else {
e.persist();
props.mutators.change({ ...value, countryCode: e.target.value });
}
};
return (
<Row>
<Col span={8}>
<Select
value={defaultValue.countryCode}
onChange={val => handleChange('select', val)}
placeholder={selectPh}
>
{dataSource.map((v, i) => {
return (
<Option key={v.text} value={v.id}>
<div style={{ display: 'flex', alignItems: 'center' }}>
<img
style={{
width: '24px',
height: '17px',
marginRight: '8px',
}}
src={v.url}
/>
{v.text}
</div>
</Option>
);
})}
</Select>
</Col>
<Col span={15} offset={1}>
<Input
defaultValue={defaultValue.phone}
placeholder={inputPh}
maxLength={11}
onChange={e => handleChange('input', e)}
/>
</Col>
</Row>
);
};
registryPhone.defaultProps = {};
registryPhone.isFieldComponent = true;
export default registryPhone;
import React from 'react'
import { Slider, Input, Space } from 'antd'
const CustomSlider = (props) => {
const value = props.value || 0
const max = props.props['x-component-props']?.max || 0
return (
<div style={{width: '100%'}}>
<Slider
value={value}
onChange={e => props.mutators.change(e)}
{...props.props['x-component-props']}></Slider>
<Space>
<Input type='number' disabled max={max} value={props.value} onChange={e => props.mutators.change(e.target.value)} addonAfter='尺'/>
{ max && <span>还剩:{max - value}</span> }
</Space>
</div>
)
}
CustomSlider.defaultProps = {}
CustomSlider.isFieldComponent = true;
export default CustomSlider
\ No newline at end of file
import React from 'react';
import { Space } from 'antd';
const CustomStatus = props => {
console.log(props);
return (
<>
<Space>
<span
className={
props.value === 1 ? 'commonStatusValid' : 'commonStatusInvalid'
}
></span>
<span>{props.value === 1 ? '有效' : '无效'}</span>
</Space>
</>
);
};
export default CustomStatus;
import React from 'react'
import UploadImage from "@/components/UploadImage"
const CustomUpload = (props) => {
const { mutators } = props
return <UploadImage
imgUrl={props.value}
onChange={data => {
// 这里能拿到change后的data值
mutators.change(data)
}}
/>
}
CustomUpload.isFieldComponent = true
export default CustomUpload
\ No newline at end of file
import React, { useState } from 'react'
import { Input, Space, Button, Table } from 'antd'
import { PlusOutlined } from '@ant-design/icons'
const MultTable = (props) => {
const { columns } = props.props['x-component-props']
const value = props.value || []
return (
<div style={{width: '100%'}}>
<Button block icon={<PlusOutlined/>} type='dashed'>选择指定会员</Button>
<Table
rowKey='id'
columns={columns}
dataSource={value}
/>
</div>
)
}
MultTable.defaultProps = {}
MultTable.isFieldComponent = true;
export default MultTable
\ No newline at end of file
import React, { useState } from 'react'
import { Input, Space, Button } from 'antd'
import { CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons'
import { useFieldState, FormPath } from '@formily/antd'
import { FORM_FILTER_PATH } from '@/formSchema/const'
export interface SearchProps {
value: string,
mutators: any,
props: any
}
const Search = (props) => {
console.log(props)
const [state, setState] = useFieldState({
filterSearch: false
})
const changeFilterVisible = () => {
if (state.filterSearch) {
props.form.reset({
// 清除FILTER_PARAMS下所有字段
selector: `*.${FORM_FILTER_PATH}.*`
})
}
setState({
filterSearch: !state.filterSearch
})
}
return (
<Space size={20} style={{justifyContent: 'flex-end', width: '100%'}}>
<Input.Search
value={props.value || ''}
onChange={e => props.mutators.change(e.target.value)}
onSearch={(_,e) => {
e.preventDefault()
props.form.submit()
}}
{...props.props['x-component-props']}
/>
<Button onClick={changeFilterVisible}>高级筛选{state.filterSearch ? <CaretUpOutlined /> : <CaretDownOutlined />}</Button>
<Button onClick={() => props.form.reset()}>重置</Button>
</Space>
)
}
Search.defaultProps = {}
Search.isFieldComponent = true;
export default Search
\ No newline at end of file
import React, { useState } from 'react'
import { Input, Space, Button } from 'antd'
const Submit = (props) => {
return (
<Button htmlType='submit' type='primary'>查询</Button>
)
}
Submit.defaultProps = {}
Submit.isFieldComponent = true;
export default Submit
\ No newline at end of file
import React from 'react'
const Text = (props) => {
return (
<span {...props.props['x-component-props']}>{props.value}</span>
)
}
Text.defaultProps = {}
Text.isFieldComponent = true;
export default Text
\ No newline at end of file
import React from 'react';
import SchemaForm, {
IAntdSchemaFormProps,
createFormActions,
FormPath,
SchemaField,
} from '@formily/antd';
import { Button, Space } from 'antd';
import CustomUpload from './components/CustomUpload';
import CustomStatus from './components/CustomStatus';
import CustomAddArray from './components/CustomAddArray';
import CustomSlider from './components/CustomSlider';
import Search from './components/Search';
import Submit from './components/Submit';
import Text from './components/Text';
import CardCheckBox from './components/CardCheckBox';
import MultTable from './components/MultTable';
import CustomRegistryPhone from './components/CustomRegistryPhone';
export interface NiceFormProps extends IAntdSchemaFormProps {}
const NiceForm: React.FC<NiceFormProps> = props => {
const { children, components, ...reset } = props;
const customComponents = {
CustomUpload,
CustomStatus,
CustomAddArray,
CustomSlider,
Search,
Submit,
Text,
CardCheckBox,
MultTable,
CustomRegistryPhone,
};
const defineComponents = Object.assign(customComponents, components);
return (
<SchemaForm colon={false} components={defineComponents} {...reset}>
{children}
</SchemaForm>
);
};
NiceForm.defaultProps = {};
export default NiceForm;
import React, { Component } from 'react'
import {
ArrowLeftOutlined
} from '@ant-design/icons'
interface IProps {
description?: string;
logoSrc?: string;
}
const ReutrnEle:React.FC<IProps> = (props) => {
const { description, logoSrc } = props
return <>
<span style={{fontSize:15,color:'#6B778CFF'}}><ArrowLeftOutlined /> {logoSrc?<img src={logoSrc} style={{width:48,height:48,margin:'0 0 0 14px'}}/>:description}</span>
</>
}
export default ReutrnEle
\ No newline at end of file
.upload_image_wrap {
display: flex;
align-items: center;
.size_require {
color: #97A0AF;
}
.upload_btn {
width: 104px;
height: 104px;
display: flex;
margin-right: 24px;
align-items: center;
justify-content: center;
color: #6B778C;
flex-direction: column;
background: rgba(250, 251, 252, 1);
border-radius: 2px;
border: 1px solid rgba(223, 225, 230, 1);
cursor: pointer;
overflow: hidden;
&.isAdd {
border: 1px dashed rgba(223, 225, 230, 1);
}
&>img {
height: 100%;
width: auto;
display: block;
margin: 0 auto;
}
&>p {
margin-top: 12px;
}
}
}
\ No newline at end of file
import React, { useState, Fragment, forwardRef } from 'react'
import { Upload, message } from 'antd'
import { LoadingOutlined, PlusOutlined } from '@ant-design/icons'
import { UploadFile, UploadChangeParam } from 'antd/lib/upload/interface'
import cx from 'classnames'
import styles from './index.less'
interface UploadImagePorpsType {
imgUrl: string;
size?: string;
onChange: Function;
disabled?: boolean;
}
const UploadImage: React.FC<UploadImagePorpsType> = forwardRef((props, ref) => {
const { imgUrl, onChange, size = "386x256", disabled = false } = props
const [loading, setLoading] = useState<boolean>(false)
const beforeUpload = (file: UploadFile) => {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg';
if (!isJpgOrPng) {
message.error('仅支持上传JPEG/JPG/PNG文件!');
}
const isLt200k = file.size / 1024 < 200;
if (!isLt200k) {
message.error('上传图片不超过200K!');
}
return isJpgOrPng && isLt200k;
}
const uploadProps = {
name: 'file',
action: '/api/file/file/upload',
headers: {},
data: {
fileType: 1
},
disabled: loading || disabled,
showUploadList: false,
onChange(info: UploadChangeParam) {
if (info.file.status === 'uploading') {
setLoading(true)
return;
}
if (info.file.status === 'done') {
// 图片回显
const { code, data } = info.file.response
if (code === 1000) {
console.log('upload success')
onChange(data)
}
setLoading(false)
}
},
beforeUpload
};
const uploadButton = (
<Fragment>
{loading ? <LoadingOutlined /> : <PlusOutlined />}
<p>上传图片</p>
</Fragment>
);
return (
<div className={styles.upload_image_wrap}>
<Upload {...uploadProps}>
{<div className={cx(styles.upload_btn, !imgUrl ? styles.isAdd : "")}>
{
imgUrl ? <img src={imgUrl} /> : uploadButton
}
</div>}
</Upload>
<div className={styles.size_require}>
<p>支持JPG/PNG/JPEG, <br />最大不超过 200K, <br />尺寸:{size}</p>
</div>
</div>
)
})
export default UploadImage
export const FORM_FILTER_PATH = 'FORM_FILTER_PATH'
\ No newline at end of file
import { useValueLinkageEffect, ISchemaFormActions, ISchemaFormAsyncActions } from "@formily/antd"
/**
* @param origin 触发联动的字段路径
* @param target 关联的字段路径
*/
export const useStateFilterSearchLinkageEffect = (context, actions: ISchemaFormActions | ISchemaFormAsyncActions, origin: string, target: string) => {
const { setFieldState, reset } = actions
context('onFieldChange', origin).subscribe(state => {
setFieldState(target, fieldState => {
fieldState.visible = state.filterSearch
})
})
}
\ No newline at end of file
import { createFormActions, FormEffectHooks } from '@formily/antd'
import { useLinkageUtils } from '@/utils/formEffectUtils'
/**
* 定义表单副作用的集合
*/
const { onFieldValueChange$ } = FormEffectHooks
export const usePublicSelectEffects = context => {
const linkage = useLinkageUtils()
onFieldValueChange$('select').subscribe(({ value }) => {
linkage.visible(value)
})
}
\ No newline at end of file
...@@ -50,8 +50,10 @@ export default { ...@@ -50,8 +50,10 @@ export default {
'menu.memberAbility.memberMaintain': '会员维护', 'menu.memberAbility.memberMaintain': '会员维护',
'menu.memberAbility.memberPrSubmit': '待提交审核', 'menu.memberAbility.memberPrSubmit': '待提交审核',
'menu.memberAbility.auditPrSubmit': '待提交审核详情', 'menu.memberAbility.auditPrSubmit': '待提交审核详情',
'menu.memberAbility.memberPr': '待审核', 'menu.memberAbility.memberPr1': '待审核(一级)',
'menu.memberAbility.auditPr': '待审核详情', 'menu.memberAbility.memberPr2': '待审核(二级)',
'menu.memberAbility.auditPr1': '待审核详情(一级)',
'menu.memberAbility.auditPr2': '待审核详情(二级)',
'menu.memberAbility.memberPrConfirm': '待确认审核', 'menu.memberAbility.memberPrConfirm': '待确认审核',
'menu.memberAbility.auditPrComfirm': '待确认审核详情', 'menu.memberAbility.auditPrComfirm': '待确认审核详情',
'menu.memberAbility.memberUpgradeRule': '会员升级规则', 'menu.memberAbility.memberUpgradeRule': '会员升级规则',
......
import React, { ReactNode, useRef, useState } from 'react'; import React, { ReactNode, useRef, useState, useEffect } from 'react';
import { history } from 'umi'; import { history } from 'umi';
import { StopOutlined, CheckSquareOutlined } from '@ant-design/icons'; import { StopOutlined, CheckSquareOutlined } from '@ant-design/icons';
import { PageHeaderWrapper } from '@ant-design/pro-layout'; import { PageHeaderWrapper } from '@ant-design/pro-layout';
...@@ -17,12 +17,14 @@ import { ...@@ -17,12 +17,14 @@ import {
import { StandardTable } from 'god'; import { StandardTable } from 'god';
import { ColumnType } from 'antd/lib/table/interface'; import { ColumnType } from 'antd/lib/table/interface';
import style from './index.less'; import style from './index.less';
import { PublicApi } from '@/services/api';
const { TabPane } = Tabs; const { TabPane } = Tabs;
const { Step } = Steps; const { Step } = Steps;
interface ItemProps { interface ItemProps {
auditType: string; auditType: string;
routeParams: any;
} }
const data = [ const data = [
...@@ -37,7 +39,7 @@ const data = [ ...@@ -37,7 +39,7 @@ const data = [
}, },
]; ];
const auditDetail: React.FC<ItemProps> = props => { const auditDetail: React.FC<ItemProps> = (props: any) => {
const ref = useRef({}); const ref = useRef({});
const [fActived, setfActived] = useState('1'); const [fActived, setfActived] = useState('1');
const [lActived, setlActived] = useState('1'); const [lActived, setlActived] = useState('1');
...@@ -278,6 +280,13 @@ const auditDetail: React.FC<ItemProps> = props => { ...@@ -278,6 +280,13 @@ const auditDetail: React.FC<ItemProps> = props => {
}, },
]; ];
useEffect(() => {
PublicApi.getMemberValidateCommitDetail({
memberId: props.routeParams.memberId,
validateId: props.routeParams.validateId,
}).then(res => {});
});
// 模拟请求 // 模拟请求
const fetchData = (params: any) => { const fetchData = (params: any) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
......
import React, { ReactNode, useState, useRef } from 'react'; import React, { ReactNode, useState, useEffect, useRef } from 'react';
import { history } from 'umi'; import { history } from 'umi';
import { import {
Row, Row,
...@@ -9,6 +9,7 @@ import { ...@@ -9,6 +9,7 @@ import {
Popconfirm, Popconfirm,
Select, Select,
Input, Input,
Badge,
} from 'antd'; } from 'antd';
import { import {
EyeOutlined, EyeOutlined,
...@@ -19,6 +20,8 @@ import { ...@@ -19,6 +20,8 @@ import {
import { StandardTable } from 'god'; import { StandardTable } from 'god';
import { ColumnType } from 'antd/lib/table/interface'; import { ColumnType } from 'antd/lib/table/interface';
import style from './index.less'; import style from './index.less';
import { PublicApi } from '@/services/api';
import { timeRange } from '@/utils/index';
interface PageProps { interface PageProps {
pageType: string; // 页面类型 1 待提交审核 2 待审核 3 待确认审核 pageType: string; // 页面类型 1 待提交审核 2 待审核 3 待确认审核
...@@ -26,115 +29,31 @@ interface PageProps { ...@@ -26,115 +29,31 @@ interface PageProps {
const { Option } = Select; const { Option } = Select;
const data = [
{
key: '1',
id: '1',
level: '1',
name: '温州隆昌皮具有限公司1',
type: 1,
role: 1,
applyTime: '2020-05-12 08:08',
status: 1,
source: 1,
outSideStatus: 1,
inSideStatus: 1,
externalStatus: '待提交',
},
{
key: '2',
id: '2',
level: '2',
name: '温州隆昌皮具有限公司2',
type: 2,
role: 2,
applyTime: '2020-05-12 08:08',
status: -1,
source: 2,
outSideStatus: 1,
inSideStatus: 2,
externalStatus: '待提交',
},
{
key: '3',
id: '3',
level: '3',
name: '温州隆昌皮具有限公司3',
type: 1,
role: 3,
applyTime: '2020-05-12 08:08',
status: 1,
source: 3,
outSideStatus: 2,
inSideStatus: 3,
externalStatus: '待提交',
},
{
key: '4',
id: '4',
level: '3',
name: '温州隆昌皮具有限公司4',
type: 2,
role: 4,
applyTime: '2020-05-12 08:08',
status: 1,
source: 4,
outSideStatus: 4,
inSideStatus: 4,
externalStatus: '待提交',
},
{
key: '5',
id: '5',
level: '3',
name: '温州隆昌皮具有限公司4',
type: 2,
role: 5,
applyTime: '2020-05-12 08:08',
status: 1,
source: 4,
outSideStatus: 4,
inSideStatus: 2,
externalStatus: '待提交',
},
{
key: '6',
id: '6',
level: '3',
name: '温州隆昌皮具有限公司4',
type: 2,
role: 6,
applyTime: '2020-05-12 08:08',
status: 1,
source: 4,
outSideStatus: 4,
inSideStatus: 2,
externalStatus: '待提交',
},
];
const auditList: React.FC<PageProps> = props => { const auditList: React.FC<PageProps> = props => {
const ref = useRef({}); const ref = useRef<any>({});
let [isSearch, setIsSearch] = useState(false); let [isSearch, setIsSearch] = useState(false);
const [searchForm, setSearchForm] = useState({ const [searchForm, setSearchForm] = useState<any>({
memberIdorName: '', roleId: 0, // 会员角色
memberType: '', name: '', // 会员名称
memberRole: '', memberType: 0, // 会员类型
memberLevel: '', level: 0, // 会员等级
applySource: '', source: 0, // 注册来源
insideStatus: '', innerStatus: 0, // 内部状态
outSideStatus: '', outerStatus: 0, // 外部状态
memberStatus: '', status: 0, // 会员状态
TimeRange: '', timeRange: 0, // 申请时间
startDate: '', // 申请开始时间
endDate: '', // 申请结束时间
}); });
const [searchItem, setSearchItem] = useState<any>({});
const [selectedRowKeys, setSelectedRowKeys] = useState<Array<string>>([]); const [selectedRowKeys, setSelectedRowKeys] = useState<Array<string>>([]);
const columns: ColumnType<any>[] = [ const defaultColumns: ColumnType<any>[] = [
{ {
title: 'ID', title: 'ID',
dataIndex: 'id', dataIndex: 'memberId',
align: 'center', align: 'center',
key: 'id', key: 'memberId',
}, },
{ {
title: '会员名称', title: '会员名称',
...@@ -146,7 +65,7 @@ const auditList: React.FC<PageProps> = props => { ...@@ -146,7 +65,7 @@ const auditList: React.FC<PageProps> = props => {
<div className={style.nameCell}> <div className={style.nameCell}>
<div <div
className={style.nameCellTitle} className={style.nameCellTitle}
onClick={() => handleSee(record)} onClick={() => handleChange(record, 'check')}
> >
{text}&nbsp; {text}&nbsp;
<EyeOutlined /> <EyeOutlined />
...@@ -158,58 +77,34 @@ const auditList: React.FC<PageProps> = props => { ...@@ -158,58 +77,34 @@ const auditList: React.FC<PageProps> = props => {
}, },
{ {
title: '会员类型', title: '会员类型',
dataIndex: 'type', dataIndex: 'memberTypeName',
align: 'center', align: 'center',
key: 'type', key: 'memberTypeName',
render: (text: any, record: any) => ( render: (text: any, record: any) => <>{text}</>,
<>{record.type === 1 ? '企业会员' : '渠道企业会员'}</>
),
}, },
{ {
title: '会员角色', title: '会员角色',
dataIndex: 'role', dataIndex: 'roleName',
align: 'center', align: 'center',
key: 'role', key: 'roleName',
render: (text: any, record: any) => { render: (text: any, record: any) => {
let component: ReactNode = null; let component: ReactNode = null;
component = ( component = <div>{text}</div>;
<div>
{record.role === 1
? '供应商'
: record.role === 2
? '加工企业'
: record.role === 3
? '物流服务商'
: record.role === 4
? '金融服务商'
: record.role === 5
? '采购商'
: '渠道供应商'}
</div>
);
return component; return component;
}, },
}, },
{ {
title: '申请来源/时间', title: '申请来源/时间',
dataIndex: 'applyTime', dataIndex: 'sourceName',
align: 'center', align: 'center',
key: 'applyTime', key: 'sourceName',
render: (text: any, record: any) => { render: (text: any, record: any) => {
let component: ReactNode = null; let component: ReactNode = null;
component = ( component = (
<> <>
<div>{text}</div>
<div> <div>
{record.source === 1 <ClockCircleOutlined /> {record.registerTime}
? '平台录入'
: record.source === 2
? 'WEB企业商城申请'
: record.source === 3
? '商户录入'
: '渠道录入'}
</div>
<div>
<ClockCircleOutlined /> {record.applyTime}
</div> </div>
</> </>
); );
...@@ -218,13 +113,12 @@ const auditList: React.FC<PageProps> = props => { ...@@ -218,13 +113,12 @@ const auditList: React.FC<PageProps> = props => {
}, },
{ {
title: '会员状态', title: '会员状态',
dataIndex: 'status', dataIndex: 'statusName',
align: 'center', align: 'center',
key: 'status', key: 'memberStatus',
filters: [ filters: [],
{ text: '123', value: '123' }, filteredValue: searchForm.innerStatus || ['0'],
{ text: '456', value: '456' }, filterMultiple: false,
],
render: (text: any, record: any) => { render: (text: any, record: any) => {
let component: ReactNode = null; let component: ReactNode = null;
component = ( component = (
...@@ -233,7 +127,7 @@ const auditList: React.FC<PageProps> = props => { ...@@ -233,7 +127,7 @@ const auditList: React.FC<PageProps> = props => {
record.status === 1 ? { color: '#00B37A' } : { color: '#42526E' } record.status === 1 ? { color: '#00B37A' } : { color: '#42526E' }
} }
> >
{record.outSideStatus === 1 ? '正常' : '冻结'} {text}
</div> </div>
); );
return component; return component;
...@@ -241,78 +135,29 @@ const auditList: React.FC<PageProps> = props => { ...@@ -241,78 +135,29 @@ const auditList: React.FC<PageProps> = props => {
}, },
{ {
title: '外部状态', title: '外部状态',
dataIndex: 'outSideStatus', dataIndex: 'outerStatusName',
align: 'center', align: 'center',
key: 'outSideStatus', key: 'outerStatus',
filters: [ filters: [],
{ text: '123', value: '123' }, filteredValue: searchForm.innerStatus || ['0'],
{ text: '456', value: '456' }, filterMultiple: false,
],
render: (text: any, record: any) => { render: (text: any, record: any) => {
let component: ReactNode = null; let component: ReactNode = null;
component = ( component = <div style={{ color: '#FF991F' }}>{text}</div>;
<div
style={
record.outSideStatus === 1
? { color: '#FF991F' }
: record.outSideStatus === 2
? { color: '#00B37A' }
: { color: '#E63F3B' }
}
>
{record.outSideStatus === 1
? '待审核'
: record.outSideStatus === 2
? '审核通过'
: '审核不通过'}
</div>
);
return component; return component;
}, },
}, },
{ {
title: '内部状态', title: '内部状态',
dataIndex: 'inSideStatus', dataIndex: 'innerStatusName',
align: 'center', align: 'center',
key: 'inSideStatus', key: 'innerStatus',
filters: [ filters: [],
{ text: '123', value: '123' }, filteredValue: searchForm.innerStatus || ['0'],
{ text: '456', value: '456' }, filterMultiple: false,
], render: (text: any, record: any) => (
render: (text: any, record: any) => { <Badge color={'#6C9CEB'} text={text} />
let component: ReactNode = null; ),
component = (
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<span
className={
record.inSideStatus === 1
? 'commonStatusModify'
: record.inSideStatus === 2
? 'commonStatusInvalid'
: record.inSideStatus === 3
? 'commonStatusValid'
: 'commonStatusNoPass'
}
>
<span className="commonStatus"></span>
</span>
{record.inSideStatus === 1
? '待提交'
: record.inSideStatus === 2
? '待审核'
: record.inSideStatus === 3
? '审核通过'
: '审核不通过'}
</div>
);
return component;
},
}, },
{ {
title: '操作', title: '操作',
...@@ -321,7 +166,7 @@ const auditList: React.FC<PageProps> = props => { ...@@ -321,7 +166,7 @@ const auditList: React.FC<PageProps> = props => {
render: (text: any, record: any) => { render: (text: any, record: any) => {
let component: ReactNode = null; let component: ReactNode = null;
component = ( component = (
<Button type="link" onClick={() => handleChange(record)}> <Button type="link" onClick={() => handleChange(record, 'audit')}>
{props.pageType === '1' {props.pageType === '1'
? '提交审核' ? '提交审核'
: props.pageType === '2' : props.pageType === '2'
...@@ -334,6 +179,8 @@ const auditList: React.FC<PageProps> = props => { ...@@ -334,6 +179,8 @@ const auditList: React.FC<PageProps> = props => {
}, },
]; ];
const [columns, setColumns] = useState<any[]>(defaultColumns);
const rowSelection = { const rowSelection = {
onChange: (selectedRowKeys: any, selectedRows: any) => { onChange: (selectedRowKeys: any, selectedRows: any) => {
setSelectedRowKeys(selectedRowKeys); setSelectedRowKeys(selectedRowKeys);
...@@ -349,42 +196,158 @@ const auditList: React.FC<PageProps> = props => { ...@@ -349,42 +196,158 @@ const auditList: React.FC<PageProps> = props => {
// 模拟请求 // 模拟请求
const fetchData = (params: any) => { const fetchData = (params: any) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const queryResult = data.find(v => v.key === params.keywords); let requestParams = {
setTimeout(() => { ...searchForm,
resolve({ name: params.name || '',
code: 200, current: params.current,
message: '', pageSize: params.pageSize,
data: queryResult ? [queryResult] : data, };
if (props.pageType === '1')
return PublicApi.getMemberValidateCommitPage(requestParams).then(
res => {
resolve(res.data);
},
);
if (props.pageType === '2')
return PublicApi.getMemberValidateStep1Page(requestParams).then(res => {
resolve(res.data);
}); });
}, 1000); if (props.pageType === '3')
return PublicApi.getMemberValidateStep2Page(requestParams).then(res => {
resolve(res.data);
});
if (props.pageType === '4')
return PublicApi.getMemberValidateConfirmPage(requestParams).then(
res => {
resolve(res.data);
},
);
}); });
}; };
const handleSearch = () => {}; useEffect(() => {
// if (!isFirst) return setIsFirst(true);
// ref.current.reload();
}, [
searchForm.memberType,
searchForm.roleId,
searchForm.level,
searchForm.source,
]);
// 初始化表头筛选项接收的数据类型
const processData = (data: any) => {
for (let elem of data) {
elem.value = elem.id;
}
};
useEffect(() => {
ref.current.reload();
}, [searchForm.timeRange]);
const handleDel = (e: any) => {}; const deassign = (res: any) => {
processData(res.data.memberStatus),
processData(res.data.innerStatus),
processData(res.data.outerStatus),
setSearchItem(res.data),
defaultColumns.find((target: any) => {
if (target.filters) {
target.filters = res.data[target.key];
}
});
setColumns([...defaultColumns]);
};
const handleReset = () => {}; useEffect(() => {
// 根据页面入口类型请求对应接口
if (props.pageType === '1') {
// 待提交审核
PublicApi.getMemberMaintenancePageitems().then(res => {
deassign(res);
});
} else if (props.pageType === '2') {
// 待审核(一级)
PublicApi.getMemberValidateStep1Pageitems().then(res => {
deassign(res);
});
} else if (props.pageType === '3') {
// 待审核(二级)
PublicApi.getMemberValidateStep2Pageitems().then(res => {
deassign(res);
});
} else {
// 待确认审核
PublicApi.getMemberValidateConfirmPageitems().then(res => {
deassign(res);
});
}
}, ['searchItem']);
const handleSee = (record: any) => {}; const handleSearch = (filter: any) => {
let filterKeys = Object.keys(filter);
columns.find((target: any) => {
if (filterKeys.includes(target.key)) {
target.filteredValue = filter[target.key];
}
});
};
const handleReset = () => {
let searchKey = {
roleId: 0,
name: '',
memberType: 0,
level: 0,
source: 0,
innerStatus: ['0'],
outerStatus: ['0'],
status: ['0'],
timeRange: 0,
startDate: '',
endDate: '',
};
setSearchForm({ ...searchKey });
};
const handleSubmit = (val: any) => { const handleSubmit = (val: any) => {
console.log(val); console.log(val);
}; };
const handleChange = (record: object) => { const handleChange = (record: any, type: string) => {
let path = let path =
props.pageType === '1' props.pageType === '1'
? 'auditPrSubmit' ? 'auditPrSubmit'
: props.pageType === '2' : props.pageType === '2'
? 'auditPr' ? 'auditPr1'
: props.pageType === '3'
? 'auditPr2'
: 'auditPrComfirm'; : 'auditPrComfirm';
history.push(`/memberAbility/manage/${path}`); history.push({
pathname: `/memberAbility/manage/${path}`,
query: {
type: type,
memberId: record.memberId,
validateId: record.validateId,
},
});
}; };
return ( return (
<Card> <Card>
<StandardTable <StandardTable
tableProps={{
rowKey: 'memberId',
onChange: (pagination: any, filter: any) => {
handleSearch(filter),
setSearchForm({
...searchForm,
status: filter.memberStatus || ['0'],
outerStatus: filter.outerStatus || ['0'],
innerStatus: filter.innerStatus || ['0'],
});
},
}}
columns={columns} columns={columns}
currentRef={ref} currentRef={ref}
fetchTableData={(params: any) => fetchData(params)} fetchTableData={(params: any) => fetchData(params)}
...@@ -413,15 +376,15 @@ const auditList: React.FC<PageProps> = props => { ...@@ -413,15 +376,15 @@ const auditList: React.FC<PageProps> = props => {
> >
<Input.Search <Input.Search
style={{ width: '232px' }} style={{ width: '232px' }}
value={searchForm.memberIdorName} value={searchForm.name}
placeholder="搜索" placeholder="搜索"
onChange={e => onChange={e =>
setSearchForm({ setSearchForm({
...searchForm, ...searchForm,
memberIdorName: e.target.value, name: e.target.value,
}) })
} }
onSearch={() => handleSearch} // onSearch={() => handleSearch}
/> />
</Tooltip> </Tooltip>
<Button <Button
...@@ -442,96 +405,87 @@ const auditList: React.FC<PageProps> = props => { ...@@ -442,96 +405,87 @@ const auditList: React.FC<PageProps> = props => {
setSearchForm({ ...searchForm, memberType: val }) setSearchForm({ ...searchForm, memberType: val })
} }
> >
<Option value="">会员类型(全部)</Option> {searchItem.memberTypes &&
<Option value="1">企业会员</Option> searchItem.memberTypes.map((item: any, index: string) => {
<Option value="2">个人会员</Option> return (
<Option value="3">渠道企业会员</Option> <Option value={item.id} key={index}>
<Option value="4">渠道个人会员</Option> {item.text}
</Select> </Option>
<Select );
className={style.select} })}
value={searchForm.memberRole}
onChange={val =>
setSearchForm({ ...searchForm, memberRole: val })
}
>
<Option value="">会员角色(全部)</Option>
<Option value="1">供应商</Option>
<Option value="2">采购商</Option>
<Option value="3">加工企业</Option>
<Option value="4">金融服务商</Option>
<Option value="5">物流服务商</Option>
<Option value="6">渠道供应商</Option>
<Option value="7">渠道采购商</Option>
</Select>
<Select
className={style.select}
value={searchForm.memberLevel}
onChange={val =>
setSearchForm({ ...searchForm, memberLevel: val })
}
>
<Option value="">会员等级(全部)</Option>
<Option value="1">青铜会员</Option>
<Option value="2">白银会员</Option>
<Option value="3">黄金会员</Option>
<Option value="4">钻石会员</Option>
</Select> </Select>
<Select <Select
className={style.select} className={style.select}
value={searchForm.applySource} value={searchForm.roleId}
onChange={val => onChange={val =>
setSearchForm({ ...searchForm, applySource: val }) setSearchForm({ ...searchForm, roleId: val })
} }
> >
<Option value="">申请来源(全部)</Option> {searchItem.memberRoles &&
<Option value="1">WEB企业商城申请</Option> searchItem.memberRoles.map((item: any, index: string) => {
<Option value="2">H5企业商城申请</Option> return (
<Option value="3">WEB渠道商城申请</Option> <Option value={item.id} key={index}>
<Option value="4">H5渠道商城申请</Option> {item.text}
<Option value="5">商户代录入</Option> </Option>
<Option value="6">渠道代录入</Option> );
})}
</Select> </Select>
<Select <Select
className={style.select} className={style.select}
value={searchForm.outSideStatus} value={searchForm.level}
onChange={val => onChange={val =>
setSearchForm({ ...searchForm, outSideStatus: val }) setSearchForm({ ...searchForm, level: val })
} }
> >
<Option value="">外部状态(全部)</Option> {searchItem.memberLevels &&
<Option value="1">待审核</Option> searchItem.memberLevels.map(
<Option value="2">审核通过</Option> (item: any, index: string) => {
<Option value="3">审核不通过</Option> return (
<Option value={item.id} key={index}>
{item.text}
</Option>
);
},
)}
</Select> </Select>
<Select <Select
className={style.select} className={style.select}
value={searchForm.insideStatus} value={searchForm.source}
onChange={val => onChange={val =>
setSearchForm({ ...searchForm, insideStatus: val }) setSearchForm({ ...searchForm, source: val })
} }
> >
<Option value="">内部状态(全部)</Option> {searchItem.memberSource &&
<Option value="1">待提交审核</Option> searchItem.memberSource.map(
<Option value="2">待审核</Option> (item: any, index: string) => {
<Option value="3">审核通过</Option> return (
<Option value="4">审核不通过</Option> <Option value={item.id} key={index}>
{item.text}
</Option>
);
},
)}
</Select> </Select>
<Select <Select
className={style.select} className={style.select}
value={searchForm.TimeRange} value={searchForm.timeRange}
onChange={val => onChange={val =>
setSearchForm({ ...searchForm, TimeRange: val }) setSearchForm({
...searchForm,
timeRange: val,
startDate: timeRange(val).st,
endDate: timeRange(val).et,
})
} }
> >
<Option value="">时间范围(全部)</Option> <Option value={0}>时间范围(全部)</Option>
<Option value="1">今天</Option> <Option value={1}>今天</Option>
<Option value="2">一周内</Option> <Option value={2}>一周内</Option>
<Option value="3">一个月内</Option> <Option value={3}>一个月内</Option>
<Option value="4">三个月内</Option> <Option value={4}>三个月内</Option>
<Option value="5">六个月内</Option> <Option value={5}>六个月内</Option>
<Option value="6">一年内</Option> <Option value={6}>一年内</Option>
<Option value="7">一年前</Option> <Option value={7}>一年前</Option>
</Select> </Select>
</Col> </Col>
</Row> </Row>
......
import React, { useState, useEffect, useRef, ReactNode } from 'react'; import React, { useState, useEffect, useRef, ReactNode } from 'react';
import { history } from 'umi'; import { history } from 'umi';
import { Tabs, Badge, Button, Card, Row, Col, message } from 'antd'; import { Tabs, Badge, Button, Card, Row, Col, message, Upload } from 'antd';
import { PageHeaderWrapper } from '@ant-design/pro-layout'; import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { ContainerOutlined } from '@ant-design/icons'; import {
import { Form, FormItem, createFormActions } from '@formily/antd'; ContainerOutlined,
import { Select, Input, Upload } from '@formily/antd-components'; PlusOutlined,
SaveOutlined,
} from '@ant-design/icons';
import { createFormActions } from '@formily/antd';
import { StandardTable } from 'god'; import { StandardTable } from 'god';
import { ColumnType } from 'antd/lib/table/interface'; import { ColumnType } from 'antd/lib/table/interface';
import {
IFormFilter,
IButtonFilter,
} from 'god/dist/src/standard-table/TableController';
import ReutrnEle from '@/components/ReturnEle';
import styles from './index.less';
import NiceForm from '@/components/NiceForm';
import { initDetailSchema } from './schema';
import style from './index.less'; import style from './index.less';
import { PublicApi } from '@/services/api'; import { PublicApi } from '@/services/api';
const { TabPane } = Tabs; const { TabPane } = Tabs;
const actions = createFormActions(); const addSchemaAction = createFormActions();
const addMember: React.FC<any> = props => { const addMember: React.FC<any> = props => {
const ref = useRef({}); const ref = useRef({});
const [actived, setActived] = useState('-1');
const [editable, setEditable] = useState(
props.location.query.type != 'check',
);
const selectList: any = [ const selectList: any = [
{ {
label: '', label: '',
...@@ -30,15 +38,10 @@ const addMember: React.FC<any> = props => { ...@@ -30,15 +38,10 @@ const addMember: React.FC<any> = props => {
// ) // )
value: '1', value: '1',
}, },
{ label: '', value: '2' },
{ label: '', value: '3' },
{ label: '', value: '4' },
{ label: '', value: '5' },
]; ];
/* 会员类型、会员角色、会员等级、注册手机号选项 */ /* 会员类型、会员角色、会员等级、注册手机号选项 */
const [memberItems, setMemberItems] = useState<any>({}); const [memberItems, setMemberItems] = useState<any>({});
const [loading, setLoading] = useState(false);
const data = [ const data = [
{ {
...@@ -146,181 +149,34 @@ const addMember: React.FC<any> = props => { ...@@ -146,181 +149,34 @@ const addMember: React.FC<any> = props => {
return isJpgOrPng && isLt2M; return isJpgOrPng && isLt2M;
}; };
const handleChange = (items: any, file: any) => {
for (let elem of file) {
elem.url = elem.data;
}
};
return ( return (
<PageHeaderWrapper <PageHeaderWrapper
onBack={() => history.goBack()} onBack={() => history.goBack()}
backIcon={<ReutrnEle description="返回" />}
title={ title={
<> props.location.query.type === 'add'
<div className={style.headerTop}> ? '新建会员'
<span>返回</span> : props.location.query.type === 'change'
<span> ? '编辑会员'
{props.location.query.type === 'add' : '查看会员'
? '新建会员'
: props.location.query.type === 'change'
? '编辑会员'
: '查看会员'}
</span>
</div>
</>
}
extra={
<>
<Button
className={style.saveBtn}
icon={<ContainerOutlined />}
onClick={() => actions.submit()}
>
保存
</Button>
</>
} }
extra={[
<Button
key="1"
type="primary"
icon={<SaveOutlined />}
onClick={() => addSchemaAction.submit()}
>
保存
</Button>,
]}
> >
<Card> <Card>
<Form <NiceForm
editable={editable} onSubmit={handleSubmit}
labelCol={3} actions={addSchemaAction}
wrapperCol={10} schema={initDetailSchema(memberItems)}
labelAlign="left" />
actions={actions}
>
<Tabs
tabBarGutter={30}
activeKey={actived}
onChange={activeKey => setActived(activeKey)}
>
<TabPane
tab={
// <Badge count={tabCount['1']} offset={[10, 0]}>
'基本信息'
// </Badge>
}
key="-1"
>
<FormItem
label="会员类型"
name="memberTypes"
dataSource={memberItems.memberTypes}
rules={[{ required: true, message: '请选择会员类型!' }]}
component={Select}
/>
<FormItem
label="会员角色"
name="memberRoles"
dataSource={memberItems.memberRoles}
rules={[{ required: true, message: '请选择会员角色!' }]}
component={Select}
/>
<FormItem
label="会员等级"
name="memberLevels"
dataSource={memberItems.memberLevels}
rules={[{ required: true, message: '请选择会员等级!' }]}
component={Select}
/>
<FormItem
label={
<>
<span className={style.required}>*</span>
注册手机号
</>
}
name="registry"
>
<Row gutter={10}>
<Col span={6}>
<FormItem
itemStyle={{ marginBottom: 0 }}
name="country"
dataSource={memberItems.countryCodes}
rules={[{ required: true, message: '请选择会员角色!' }]}
component={Select}
/>
</Col>
<Col span={18}>
<FormItem
name="phoneMobile"
itemStyle={{ marginBottom: 0 }}
rules={[{ required: true, message: '请选择会员角色!' }]}
component={Input}
/>
</Col>
</Row>
</FormItem>
<FormItem
label="注册邮箱"
name="memberEmail"
itemStyle={{ marginBottom: 0 }}
component={Input}
/>
</TabPane>
{memberItems.groups &&
memberItems.groups.map((item: any, index: number) => {
return (
<TabPane
tab={
// <Badge count={tabCount['1']} offset={[10, 0]}>
item.groupName
// </Badge>
}
key={index}
>
{item.elements.map((items: any, indexs: number) => {
return (
<div key={indexs}>
{items.fieldType === 'String' ? (
<FormItem
itemStyle={
item.elements.length - 1 === indexs
? { marginBottom: 0 }
: {}
}
label={items.fieldCNName}
name={items.fieldName}
required={items.fieldEmpty === 0}
// rules={items.checkRules}
component={Input}
key={indexs}
/>
) : (
<FormItem
itemStyle={
item.elements.length - 1 === indexs
? { marginBottom: 0 }
: {}
}
label={items.fieldCNName}
name={items.fieldName}
action="/api/file/file/upload"
listType="picture-card"
required={items.fieldEmpty === 0}
// rules={items.checkRules}
data={{ fileType: 2 }}
beforeUpload={beforeUpload}
onChange={(file: any) =>
handleChange(items, file)
}
showUploadList={{
showRemoveIcon:
items.value && items.value.length > 0,
}}
key={indexs}
component={Upload}
/>
)}
</div>
);
})}
</TabPane>
);
})}
</Tabs>
</Form>
</Card> </Card>
</PageHeaderWrapper> </PageHeaderWrapper>
); );
......
import React, { useState, useEffect, useRef, ReactNode } from 'react';
import { history } from 'umi';
import { Tabs, Badge, Button, Card, Row, Col, message, Upload } from 'antd';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { ContainerOutlined, PlusOutlined } from '@ant-design/icons';
import { Form, FormItem, createFormActions } from '@formily/antd';
import { Select, Input } from '@formily/antd-components';
import { StandardTable } from 'god';
import { ColumnType } from 'antd/lib/table/interface';
import style from './index.less';
import { PublicApi } from '@/services/api';
const { TabPane } = Tabs;
const actions = createFormActions();
const addMember: React.FC<any> = props => {
const ref = useRef({});
const [actived, setActived] = useState('-1');
const [editable, setEditable] = useState(
props.location.query.type != 'check',
);
const selectList: any = [
{
label: '',
// (
// <>
// <img src={ChinaImg} style={{ width: 24, height: 17 }} /> +86
// </>
// )
value: '1',
},
{ label: '', value: '2' },
{ label: '', value: '3' },
{ label: '', value: '4' },
{ label: '', value: '5' },
];
/* 会员类型、会员角色、会员等级、注册手机号选项 */
const [memberItems, setMemberItems] = useState<any>({});
const [fileList, setFileList] = useState([]);
const data = [
{
key: '1',
sn: '1',
roleName: '供应商',
status: '1',
operation: '申请注册',
useTime: '2020-05-12 08:08',
result: '无',
},
];
const columns: ColumnType<any>[] = [
{
title: '序号',
dataIndex: 'sn',
align: 'center',
key: 'sn',
},
{
title: '操作角色',
dataIndex: 'roleName',
align: 'center',
key: 'roleName',
},
{
title: '状态',
dataIndex: 'status',
align: 'center',
key: 'status',
render: (text: any, record: any) => {
let component: ReactNode = null;
component = <Badge color="#FFC400" text="待审核" />;
return component;
},
},
{
title: '操作',
dataIndex: 'operation',
align: 'center',
key: 'operation',
},
{
title: '操作时间',
dataIndex: 'useTime',
align: 'center',
key: 'useTime',
},
{
title: '审核意见',
dataIndex: 'result',
align: 'center',
key: 'result',
},
];
// 模拟请求
const fetchData = (params: any) => {
return new Promise((resolve, reject) => {
const queryResult = data.find(v => v.key === params.keywords);
setTimeout(() => {
resolve({
code: 200,
message: '',
data: queryResult ? [queryResult] : data,
});
}, 1000);
});
};
const handleSubmit = (values: any) => {
console.log(values);
};
// 处理数据
const processData = (data: any) => {
for (let elem of data) {
elem.label = elem.text;
elem.value = elem.id;
}
};
useEffect(() => {
PublicApi.getMemberMaintenanceAddpageitems().then(res => {
processData(res.data.memberLevels);
processData(res.data.memberRoles);
processData(res.data.memberTypes);
setMemberItems(res.data);
});
}, ['memberItems']);
const beforeUpload = (file: any) => {
const isJpgOrPng =
file.type === 'image/jpeg' ||
file.type === 'image/png' ||
file.type === 'image/jpg';
if (!isJpgOrPng) {
message.error('仅支持上传JPEG/JPG/PNG文件!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('上传图片不超过2MB!');
}
return isJpgOrPng && isLt2M;
};
// const handleChange = (items: any, file: any, fileList: any) => {
// console.log(file);
// for (let elem of file) {
// elem.url = elem.data;
// }
// };
return (
<PageHeaderWrapper
onBack={() => history.goBack()}
title={
<>
<div className={style.headerTop}>
<span>返回</span>
<span>
{props.location.query.type === 'add'
? '新建会员'
: props.location.query.type === 'change'
? '编辑会员'
: '查看会员'}
</span>
</div>
</>
}
extra={
<>
<Button
className={style.saveBtn}
icon={<ContainerOutlined />}
onClick={() => actions.submit()}
>
保存
</Button>
</>
}
>
<Card>
<Form
editable={editable}
labelCol={3}
wrapperCol={10}
labelAlign="left"
actions={actions}
>
<Tabs
tabBarGutter={30}
activeKey={actived}
onChange={activeKey => setActived(activeKey)}
>
<TabPane
tab={
// <Badge count={tabCount['1']} offset={[10, 0]}>
'基本信息'
// </Badge>
}
key="-1"
>
<FormItem
label="会员类型"
name="memberTypes"
dataSource={memberItems.memberTypes}
rules={[{ required: true, message: '请选择会员类型!' }]}
component={Select}
/>
<FormItem
label="会员角色"
name="memberRoles"
dataSource={memberItems.memberRoles}
rules={[{ required: true, message: '请选择会员角色!' }]}
component={Select}
/>
<FormItem
label="会员等级"
name="memberLevels"
dataSource={memberItems.memberLevels}
rules={[{ required: true, message: '请选择会员等级!' }]}
component={Select}
/>
<FormItem
label={
<>
<span className={style.required}>*</span>
注册手机号
</>
}
name="registry"
>
<Row gutter={10}>
<Col span={6}>
<FormItem
itemStyle={{ marginBottom: 0 }}
name="country"
dataSource={memberItems.countryCodes}
rules={[{ required: true, message: '请选择会员角色!' }]}
component={Select}
/>
</Col>
<Col span={18}>
<FormItem
name="phoneMobile"
itemStyle={{ marginBottom: 0 }}
rules={[{ required: true, message: '请选择会员角色!' }]}
component={Input}
/>
</Col>
</Row>
</FormItem>
<FormItem
label="注册邮箱"
name="memberEmail"
itemStyle={{ marginBottom: 0 }}
component={Input}
/>
</TabPane>
{memberItems.groups &&
memberItems.groups.map((item: any, index: number) => {
return (
<TabPane
tab={
// <Badge count={tabCount['1']} offset={[10, 0]}>
item.groupName
// </Badge>
}
key={index}
>
{item.elements.map((items: any, indexs: number) => {
return (
<div key={indexs}>
{items.fieldType === 'String' ? (
<FormItem
itemStyle={
item.elements.length - 1 === indexs
? { marginBottom: 0 }
: {}
}
label={items.fieldCNName}
name={items.fieldName}
required={items.fieldEmpty === 0}
// rules={items.checkRules}
component={Input}
key={indexs}
/>
) : (
<FormItem
itemStyle={
item.elements.length - 1 === indexs
? { marginBottom: 0 }
: {}
}
label={items.fieldCNName}
name={items.fieldName}
>
<Upload
action="/api/file/file/upload"
listType="picture-card"
fileList={fileList}
data={{ fileType: 2 }}
onChange={(info: any) =>
setFileList(info.fileList)
}
>
{fileList.length >= 8 ? null : (
<div>
<PlusOutlined />
<div className="ant-upload-text">
Upload
</div>
</div>
)}
</Upload>
</FormItem>
// <FormItem
// itemStyle={
// item.elements.length - 1 === indexs
// ? { marginBottom: 0 }
// : {}
// }
// label={items.fieldCNName}
// name={items.fieldName}
// action="/api/file/file/upload"
// listType="picture-card"
// required={items.fieldEmpty === 0}
// fileList={fileList}
// // rules={items.checkRules}
// data={{ fileType: 2 }}
// beforeUpload={beforeUpload}
// onChange={(file: any, fileList: any) =>
// handleChange(items, file, fileList)
// }
// showUploadList={{
// showRemoveIcon:
// items.value && items.value.length > 0,
// }}
// key={indexs}
// component={Upload}
// />
)}
</div>
);
})}
</TabPane>
);
})}
</Tabs>
</Form>
</Card>
</PageHeaderWrapper>
);
};
export default addMember;
...@@ -51,9 +51,9 @@ const memberMaintain: React.FC<[]> = () => { ...@@ -51,9 +51,9 @@ const memberMaintain: React.FC<[]> = () => {
memberType: 0, // 会员类型 memberType: 0, // 会员类型
level: 0, // 会员等级 level: 0, // 会员等级
source: 0, // 注册来源 source: 0, // 注册来源
innerStatus: 0, // 内部状态 innerStatus: ['0'], // 内部状态
outerStatus: 0, // 外部状态 outerStatus: ['0'], // 外部状态
status: 0, // 会员状态 status: ['0'], // 会员状态
timeRange: 0, // 申请时间 timeRange: 0, // 申请时间
startDate: '', // 申请开始时间 startDate: '', // 申请开始时间
endDate: '', // 申请结束时间 endDate: '', // 申请结束时间
...@@ -134,6 +134,7 @@ const memberMaintain: React.FC<[]> = () => { ...@@ -134,6 +134,7 @@ const memberMaintain: React.FC<[]> = () => {
key: 'memberStatus', key: 'memberStatus',
filters: [], filters: [],
filteredValue: searchForm.memberStatus || ['0'], filteredValue: searchForm.memberStatus || ['0'],
filterMultiple: false,
render: (text: any, record: any) => { render: (text: any, record: any) => {
let component: ReactNode = null; let component: ReactNode = null;
component = ( component = (
...@@ -155,6 +156,7 @@ const memberMaintain: React.FC<[]> = () => { ...@@ -155,6 +156,7 @@ const memberMaintain: React.FC<[]> = () => {
key: 'outerStatus', key: 'outerStatus',
filters: [], filters: [],
filteredValue: searchForm.outerStatus || ['0'], filteredValue: searchForm.outerStatus || ['0'],
filterMultiple: false,
render: (text: any, record: any) => { render: (text: any, record: any) => {
let component: ReactNode = null; let component: ReactNode = null;
component = ( component = (
...@@ -180,6 +182,7 @@ const memberMaintain: React.FC<[]> = () => { ...@@ -180,6 +182,7 @@ const memberMaintain: React.FC<[]> = () => {
key: 'innerStatus', key: 'innerStatus',
filters: [], filters: [],
filteredValue: searchForm.innerStatus || ['0'], filteredValue: searchForm.innerStatus || ['0'],
filterMultiple: false,
render: (text: any, record: any) => { render: (text: any, record: any) => {
let component: ReactNode = null; let component: ReactNode = null;
component = ( component = (
...@@ -290,17 +293,6 @@ const memberMaintain: React.FC<[]> = () => { ...@@ -290,17 +293,6 @@ const memberMaintain: React.FC<[]> = () => {
}; };
useEffect(() => { useEffect(() => {
if (!isFirst) return;
let timeRanges = timeRange(searchForm.timeRange);
// setIsFirst(false);
// setSearchForm({
// ...searchForm,
// startDate: timeRanges.st,
// endDate: timeRanges.et,
// });
}, [searchForm.timeRange]);
useEffect(() => {
if (!isFirst) return setIsFirst(true); if (!isFirst) return setIsFirst(true);
ref.current.reload(); ref.current.reload();
}, [ }, [
...@@ -311,6 +303,19 @@ const memberMaintain: React.FC<[]> = () => { ...@@ -311,6 +303,19 @@ const memberMaintain: React.FC<[]> = () => {
]); ]);
useEffect(() => { useEffect(() => {
// if (!isFirst) return;
// setIsFirst(false);
let timeRanges = timeRange(searchForm.timeRange);
setSearchForm({
...searchForm,
startDate: timeRanges.st,
endDate: timeRanges.et,
});
ref.current.reload();
// console.log(timeRanges);
}, [searchForm.timeRange]);
useEffect(() => {
PublicApi.getMemberMaintenancePageitems().then(res => { PublicApi.getMemberMaintenancePageitems().then(res => {
Promise.all([ Promise.all([
processData(res.data.memberStatus), processData(res.data.memberStatus),
...@@ -335,9 +340,9 @@ const memberMaintain: React.FC<[]> = () => { ...@@ -335,9 +340,9 @@ const memberMaintain: React.FC<[]> = () => {
memberType: 0, memberType: 0,
level: 0, level: 0,
source: 0, source: 0,
innerStatus: 0, innerStatus: ['0'],
outerStatus: 0, outerStatus: ['0'],
status: 0, status: ['0'],
timeRange: 0, timeRange: 0,
startDate: '', startDate: '',
endDate: '', endDate: '',
......
import React from 'react';
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
export const maintianSchema: ISchema = {
type: 'object',
properties: {
megaLayout: {
type: 'object',
'x-component': 'mega-layout',
properties: {
search: {
type: 'string',
'x-component': 'Search',
'x-mega-props': {},
'x-component-props': {
placeholder: '请输入仓位名称',
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'mega-layout',
visible: false,
'x-component-props': {
inline: true,
},
properties: {
productName: {
type: 'string',
'x-component-props': {
placeholder: '商品名称',
},
},
productId: {
type: 'string',
'x-component-props': {
placeholder: '商品ID',
},
},
category: {
type: 'string',
'x-component-props': {
placeholder: '请选择品类',
},
enum: [],
},
brand: {
type: 'string',
'x-component-props': {
placeholder: '请选择品牌',
},
enum: [],
},
submit: {
'x-component': 'Submit',
'x-component-props': {
children: '查询',
},
},
},
},
},
},
},
};
const registryPhone = <></>;
const getCompnentValue = (elements: any) => {
let components = {};
for (let item of elements) {
let xComponentProps =
item.fieldType === 'string'
? {
placeholder: item.fieldRemark,
}
: {
listType: 'card',
action: '/api/file/file/upload',
data: { fileType: 2 },
};
components[item.fieldName] = {
type: item.fieldType,
required: item.fieldEmpty === 0,
title: item.fieldCNName,
'x-component-props': xComponentProps,
};
}
return components;
};
export const initDetailSchema = (props: any) => {
let tabSchema = {
properties: {
'tab-1': {
type: 'object',
'x-component': 'tabpane',
'x-component-props': {
tab: '基本信息',
},
properties: {
MEGA_LAYOUT1: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
labelCol: 4,
wrapperCol: 8,
labelAlign: 'left',
},
properties: {
memberTypes: {
type: 'string',
required: true,
title: '会员类型',
enum: props.memberTypes,
'x-component-props': {
placeholder: '请选择',
},
},
memberRoles: {
type: 'string',
required: true,
title: '会员角色',
enum: props.memberRoles,
'x-component-props': {
placeholder: '请选择',
},
},
memberLevels: {
type: 'string',
required: true,
title: '会员等级',
enum: [{ label: '1', value: 1 }],
// enum: props.memberLevels,
'x-component-props': {
placeholder: '请选择',
},
},
memberPhone: {
type: 'object',
required: true,
title: '注册手机',
'x-component': 'CustomRegistryPhone',
'x-component-props': {
dataSource: [
{
text: '+86',
id: 1,
url: require('../../../../../public/static/imgs/level1@2x.png'),
},
{
text: '+126',
id: 2,
url: require('../../../../../public/static/imgs/level2@2x.png'),
},
],
selectPh: '请选择',
inputPh: '请输入你的手机号码',
},
},
memberEmail: {
type: 'string',
title: '邮箱',
'x-component-props': {},
},
},
},
},
},
},
};
if (Object.keys(props).length > 0) {
for (let [index, item] of props.groups.entries()) {
tabSchema.properties[`tab-${index + 2}`] = {
type: 'object',
'x-component': 'tabpane',
'x-component-props': {
tab: item.groupName,
},
properties: {
[`MEGA_LAYOUT${index + 2}`]: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
labelCol: 4,
wrapperCol: 8,
labelAlign: 'left',
},
properties: getCompnentValue(item.elements),
},
},
};
}
}
let detailSchema = {
type: 'object',
properties: {
REPOSIT_TABS: {
type: 'object',
'x-component': 'tab',
'x-component-props': {},
...tabSchema,
},
},
};
const maintianDetailSchema: ISchema = detailSchema;
return maintianDetailSchema;
};
import React from 'react'; import React from 'react';
import AuditDetail from '../components/auditDetail'; import AuditDetail from '../components/auditDetail';
const auditPr = () => { const auditPr = (props: any) => {
return <AuditDetail auditType="2" />; return <AuditDetail auditType="2" routeParams={props.location.query} />;
}; };
export default auditPr; export default auditPr;
import React from 'react';
import AuditDetail from '../components/auditDetail';
const auditPr = (props: any) => {
return <AuditDetail auditType="2" routeParams={props.location.query} />;
};
export default auditPr;
import React from 'react';
import AuditList from '../components/auditList';
const memberPr = () => {
return <AuditList pageType="3" />;
};
export default memberPr;
import React from 'react'; import React from 'react';
import AuditDetail from '../components/auditDetail'; import AuditDetail from '../components/auditDetail';
const auditPrConfirm = () => { const auditPrConfirm = (props: any) => {
return <AuditDetail auditType="3" />; return <AuditDetail auditType="3" routeParams={props.location.query} />;
}; };
export default auditPrConfirm; export default auditPrConfirm;
...@@ -2,7 +2,7 @@ import React from 'react'; ...@@ -2,7 +2,7 @@ import React from 'react';
import AuditList from '../components/auditList'; import AuditList from '../components/auditList';
const memberPrConfirm = () => { const memberPrConfirm = () => {
return <AuditList pageType="3" />; return <AuditList pageType="4" />;
}; };
export default memberPrConfirm; export default memberPrConfirm;
import React from 'react'; import React from 'react';
import AuditDetail from '../components/auditDetail'; import AuditDetail from '../components/auditDetail';
const auditPrSubmit = () => { const auditPrSubmit = (props: any) => {
return <AuditDetail auditType="1" />; return <AuditDetail auditType="1" routeParams={props.location.query} />;
}; };
export default auditPrSubmit; export default auditPrSubmit;
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -135,6 +135,20 @@ export const getAsyncSelectList = async (asyncList: any[]) => { ...@@ -135,6 +135,20 @@ export const getAsyncSelectList = async (asyncList: any[]) => {
} }
} }
export const findItemAndDelete = (arr: any[], target) => {
const newArr = [...arr]
if (newArr.length > 0 && isObject(newArr[0])) {
return newArr.filter(v => v.id !== target)
}
const targetIndex = arr.indexOf(target)
if (targetIndex === -1) {
return newArr
} else {
newArr.splice(targetIndex, 1)
return newArr
}
}
export default { export default {
isArray, isArray,
isObject, isObject,
......
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