Commit ec119f2e authored by LeeJiancong's avatar LeeJiancong

新增物流模板

parents 4183cf29 9743ea94
......@@ -22,3 +22,4 @@
# mockStatic
/.idea
config/base.config.json
{"global":{"logo":"http://lingxi-frontend-test.oss-cn-hangzhou.aliyuncs.com/images/logo.png","countryList":[{"name":"简体中文-ZH","key":"cn","icon":"http://lingxi-frontend-test.oss-cn-hangzhou.aliyuncs.com/images/china.png"},{"name":"English-EN","key":"en","icon":"http://lingxi-frontend-test.oss-cn-hangzhou.aliyuncs.com/images/us.png"},{"name":"日本語-JP","key":"jp","icon":"http://lingxi-frontend-test.oss-cn-hangzhou.aliyuncs.com/images/japen.png"},{"name":"한국어-KO","key":"ko","icon":"http://lingxi-frontend-test.oss-cn-hangzhou.aliyuncs.com/images/koren.png"}]}}
{"userRegister":{"useType":{"memberType":[{"id":1,"typeName":"企业会员"},{"id":2,"typeName":"个人会员"},{"id":3,"typeName":"渠道企业会员"},{"id":4,"typeName":"渠道个人会员"}],"businessType":[{"id":1,"typeName":"new11"},{"id":2,"typeName":"王者农药"}]},"useDetail":[{"groupName":"企业组","elements":[{"id":2,"fieldName":"company","fieldCNName":"企业","fieldType":null,"fieldLength":10,"fieldEmpty":0,"fieldOrder":1,"fieldRemark":"test","checkRules":[]}]},{"groupName":"企业信息","elements":[{"id":3,"fieldName":"company_name","fieldCNName":"公司名称","fieldType":null,"fieldLength":128,"fieldEmpty":1,"fieldOrder":1,"fieldRemark":"","checkRules":[]},{"id":4,"fieldName":"company_type","fieldCNName":"公司类型","fieldType":null,"fieldLength":128,"fieldEmpty":0,"fieldOrder":2,"fieldRemark":"","checkRules":[]}]},{"groupName":"444","elements":[{"id":1,"fieldName":"444","fieldCNName":"44","fieldType":null,"fieldLength":44,"fieldEmpty":1,"fieldOrder":44,"fieldRemark":null,"checkRules":[]}]}]},"global":{"logo":"http://lingxi-frontend-test.oss-cn-hangzhou.aliyuncs.com/images/logo.png","countryList":[{"name":"简体中文-ZH","key":"cn","icon":"http://lingxi-frontend-test.oss-cn-hangzhou.aliyuncs.com/images/china.png"},{"name":"English-EN","key":"en","icon":"http://lingxi-frontend-test.oss-cn-hangzhou.aliyuncs.com/images/us.png"},{"name":"日本語-JP","key":"jp","icon":"http://lingxi-frontend-test.oss-cn-hangzhou.aliyuncs.com/images/japen.png"},{"name":"한국어-KO","key":"ko","icon":"http://lingxi-frontend-test.oss-cn-hangzhou.aliyuncs.com/images/koren.png"}]}}
......@@ -54,7 +54,7 @@ export default defineConfig({
},
// icon
// favicon: '',
hash: true,
hash: false,
/**
* 会自动添加到网页html的顶部
*/
......
......@@ -34,7 +34,7 @@ const mockData = {
exports.fetchConfig = async () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(mockData)
resolve(mockData.data)
}, 2* 1000)
})
}
\ No newline at end of file
......@@ -27,7 +27,7 @@
"@umijs/preset-react": "1.x",
"@umijs/test": "^3.2.0",
"bizcharts": "^4.0.7",
"god": "0.1.7",
"god": "0.1.11",
"lint-staged": "^10.0.7",
"mobx": "^5.15.4",
"mobx-react": "^6.2.2",
......@@ -41,7 +41,9 @@
},
"devDependencies": {
"@types/qrcode": "^1.3.4",
"axios": "^0.19.2",
"chalk": "^4.1.0",
"clone": "^2.1.2",
"fs-extra": "^9.0.1",
"gulp": "^4.0.2",
"json2ts": "^0.0.7",
......
......@@ -2,7 +2,9 @@ const path = require('path')
const Logs = require('./utils/log')
const fse = require('fs-extra')
const Type = require('./utils/type')
const fetchConfig = require('../demo').fetchConfig
const runFile = './services'
const fetchConfig = require(runFile).fetchConfig
const gulp = require('gulp')
const json2ts = require('json2ts')
......@@ -56,5 +58,5 @@ function genarateDtsFile(json, done) {
*/
async function getAsyncConfig(done) {
const data = await fetchConfig()
genarateBaseJson(data.data, done)
genarateBaseJson(data, done)
}
\ No newline at end of file
/**
* 用于在项目开始前获取所有的配置
* 在项目开始前运行`yarn scripts:build`
* @todo 缺少异常处理清空
* @author xjm
*/
const Axios = require('axios').default;
const deepClone = require('clone')
const demoFetch = require('../../demo').fetchConfig
const isDemo = true
const axios = Axios.create({
baseURL: 'http://10.0.0.25:8100',
responseType: 'json',
})
const serviceConfig = {
// 用于注册页
userRegister: {
useType: {
url: '/member/menu/register/type',
method: 'get'
},
useDetail: {
url: '/member/menu/register/detail',
method: 'get'
}
}
}
// 批量组装接口
async function batchAxiosHttps() {
const asyncHttpQueue = deepClone(serviceConfig)
for (const item in serviceConfig) {
for (const subItem in serviceConfig[item]) {
const data = await axios(serviceConfig[item][subItem])
asyncHttpQueue[item][subItem] = data.data.data
}
}
return isDemo ? Object.assign(asyncHttpQueue, await demoFetch()) : asyncHttpQueue
}
exports.fetchConfig = batchAxiosHttps
\ No newline at end of file
......@@ -5,7 +5,10 @@ import MobxProvider from './store'
import '@/global/styles/global.less'; // 导入全局样式
let extraRoutes: never[] = []
// 默认引入所有的ant样式, 不引入css因为无法做到变量覆盖
import 'antd/dist/antd.less'
let extraRoutes = []
/**
* @description 配置函数,对已配置的路由做修改, 一般与render函数一起结合可根据接口动态配置路由
......
......@@ -4,7 +4,7 @@ import styles from './index.less'
export interface TextLinkProps {
url: string,
}
const TextLink:React.FC = (props) => {
const TextLink:React.FC<any> = (props) => {
return (
<span className={styles.link}>
{props.children}
......
export interface MemberType {
id: number;
typeName: string;
}
export interface BusinessType {
id: number;
typeName: string;
}
export interface UseType {
memberType: MemberType[];
businessType: BusinessType[];
}
export interface Element {
id: number;
fieldName: string;
fieldCNName: string;
fieldType?: any;
fieldLength: number;
fieldEmpty: number;
fieldOrder: number;
fieldRemark: string;
checkRules: any[];
}
export interface UseDetail {
groupName: string;
elements: Element[];
}
export interface UserRegister {
useType: UseType;
useDetail: UseDetail[];
}
export interface CountryList {
name: string;
key: string;
......@@ -10,5 +47,6 @@ export interface Global {
}
export interface RootObject {
userRegister: UserRegister;
global: Global;
}
\ No newline at end of file
......@@ -85,3 +85,13 @@ h1, h2, h3, h4, h5, h6 {
.commonStatus();
background-color: @status-invalid; // 无效、未生成
}
.sc-fzpans {
display: block;
width: 100%;
}
// 间距
.mr_t-40 {
margin-top: 40px;
}
\ No newline at end of file
......@@ -2,7 +2,7 @@
* @Author: LeeJiancong
* @Date: 2020-07-15 10:31:55
* @LastEditors: LeeJiancong
* @LastEditTime: 2020-07-16 18:09:37
* @LastEditTime: 2020-07-17 18:04:19
*/
import React, { Component, useState,useEffect } from 'react';
import ReactDOM from 'react-dom'
......@@ -22,6 +22,12 @@ import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { MegaLayout, Input, Switch, Select, FormMegaLayout } from '@formily/antd-components'
import ReutrnEle from '@/components/ReturnEle'
import 'antd/dist/antd.css'
let selectList: any = [
{ label: '+86', value: '1' },
{ label: 'Two', value: '2' },
{ label: 'Three', value: '3' },
{ label: 'Four', value: '4' }
];
import ChinaImg from '../../../../../mockStatic/china.png'
import gou from '../../../../../mockStatic/gou.png'
import japenImg from '../../../../../mockStatic/japen.png'
......
......@@ -107,6 +107,10 @@
margin-bottom: 0;
}
}
.registerForm {
max-width: 335px;
margin: 40px auto;
}
.registerBox {
width: 100%;
......@@ -144,13 +148,14 @@
}
.continueButton{
.make-center(block);
width: 320px;
width: 340px;
height: 40px;
.make-center-space(margin, 8);
}
.identityRadio{
display: flex;
flex-direction: column;
margin: 0 auto;
.make-center(text);
& label{
width: 320px;
......@@ -284,3 +289,7 @@
}
}
}
.mr_t-40 {
margin-top: 40px;
}
\ No newline at end of file
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
[x: string]: string | undefined;
'adBox': string;
'businessRadio': string;
'commonPanelTitle': string;
'continueButton': string;
'description': string;
'formBefore': string;
'formBoxStep1': string;
'formBoxStep2': string;
'formBoxStep3': string;
'guid': string;
'identityRadio': string;
'lingxi-business-content1024': string;
'lingxi-business-margin_content': string;
'lingxiBusinessContent1024': string;
'lingxiBusinessMarginContent': string;
'login-ctl': string;
'login-item': string;
'loginCtl': string;
'loginDesc': string;
'loginItem': string;
'loginMain': string;
'loginVerBtn': string;
'loginWrap': string;
'mb-10': string;
'mb-100': string;
'mb-20': string;
'mb-30': string;
'mb-50': string;
'mb10': string;
'mb100': string;
'mb20': string;
'mb30': string;
'mb50': string;
'ml-10': string;
'ml-100': string;
'ml-20': string;
'ml-30': string;
'ml-50': string;
'ml10': string;
'ml100': string;
'ml20': string;
'ml30': string;
'ml50': string;
'mr-10': string;
'mr-100': string;
'mr-20': string;
'mr-30': string;
'mr-50': string;
'mr10': string;
'mr100': string;
'mr20': string;
'mr30': string;
'mr50': string;
'mt-10': string;
'mt-100': string;
'mt-20': string;
'mt-30': string;
'mt-50': string;
'mt10': string;
'mt100': string;
'mt20': string;
'mt30': string;
'mt50': string;
'qrcodeLogin': string;
'register': string;
'registerBox': string;
'scanLoginWrap': string;
'scanTips': string;
'stepWrap': string;
'thirdLogin': string;
}
export const cssExports: CssExports;
export default cssExports;
import React, { useState, useEffect } from 'react'
import { Input, Form, Steps, Button, Row, Col, Radio, Divider, Tooltip, Upload, message } from 'antd'
import { Form, Steps, Button, Row, Col, Radio, Divider, Tooltip, Upload, message, Input as AntdInput } from 'antd'
import {
UploadOutlined,
QuestionCircleOutlined
......@@ -12,10 +12,16 @@ import { IFormControllers, IFormButtonTypes } from 'god/dist/src/form-page'
import { Link, history } from 'umi'
import im_success from '../../../mockStatic/im_success.png'
import { postMemberRegister, getRegisterTypeList, postMemberRegisterType } from '@/services/member'
import { FormStep, FormBlock, Input, Password, Checkbox } from '@formily/antd-components'
import SchemaForm, { Field, FormMegaLayout, FormButtonGroup, createFormActions, FormEffectHooks } from '@formily/antd';
import useCountDown from '@/utils/hooks';
import { GlobalConfig } from '@/global/config';
const { TextArea } = Input;
const Step = Steps.Step
const { onFieldValueChange$ } = FormEffectHooks
const formItemLayout = {
labelCol: {
span: 2,
......@@ -27,310 +33,70 @@ const formItemLayout = {
},
};
const stepList = [
{ title: '填写信息', key: 'message' },
{ title: '完善资料', key: 'over' },
{ title: '等待审核', key: 'wait' },
{ title: '注册成功', key: 'success' },
]
const registerForm: IFormControllers[] = [
{
type: 'Input',
name: 'phone',
span: 24,
inputProps: {
addonBefore: <div className={styles.formBefore}>+86</div>,
placeholder: '请输入你的手机号码',
size: 'large',
},
rules: [
{ required: true, message: '手机号为必填项!' }
]
},
{
type: 'Verification',
name: 'smsCode',
span: 24,
inputProps: {
size: 'large',
}
},
{
type: 'Input',
name: 'password',
span: 24,
inputProps: {
type: 'password',
placeholder: '设置你的密码',
size: 'large',
},
rules: [
{ required: true, message: '密码为必填项!' },
{ pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,20}$/, message: '密码长度8-20个字符,必须包含大小写字母和数字!' }
],
},
let formCache: any = {}
const CustomCheckbox = props => {
const { layout } = props
return (
<Radio.Group value={props.value} onChange={props.onChange} className={layout === 'column' ? styles.identityRadio : styles.businessRadio} name={props.name}>
{
type: 'Input',
name: 'confirm',
span: 24,
dependencies: ['password'],
inputProps: {
type: 'password',
placeholder: '请再次输入你的登录密码',
size: 'large',
},
rules: [
{ required: true, message: '请再次确认密码!' },
({ getFieldValue }) => ({
validator(rule, value) {
if (!value || getFieldValue('password') === value) {
return Promise.resolve();
props.dataSource && props.dataSource.map((v, i) => <Radio.Button value={v.value} key={v.value + i}>{v.label}</Radio.Button>)
}
return Promise.reject('两次的密码输入不一致!');
},
}),
]
},
{
type: 'Input',
name: 'email',
span: 24,
inputProps: {
type: 'email',
placeholder: '请输入你的邮箱(选填)',
size: 'large',
</Radio.Group>
)
}
const CustomInput = props => {
const { help } = props
return (
<AntdInput
value={props.value}
onChange={props.onChange}
addonAfter={help ? <Tooltip title={help}><QuestionCircleOutlined style={{color: '#6B778C', marginLeft: 5}}/></Tooltip> : undefined}
/>
)
}
// 检验联动
const useLinkageValidateEffects = () => {
const { setFieldState, getFieldState } = createFormActions()
onFieldValueChange$('*(password,confirmPassword)').subscribe(fieldState => {
const selfName = fieldState.name
const selfValue = fieldState.value
const otherName = selfName == 'password' ? 'confirmPassword' : 'password'
const otherValue = getFieldState(otherName, state => state.value)
setFieldState(otherName, state => {
if (selfValue && otherValue && selfValue !== otherValue) {
state.errors = ['两次密码输入不一致']
} else {
state.errors = ['']
}
},
{
type: 'Agreement',
name: 'readme',
span: 24,
labelCol: {
span: 22,
order: 2,
},
wrapperCol: {
span: 2,
order: 1,
},
style: {overflow: 'visible'},
label: <span style={{fontSize:12,overflow:'visible'}}>阅读并同意<Link to='/'>《会员服务协议》</Link><Link to='/'>《法律条款》</Link><Link to='/user/policy'>《隐私政策》</Link></span>,
colon: false,
},
{
span: 24,
// @ts-ignore
custom: () => <Row>
<Button type='primary' className={styles.continueButton} htmlType="submit">同意协议并注册</Button>
</Row>
})
setFieldState(selfName, state => {
if (selfValue && otherValue && selfValue !== otherValue) {
state.errors = ['两次密码输入不一致']
} else {
state.errors = ['']
}
]
// const registerButtons: IFormButtonTypes[] = [
// {
// text: '同意协议并注册',
// type: 'primary',
// htmlType: 'submit',
// block: true,
// disabled: false,
// }
// ]
})
})
}
let timeChange: any; // 定时器
const actions = createFormActions()
const UserRegistry = () => {
const [identityForm1] = Form.useForm();
const [licenseForm] = Form.useForm();
const [current, setCurrent] = useState(0)
const [identityFormData, setIdentityFormData] = useState<IFormControllers[]>([])
const [licenseFormData, setLicenseFormData] = useState<IFormControllers[]>([])
useEffect(() => {
const identityForm: IFormControllers[] = [
{
span: 24,
custom: () => <>
<h3 className={styles.commonPanelTitle}>请选择您的身份</h3>
<Divider />
</>
},
{
span: 24,
custom: () => <Form.Item name='typeId' initialValue="a">
<Radio.Group onChange={onChange} className={styles.identityRadio} name="typeId">
<Radio.Button value="a">企业</Radio.Button>
<Radio.Button value="b">个人</Radio.Button>
</Radio.Group>
</Form.Item>
},
{
span: 24,
custom: () => <>
<h3 className={styles.commonPanelTitle}>请选择您要开展的业务</h3>
<Divider />
</>
},
{
span: 24,
custom: () => <Form.Item name='businessTypeId' initialValue="f">
<Radio.Group onChange={onChange} className={styles.businessRadio} name="businessTypeId">
<Radio.Button value="c">采购</Radio.Button>
<Radio.Button value="d">商品销售</Radio.Button>
<Radio.Button value="e">加工服务</Radio.Button>
<Radio.Button value="f">物流服务</Radio.Button>
<Radio.Button value="g">金融服务</Radio.Button>
<Radio.Button value="h">保险服务</Radio.Button>
</Radio.Group>
</Form.Item>
},
{
span: 24,
custom: () => <Row>
<Button type='primary' className={styles.continueButton} htmlType="submit">下一步:继续</Button>
</Row>
}
const stepList = [
{ title: '填写信息', key: 'message', name: 'message' },
{ title: '完善资料', key: 'over', name: 'over' },
{ title: '等待审核', key: 'wait', name: 'wait' },
{ title: '注册成功', key: 'success', name: 'success' },
]
setIdentityFormData(identityForm)
}, [])
useEffect(() => {
const licenseForm: IFormControllers[] = [
{
span: 24,
custom: () => <>
<h3 className={styles.commonPanelTitle}>请填写营业执照信息</h3>
<Divider />
</>
},
// @ts-ignore
[{
type: 'Input',
name: 'companyName',
label: <>
<Tooltip title="请填写法定代表人信息请填请填写法定代表人信息请填写法定代表人信息请填写法定代表人信息请填写法定代表人信息请填写法定代表人信息">
<QuestionCircleOutlined />
</Tooltip>
</>,
span: 12,
rules: [
{
required: true,
message: '请输入公司名称'
},
],
inputProps: {
placeholder: '请输入公司名称(必填)',
size: 'large',
}
},
{
type: 'Input',
name: 'companyType',
label: <>
<Tooltip title="请填写法定代表人信息请填请填写法定代表人信息请填写法定代表人信息请填写法定代表人信息请填写法定代表人信息请填写法定代表人信息">
<QuestionCircleOutlined />
</Tooltip>
</>,
span: 12,
rules: [
{
required: true,
message: '请输入企业类型'
},
],
inputProps: {
placeholder: '请输入企业类型(必填)',
size: 'large',
}
}],
{
type: 'TextArea',
name: 'business',
label: <>
<Tooltip title="请填写法定代表人信息请填请填写法定代表人信息请填写法定代表人信息请填写法定代表人信息请填写法定代表人信息请填写法定代表人信息">
<QuestionCircleOutlined />
</Tooltip>
</>,
span: 24,
labelCol: {
span: 1,
order: 2
},
wrapperCol: {
span: 23,
order: 1
},
rules: [
{
required: true,
message: '请输入经营范围'
},
],
inputProps: {
placeholder: '请输入经营范围(必填)',
size: 'large',
}
},
{
span: 12,
custom: () =>
<Form.Item
name="runLicense"
valuePropName="fileList"
getValueFromEvent={normFile}
extra="附件大小不能超过5M"
rules={[
{
required: true,
message: '营业执照附件为必须项!'
},
{
validator: checkoutFile
}
]}
>
<Upload name="logo" action="/upload.do" beforeUpload={beforeUpload}>
<Button>
<UploadOutlined /> 上传营业执照附件
</Button>
</Upload>
</Form.Item>
},
{
span: 24,
custom: () => <>
<h3 className={styles.commonPanelTitle}>请填写法定代表人信息</h3>
<Divider />
</>
},
{
type: 'Input',
name: 'legalInfo',
label: <>
<Tooltip title="请填写法定代表人信息请填请填写法定代表人信息请填写法定代表人信息请填写法定代表人信息请填写法定代表人信息请填写法定代表人信息">
<QuestionCircleOutlined />
</Tooltip>
</>,
span: 12,
rules: [
{
required: true,
message: '请输入法人身份证号码'
},
],
inputProps: {
placeholder: '请输入法人身份证号码(必填)',
size: 'large',
}
},
{
span: 24,
custom: () => <Row>
<Button type='primary' className={styles.continueButton} htmlType="submit">下一步:继续</Button>
</Row>
}
]
setLicenseFormData(licenseForm)
}, [])
const handleOneSubmit = (values: any) => {
let obj = { ...values }
......@@ -369,22 +135,22 @@ const UserRegistry = () => {
}
const [time, setTime] = useState(5); // timer
useEffect(() => {
clearInterval(timeChange)
handleRegisterTypeList()
}, [])
useEffect(() => {
console.log(current)
if(current === 2) runTimerJump()
}, [current])
useEffect(() => {
if(time === 0){
clearInterval(timeChange)
setTime(60)
history.push('/user/login')
console.log('执行登录跳转!')
}
}, [time])
// useEffect(() => {
// clearInterval(timeChange)
// handleRegisterTypeList()
// }, [])
// useEffect(() => {
// console.log(current)
// if(current === 2) runTimerJump()
// }, [current])
// useEffect(() => {
// if(time === 0){
// clearInterval(timeChange)
// setTime(60)
// history.push('/user/login')
// console.log('执行登录跳转!')
// }
// }, [time])
const runTimerJump = () => {
timeChange = setInterval(() => setTime(t => --t), 1000)
}
......@@ -420,28 +186,154 @@ const UserRegistry = () => {
return isLt5M;
}
const {text, isActive, start} = useCountDown({
maxTime: 60,
minTime: 0,
initText: '获取验证码',
onEnd: () => {},
decayRate: 1,
delay: 1 * 1000
})
const handleActionBtn = () => {
actions.dispatch('onFormStepNext', () => {
setCurrent(current + 1)
})
// FormStep
// FormStep.onStepNext$()
}
const mapMemberType = GlobalConfig.userRegister.useType.memberType.map(v => {
return {
value: v.id,
label: v.typeName
}
})
const mapServerType = GlobalConfig.userRegister.useType.businessType.map(v => {
return {
value: v.id,
label: v.typeName
}
})
const submitForm = () => {
actions.submit().then(data => {
const { values } = data
formCache = Object.assign(values, formCache)
// 写死传入的区号
formCache.countryCode = '+86'
console.log(formCache)
})
}
return (
<div className={cx(styles.register, globalStyles.lingxiBusinessContent1024)}>
<h3>欢迎您注册数商云账号</h3>
<div className={cx(styles.registerBox, globalStyles.lingxiBusinessMarginContent)}>
<Steps current={current} className={styles.stepWrap} size='small'>
<div>
<SchemaForm
actions={actions}
components={{
Input,
Password,
CheckboxSingle: Checkbox,
CustomRadio: CustomCheckbox,
CustomInput
}}
effects={() => {
useLinkageValidateEffects()
}}
onValidateFailed={valid => console.log(valid)}
>
<FormStep
dataSource={stepList}
className={styles.stepWrap}
size='small'
current={current}
>
</FormStep>
<FormMegaLayout className={styles.registerForm} name='message'>
<Field name="phone" x-rules={{required: true, pattern: /^1[3|4|5|6|7|8|9][0-9]{9}$/}} x-component-props={{placeholder: '请输入你的手机号码', size: 'large'}} x-props={{addonBefore: <div className={styles.formBefore}>+86</div>}} x-component="Input" />
<Field name="smsCode" x-rules={{required: true, pattern: /^\d{6}$/}} x-component-props={{ size: 'large', style: {width: 220}}} x-props={{addonAfter: <Button disabled={isActive} style={{minWidth: 110, marginLeft: 8}} size='large' onClick={start}>{text}</Button>}} x-component="Input" />
<Field name="password" x-rules={{required: true}} x-component-props={{ placeholder: '设置你的登录密码', size: 'large'}} x-component="Password" />
<Field name="confirmPassword" x-rules={{required: true}} x-component-props={{ placeholder: '请再次输入你的登录密码',size: 'large'}} x-component="Password" />
<Field name="email" x-rules={{message: '请输入正确的邮箱', pattern: /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/}} x-component-props={{ placeholder: '请输入你的邮箱(选填)',size: 'large', type: 'email'}} x-component="Input" />
<Field name="isRead" x-rules={{message: '请勾选', required: true}} x-component-props={{
children:<span style={{fontSize: 12}}>阅读并同意<span className='commonPickColor'>《会员服务协议》《法律条款》《隐私政策》</span></span>
}} x-component="CheckBoxSingle" />
</FormMegaLayout>
<FormMegaLayout name='over' className={styles.formBoxStep2}>
<FormBlock className={styles['mr_t-40']} name='memberType' visible={current === 1} title={<span className={styles.commonPanelTitle}>请选择你的身份</span>}>
<Field
name="typeId"
x-rules={{required: true}}
x-component-props={{layout: 'column'}}
x-component='CustomRadio' enum={mapMemberType}>
</Field>
</FormBlock>
<FormBlock className={styles['mr_t-40']} name='serviceType' visible={current === 1} title={<span className={styles.commonPanelTitle}>请选择您要开展的业务</span>}>
<Field name="businessTypeId" x-rules={{required: true}} x-component-props={{layout: 'rows'}} x-component='CustomRadio' enum={mapServerType}></Field>
</FormBlock>
{/* 注册主体类型, 为多输入框 */}
<Field name='detail' type='object'>
{
stepList.map((v,i) => <Step title={v.title} key={v.key} onClick={() => {setCurrent(i)}}/>)
GlobalConfig.userRegister.useDetail.map(v => {
return (
<FormBlock className={styles['mr_t-40']} visible={current === 2} key={v.groupName} title={<span className={styles.commonPanelTitle}>{v.groupName}</span>}>
<FormMegaLayout columns={2} grid>
{
v.elements.map(field => {
// 字段类型暂时为null, 所以固定为input
return (
<Field x-mega-props={{span: 1}} name={field.fieldName} key={field.fieldName} x-component-props={{ help: field.fieldRemark}} x-component='CustomInput'></Field>
)
})
}
</Steps>
</FormMegaLayout>
</FormBlock>
)
})
}
</Field>
</FormMegaLayout>
<FormButtonGroup className={styles.registerForm}>
{
current === 0 && <div className={styles.formBoxStep1}>
<FormPage
renderFormLists={registerForm}
// renderButtonLists={registerButtons}
onSubmit={handleOneSubmit}
>
current === 0 &&
<Button type='primary' className={styles.continueButton} onClick={handleActionBtn}>同意协议并注册</Button>
}
{
current === 1 &&
<Button type='primary' className={styles.continueButton} onClick={() => {
actions.submit().then(data => {
const { values } = data
formCache = values
setCurrent(current + 1)
})
}}>下一步:继续完善</Button>
}
{
current === 2 &&
<Button type='primary' className={styles.continueButton} onClick={submitForm}>提交注册资料</Button>
}
</FormButtonGroup>
</SchemaForm>
<Row justify='center' align='middle'>
已有平台账号?<Button type='link' onClick={handleJumpLogin}>去登陆</Button>
</Row>
</FormPage>
</div>
</div>
</div>
)
return (
<div className={cx(styles.register, globalStyles.lingxiBusinessContent1024)}>
<h3>欢迎您注册数商云账号</h3>
<div className={cx(styles.registerBox, globalStyles.lingxiBusinessMarginContent)}>
<Steps current={current} className={styles.stepWrap} size='small'>
{
stepList.map((v,i) => <Step title={v.title} key={v.key} onClick={() => {setCurrent(i)}}/>)
}
</Steps>
{
current === 1 && <div className={styles.formBoxStep2}>
<FormPage
......
import React, { useState, useEffect } from 'react'
export interface UseCountDownProps {
maxTime: number,
minTime: number,
initText: React.ReactNode,
delay: number,
onEnd(): void,
decayRate: number
}
export interface ReturnValue {
start(): void,
text: React.ReactNode,
isActive: boolean
}
const useCountDown = (options: UseCountDownProps): ReturnValue => {
const [activeText, setActiveText] = useState(options.initText)
const [isOpen, setIsOpen] = useState(false)
useEffect(() => {
const { maxTime = 60, minTime = 0, initText = '获取验证码', delay = 1 * 1000, onEnd = () => {}, decayRate = 1 } = options
let activeInterval: any = null
let activeTime = maxTime
if (isOpen) {
activeInterval = setInterval(() => {
if (activeTime === minTime) {
setActiveText(initText)
setIsOpen(false)
clearInterval(activeInterval)
onEnd && onEnd()
} else {
setActiveText((activeTime -= decayRate) + 's')
}
}, delay)
}
return () => {
clearInterval(activeInterval)
}
}, [isOpen])
function start() {
if (isOpen) {
return false
}
setIsOpen(true)
setActiveText(options.maxTime + 's')
}
return {
start,
text: activeText,
isActive: isOpen
}
}
export default useCountDown
\ No newline at end of file
......@@ -7,9 +7,9 @@
"importHelpers": true,
"jsx": "react",
"esModuleInterop": true,
"noImplicitAny": false,
"sourceMap": true,
"baseUrl": "./",
"strict": true,
"paths": {
"@/*": ["src/*"],
"@mock/*": ["mockStatic/*"],
......
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