Commit a0ab05f7 authored by 前端-钟卫鹏's avatar 前端-钟卫鹏
parents db2371d2 53ba6f5f
{"userRegister":{"useType":{"memberType":[{"id":1,"typeName":"企业会员"},{"id":3,"typeName":"渠道企业会员"},{"id":4,"typeName":"渠道个人会员"},{"id":2,"typeName":"个人会员"}],"businessType":[{"id":1,"typeName":"采购"},{"id":39,"typeName":"供货"},{"id":40,"typeName":"供货商消费者"},{"id":41,"typeName":"供货商消费者渠道会员"}]}},"web":{"shopInfo":[]},"global":{"siteId":602,"siteUrl":"http://localhost:4396","logo":"https://shushangyun01.oss-cn-shenzhen.aliyuncs.com/4db4e7c5424c471c968ab540bce027f31597319423082.png","countryList":[{"name":"简体中文-ZH","key":"zh-CN","icon":"http://lingxi-frontend-test.oss-cn-hangzhou.aliyuncs.com/images/china.png"},{"name":"English-EN","key":"en-US","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"}]}}
......@@ -21,40 +21,40 @@ const LogisticsRoute = {
key: 'logistics',
routes: [
{
path: '/memberCenter/logisticsAbility/logistics/list/company',
path: '/memberCenter/logisticsAbility/logistics/company',
name: 'company',
component: '@/pages/logistics/list/company'
},
{
path: '/memberCenter/logisticsAbility/logistics/list/addCompany',
path: '/memberCenter/logisticsAbility/logistics/addCompany',
name: 'addCompany',
component: '@/pages/logistics/list/addCompany',
hideInMenu: true
},
//送货地址
{
path: '/memberCenter/logisticsAbility/logistics/list/deliveryAddress',
path: '/memberCenter/logisticsAbility/logistics/deliveryAddress',
name: 'deliveryAddress',
component: '@/pages/logistics/list/deliveryAddress'
},
{
path: '/memberCenter/logisticsAbility/logistics/list/addressForm',
path: '/memberCenter/logisticsAbility/logistics/addressForm',
name: 'addressForm',
component: '@/pages/logistics/list/components/addressForm',
hideInMenu: true
},
{
path: '/memberCenter/logisticsAbility/logistics/list/receivingAddress',
path: '/memberCenter/logisticsAbility/logistics/receivingAddress',
name: 'receivingAddress',
component: '@/pages/logistics/list/receivingAddress'
},
{
path: '/memberCenter/logisticsAbility/logistics/list/template',
path: '/memberCenter/logisticsAbility/logistics/template',
name: 'template',
component: '@/pages/logistics/list/template'
},
{
path: '/memberCenter/logisticsAbility/logistics/list/templateForm',
path: '/memberCenter/logisticsAbility/logistics/templateForm',
name: 'templateForm',
component: '@/pages/logistics/list/components/templateForm',
hideInMenu: true
......
......@@ -120,7 +120,7 @@ const MemberRoute = {
key: 'addEquity',
hideInMenu: true,
component: '@/pages/member/memberLevel/addEquity',
}
},
]
}
]
......
......@@ -43,6 +43,7 @@
"moment": "^2.27.0",
"prettier": "^1.19.1",
"qrcode": "^1.4.4",
"query-string": "^6.13.1",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-fontawesome": "^1.7.1",
......
......@@ -2,6 +2,7 @@ import { IRoutes } from '.';
import { history, RequestConfig, Redirect } from 'umi';
import React from 'react'
import MobxProvider from './store'
import queryString from 'query-string'
import '@/global/styles/reset.less'; // 重置antd样式
import '@/global/styles/global.less'; // 导入全局样式
......@@ -9,7 +10,7 @@ import '@/global/styles/global.less'; // 导入全局样式
import 'antd/dist/antd.less'
import { isDev } from '@/constants'
import { setup } from '@formily/antd-components';
import { getRouters, getAuth, asyncRouter, setAuth, setRouters } from './utils/auth';
import { getRouters, getAuth, asyncRouter, setAuth, setRouters, removeAuth, removeRouters } from './utils/auth';
import { PublicApi } from './services/api';
setup()
......@@ -66,13 +67,20 @@ export function render(oldRender: Function) {
const authInfo = getAuth()
if (authInfo) {
PublicApi.getMemberLoginReget().then(res => {
const { data } = res
setAuth({
memberId: data.memberId,
userId: data.userId,
token: data.token
})
setRouters(data.urls)
const { data, code } = res
if (code === 1000) {
setAuth({
memberId: data.memberId,
userId: data.userId,
token: data.token
})
setRouters(data.urls)
} else {
removeAuth()
removeRouters()
history.push('/user/login')
}
oldRender()
})
} else {
......@@ -89,20 +97,33 @@ export function render(oldRender: Function) {
*/
export function onRouteChange({ routes, matchedRoutes, location, action }) {
console.log('onRouteChange')
if (isDev) {
return;
}
// if (isDev) {
// return;
// }
if (whiteLists.includes(location.pathname)) return;
const routeAuthUrls = getRouters()
// 是否登录
if (getAuth()) {
if (routeAuthUrls.includes(location.pathname)) {
} else {
// 无权限访问时
history.replace('/memberCenter/noAuth')
const { query, pathname } = location
// 固定配置, 出现此参数说明需携带参数校验权限路由
if (query.page_type && routeAuthUrls.find(authPath => {
const parseUrl = queryString.parseUrl(authPath)
const { query: selfQuery, url } = parseUrl
// 当页面出现参数page_type时, 需进入深度校验, 即对应的参数和路径匹配
return url === pathname && selfQuery.page_type === query.page_type
})) {
// 深度匹配成功, 可正常访问
return ;
}
// 是否在路由权限列表里
if (routeAuthUrls.includes(pathname)) {
return ;
}
// 无权限访问时
history.replace('/memberCenter/noAuth')
} else {
history.replace('/user/login')
}
......
import React from 'react';
import { Radio, Tooltip } from 'antd';
const CustomCheckbox = props => {
const { layout } = props
return (
<Radio.Group value={props.value} onChange={props.onChange} className={layout === 'column' ? 'identityRadio' : 'businessRadio'} name={props.name}>
{
props.dataSource && props.dataSource.map((v, i) => <Tooltip title={v.label} placement='leftTop' key={v.value + i}><Radio.Button value={v.value} >{v.label}</Radio.Button></Tooltip>)
}
</Radio.Group>
)
}
export default CustomCheckbox
\ No newline at end of file
......@@ -3,12 +3,14 @@ import UploadImage from "@/components/UploadImage"
const CustomUpload = (props) => {
const { mutators } = props
const uploadProps = props.props['x-component-props'] || {}
return <UploadImage
imgUrl={props.value}
onChange={data => {
// 这里能拿到change后的data值
mutators.change(data)
}}
{...uploadProps}
/>
}
......
import React from 'react'
import { Row, Input, Col, Button } from 'antd';
import useCountDown from '@/utils/hooks';
const Phone = (props) => {
const {text, isActive, start} = useCountDown({
maxTime: 60,
minTime: 0,
initText: '获取验证码',
onEnd: () => {},
decayRate: 1,
delay: 1 * 1000
})
const { value } = props
return (
<Row style={{width: '100%'}}>
<Col flex={1}>
<Input
value={value || ''}
onChange={e => props.mutators.change(e.target.value)}
{...props.props['x-component-props']}
/>
</Col>
<Col style={{marginLeft: 8}}>
<Button disabled={isActive} style={{minWidth: 110, marginLeft: 8}} size='large' onClick={start}>{text}</Button>
</Col>
</Row>
)
}
Phone.defaultProps = {}
Phone.isFieldComponent = true;
export default Phone
\ No newline at end of file
......@@ -18,8 +18,10 @@ import CustomRegistryPhone from './components/CustomRegistryPhone';
import CustomRelevance from './components/CustomRelevance';
import Children from './components/Children';
import CircleBox from './components/CircleBox';
import Phone from './components/Phone';
import CustomRadio from './components/CustomRadio';
import './index.less'
import { Input } from '@formily/antd-components';
import { Checkbox } from '@formily/antd-components';
export interface NiceFormProps extends IAntdSchemaFormProps {}
......@@ -78,10 +80,12 @@ const schemaLayout = createControllerBox("schemaLayout", (_props) => {
const NiceForm: React.FC<NiceFormProps> = props => {
const { children, components, ...reset } = props;
const customComponents = {
CheckboxSingle: Checkbox,
CustomUpload,
CustomStatus,
CustomAddArray,
CustomSlider,
CustomRadio,
Search,
CustomInputSearch,
Submit,
......@@ -93,7 +97,8 @@ const NiceForm: React.FC<NiceFormProps> = props => {
Children,
CircleBox,
SchemaFormButtonGroup,
FlexBox
FlexBox,
Phone,
};
const defineComponents = Object.assign(customComponents, components);
......
......@@ -4,6 +4,7 @@ import { LoadingOutlined, PlusOutlined } from '@ant-design/icons'
import { UploadFile, UploadChangeParam } from 'antd/lib/upload/interface'
import cx from 'classnames'
import styles from './index.less'
import { UPLOAD_TYPE } from '@/constants'
interface UploadImagePorpsType {
imgUrl: string;
......@@ -12,10 +13,11 @@ interface UploadImagePorpsType {
disabled?: boolean;
large?: boolean;
fileMaxSize?: number;
showDesc?: boolean
}
const UploadImage: React.FC<UploadImagePorpsType> = forwardRef((props, ref) => {
const { imgUrl, onChange, size = "386x256", disabled = false, large = false, fileMaxSize = 200 } = props
const { imgUrl, onChange, showDesc = true, size = "386x256", disabled = false, large = false, fileMaxSize = 200 } = 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';
......@@ -34,7 +36,7 @@ const UploadImage: React.FC<UploadImagePorpsType> = forwardRef((props, ref) => {
action: '/api/file/file/upload',
headers: {},
data: {
fileType: 1
fileType: UPLOAD_TYPE
},
disabled: loading || disabled,
showUploadList: false,
......@@ -72,9 +74,12 @@ const UploadImage: React.FC<UploadImagePorpsType> = forwardRef((props, ref) => {
}
</div>}
</Upload>
<div className={styles.size_require}>
<p>支持JPG/PNG/JPEG, <br />最大不超过 {fileMaxSize}K, <br />尺寸:{size}</p>
</div>
{
showDesc &&
<div className={styles.size_require}>
<p>支持JPG/PNG/JPEG, <br />最大不超过 {fileMaxSize}K, <br />尺寸:{size}</p>
</div>
}
</div>
)
})
......
......@@ -10,6 +10,7 @@ export const MALL_TYPE = {
// 本地环境跳过权限校验
export const isDev = process.env.NODE_ENV === "development"
// export const isDev = false
export const Environment_Status = {
0: "所有",
......
......@@ -4,30 +4,40 @@ const { onFormInit$ } = FormEffectHooks
/**
* @description 处理异步请求的下拉选择
* @param name 待处理的表单路径
* @param service 触发的异步函数, 需返回一个{label: any, value: any}形式的数组
* @param {sting[]} name 待处理的表单路径
* @param {func} service 触发的异步函数, 需返回一个 { label: any, value: any }形式的数组
*/
export const useAsyncInitSelect = (name: string[], service?: () => Promise<any>) => {
const { dispatch, setFieldState } = createFormActions()
const linkage = useLinkageUtils()
const { dispatch, setFieldState } = createFormActions();
const linkage = useLinkageUtils();
onFormInit$().subscribe(() => {
setFieldState(name, state => {
FormPath.setIn(state, 'props.x-props.hasFeedback', true)
})
name.forEach(v => linkage.loaded(v))
const nameStr: string = name.toString();
const formPath: string = `*(${nameStr})`;
setFieldState(formPath, state => {
FormPath.setIn(state, 'props.x-props.hasFeedback', true);
});
linkage.loading(formPath);
service().then(res => {
name.forEach(v => {
linkage.loaded(v)
linkage.enum(v, res[v])
})
//请求结束可以dispatch一个自定义事件收尾,方便后续针对该事件做联动
dispatch('requestAsyncSelect', {
name,
payload: res
})
if (res.code === 1000) {
linkage.loaded(formPath);
name.forEach(v => {
linkage.enum(v, res[v]);
});
// 请求结束可以dispatch一个自定义事件收尾,方便后续针对该事件做联动
dispatch('requestAsyncSelect', {
name,
payload: res,
});
return;
}
linkage.loaded(formPath);
}).catch(err => {
// linkage.loaded(name)
// linkage.enum(name, [])
})
linkage.loaded(formPath);
});
})
}
\ No newline at end of file
@import './mixins/layout.less';
#root {
// 去除input type为number时的箭头
.ant-input-number-handler-wrap {
display: none;
}
.common_checkbox {
&:hover,
......
......@@ -8,7 +8,7 @@ export enum PageStatus {
}
export const usePageStatus = () => {
const { preview, id = '' } = history.location.query
const { preview, id = '', ...rest } = history.location.query
// 默认预览状态
let pageStatus = PageStatus.PREVIEW
if (preview === '1') {
......@@ -24,6 +24,7 @@ export const usePageStatus = () => {
return {
pageStatus,
id,
preview
preview,
...rest,
}
}
\ No newline at end of file
......@@ -112,6 +112,7 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
{titleDom}
</Link>
)}
collapsed={collapsed}
onCollapse={handleMenuCollapse}
breadcrumbRender={(routers = []) => [
......
......@@ -259,7 +259,7 @@ const company: React.FC<{}> = () => {
</Form.Item>
</Col>
{
(pageStatus === PageStatus.PREVIEW) &&
(pageStatus !== PageStatus.PREVIEW) &&
<Col span={18}>
<Row>
<Col span={6}></Col>
......
EyePreview/*
/*
* @Date: 2020-07-13 15:01:40
* @LastEditors: LeeJiancong
* @LastEditTime: 2020-08-03 16:52:53
* @LastEditTime: 2020-08-19 10:52:37
*/
import React, { ReactNode, useRef } from 'react'
......@@ -20,8 +20,6 @@ import { IFormFilter, IButtonFilter } from 'god/dist/src/standard-table/TableCon
import {PublicApi,CustomApi} from '@/services/api'
import EyePreview from '@/components/EyePreview'
import StatusSwitch from '@/components/StatusSwitch'
import { getCompanyList, delCompany,updateCompanyStatus } from '@/services/logistics/index'
const data = [
{
key: '1',
......@@ -76,7 +74,7 @@ const Company: React.FC<{}> = () => {
align: 'center',
key: 'name',
render: (text: any, record: any) => (
<EyePreview url={`/memberCenter/logisticsAbility/logistics/list/addCompany?id=${record.id}&preview=1`}>{text}</EyePreview>
<EyePreview url={`/memberCenter/logisticsAbility/logistics/addCompany?id=${record.id}&preview=1`}>{text}</EyePreview>
)
},
{
......@@ -109,7 +107,7 @@ const Company: React.FC<{}> = () => {
<>
{ record.status === 0 ?
<>
<Button type='link' onClick={() => history.push(`/memberCenter/logisticsAbility/logistics/list/addCompany?id=${record.id}`)}>编辑</Button>
<Button type='link' onClick={() => history.push(`/memberCenter/logisticsAbility/logistics/addCompany?id=${record.id}`)}>编辑</Button>
<Popconfirm title="确定要删除吗?" okText="是" cancelText="否" onConfirm={() => handleDelete(record.id)}>
<Button type='link'>
删除
......@@ -139,7 +137,7 @@ const Company: React.FC<{}> = () => {
text: '新建',
icon: <PlusOutlined />,
handler: () => {
history.push('/memberCenter/logisticsAbility/logistics/list/addCompany')
history.push('/memberCenter/logisticsAbility/logistics/addCompany')
}
}
]
......@@ -157,7 +155,7 @@ const Company: React.FC<{}> = () => {
}
const handleSee = (id: number) => {
history.push(`/memberCenter/logisticsAbility/logistics/list/addCompany?id=${id}&isSee=true`)
history.push(`/memberCenter/logisticsAbility/logistics/addCompany?id=${id}&isSee=true`)
}
const confirm = () => {
......@@ -184,7 +182,7 @@ const Company: React.FC<{}> = () => {
formilyChilds={{
children: (
<>
<Button type="primary" onClick={() => history.push('/memberCenter/logisticsAbility/logistics/list/addCompany')}>
<Button type="primary" onClick={() => history.push('/memberCenter/logisticsAbility/logistics/addCompany')}>
新建 <PlusOutlined />
</Button>
</>
......
......@@ -2,7 +2,7 @@
* @Author: LeeJiancong
* @Date: 2020-07-14 15:07:34
* @LastEditors: LeeJiancong
* @LastEditTime: 2020-07-29 20:37:05
* @LastEditTime: 2020-08-19 10:53:33
*/
import React, { Component, ReactNode, useRef, useState } from 'react'
import { history } from 'umi'
......@@ -117,12 +117,12 @@ const EditableCell: React.FC<EditableCellProps> = ({
*/
const AddressList: React.FC<ListProps> = (props) => {
console.log(props)
const ref = useRef({})
const ref = useRef<any>({})
const [form] = Form.useForm();
const [table, setTable] = useState([])
const [editingKey, setEditingKey] = useState('');
const toEdit = (id: number) => {
history.push(`/memberCenter/logisticsAbility/logistics/list/addressForm?type=${props.type}&id=${id}`)
history.push(`/memberCenter/logisticsAbility/logistics/addressForm?type=${props.type}&id=${id}`)
};
const columns: ColumnType<any>[] = [
{
......@@ -246,7 +246,7 @@ const AddressList: React.FC<ListProps> = (props) => {
text: '新建',
icon: <PlusOutlined />,
handler: () => {
history.push('/logisticsAbility/logistics/list/addCompany')
history.push('/logisticsAbility/logistics/addCompany')
}
}
]
......@@ -280,7 +280,7 @@ const AddressList: React.FC<ListProps> = (props) => {
formilyChilds={{
children: (
<>
<Button type="primary" icon={<PlusOutlined />} onClick={() => history.push(`/memberCenter/logisticsAbility/logistics/list/addressForm?type=${props.type}&id=0`)}>新建</Button>
<Button type="primary" icon={<PlusOutlined />} onClick={() => history.push(`/memberCenter/logisticsAbility/logistics/addressForm?type=${props.type}&id=0`)}>新建</Button>
</>
)
}}
......
/*
EyePreview/*
* @Author: LeeJiancong
* @Date: 2020-07-14 15:07:34
* @LastEditors: LeeJiancong
* @LastEditTime: 2020-08-03 11:19:53
* @LastEditTime: 2020-08-19 11:03:37
*/
import React, { Component, ReactNode, useRef, useState } from 'react'
import { history } from 'umi'
......@@ -18,6 +18,8 @@ import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { StandardTable } from 'god'
import { ColumnType } from 'antd/lib/table/interface'
import { IFormFilter, IButtonFilter } from 'god/dist/src/standard-table/TableController'
import StatusSwitch from '@/components/StatusSwitch'
import EyePreview from '@/components/EyePreview'
import { PublicApi} from '@/services/api'
const data = [
......@@ -124,8 +126,11 @@ const Template: React.FC<ListProps> = (props) => {
{
title: '模板名称',
dataIndex: 'name',
align: 'center',
align: 'left',
key: 'name',
render: (text:any,record:any) => (
<EyePreview url={`/memberCenter/logisticsAbility/logistics/templateForm?id=${record.id}&isSee=${true}`}>{text}</EyePreview>
)
},
{
title: '计价方式',
......@@ -160,32 +165,21 @@ const Template: React.FC<ListProps> = (props) => {
align: 'center',
dataIndex: 'status',
key: 'status',
render: (_:any,record: any) => {
return (
<Button type="link" style={record.status === 1 ? { color: '#00B37A' } : { color: 'red' }}>{record.status === 1 ? '有效' : '无效'}
{record.status === 1 ? <PlayCircleOutlined /> : <PauseCircleOutlined />}
</Button>
)
}
render: (text: any, record: any) => (
<StatusSwitch fieldNames="status" handleConfirm={() => handleChangeStatus(record.id,record.status)} record={record}/>
)
},
{
title: '操作',
dataIndex: 'option',
align: 'center',
render: (_: any, record: any) => {
const status = record.status === 0?'启用':'停用'
const title = `确定要${status}吗?`
return (
<>
<Popconfirm title={title} okText="是" cancelText="否" onConfirm={() => handleChangeStatus(record.id,record.status)}>
<Button type='link'>
{ record.status === 0?'启用':'停用'}
</Button>
</Popconfirm>
{
record.status === 0 ?
<>
<Button type='link' onClick={() => history.push(`/memberCenter/logisticsAbility/logistics/list/templateForm?id=${record.id}`)}>编辑</Button>
<Button type='link' onClick={() => history.push(`/memberCenter/logisticsAbility/logistics/templateForm?id=${record.id}`)}>编辑</Button>
<Popconfirm title="确定要删除吗?" okText="是" cancelText="否" onConfirm={() =>handleDelete(record.id)}>
<Button type='link'>
删除
......@@ -193,7 +187,6 @@ const Template: React.FC<ListProps> = (props) => {
</Popconfirm>
</> : ''
}
<Button type='link' onClick={() => handleSee(record.id)}>查看</Button>
</>
)
}
......@@ -238,7 +231,7 @@ const Template: React.FC<ListProps> = (props) => {
}
]
const handleSee = (id: number) => {
history.push(`/memberCenter/logisticsAbility/logistics/list/templateForm?id=${id}&isSee=${true}`)
history.push(`/memberCenter/logisticsAbility/logistics/templateForm?id=${id}&isSee=${true}`)
}
const confirm = () => {
......@@ -265,7 +258,7 @@ const Template: React.FC<ListProps> = (props) => {
formilyChilds={{
children: (
<>
<Button type="primary" icon={<PlusOutlined />} onClick={() => history.push(`/memberCenter/logisticsAbility/logistics/list/templateForm?id=0`)}>
<Button type="primary" icon={<PlusOutlined />} onClick={() => history.push(`/memberCenter/logisticsAbility/logistics/templateForm?id=0`)}>
新建
</Button>
</>
......
......@@ -87,7 +87,7 @@ const AuthDetail: React.FC<PageProps> = (props: any) => {
customKey="id"
checkable
actions={treeActions}
treeData={treeData}
treeData={[]}
handleSelect={handleSelect}
disabled={pageStatus === PageStatus.PREVIEW}
/>
......
......@@ -17,15 +17,15 @@ const { TabPane } = Tabs;
const { Step } = Steps;
const MemberDetail: React.FC<{}> = () => {
const { pageStatus, id } = usePageStatus();
const { pageStatus, id, validateId } = usePageStatus();
const [hActived, setHActived] = useState('3');
const [detailData, setDetailData] = useState<any>({});
useEffect(() => {
const fetchDetailData = async () => {
const { data } = await PublicApi.getMemberValidateCommitDetail({
memberId: '2',
validateId: '63',
memberId: id,
validateId: validateId,
});
setDetailData(data);
};
......
......@@ -57,7 +57,7 @@ const memberMaintain: React.FC<[]> = () => {
key: 'name',
render: (text: any, record: any) => (
<EyePreview
url={`/memberCenter/memberAbility/manage/importDetail?id=${record.id}&preview=1`}
url={`/memberCenter/memberAbility/manage/importDetail?id=${record.memberId}&validateId=${record.validateId}&preview=1`}
>
{text}
</EyePreview>
......
......@@ -46,25 +46,25 @@ export const importSchema: ISchema = {
properties: {
memberType: {
type: 'string',
default: 0,
default: undefined,
enum: [],
'x-component-props': {},
},
roleId: {
type: 'string',
default: 0,
default: undefined,
enum: [],
'x-component-props': {},
},
level: {
type: 'string',
default: 0,
default: undefined,
enum: [],
'x-component-props': {},
},
source: {
type: 'string',
default: 0,
default: undefined,
enum: [],
'x-component-props': {},
},
......
.headerTop {
display: flex;
align-items: center;
font-size: 20px;
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: #172B4D;
margin: 0 8px 0 12px;
}
&-identity {
width: 72px;
height: 24px;
line-height: 24px;
background-color: #FFEBE6;
border-radius: 4px;
color: #E63F3B;
font-size: 14px;
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: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #6B778C;
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;
.saveBtn {
color: #fff;
background: @main-color
}
}
}
.extra {
margin-bottom: 48px;
&-main {
display: flex;
&-content {
position: relative;
flex: 1;
height: 104px;
&:nth-last-of-type(1) {
flex: 2.5;
}
}
.left {
display: flex;
justify-content: center;
align-items: center;
.icon {
position: absolute;
left: 0;
top: 0;
width: 72px;
height: 24px;
color: #fff;
background-color: #42526E;
border-radius: 4px 0px 4px 0px;
text-align: center;
}
.input {
display: flex;
justify-content: center;
&-main {
position: relative;
width: 128px;
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: #172B4D;
&:focus {
border: none;
box-shadow: none;
background-color: transparent;
}
}
}
}
}
.right {
padding: 27px 40px;
}
}
}
import React, { ReactNode, useState, useRef } from 'react'
import { history } from 'umi'
import { Button, Popconfirm, Card, Input, Slider } from 'antd'
import { ColumnType } from 'antd/lib/table/interface'
import classNames from 'classnames'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { PlayCircleOutlined, ContainerOutlined } from '@ant-design/icons'
import { StandardTable } from 'god'
import { ColumnType } from 'antd/lib/table/interface'
import './index.less'
import styles from './addEquity.less'
const data = [
{
......@@ -143,69 +144,74 @@ const addEquity: React.FC<[]> = () => {
onBack={() => window.history.back()}
title={
<>
<div className='headerTop'>
<div className='headerTop-icon'></div>
<div className='headerTop-level'>钻石会员</div>
<div className='headerTop-identity'>商户会员</div>
<div className={styles.headerTop}>
<div className={styles['headerTop-icon']}></div>
<div className={styles['headerTop-level']}>钻石会员</div>
<div className={styles['headerTop-identity']}>商户会员</div>
</div>
</>
}
content={
<div className='headerMain'>
<div className='headerMain-left'>
<div className='headerMain-left-option'>
<div className={styles.headerMain}>
<div className={styles['headerMain-left']}>
<div className={styles['headerMain-left-option']}>
<div>会员等级:</div>
<div>1</div>
</div>
<div className='headerMain-left-option'>
<div className={styles['headerMain-left-option']}>
<div>升级分值标签:</div>
<div>交易分</div>
</div>
<div className='headerMain-left-option'>
<div className={styles['headerMain-left-option']}>
<div>角色类型:</div>
<div>服务消费</div>
</div>
<div className='headerMain-left-option'>
<div className={styles['headerMain-left-option']}>
<div>会员等级说明:</div>
<div>商户所属钻石会员</div>
</div>
<div className='headerMain-left-option'>
<div className={styles['headerMain-left-option']}>
<div>会员角色名称:</div>
<div>采购商</div>
</div>
<div className='headerMain-left-option'>
<div className={styles['headerMain-left-option']}>
<div>会员类型:</div>
<div>企业会员</div>
</div>
</div>
<div className='headerMain-right'>
<Button className='saveBtn' icon={<ContainerOutlined />}>保存</Button>
<div className={styles['headerMain-right']}>
<Button className={styles.saveBtn} icon={<ContainerOutlined />}>保存</Button>
</div>
</div>
}
>
<Card>
<StandardTable
tableProps={{
rowKey: 'id',
pagination: false,
}}
columns={columns}
currentRef={ref}
fetchTableData={(params: any) => fetchData(params)}
controlRender={
<>
<div className='extra'>
<div className={styles.extra}>
<h3>升级阀值</h3>
<div className='extra-main'>
<div className='extra-main-content left'>
<div className='icon'>当前阀值</div>
<div className='input'>
<div className='input-main'>
<Input className='input-main-com'
<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={(e: any) => { e.persist(); setThresholdValue(e.target.value) }}
/>
</div>
</div>
</div>
<div className='extra-main-content right'>
<div className={classNames(styles['extra-main-content'], styles.right)}>
<Slider
marks={marks}
max={50000}
......
......@@ -7,51 +7,6 @@
margin-left: 16px;
}
.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 : 14px;
font-family : PingFangSC-Regular, PingFang SC;
font-weight : 400;
color : #6B778C;
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;
.saveBtn {
color : #fff;
background: @main-color
}
}
}
.nameCellTitle {
color : @main-color;
cursor: pointer;
......@@ -85,116 +40,7 @@
background-size: 24px 20px;
}
.headerTop {
display : flex;
align-items: center;
font-size : 20px;
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 : #172B4D;
margin: 0 8px 0 12px;
}
&-identity {
width : 72px;
height : 24px;
line-height : 24px;
background-color: #FFEBE6;
border-radius : 4px;
color : #E63F3B;
font-size : 14px;
font-weight : 400;
text-align : center;
}
}
h3 {
margin-bottom: 20px;
}
.extra {
margin-bottom: 48px;
&-main {
display: flex;
&-content {
position: relative;
flex : 1;
height : 104px;
&:nth-last-of-type(1) {
flex: 2.5;
}
}
.left {
display : flex;
justify-content: center;
align-items : center;
.icon {
position : absolute;
left : 0;
top : 0;
width : 72px;
height : 24px;
color : #fff;
background-color: #42526E;
border-radius : 4px 0px 4px 0px;
text-align : center;
}
.input {
display : flex;
justify-content: center;
&-main {
position : relative;
width : 128px;
height : 38px;
padding-bottom: 8px;
&::after {
content : '';
position : absolute;
left : 0;
bottom : 0;
width : 100%;
height : 1px;
background-color: #DFE1E6;
}
&-com {
width : 100%;
height : 100%;
border : 0;
outline : none;
background-color: rgba(0, 0, 0, 0);
font-size : 32px;
font-family : PingFangSC-Medium, PingFang SC;
font-weight : 500;
color : #172B4D;
}
}
}
}
.right {
padding: 27px 40px;
}
}
}
\ No newline at end of file
......@@ -46,7 +46,7 @@ const MemberLevel: React.FC<[]> = () => {
key: 'levelTag',
render: (text: any, record: any) => (
<EyePreview
url={`/memberCenter/memberAbility/manage/addEquity?id=${record.id}&preview=1`}
url={`/memberCenter/memberAbility/manage/level/addEquity?id=${record.id}&preview=1`}
>
{text}
</EyePreview>
......@@ -109,7 +109,7 @@ const MemberLevel: React.FC<[]> = () => {
<Button
type="link"
onClick={() =>
history.push(`/memberCenter/memberAbility/manage/addEquity?id=${record.id}`)
history.push(`/memberCenter/memberAbility/manage/level/addEquity?id=${record.id}`)
}
>
设置
......
......@@ -57,7 +57,7 @@ const memberMaintain: React.FC<[]> = () => {
key: 'name',
render: (text: any, record: any) => (
<EyePreview
url={`/memberCenter/memberAbility/manage/maintainDetail?id=${record.id}&preview=1`}
url={`/memberCenter/memberAbility/manage/importDetail?id=${record.memberId}&validateId=${record.validateId}&preview=1`}
>
{text}
</EyePreview>
......
......@@ -85,7 +85,7 @@ const LoginWrap: React.FC = () => {
</Form.Item>)
}
<Form.Item>
<Button type='primary' size='large' htmlType='submit' block>点击登录</Button>
<Button type='primary' size='large' htmlType='submit' block>登录</Button>
</Form.Item>
</Form>
}
......
This diff is collapsed.
import { ISchema } from '@formily/antd';
import { PATTERN_MAPS } from '@/constants/regExp';
import { GlobalConfig } from '@/global/config';
export const registerStep0Schema: ISchema = {
type: 'object',
properties: {
REGISTER_STEP: {
type: 'object',
"x-component": 'mega-layout',
"x-component-props": {
className: 'registerForm',
full: true
},
properties: {
phone: {
type: 'string',
required: true,
"x-rules": [
{
pattern: PATTERN_MAPS.phone,
message: '请填写手机号'
}
],
"x-component-props": {
placeholder: '请输入您的手机号码',
size: 'large'
},
"x-props": {
addonBefore: "{{phoneBefore}}"
}
},
smsCode: {
type: 'string',
"x-component": 'Phone',
required: true,
"x-rules": [
{
pattern: PATTERN_MAPS.smsCode,
message: '请输入正确的6位验证码'
}
],
"x-component-props": {
size: 'large',
}
},
password: {
type: 'password',
required: true,
"x-rules": [
{
pattern: PATTERN_MAPS.password,
message: '请输入正确的密码'
}
],
"x-component-props": {
placeholder: '请设置你的登录密码',
size: 'large',
}
},
confirmPassword: {
type: 'password',
required: true,
"x-rules": [
{
pattern: PATTERN_MAPS.password,
message: '请输入正确的密码'
}
],
"x-component-props": {
placeholder: '请再次输入你的登录密码',
size: 'large',
}
},
email: {
type: 'string',
"x-rules": [
{
pattern: PATTERN_MAPS.email,
message: '请输入正确的邮箱'
}
],
"x-component-props": {
placeholder: '请输入你的邮箱(选填)',
size: 'large',
type: 'email'
}
},
isRead: {
required: true,
"x-component": 'CheckboxSingle',
"x-component-props": {
children: "{{checkBoxChildren}}"
}
}
}
},
}
}
export const registerStep1Schema: ISchema = {
type: 'object',
properties: {
REGISTER_STEP: {
type: 'object',
"x-component": 'mega-layout',
"x-component-props": {
className: 'formBoxStep2'
},
properties: {
BLOCK_LAYOUT1: {
type: 'object',
"x-component": 'block',
"x-component-props": {
title: "{{memberTypeTitle}}",
className: 'mr_t-40'
},
properties: {
typeId: {
type: 'string',
required: true,
"x-component": 'CustomRadio',
"x-component-props": {
layout: 'column'
},
enum: GlobalConfig.userRegister.useType.memberType.map(v => {
return {
value: v.id,
label: v.typeName
}
})
},
}
},
BLOCK_LAYOUT2: {
type: 'object',
"x-component": 'block',
"x-component-props": {
title: "{{businessTypeTitle}}",
className: 'mr_t-40'
},
properties: {
businessTypeId: {
type: 'string',
required: true,
"x-component": 'CustomRadio',
"x-component-props": {
layout: 'row'
},
enum: GlobalConfig.userRegister.useType.businessType.map(v => {
return {
value: v.id,
label: v.typeName
}
})
},
}
}
},
}
}
}
export default {
schema0: registerStep0Schema,
schema1: registerStep1Schema
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
import { ReactText } from 'react';
import React, { ReactText } from 'react';
import moment from 'moment';
import deepClone from 'clone'
import { ISchema } from '@formily/antd';
import { UPLOAD_TYPE } from '@/constants';
import queryString from 'query-string'
function isArray(arr: any) {
return Array.isArray(arr)
......@@ -239,6 +242,102 @@ export const findTreeKeys = (arr: any[], keyword?: ReactText) => {
return results
}
// 转化object 成schema
export const transFormSchema = (data: any[]): ISchema => {
return {
type: 'object',
properties: {
'MEGA_LAYOUT2': {
type: 'object',
"x-component": 'mega-layout',
"x-component-props": {
className: 'formBoxStep2'
},
properties: {
detail: {
type: 'object',
properties: data.reduce((prev, next, index) => {
prev[`NO_SUBMIT_BLOCK${index}`] = {
type: 'object',
"x-component": 'block',
"x-component-props": {
className: 'mr_t-40',
title: <span className={'commonPanelTitle'}>{next.groupName}</span>
},
properties: {
[`NO_SUBMIT_BLOCK_MEGA${index}`]: {
type: 'object',
"x-component": 'mega-layout',
"x-component-props": {
columns: 2,
grid: true,
autoRow: true,
size: 'large',
className: 'mr_t-24'
},
properties: next.elements.reduce((subP, subN, subI) => {
subP[subN.fieldName] = getFieldType(subN)
return subP
}, {})
}
}
}
return prev
}, {})
}
}
}
}
}
}
// 获取字段类型,改为schema可识别的
export const getFieldType = (field) => {
if (field.fieldType === 'upload') {
return {
type: 'string',
"x-component": "CustomUpload",
"x-mega-props": {
span: 2
},
required: field.fieldEmpty === 0,
title: field.fieldCNName,
"x-component-props": {
showDesc: false
}
}
} else {
return {
type: 'string',
"x-mega-props": {
span: 1
},
"x-component": "CustomInput",
required: field.fieldEmpty === 0,
"x-rules": field.checkRules.map(v => {
return {
message: v.msg,
pattern: v.rulePattern
}
}),
maxLength: field.fieldLength,
"x-component-props": {
help: field.fieldRemark,
placeholder: `请输入${field.fieldCNName}`,
size: 'large'
}
}
}
}
export const getQueryStringParams = (url?: string) => {
const nowUrl = url || window.location.href
const firstIndex = nowUrl.indexOf('?')
const searchParam = url ? url.substring(firstIndex) : window.location.search
return queryString.parse(searchParam)
}
export default {
isArray,
isObject,
......
......@@ -115,11 +115,8 @@ class ApiRequest {
options.ctlType === 'message' && message.success(res.message)
resolve(res)
} else {
// 未登录
if (res.code === 1101) {
history.push('/user/login')
reject()
}
// 使用resolve将数据返回, 请求时需手动处理data为null的情况
resolve(res)
message.error(res.message)
}
......
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