Commit fb95bffe authored by 前端-钟卫鹏's avatar 前端-钟卫鹏
parents f0554366 9ce79b83
......@@ -28,7 +28,7 @@ const MemberRoute = {
name: 'importDetail',
key: 'importDetail',
hideInMenu: true,
component: '@/pages/member/components/memberDetail/index',
component: '@/pages/member/memberImport/importDetail',
},
{
path: '/memberCenter/memberAbility/manage/addMember',
......@@ -48,7 +48,7 @@ const MemberRoute = {
name: 'maintainDetail',
key: 'maintainDetail',
hideInMenu: true,
component: '@/pages/member/components/memberDetail/index',
component: '@/pages/member/memberMaintain/maintainDetail',
},
{
path: '/memberCenter/memberAbility/manage/memberPrSubmit',
......@@ -122,9 +122,62 @@ const MemberRoute = {
component: '@/pages/member/memberLevel/addEquity',
},
]
}
},
{
path: '/memberCenter/memberAbility/query',
name: 'memberQuery',
key: 'memberQuery',
component: '@/pages/member/memberQuery/index',
},
{
path: '/memberCenter/memberAbility/query/detailed',
name: 'memberQueryDetailed',
key: 'memberQueryDetailed',
component: '@/pages/member/memberQuery/detailed',
hideInMenu: true,
routes: [
{
path: '/memberCenter/memberAbility/query/detailed',
redirect: '/memberCenter/memberAbility/query/detailed/basicInfo',
},
{
path: '/memberCenter/memberAbility/query/detailed/basicInfo',
name: 'basicInfo',
key: 'basicInfo',
component: '@/pages/member/memberQuery/detailed/basicInfo',
hideInMenu: true,
},
{
path: '/memberCenter/memberAbility/query/detailed/powerInfo',
name: 'powerInfo',
key: 'powerInfo',
component: '@/pages/member/memberQuery/detailed/powerInfo',
hideInMenu: true,
},
{
path: '/memberCenter/memberAbility/query/detailed/levelInfo',
name: 'levelInfo',
key: 'levelInfo',
component: '@/pages/member/memberQuery/detailed/levelInfo',
hideInMenu: true,
},
{
path: '/memberCenter/memberAbility/query/detailed/equityInfo',
name: 'equityInfo',
key: 'equityInfo',
component: '@/pages/member/memberQuery/detailed/equityInfo',
hideInMenu: true,
},
{
path: '/memberCenter/memberAbility/query/detailed/sincerityInfo',
name: 'sincerityInfo',
key: 'sincerityInfo',
component: '@/pages/member/memberQuery/detailed/sincerityInfo',
hideInMenu: true,
},
],
},
]
}
export default MemberRoute
......@@ -29,12 +29,13 @@
"dependencies": {
"@ant-design/icons": "^4.2.1",
"@ant-design/pro-layout": "^5.0.16",
"@antv/data-set": "^0.11.5",
"@formily/antd": "^1.2.11",
"@formily/antd-components": "^1.2.11",
"@umijs/hooks": "^1.9.3",
"@umijs/preset-react": "1.x",
"@umijs/test": "^3.2.0",
"bizcharts": "^4.0.7",
"bizcharts": "^4.0.14",
"copy-to-clipboard": "^3.3.1",
"god": "^0.1.25",
"lingxi-design": "^1.0.7",
......@@ -42,6 +43,7 @@
"lingxi-editor-core": "^1.0.6",
"lingxi-web": "^1.0.6",
"lint-staged": "^10.0.7",
"lodash": "^4.17.20",
"mobx": "^5.15.4",
"mobx-react": "^6.2.2",
"moment": "^2.27.0",
......
.miniChart {
position: relative;
width: 100%;
.chartContent {
position: absolute;
bottom: -28px;
width: 100%;
> div {
margin: 0 -5px;
overflow: hidden;
}
}
.chartLoading {
position: absolute;
top: 16px;
left: 50%;
margin-left: -7px;
}
}
import React from 'react';
import { Axis, Chart, Geom, Tooltip } from 'bizcharts';
import { IAxis } from 'bizcharts/lib/components/Axis';
import autoHeight from '../autoHeight';
import styles from './index.less';
import { ShapeString, ShapeAttrCallback, IChartProps } from 'bizcharts/lib/interface';
export interface MiniAreaProps {
color?: string;
height?: number;
borderColor?: string;
line?: boolean;
animate?: boolean;
xAxis?: IAxis;
autoFit?: boolean;
scale?: {
x?: {
tickCount?: number;
alias?: string;
};
y?: {
tickCount?: number;
alias?: string;
};
};
yAxis?: Partial<IAxis>;
borderWidth?: number;
data: {
x: number | string;
y: number;
}[];
padding?: number | number[] | 'auto';
borderShape?: ShapeString | ShapeString | [ShapeString, ShapeString[] | ShapeAttrCallback];
}
const MiniArea: React.FC<MiniAreaProps> = (props) => {
const {
height = 1,
data = [],
autoFit = true,
color = 'rgba(24, 144, 255, 0.2)',
borderColor = '#1089ff',
scale = { x: {}, y: {} },
borderWidth = 2,
line,
xAxis,
yAxis,
animate = true,
padding,
borderShape = 'line',
} = props;
const newPadding = padding || [36, 5, 30, 5];
const scaleProps = {
x: {
type: 'cat',
range: [0, 1],
...scale.x,
},
y: {
min: 0,
...scale.y,
},
};
const tooltip: [string, (...args: any[]) => { name?: string; value: string }] = [
'x*y',
(x: string, y: string) => ({
name: x,
value: y,
}),
];
const chartHeight = height + 54;
return (
<div className={styles.miniChart} style={{ height }}>
<div className={styles.chartContent}>
{height > 0 && (
<Chart
animate={animate}
scale={scaleProps}
height={chartHeight}
autoFit={autoFit}
data={data}
padding={newPadding}
>
<Axis
key="axis-x"
name="x"
label={null}
line={null}
tickLine={null}
grid={null}
{...xAxis}
/>
<Axis
key="axis-y"
name="y"
label={null}
line={null}
tickLine={null}
grid={null}
{...yAxis}
/>
<Tooltip showTitle={false} />
<Geom
type="area"
position="x*y"
color={color}
tooltip={tooltip}
// shape="smooth"
style={{
fillOpacity: 0.3,
}}
/>
{line ? (
<Geom
type="line"
position="x*y"
shape={borderShape}
color={borderColor}
size={borderWidth}
tooltip={false}
/>
) : (
<span style={{ display: 'none' }} />
)}
</Chart>
)}
</div>
</div>
);
};
export default autoHeight()(MiniArea);
@import '~antd/es/style/themes/default.less';
@import '../../../global/styles/utils.less';
.pie {
position: relative;
.chart {
position: relative;
}
&.hasLegend .chart {
width: ~'calc(100% - 240px)';
}
.legend {
position: absolute;
top: 50%;
right: 0;
min-width: 200px;
margin: 0 20px;
padding: 0 0 0 6%;
display: flex;
list-style: none;
transform: translateY(-50%);
&-item {
cursor: pointer;
.textOverflow();
}
li {
flex: 0 0 33.33%;
height: 22px;
margin-bottom: 16px;
line-height: 22px;
cursor: pointer;
&:last-child {
margin-bottom: 0;
}
}
}
.dot {
position: relative;
top: -1px;
display: inline-block;
width: 8px;
height: 8px;
margin-right: 8px;
border-radius: 8px;
}
.line {
display: inline-block;
width: 1px;
height: 16px;
margin-right: 8px;
background-color: @border-color-split;
}
.legendTitle {
color: @text-color;
}
.percent {
color: @text-color-secondary;
}
.value {
position: absolute;
right: 0;
}
.title {
margin-bottom: 8px;
}
.total {
position: absolute;
top: 50%;
left: 50%;
max-height: 62px;
text-align: center;
transform: translate(-50%, -50%);
& > h4 {
height: 22px;
margin-bottom: 8px;
color: @text-color-secondary;
font-weight: normal;
font-size: 14px;
line-height: 22px;
}
& > p {
display: block;
height: 32px;
color: @heading-color;
line-height: 32px;
font-size: 24px;
font-weight: 500;
white-space: nowrap;
}
}
}
.legendBlock {
&.hasLegend .chart {
width: 100%;
margin: 0 0 32px 0;
}
.legend {
position: relative;
transform: none;
}
}
import {
Chart,
Axis,
Interval,
Interaction,
Coordinate,
Legend,
Tooltip,
registerShape,
} from 'bizcharts';
import React, { Component } from 'react';
import { Row, Col } from 'antd';
import { RowProps, ColProps } from 'antd/lib/grid';
import DataSet from '@antv/data-set';
import G2 from '@antv/g2/lib/chart/chart';
import Debounce from 'lodash.debounce';
import { Divider } from 'antd';
import classNames from 'classnames';
import autoHeight from '../autoHeight';
import styles from './index.less';
export interface PieProps {
animate?: boolean;
color?: string;
colors?: string[];
height?: number;
margin?: [number, number, number, number];
hasLegend?: boolean;
padding?: [number, number, number, number];
percent?: number;
data?: {
x: string | string;
y: number;
}[];
inner?: number;
lineWidth?: number;
autoFit?: boolean;
style?: React.CSSProperties;
className?: string;
total?: React.ReactNode | number | (() => React.ReactNode | number);
title?: React.ReactNode;
tooltip?: boolean;
valueFormat?: (value: string) => string | React.ReactNode;
subTitle?: React.ReactNode;
rowProps?: RowProps;
colProps?: ColProps;
}
interface PieState {
legendData: { checked: boolean; x: string; color: string; percent: number; y: string }[];
legendBlock: boolean;
}
class Pie extends Component<PieProps, PieState> {
state: PieState = {
legendData: [],
legendBlock: true, // 这里默认为 true,为 false 的话会触发相应的 css 设置宽度,从而导致画布容器的宽度过去,图表画不出来报错
};
requestRef: number | undefined = undefined;
root: HTMLDivElement | undefined = undefined;
chart: G2 | undefined = undefined;
// for window resize auto responsive legend
resize = Debounce(() => {
const { hasLegend } = this.props;
const { legendBlock } = this.state;
if (!hasLegend || !this.root) {
window.removeEventListener('resize', this.resize);
return;
}
if (
this.root &&
this.root.parentNode &&
(this.root.parentNode as HTMLElement).clientWidth <= 400
) {
if (!legendBlock) {
this.setState({
legendBlock: true,
});
}
} else if (legendBlock) {
this.setState({
legendBlock: false,
});
}
}, 400);
componentDidMount() {
window.addEventListener(
'resize',
() => {
this.requestRef = requestAnimationFrame(() => this.resize());
},
{ passive: true },
);
}
componentDidUpdate(preProps: PieProps) {
const { data } = this.props;
if (data !== preProps.data) {
// because of charts data create when rendered
// so there is a trick for get rendered time
this.getLegendData();
}
}
componentWillUnmount() {
if (this.requestRef) {
window.cancelAnimationFrame(this.requestRef);
}
window.removeEventListener('resize', this.resize);
if (this.resize) {
(this.resize as any).cancel();
}
}
getG2Instance = (chart: G2) => {
this.chart = chart;
requestAnimationFrame(() => {
this.getLegendData();
this.resize();
});
};
// for custom lengend view
getLegendData = () => {
if (!this.chart) return;
const geom = this.chart.geometries[0]; // 获取所有的图形
if (!geom) return;
const items = (geom as any).dataArray || []; // 获取图形对应的
const legendData = items.map((item: { color: any; _origin: any }[]) => {
/* eslint no-underscore-dangle:0 */
const origin = {...item[0]._origin};
origin.color = item[0].color;
origin.checked = true;
return origin;
});
this.setState({
legendData,
});
};
handleRoot = (n: HTMLDivElement) => {
this.root = n;
};
handleLegendClick = (item: any, i: string | number) => {
const newItem = item;
newItem.checked = !newItem.checked;
const { legendData } = this.state;
legendData[i] = newItem;
const filteredLegendData = legendData.filter((l) => l.checked).map((l) => l.x);
if (this.chart) {
this.chart.filter('x', (val) => filteredLegendData.indexOf(`${val}`) > -1);
}
this.setState({
legendData,
});
};
render() {
const {
valueFormat,
subTitle,
total,
hasLegend = false,
className,
style,
height = 0,
autoFit = true,
percent,
color,
inner = 0.75,
animate = true,
colors,
lineWidth = 1,
} = this.props;
const { legendData, legendBlock } = this.state;
const pieClassName = classNames(styles.pie, className, {
[styles.hasLegend]: !!hasLegend,
[styles.legendBlock]: legendBlock,
});
const {
data: propsData,
tooltip: propsTooltip = true,
rowProps = {},
colProps = {},
} = this.props;
let data = propsData || [];
let tooltip = propsTooltip;
const { gutter: propsGutter, ...rowRest } = rowProps;
const { span: propsSpan, ...colRest } = colProps;
const gutter = propsGutter || [12, 12];
const span = propsSpan || 12;
const defaultColors = colors;
data = data || [];
tooltip = tooltip || true;
let formatColor;
const scale = {
x: {
type: 'cat',
range: [0, 1],
},
y: {
min: 0,
},
};
if (percent || percent === 0) {
tooltip = false;
formatColor = (value: string) => {
if (value === '占比') {
return color || 'rgba(24, 144, 255, 0.85)';
}
return '#F0F2F5';
};
data = [
{
x: '占比',
y: parseFloat(`${percent}`),
},
{
x: '反比',
y: 100 - parseFloat(`${percent}`),
},
];
}
const tooltipFormat: [string, (...args: any[]) => { name?: string; value: string }] = [
'x*y*percent',
(x: string, y: number, p: number) => ({
name: x,
value: `${y} | ${(p * 100).toFixed(2)}%`,
}),
];
const padding = [12, 0, 12, 0] as [number, number, number, number];
const { DataView } = DataSet;
const dv = new DataView();
dv.source(data).transform({
type: 'percent',
field: 'y',
dimension: 'x',
as: 'percent',
});
return (
<div ref={this.handleRoot} className={pieClassName} style={style}>
<div className={styles.chart}>
<Chart
scale={scale}
height={height}
autoFit={autoFit}
data={dv}
padding={padding}
animate={animate}
onGetG2Instance={this.getG2Instance}
>
<Coordinate type="theta" innerRadius={inner} />
<Axis visible={false} />
{!!tooltip && <Tooltip showTitle={false} />}
<Interval
adjust="stack"
position="y"
color={['x', percent || percent === 0 ? formatColor : defaultColors] as any}
shape="sliceShape"
tooltip={tooltip ? tooltipFormat : undefined}
/>
<Legend visible={false} />
<Interaction type="element-single-selected" />
</Chart>
{(subTitle || total) && (
<div className={styles.total}>
{subTitle && <h4 className="pie-sub-title">{subTitle}</h4>}
{/* eslint-disable-next-line */}
{total && (
<p className="pie-stat">
{typeof total === 'function' ? total() : total}
</p>
)}
</div>
)}
</div>
{hasLegend && (
<Row
className={styles.legend}
gutter={gutter}
{...rowRest}
>
{legendData.map((item, i) => (
<Col
key={item.x}
className={styles['legend-item']}
onClick={() => this.handleLegendClick(item, i)}
span={span}
{...colProps}
>
<span
className={styles.dot}
style={{
backgroundColor: !item.checked ? '#aaa' : item.color,
}}
/>
<span className={styles.legendTitle}>{item.x}</span>
{/* <Divider type="vertical" />
<span className={styles.percent}>
{`${(Number.isNaN(item.percent) ? 0 : item.percent * 100).toFixed(2)}%`}
</span>
<span className={styles.value}>{valueFormat ? valueFormat(item.y) : item.y}</span> */}
</Col>
))}
</Row>
)}
</div>
);
}
}
export default autoHeight()(Pie);
import React from 'react';
export type IReactComponent<P = any> =
| React.StatelessComponent<P>
| React.ComponentClass<P>
| React.ClassicComponentClass<P>;
function computeHeight(node: HTMLDivElement) {
const { style } = node;
style.height = '100%';
const totalHeight = parseInt(`${getComputedStyle(node).height}`, 10);
const padding =
parseInt(`${getComputedStyle(node).paddingTop}`, 10) +
parseInt(`${getComputedStyle(node).paddingBottom}`, 10);
return totalHeight - padding;
}
function getAutoHeight(n: HTMLDivElement | undefined) {
if (!n) {
return 0;
}
const node = n;
let height = computeHeight(node);
const parentNode = node.parentNode as HTMLDivElement;
if (parentNode) {
height = computeHeight(parentNode);
}
return height;
}
interface AutoHeightProps {
height?: number;
}
function autoHeight() {
return <P extends AutoHeightProps>(
WrappedComponent: React.ComponentClass<P> | React.FC<P>,
): React.ComponentClass<P> => {
class AutoHeightComponent extends React.Component<P & AutoHeightProps> {
state = {
computedHeight: 0,
};
root: HTMLDivElement | undefined = undefined;
componentDidMount() {
const { height } = this.props;
if (!height) {
let h = getAutoHeight(this.root);
this.setState({ computedHeight: h });
if (h < 1) {
h = getAutoHeight(this.root);
this.setState({ computedHeight: h });
}
}
}
handleRoot = (node: HTMLDivElement) => {
this.root = node;
};
render() {
const { height } = this.props;
const { computedHeight } = this.state;
const h = height || computedHeight;
return (
<div ref={this.handleRoot}>
{h > 0 && <WrappedComponent {...this.props} height={h} />}
</div>
);
}
}
return AutoHeightComponent;
};
}
export default autoHeight;
import MiniArea from './MiniArea';
import Pie from './Pie';
const Charts = {
MiniArea,
Pie,
};
export {
Charts as default,
MiniArea,
Pie,
};
.mellow {
:global {
.ant-card {
border-radius: 8px;
&-head {
border-bottom: none;
&-title {
line-height: 24px;
padding-bottom: 0;
font-size: 16px;
font-weight: 500;
color: rgba(23, 43, 77, 1);
}
}
&-body {
padding: 14px 24px 24px;
}
}
}
}
\ No newline at end of file
/*
* @Author: XieZhiXiong
* @Date: 2020-08-26 17:32:45
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-08-26 17:33:28
* @Description: 基于 antd Card 封装的适合项目 UI 的 Card,使用方式跟 antd Card 一样,这里只是修改了样式
*/
import React from 'react';
import { Card } from 'antd';
import { CardProps } from 'antd/lib/card';
import styles from './index.less';
const MellowCard: React.FC<CardProps> = props => {
const { children, ...rest } = props;
return (
<div className={styles.mellow}>
<Card {...rest}>
{children}
</Card>
</div>
)
};
export default MellowCard;
\ No newline at end of file
......@@ -2,7 +2,6 @@ import React from 'react';
import SchemaForm, {
IAntdSchemaFormProps, createVirtualBox, registerVirtualBox, Schema, SchemaField, FormButtonGroup, Reset, createControllerBox, registerValidationRules,
} from '@formily/antd';
import { Input } from '@formily/antd-components';
import { Button, Space, Row, Col } from 'antd';
import CustomUpload from './components/CustomUpload';
import CustomStatus from './components/CustomStatus';
......@@ -23,7 +22,7 @@ import CustomRadio from './components/CustomRadio';
import SearchSelect from './components/SearchSelect';
import TableTagList from './components/TableTagList';
import './index.less'
import { Checkbox } from '@formily/antd-components';
import { Checkbox, Input } from '@formily/antd-components';
export interface NiceFormProps extends IAntdSchemaFormProps {}
......
/*
* @Author: XieZhiXiong
* @Date: 2020-08-21 11:13:55
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-08-25 10:05:19
* @Description:
*/
import { TableProps, TablePaginationConfig, ColumnType } from 'antd/lib/table';
export interface StandardTableProps extends TableProps<any> {
......@@ -10,7 +17,7 @@ export interface EditableCellProps {
onValidateError?: (error: {[key: string]: any}) => void,
record?: any;
index?: number;
dataIndex: string | number;
dataIndex?: string | number;
title?: React.ReactNode;
editable?: boolean;
children?: React.ReactNode;
......
.textOverflow() {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
word-break: break-all;
}
.textOverflowMulti(@line: 3, @bg: #fff) {
position: relative;
max-height: @line * 1.5em;
margin-right: -1em;
padding-right: 1em;
overflow: hidden;
line-height: 1.5em;
text-align: justify;
&::before {
position: absolute;
right: 14px;
bottom: 0;
padding: 0 1px;
background: @bg;
content: '...';
}
&::after {
position: absolute;
right: 14px;
width: 1em;
height: 1em;
margin-top: 0.2em;
background: white;
content: '';
}
}
.textOverflowMulti2(@line: 3) {
display: -webkit-box;
/* autoprefixer: off */
-webkit-box-orient:vertical;
/* autoprefixer: on */
-webkit-line-clamp: @line;
overflow: hidden;
}
\ No newline at end of file
/*
* @Author: LeeJiancong
* @Date: 2020-07-13 14:08:50
* @LastEditors: LeeJiancong
* @LastEditTime: 2020-08-25 11:25:00
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-08-28 17:48:20
*/
export default {
......@@ -73,6 +73,13 @@ export default {
'menu.memberAbility.memberManage.memberLevel': '会员等级',
'menu.memberAbility.memberManage.addEquity': '会员权益设置',
'menu.memberAbility.memberManage.maintainDetail': '未命名',
'menu.memberAbility.memberQuery': '会员信息查询',
'menu.memberAbility.memberQueryDetailed': '会员信息详情',
'menu.memberAbility.memberQueryDetailed.basicInfo': '会员基本信息',
'menu.memberAbility.memberQueryDetailed.powerInfo': '会员权限信息',
'menu.memberAbility.memberQueryDetailed.levelInfo': '会员等级信息',
'menu.memberAbility.memberQueryDetailed.equityInfo': '权益信息',
'menu.memberAbility.memberQueryDetailed.sincerityInfo': '诚信信息',
// 店铺能力
'menu.shopAbility': '店铺',
......
import React from 'react';
import {
Steps,
Tabs,
} from 'antd';
import MellowCard from '@/components/MellowCard';
import styles from './index.less';
interface AuditProcessProp {
single?: string
};
const AuditProcess: React.FC<{}> = () => (
<MellowCard>
<Tabs onChange={() => {}}>
<Tabs.TabPane tab="外部审核流程" key="1">
<Steps style={{ marginTop: 30 }} progressDot current={2}>
<Steps.Step title="会员" description="申请注册" />
<Steps.Step title="平台" description="审核会员" />
<Steps.Step title="完成" description="" />
</Steps>
</Tabs.TabPane>
<Tabs.TabPane tab="内部审核流程" key="2">
<Steps style={{ marginTop: 30 }} progressDot current={2}>
<Steps.Step title="提交审核会员" description="运营经理" />
<Steps.Step title="审核会员" description="运营经理" />
<Steps.Step title="审核会员" description="副总经理" />
<Steps.Step title="确认会员审核结果" description="运营人员" />
</Steps>
</Tabs.TabPane>
</Tabs>
</MellowCard>
);
export default AuditProcess;
\ No newline at end of file
.basicInfo {
.descriptions {
:global {
.ant-descriptions-item-label {
flex: 0 0 128px;
color: rgba(107, 119, 140, 1);
}
}
}
}
\ No newline at end of file
import React, { useState } from 'react';
import {
Row,
Col,
Descriptions,
} from 'antd';
import MellowCard from '@/components/MellowCard';
import PicWrap from '../PicWrap';
import FlowRecords from '../FlowRecords';
import styles from './index.less';
interface PageProps {
detailData: any;
}
const BasicInfo: React.FC<{}> = props => {
return (
<div className={styles.basicInfo}>
<Row gutter={[0, 24]}>
<Col span={24}>
<MellowCard
title="基本信息"
>
<Descriptions column={2} className={styles.descriptions}>
<Descriptions.Item label="登录账户">185 2929 6547</Descriptions.Item>
<Descriptions.Item label="注册手机号">1810000000</Descriptions.Item>
<Descriptions.Item label="注册邮箱">kuaimeizheng@163.com</Descriptions.Item>
<Descriptions.Item label="申请时间">2020-12-26 13:45</Descriptions.Item>
</Descriptions>
</MellowCard>
</Col>
<Col span={24}>
<MellowCard
title="渠道信息"
>
<Descriptions column={2} className={styles.descriptions}>
<Descriptions.Item label="渠道级别">二级</Descriptions.Item>
<Descriptions.Item label="渠道类型">电商渠道</Descriptions.Item>
<Descriptions.Item label="代理地市">
<Row gutter={[16, 16]}>
<Col span={12}>广东省/广州市</Col>
<Col span={12}>广东省/广州市</Col>
<Col span={12}>广东省/广州市</Col>
<Col span={12}>广东省/广州市</Col>
</Row>
</Descriptions.Item>
<Descriptions.Item label="渠道描述">门店</Descriptions.Item>
</Descriptions>
</MellowCard>
</Col>
<Col span={24}>
<MellowCard
title="营业执照"
>
<Row gutter={20}>
<Col span={12}>
<Descriptions column={1} className={styles.descriptions}>
<Descriptions.Item label="公司名称">温州市隆昌皮业有限公司</Descriptions.Item>
<Descriptions.Item label="企业类型">
股份有限公司(非上市)
</Descriptions.Item>
<Descriptions.Item label="住所">中国浙江省温州市</Descriptions.Item>
<Descriptions.Item label="法定代表人">张三</Descriptions.Item>
<Descriptions.Item label="注册资本">壹仟万元整</Descriptions.Item>
<Descriptions.Item label="成立日期">2010-06-14</Descriptions.Item>
<Descriptions.Item label="营业期限">2010-06-14 至 长期有效</Descriptions.Item>
<Descriptions.Item label="经营范围">
经营全粒面牛皮,修面皮,漆色皮,打腊皮,水腊皮,疯马皮,珠光变色,大小荔枝纹,打腊水腊皮,
高光变色皮,胎牛皮、小牛纳帕皮、磨砂皮、镜面皮、开边珠、自然摔、烧焦打蜡皮,牛巴革,混种
羊面皮,山羊里皮,仿鹿皮,羊皮羊反绒系列
</Descriptions.Item>
</Descriptions>
</Col>
<Col span={12}>
<Descriptions column={1} className={styles.descriptions}>
<Descriptions.Item label="登记机关">广州市工商局</Descriptions.Item>
<Descriptions.Item label="登记时间">2010-06-14</Descriptions.Item>
<Descriptions.Item label="统一社会信用代码">4324324325425435</Descriptions.Item>
<Descriptions.Item label="营业执照">
<PicWrap
pics={[
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1598594727734&di=20420459d5a6f2c95dd9bc5c47786e98&imgtype=0&src=http%3A%2F%2Fa3.att.hudong.com%2F14%2F75%2F01300000164186121366756803686.jpg',
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1598594742248&di=b76fef1833c6566d330ac88f6dbe9bae&imgtype=0&src=http%3A%2F%2Fa1.att.hudong.com%2F05%2F00%2F01300000194285122188000535877.jpg',
]}
/>
</Descriptions.Item>
</Descriptions>
</Col>
</Row>
</MellowCard>
</Col>
<Col span={24}>
<MellowCard
title="法定代表人信息"
>
<Row gutter={20}>
<Col span={12}>
<Descriptions column={1} className={styles.descriptions}>
<Descriptions.Item label="法人姓名">张三</Descriptions.Item>
<Descriptions.Item label="法人手机号">
+86 186 7700 2345
</Descriptions.Item>
<Descriptions.Item label="法人身份证号">440911198809076654</Descriptions.Item>
</Descriptions>
</Col>
<Col span={12}>
<Descriptions column={1} className={styles.descriptions}>
<Descriptions.Item label="法人身份证信息">
<PicWrap
pics={[
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1598594727734&di=20420459d5a6f2c95dd9bc5c47786e98&imgtype=0&src=http%3A%2F%2Fa3.att.hudong.com%2F14%2F75%2F01300000164186121366756803686.jpg',
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1598594742248&di=b76fef1833c6566d330ac88f6dbe9bae&imgtype=0&src=http%3A%2F%2Fa1.att.hudong.com%2F05%2F00%2F01300000194285122188000535877.jpg',
]}
/>
</Descriptions.Item>
</Descriptions>
</Col>
</Row>
</MellowCard>
</Col>
<Col span={24}>
<MellowCard
title="联系信息"
>
<Descriptions column={2} className={styles.descriptions}>
<Descriptions.Item label="联系人">张三</Descriptions.Item>
<Descriptions.Item label="地址">中国浙江省温州市</Descriptions.Item>
<Descriptions.Item label="固定联系电话">
021 33232424
</Descriptions.Item>
<Descriptions.Item label="邮编">510222</Descriptions.Item>
<Descriptions.Item label="手机号码">+86 186 77003245</Descriptions.Item>
<Descriptions.Item label="网址">www.shushangyun.com</Descriptions.Item>
<Descriptions.Item label="传真号码">021 43434353</Descriptions.Item>
<Descriptions.Item label="邮箱">kuaimeizheng@163.com</Descriptions.Item>
</Descriptions>
</MellowCard>
</Col>
<Col span={24}>
<FlowRecords />
</Col>
</Row>
</div>
);
};
export default BasicInfo;
.equityInfo {
.container {
display: flex;
flex-direction: column;
justify-content: center;
padding: 0 24px;
height: 192px;
background: #ffffff;
border-radius: 8px;
&-title {
margin-bottom: 24px;
line-height: 24px;
font-size: 16px;
font-weight: 500;
color: rgba(23, 43, 77, 1);
}
&-content {
}
}
.tofo {
display: flex;
padding: 0;
margin: 0;
&-item {
flex: 1;
list-style: none;
&-logo {
width: 40px;
height: 40px;
margin: 0 auto 4px;
text-align: center;
> img {
width: 100%;
height: 100%;
}
}
&-title {
margin-bottom: 9px;
line-height: 22px;
font-size: 14px;
font-weight: 400;
color: rgba(23, 43, 77, 1);
text-align: center;
:global {
.anticon {
margin-left: 4px;
}
}
}
&-extra {
text-align: center;
}
&-tag {
line-height: 22px;
padding: 0 6px;
font-size: 14px;
font-weight: 400;
text-align: center;
border-radius: 4px;
&-price {
color: rgba(101, 84, 192, 1);
background: rgba(234, 230, 255, 1);
}
&-recurrence {
color: rgba(230, 63, 59, 1);
background: rgba(255, 235, 230, 1);
}
&-integral {
color: rgba(255, 153, 31, 1);
background: rgba(255, 250, 230, 1);
}
}
}
}
.exhibition {
display: flex;
align-items: center;
&-left {
flex: 1;
}
&-right {
flex-shrink: 0;
}
&-title {
line-height: 20px;
margin-bottom: 24px;
font-size: 14px;
font-weight: 400;
color: rgba(107, 119, 140, 1);
}
&-amount {
font-size: 24px;
font-weight: 500;
color: rgba(23, 43, 77, 1);
line-height: 24px;
> span {
margin-left: 8px;
line-height: 12px;
font-size: 12px;
font-weight: 400;
color: rgba(107, 119, 140, 1);
}
}
&-logo {
width: 72px;
height: 72px;
> img {
width: 100%;
height: 100%;
}
}
}
}
\ No newline at end of file
import React, { useState } from 'react';
import {
Row,
Col,
Tabs,
} from 'antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
import classNames from 'classnames';
import PolymericTable from '@/components/PolymericTable';
import { EditableColumns } from '@/components/PolymericTable/interface';
import MellowCard from '@/components/MellowCard';
import equity1 from '@/assets/imgs/equity-1.png';
import equity2 from '@/assets/imgs/equity-2.png';
import equity3 from '@/assets/imgs/equity-3.png';
import equity4 from '@/assets/imgs/equity-4.png';
import equity5 from '@/assets/imgs/equity-5.png';
import styles from './index.less';
const { TabPane } = Tabs;
interface PageProps {
detailData: any;
}
const EquityInfo: React.FC<{}> = props => {
const columns: EditableColumns[] = [
{
title: 'ID',
dataIndex: 'id',
align: 'center',
},
{
title: '会员权益名称',
dataIndex: 'project',
align: 'center',
},
{
title: '获取数量',
dataIndex: 'score',
align: 'center',
},
{
title: '获取时间',
dataIndex: 'created',
align: 'center',
},
{
title: '备注',
dataIndex: 'node',
align: 'center',
ellipsis: true,
},
];
const columns2: EditableColumns[] = [
{
title: 'ID',
dataIndex: 'id',
align: 'center',
},
{
title: '会员权益名称',
dataIndex: 'project',
align: 'center',
},
{
title: '会员权益使用名称',
dataIndex: 'name',
align: 'center',
},
{
title: '使用数量',
dataIndex: 'count',
align: 'center',
},
{
title: '使用时间',
dataIndex: 'created',
align: 'center',
},
{
title: '备注',
dataIndex: 'node',
align: 'center',
ellipsis: true,
},
];
const handleTabChange = key => {
console.log('key', key)
};
return (
<div className={styles.equityInfo}>
<Row gutter={[0, 24]}>
<Col span={24}>
<Row gutter={24}>
<Col span={8}>
<div className={styles.container}>
<div className={styles['container-title']}>
当前权益
</div>
<div className={styles['container-content']}>
<ul className={styles.tofo}>
<li className={styles['tofo-item']}>
<div className={styles['tofo-item-logo']}>
<img src={equity1} />
</div>
<div className={styles['tofo-item-title']}>
价格权益
<QuestionCircleOutlined />
</div>
<div className={styles['tofo-item-extra']}>
<span className={classNames(styles['tofo-item-tag'], styles['tofo-item-tag-price'])}>95% 折扣</span>
</div>
</li>
<li className={styles['tofo-item']}>
<div className={styles['tofo-item-logo']}>
<img src={equity2} />
</div>
<div className={styles['tofo-item-title']}>
返现权益
<QuestionCircleOutlined />
</div>
<div className={styles['tofo-item-extra']}>
<span className={classNames(styles['tofo-item-tag'], styles['tofo-item-tag-recurrence'])}>0.1% 返现</span>
</div>
</li>
<li className={styles['tofo-item']}>
<div className={styles['tofo-item-logo']}>
<img src={equity3} />
</div>
<div className={styles['tofo-item-title']}>
积分权益
<QuestionCircleOutlined />
</div>
<div className={styles['tofo-item-extra']}>
<span className={classNames(styles['tofo-item-tag'], styles['tofo-item-tag-integral'])}>1% 积分</span>
</div>
</li>
</ul>
</div>
</div>
</Col>
<Col span={8}>
<div className={styles.container}>
<div className={styles['container-content']}>
<div className={styles.exhibition}>
<div className={styles['exhibition-left']}>
<div className={styles['exhibition-title']}>
累计返现金额
</div>
<div className={styles['exhibition-amount']}>
50000.00
<span>CNY</span>
</div>
</div>
<div className={styles['exhibition-right']}>
<div className={styles['exhibition-logo']}>
<img src={equity4} />
</div>
</div>
</div>
</div>
</div>
</Col>
<Col span={8}>
<div className={styles.container}>
<div className={styles['container-content']}>
<div className={styles.exhibition}>
<div className={styles['exhibition-left']}>
<div className={styles['exhibition-title']}>
可用积分
</div>
<div className={styles['exhibition-amount']}>
2000/200000
</div>
</div>
<div className={styles['exhibition-right']}>
<div className={styles['exhibition-logo']}>
<img src={equity5} />
</div>
</div>
</div>
</div>
</div>
</Col>
</Row>
</Col>
<Col span={24}>
<MellowCard
title="活跃分获取记录"
>
<Tabs onChange={handleTabChange}>
<TabPane tab="权益获取记录" key="1">
<PolymericTable
dataSource={[]}
columns={columns}
loading={false}
pagination={null}
/>
</TabPane>
<TabPane tab="权益使用记录" key="2">
<PolymericTable
dataSource={[]}
columns={columns2}
loading={false}
pagination={null}
/>
</TabPane>
</Tabs>
</MellowCard>
</Col>
</Row>
</div>
);
};
export default EquityInfo;
import React from 'react';
import {
Tabs,
Badge,
} from 'antd';
import { STATUS_COLOR_MAP, STATUS_COLOR_TXT } from '../../constant';
import PolymericTable from '@/components/PolymericTable';
import { EditableColumns } from '@/components/PolymericTable/interface';
import MellowCard from '@/components/MellowCard';
import styles from './index.less';
interface FlowRecordsProps {
};
const FlowRecords: React.FC<{}> = () => {
const columns: EditableColumns[] = [
{
title: '序号',
dataIndex: 'index',
align: 'center',
render: (text, record, index) => index + 1,
},
{
title: '操作角色',
dataIndex: 'role',
align: 'center',
},
{
title: '状态',
dataIndex: 'status',
align: 'center',
render: text => <Badge color={STATUS_COLOR_MAP[text]} text={STATUS_COLOR_TXT[text]} />,
},
{
title: '操作',
dataIndex: 'action',
align: 'center',
},
{
title: '操作时间',
dataIndex: 'created',
align: 'center',
ellipsis: true,
},
{
title: '审核意见',
dataIndex: 'opinion',
align: 'center',
ellipsis: true,
},
];
const columns2: EditableColumns[] = [
{
title: '序号',
dataIndex: 'index',
align: 'center',
render: (text, record, index) => index + 1,
},
{
title: '操作人',
dataIndex: 'operator',
align: 'center',
},
{
title: '部门',
dataIndex: 'department',
align: 'center',
},
{
title: '职位',
dataIndex: 'job',
align: 'center',
},
{
title: '状态',
dataIndex: 'status',
align: 'center',
render: text => <Badge color={STATUS_COLOR_MAP[text]} text={STATUS_COLOR_TXT[text]} />,
},
{
title: '操作',
dataIndex: 'action',
align: 'center',
},
{
title: '操作时间',
dataIndex: 'created',
align: 'center',
ellipsis: true,
},
{
title: '审核意见',
dataIndex: 'opinion',
align: 'center',
ellipsis: true,
},
];
return (
<MellowCard>
<Tabs onChange={() => {}}>
<Tabs.TabPane tab="流转记录" key="1">
<PolymericTable
dataSource={[
{
id: 1,
role: '供应商',
status: 0,
action: '申请注册',
created: '2020-05-12 08:08',
opinion: '同意',
},
]}
columns={columns}
loading={false}
pagination={null}
/>
</Tabs.TabPane>
<Tabs.TabPane tab="内部单据流转记录" key="2">
<PolymericTable
dataSource={[
{
id: 1,
operator: '供应商',
department: '运营部',
job: '运营人员',
status: 0,
action: '提交审核会员',
created: '2020-05-12 08:08',
opinion: '同意',
},
]}
columns={columns2}
loading={false}
pagination={null}
/>
</Tabs.TabPane>
</Tabs>
</MellowCard>
);
};
export default FlowRecords;
\ No newline at end of file
.head {
display: flex;
align-items: center;
font-size: 20px;
font-weight: 500;
&-prefix {
width: 48px;
height: 48px;
line-height: 48px;
border-radius: 4px;
border: 1px solid #DFE1E6;
color: #fff;
text-align: center;
background-color: #8777D9;
}
&-name {
color: #172B4D;
margin: 0 8px 0 12px;
}
}
import React from 'react';
import LevelBrand from '../LevelBrand';
import styles from './index.less';
export interface HeadInfoProps {
info: {
name: string,
level?: number,
};
extra?: React.ReactNode;
};
const HeadInfo: React.FC<HeadInfoProps> = ({ info, extra }) => (
<div className={styles.head}>
<div className={styles['head-prefix']}>
{ info && info.name.length ? info.name[0] : '' }
</div>
<div className={styles['head-name']}>
{info.name || ''}
</div>
{!extra ? (
<LevelBrand level={info.level} />
) : extra}
</div>
);
export default HeadInfo;
\ No newline at end of file
.brand {
display: inline-block;
width: 54px;
height: 16px;
line-height: 16px;
> img {
width: 100%;
height: 100%;
}
}
\ No newline at end of file
import React from 'react';
import p_level1 from '@/assets/imgs/level1.png';
import p_level2 from '@/assets/imgs/level2.png';
import p_level3 from '@/assets/imgs/level3.png';
import p_level4 from '@/assets/imgs/level4.png';
import styles from './index.less';
enum levelEnum {
'青铜会员' = 1,
'白银会员' = 2,
'黄金会员' = 3,
'钻石会员' = 4,
}
export interface LevelBrandProps {
level: levelEnum;
};
const PIC_MAP = {
1: p_level1,
2: p_level2,
3: p_level3,
4: p_level4,
};
const LevelBrand: React.FC<LevelBrandProps> = ({ level }) => {
const current = PIC_MAP[level] || '';
return (
<div className={styles.brand}>
{current && <img src={current} />}
</div>
);
};
export default LevelBrand;
\ No newline at end of file
@card-prefix: card;
.levelInfo {
.infoWrap {
display: flex;
&-left {
margin-right: 40px;
flex-shrink: 0;
}
&-right {
flex: 1;
}
}
.card {
width: 338px;
height: 190px;
padding: 32px 24px 16px 24px;
background: linear-gradient(135deg, rgba(255, 235, 225, 1) 0%, rgba(251, 196, 167, 1) 100%);
box-shadow: 0 1px 2px 0 rgba(23, 43, 77, 0.12);
border-radius: 8px;
position: relative;
z-index: 0;
&-name {
margin-bottom: 48px;
line-height: 33px;
font-size: 24px;
font-weight: 500;
color: rgba(164, 114, 104, 1);
}
&-progress {
padding: 0 72px 0 0;
:global {
.ant-progress-bg {
background: rgba(164, 114, 104, 1) !important;
}
.ant-progress-inner {
background-color: rgb(233, 191, 169, 1) !important;
}
}
}
&-txt {
display: flex;
justify-content: space-between;
}
&-experience {
font-size: 12px;
font-weight: 400;
color: rgba(164, 114, 104, 1);
line-height: 20px;
}
&-higher {
font-size: 12px;
font-weight: 400;
color: rgba(186, 140, 115, 1);
line-height: 20px;
}
&-level2 {
background: linear-gradient(135deg, rgba(233, 244, 255, 1) 0%, rgba(164, 185, 223, 1) 100%);
box-shadow: 0 1px 2px 0 rgba(23, 43, 77, 0.12);
.@{card-prefix} {
&-name {
color: rgba(91, 111, 146, 1);
}
&-progress {
:global {
.ant-progress-bg {
background: rgba(87, 108, 143, 1) !important;
}
.ant-progress-inner {
background-color: rgba(171, 192, 220, 1) !important;
}
}
}
&-experience {
color: rgba(91, 111, 146, 1);
}
&-higher {
color: rgba(133, 150, 179, 1);
}
}
}
&-level3 {
background: linear-gradient(135deg, rgba(255, 245, 222, 1) 0%, rgba(212, 191, 146, 1) 100%);
box-shadow: 0 1px 2px 0 rgba(23, 43, 77, 0.12);
.@{card-prefix} {
&-name {
color: rgba(141, 107, 56, 1);
}
&-progress {
:global {
.ant-progress-bg {
background: rgba(141, 107, 56, 1) !important;
}
.ant-progress-inner {
background-color: rgba(214, 195, 157, 1) !important;
}
}
}
&-experience {
color: rgba(141, 107, 56, 1);
}
&-higher {
color: rgba(174, 154, 113, 1);
}
}
}
&-level4 {
background: linear-gradient(135deg, rgba(232, 239, 255, 1) 0%, rgba(157, 162, 194, 1) 100%);
box-shadow: 0 1px 2px 0 rgba(23, 43, 77, 0.12);
.@{card-prefix} {
&-name {
color: rgba(89, 91, 113, 1);
}
&-progress {
:global {
.ant-progress-bg {
background: rgba(89, 91, 113, 1) !important;
}
.ant-progress-inner {
background-color: rgba(167, 170, 198, 1) !important;
}
}
}
&-experience {
color: rgba(89, 91, 113, 1);
}
&-higher {
color: rgba(134, 136, 166, 1);
}
}
}
&::after {
content: '';
display: block;
position: absolute;
top: 0;
bottom: 0;
left: 100px;
z-index: -1;
width: 100px;
transform: skewX(24deg);
background: linear-gradient(rgba(255, 255, 255, .2), rgba(255, 255, 255, 0));
}
}
}
\ No newline at end of file
import React, { useState } from 'react';
import {
Row,
Col,
Progress,
Card,
} from 'antd';
import classNames from 'classnames';
import { MiniArea } from '@/components/Charts';
import PolymericTable from '@/components/PolymericTable';
import { EditableColumns } from '@/components/PolymericTable/interface';
import MellowCard from '@/components/MellowCard';
import styles from './index.less';
interface PageProps {
detailData: any;
}
function fixedZero(val: number) {
return val * 1 < 10 ? `0${val}` : val;
}
function getActiveData() {
const activeData = [];
for (let i = 0; i < 12; i += 1) {
activeData.push({
x: `${i}月`,
y: Math.floor(Math.random() * 200) + i * 50,
});
}
return activeData;
}
const LevelInfo: React.FC<{}> = props => {
const [chartData , setChartData] = useState(getActiveData());
const columns: EditableColumns[] = [
{
title: 'ID',
dataIndex: 'id',
align: 'center',
},
{
title: '获取项目',
dataIndex: 'project',
align: 'center',
},
{
title: '获取分值',
dataIndex: 'score',
align: 'center',
},
{
title: '获取时间',
dataIndex: 'created',
align: 'center',
},
{
title: '备注',
dataIndex: 'node',
align: 'center',
ellipsis: true,
},
];
return (
<div className={styles.levelInfo}>
<Row gutter={[0, 24]}>
<Col span={24}>
<MellowCard
title="会员等级"
headStyle={{
borderBottom: 'none',
}}
>
<div className={styles.infoWrap}>
<div className={styles['infoWrap-left']}>
<div className={classNames(styles.card, styles['card-level1'])}>
<div className={styles['card-name']}>青铜会员</div>
<div className={styles['card-progress']}>
<Progress
strokeWidth={4}
strokeLinecap="square"
showInfo={false}
percent={75}
/>
</div>
<div className={styles['card-txt']}>
<div className={styles['card-experience']}>
5000/15000
</div>
<div className={styles['card-higher']}>
白银会员
</div>
</div>
<div className={styles['card-higher']}>
当前活跃分
</div>
</div>
</div>
<div className={styles['infoWrap-right']}>
<MiniArea
animate={false}
line
borderWidth={2}
height={180}
padding={[10, 20, 50, 60]}
scale={{
x: {
alias: '2021年', // 别名
},
y: {
tickCount: 5,
alias: '活跃分', // 别名
},
}}
xAxis={{
tickLine: undefined,
label: undefined,
title: {
style: {
fontSize: 12,
fill: '#97A0AF',
fontWeight: 400,
rotate: 90,
},
},
}}
yAxis={{
tickLine: undefined,
label: {
offset: 10,
},
title: {
style: {
fontSize: 12,
fill: '#97A0AF',
fontWeight: 400,
rotate: 90,
},
},
grid: {
line: {
type: 'line',
style: {
stroke: "#d9d9d9",
lineWidth: 1,
lineDash: [2, 2]
}
}
},
}}
color="l(90) 0:#AAC5FC 1:#FFFFFF"
data={chartData}
/>
</div>
</div>
</MellowCard>
</Col>
<Col span={24}>
<MellowCard
title="活跃分获取记录"
headStyle={{
borderBottom: 'none',
}}
>
<PolymericTable
dataSource={[]}
columns={columns}
loading={false}
pagination={null}
/>
</MellowCard>
</Col>
</Row>
</div>
);
};
export default LevelInfo;
.list {
display: flex;
align-items: center;
flex-wrap: wrap;
padding: 0;
margin: 0;
width: 100%;
overflow-x: auto;
&-item {
width: 175px;
height: 120px;
padding: 0 28px;
margin-bottom: 10px;
background: rgba(255, 255, 255, 1);
border: 1px solid rgba(235,236,240,1);
overflow: hidden;
list-style: none;
&:not(:last-child) {
margin-right: 16px;
}
> img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
}
\ No newline at end of file
import React from 'react';
import styles from './index.less';
interface PicWrapProps {
pics: string[];
};
const PicWrap: React.FC<PicWrapProps> = ({ pics = [] }) => (
<ul className={styles.list}>
{pics.map((item, index) => (
<li key={index} className={styles['list-item']}>
<img src={item} />
</li>
))}
</ul>
);
export default PicWrap;
\ No newline at end of file
.sincerityInfo {
.tofo {
height: 100%;
:global {
.antd-card {
height: 100%;
}
}
&-item {
width: 50%;
padding: 55px 24px;
&-logo {
width: 72px;
height: 72px;
}
}
}
}
.contentBox {
position: relative;
padding-right: 72px;
background: #ffffff;
&-main {
}
&-extra {
position: absolute;
top: 0;
right: 0;
bottom: 0;
}
.title {
margin-bottom: 20px;
line-height: 20px;
font-size: 14px;
font-weight: 400;
color: rgba(107, 119, 140, 1);
:global {
.anticon {
margin-left: 6px;
}
}
}
.txt {
line-height: 32px;
font-size: 24px;
font-weight: 500;
color: rgba(23, 43, 77, 1);
}
}
.record {
&-tabs {
:global {
.ant-tabs-nav::before {
border-bottom: none;
}
}
}
&-btns {
margin-bottom: 16px;
}
&-row {
:global {
.ant-table-cell:first-child {
background-color: rgba(250, 251, 252, 1);
}
}
}
}
\ No newline at end of file
This diff is collapsed.
......@@ -13,6 +13,33 @@ import { auditSchema } from './schema';
import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect';
import { PublicApi } from '@/services/api';
const mock = [
{
memberId: 1,
validateId: 1,
name: '模拟会员1',
memberTypeName: '模拟会员类型1',
roleName: '模拟角色',
sourceName: '2020.08.28 15:14:00',
memberStatus: '正常',
status: 1,
outerStatusName: '待审核',
innerStatusName: '待提交审核',
},
{
memberId: 2,
validateId: 2,
name: '模拟会员1',
memberTypeName: '模拟会员类型1',
roleName: '模拟角色',
sourceName: '2020.08.28 15:14:00',
memberStatus: '正常',
status: 0,
outerStatusName: '待审核',
innerStatusName: '待提交审核',
},
];
interface PageProps {
pageType: string; // 页面类型 1 待提交审核 2 待审核 3 待确认审核
}
......@@ -305,6 +332,7 @@ const auditList: React.FC<PageProps> = props => {
// innerStatus: filter.innerStatus || ['0'],
// });
// },
dataSource: mock,
}}
columns={columns}
currentRef={ref}
......
import React, { useState, useEffect, useRef, ReactNode } from 'react';
import React, { useState, useEffect, useRef, ReactNode, Suspense } from 'react';
import { history } from 'umi';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { PageHeader, Tag, Badge, Tabs, Steps, Descriptions } from 'antd';
......@@ -13,12 +13,17 @@ import LevelDetail from './levelDetail';
import EquitiesDetail from './equitiesDetail';
import IntegrityDetail from './integrityDetail';
const BasicInfo = React.lazy(() => import('../BasicInfo'));
const LevelInfo = React.lazy(() => import('../LevelInfo'));
const EquityInfo = React.lazy(() => import('../EquityInfo'));
const SincerityInfo = React.lazy(() => import('../SincerityInfo'));
const { TabPane } = Tabs;
const { Step } = Steps;
const MemberDetail: React.FC<{}> = () => {
const { pageStatus, id, validateId } = usePageStatus();
const [actived, setActived] = useState('3');
const [actived, setActived] = useState('1');
const [detailData, setDetailData] = useState<any>({});
const fetchDetailData = async () => {
......@@ -106,15 +111,24 @@ const MemberDetail: React.FC<{}> = () => {
onTabChange={handleTabChange}
>
{actived === '1' ? (
<BaseDetail detailData={detailData} />
<Suspense fallback={null}>
<BasicInfo />
</Suspense>
) : actived === '2' ? (
<AuthDetail detailData={detailData} />
) : actived === '3' ? (
<LevelDetail detailData={detailData} />
// <LevelDetail detailData={detailData} />
<Suspense fallback={null}>
<LevelInfo />
</Suspense>
) : actived === '4' ? (
<EquitiesDetail detailData={detailData} />
<Suspense fallback={null}>
<EquityInfo />
</Suspense>
) : (
<IntegrityDetail detailData={detailData} />
<Suspense fallback={null}>
<SincerityInfo />
</Suspense>
)}
</PageHeaderWrapper>
);
......
export const STATUS_COLOR_MAP = {
0: '#669EDE',
1: '#41CC9E',
2: '#EF6260',
};
export const STATUS_COLOR_TXT = {
0: '待审核',
1: '审核通过',
2: '冻结',
};
\ No newline at end of file
......@@ -11,8 +11,8 @@ import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilte
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect';
import { initDetailSchema } from './schema';
import { PublicApi } from '@/services/api';
import { initDetailSchema } from './schema';
const formActions = createFormActions();
......@@ -84,20 +84,6 @@ const addMember: React.FC<any> = props => {
});
}, []);
// 模拟请求
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);
};
......
import React from 'react';
import MemberDetail from '../components/memberDetail';
import React, { useState, useEffect } from 'react';
import { history } from 'umi';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { PageHeader, Tag, Descriptions, Steps } from 'antd';
import { STATUS_COLOR_MAP, STATUS_COLOR_TXT } from '../constant';
import { usePageStatus } from '@/hooks/usePageStatus';
import { PublicApi } from '@/services/api';
import MellowCard from '@/components/MellowCard';
import HeadInfo from '../components/HeadInfo';
import BasicInfo from '../components/BasicInfo';
import styles from './index.less';
const ImportDetail = () => {
return <MemberDetail />;
const importDetail: React.FC<{}> = () => {
const { pageStatus, id, validateId } = usePageStatus();
const [detailed, setDetailed] = useState<any>({});
useEffect(() => {
}, []);
return (
<PageHeaderWrapper
title={
<>
<PageHeader
style={{ padding: '0' }}
onBack={() => history.goBack()}
title={
<HeadInfo
info={{
name: '广州市极致皮具有限公司',
level: 1,
}}
/>
}
>
<Descriptions
size="small"
column={2}
style={{
padding: '0 32px',
}}
>
<Descriptions.Item label="会员类型">{123}</Descriptions.Item>
<Descriptions.Item label="会员角色">{123}</Descriptions.Item>
<Descriptions.Item label="会员状态">
<Tag color={STATUS_COLOR_MAP[1]}>{STATUS_COLOR_TXT[1]}</Tag>
</Descriptions.Item>
<Descriptions.Item label="外部状态">
<Tag color={STATUS_COLOR_MAP[2]}>{STATUS_COLOR_TXT[2]}</Tag>
</Descriptions.Item>
</Descriptions>
</PageHeader>
</>
}
>
<MellowCard
title="会员审核流程"
style={{
marginBottom: 24,
}}
>
<Steps style={{ marginTop: 30 }} progressDot current={2}>
<Steps.Step title="会员" description="申请注册" />
<Steps.Step title="平台" description="审核会员" />
<Steps.Step title="完成" description="" />
</Steps>
</MellowCard>
<BasicInfo />
</PageHeaderWrapper>
);
};
export default ImportDetail;
export default importDetail;
......@@ -7,11 +7,11 @@ export const importSchema: ISchema = {
properties: {
mageLayout: {
type: 'object',
'x-component': 'mega-layout',
'x-component': 'Mega-Layout',
properties: {
topLayout: {
type: 'object',
'x-component': 'mega-layout',
'x-component': 'Mega-Layout',
'x-component-props': {
grid: true,
},
......@@ -34,7 +34,7 @@ export const importSchema: ISchema = {
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component': 'Flex-Layout',
'x-component-props': {
rowStyle: {
flexWrap: 'nowrap',
......@@ -105,7 +105,7 @@ export const auditModalSchema = props => {
properties: {
MEGA_LAYOUT: {
type: 'object',
'x-component': 'mega-layout',
'x-component': 'Mega-Layout',
'x-component-props': {
labelAlign: 'top',
},
......@@ -113,7 +113,7 @@ export const auditModalSchema = props => {
remark: {
type: 'string',
title: `会员${props.status === 1 ? '解冻' : '冻结'}原因`,
'x-component': 'textarea',
'x-component': 'TextArea',
'x-component-props': {
placeholder: '在此输入你的内容,最长120个字符,60个汉字',
maxLength: 60,
......@@ -168,18 +168,18 @@ const getCompnentValue = (elements: any) => {
};
export const initDetailSchema = (props: any) => {
let tabSchema = {
let tabSchema: ISchema = {
properties: {
'tab-1': {
type: 'object',
'x-component': 'tabpane',
'x-component': 'TabPane',
'x-component-props': {
tab: '基本信息',
},
properties: {
MEGA_LAYOUT1: {
type: 'object',
'x-component': 'mega-layout',
'x-component': 'Mega-Layout',
'x-component-props': {
labelCol: 4,
wrapperCol: 8,
......@@ -214,10 +214,8 @@ export const initDetailSchema = (props: any) => {
},
},
MEGA_LAYOUT1_1: {
key: 'MEGA_LAYOUT1_1',
type: 'object',
name: 'MEGA_LAYOUT1_1',
'x-component': 'mega-layout',
'x-component': 'Mega-Layout',
'x-component-props': {
label: '注册手机',
required: true,
......@@ -250,22 +248,98 @@ export const initDetailSchema = (props: any) => {
},
},
},
},
'tab-2': {
type: 'object',
'x-component': 'TabPane',
'x-component-props': {
tab: '渠道信息',
},
properties: {
MEGA_LAYOUT1: {
type: 'object',
'x-component': 'Mega-Layout',
'x-component-props': {
labelCol: 4,
wrapperCol: 12,
labelAlign: 'left',
full: true,
},
properties: {
channelLevel: {
type: 'text',
title: '渠道级别',
},
channelType: {
type: 'string',
enum: [
{ label: '电商渠道', value: '1' },
{ label: '线下渠道', value: '2' },
],
title: '渠道类型',
required: true,
'x-component-props': {
defaultValue: '1',
},
},
cities: {
type: 'array',
title: '代理城市',
required: true,
'x-component': 'CustomAddArray',
default: [
{ province: '1', city: '2' },
{ province: '2', city: '1' },
],
items: {
type: 'object',
properties: {
province: {
type: 'string',
enum: [
{ label: '广东省', value: '1' },
{ label: '湖南省', value: '2' },
],
},
city: {
type: 'string',
enum: [
{ label: '广州', value: '1' },
{ label: '深圳', value: '2' },
],
}
}
}
},
desc: {
type: 'string',
title: '渠道描述',
required: true,
'x-component': 'TextArea',
'x-component-props': {
rows: 4,
placeholder: '最大200个字符,100个汉字',
},
},
},
},
},
},
},
};
if (Object.keys(props).length > 0) {
for (let [index, item] of props.groups.entries()) {
tabSchema.properties[`tab-${index + 2}`] = {
tabSchema.properties[`tab-${index + 3}`] = {
type: 'object',
'x-component': 'tabpane',
'x-component': 'TabPane',
'x-component-props': {
tab: item.groupName,
},
properties: {
[`MEGA_LAYOUT${index + 2}`]: {
type: 'object',
'x-component': 'mega-layout',
'x-component': 'Mega-Layout',
'x-component-props': {
labelCol: 4,
wrapperCol: 8,
......@@ -283,8 +357,10 @@ export const initDetailSchema = (props: any) => {
properties: {
REPOSIT_TABS: {
type: 'object',
'x-component': 'tab',
'x-component-props': {},
'x-component': 'Tab',
'x-component-props': {
type: 'card',
},
...tabSchema,
},
},
......
......@@ -89,9 +89,8 @@
.left {
display: flex;
justify-content: center;
align-items: center;
padding: 35px 0 28px;
padding: 35px 0 28px 8%;
background: rgba(250, 251, 252, 1);
border-radius: 4px;
......
......@@ -20,29 +20,6 @@ import { EditableCellProps, EditableColumns } from '@/components/PolymericTable/
import { GetMemberAbilityLevelGetResponse } from '@/services';
import styles from './addEquity.less';
const data = [
{
key: '1',
id: '1',
name: '价格权益',
explain: '交易一方能获得另一方的价格折扣',
type: '交易获取',
setting: '按交易金额比例设置',
params: '1',
status: 2
},
{
key: '2',
id: '2',
name: '返现权益',
explain: '交易一方能获得另一方的交易返现',
type: '交易获取',
setting: '按交易金额比例设置',
params: '1',
status: 1
}
]
const addEquity: React.FC<[]> = () => {
const { id } = usePageStatus();
......@@ -275,6 +252,7 @@ const addEquity: React.FC<[]> = () => {
<div>{ levelInfo?.memberTypeName }</div>
</div>
</div>
<div className={styles['headerMain-right']}>
<Button
type="primary"
......@@ -309,14 +287,15 @@ const addEquity: React.FC<[]> = () => {
</div>
</div>
</div>
<div className={classNames(styles['extra-main-content'], styles.right)}>
{/* <div className={classNames(styles['extra-main-content'], styles.right)}>
<Slider
marks={marks}
max={50000}
value={thresholdValue}
disabled
/>
</div>
</div> */}
</div>
</div>
</Card>
......
......@@ -29,6 +29,33 @@ import { maintianSchema, auditModalSchema } from './schema';
import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect';
import { PublicApi } from '@/services/api';
const mock = [
{
memberId: 1,
validateId: 1,
name: '模拟会员1',
memberTypeName: '模拟会员类型1',
roleName: '模拟角色',
sourceName: '2020.08.28 15:14:00',
memberStatus: '正常',
status: 1,
outerStatusName: '待审核',
innerStatusName: '审核通过',
},
{
memberId: 2,
validateId: 2,
name: '模拟会员1',
memberTypeName: '模拟会员类型1',
roleName: '模拟角色',
sourceName: '2020.08.28 15:14:00',
memberStatus: '正常',
status: 0,
outerStatusName: '待审核',
innerStatusName: '待提交审核',
},
];
const formActions = createFormActions();
const fetchData = async (params: any) => {
......@@ -57,7 +84,7 @@ const memberMaintain: React.FC<[]> = () => {
key: 'name',
render: (text: any, record: any) => (
<EyePreview
url={`/memberCenter/memberAbility/manage/importDetail?id=${record.memberId}&validateId=${record.validateId}&preview=1`}
url={`/memberCenter/memberAbility/manage/maintainDetail?id=${record.memberId}&validateId=${record.validateId}&preview=1`}
>
{text}
</EyePreview>
......@@ -258,6 +285,7 @@ const memberMaintain: React.FC<[]> = () => {
tableProps={{
rowKey: 'memberId',
// onChange: (pagination: any, filter: any) => handleSearch(filter),
dataSource: mock,
}}
columns={columns}
currentRef={ref}
......
import React from 'react';
import MemberDetail from '../components/memberDetail';
import React, { useState, useEffect } from 'react';
import { history } from 'umi';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { PageHeader, Tag, Descriptions, Button } from 'antd';
import { SettingOutlined, StopOutlined } from '@ant-design/icons';
import { STATUS_COLOR_MAP, STATUS_COLOR_TXT } from '../constant';
import { usePageStatus } from '@/hooks/usePageStatus';
import { PublicApi } from '@/services/api';
import MellowCard from '@/components/MellowCard';
import HeadInfo from '../components/HeadInfo';
import AuditProcess from '../components/AuditProcess';
import BasicInfo from '../components/BasicInfo';
import styles from './index.less';
const MaintainDetail = () => {
return <MemberDetail />;
const maintainDetail: React.FC<{}> = () => {
const { pageStatus, id, validateId } = usePageStatus();
const [detailed, setDetailed] = useState<any>({});
useEffect(() => {
}, []);
return (
<PageHeaderWrapper
title={
<>
<PageHeader
style={{ padding: '0' }}
onBack={() => history.goBack()}
title={
<HeadInfo
info={{
name: '广州市极致皮具有限公司',
level: 1,
}}
/>
}
extra={(
<>
<Button
icon={<StopOutlined />}
onClick={() => {}}
>
冻结
</Button>
<Button
type="primary"
icon={<SettingOutlined />}
onClick={() => {}}
>
解冻
</Button>
</>
)}
>
<Descriptions
size="small"
column={3}
style={{
padding: '0 32px',
}}
>
<Descriptions.Item label="会员类型">{123}</Descriptions.Item>
<Descriptions.Item label="会员角色" span={2}>{123}</Descriptions.Item>
<Descriptions.Item label="会员状态">
<Tag color={STATUS_COLOR_MAP[1]}>{STATUS_COLOR_TXT[1]}</Tag>
</Descriptions.Item>
<Descriptions.Item label="外部状态">
<Tag color={STATUS_COLOR_MAP[2]}>{STATUS_COLOR_TXT[2]}</Tag>
</Descriptions.Item>
</Descriptions>
</PageHeader>
</>
}
>
<div
style={{
marginBottom: 24,
}}
>
<AuditProcess />
</div>
<BasicInfo />
</PageHeaderWrapper>
);
};
export default MaintainDetail;
export default maintainDetail;
import React from 'react';
import AuditDetail from '../components/auditDetail';
import React, { useState, useEffect } from 'react';
import { history } from 'umi';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { PageHeader, Tag, Descriptions, Button } from 'antd';
import { FormOutlined, StopOutlined } from '@ant-design/icons';
import { STATUS_COLOR_MAP, STATUS_COLOR_TXT } from '../constant';
import { usePageStatus } from '@/hooks/usePageStatus';
import { PublicApi } from '@/services/api';
import MellowCard from '@/components/MellowCard';
import HeadInfo from '../components/HeadInfo';
import AuditProcess from '../components/AuditProcess';
import BasicInfo from '../components/BasicInfo';
import styles from './index.less';
const auditPr = (props: any) => {
return <AuditDetail auditType="2" routeParams={props.location.query} />;
const auditPr1: React.FC<{}> = () => {
const { pageStatus, id, validateId } = usePageStatus();
const [detailed, setDetailed] = useState<any>({});
useEffect(() => {
}, []);
return (
<PageHeaderWrapper
title={
<>
<PageHeader
style={{ padding: 0 }}
onBack={() => history.goBack()}
title={
<HeadInfo
info={{
name: '广州市极致皮具有限公司',
level: 1,
}}
/>
}
extra={(
<>
<Button
icon={<StopOutlined />}
onClick={() => {}}
>
审核不通过
</Button>
<Button
type="primary"
icon={<FormOutlined />}
onClick={() => {}}
>
提交审核
</Button>
</>
)}
>
<Descriptions
size="small"
column={3}
style={{
padding: '0 32px',
}}
>
<Descriptions.Item label="会员类型">{123}</Descriptions.Item>
<Descriptions.Item label="会员角色" span={2}>{123}</Descriptions.Item>
<Descriptions.Item label="会员状态">
<Tag color={STATUS_COLOR_MAP[1]}>{STATUS_COLOR_TXT[1]}</Tag>
</Descriptions.Item>
<Descriptions.Item label="外部状态">
<Tag color={STATUS_COLOR_MAP[2]}>{STATUS_COLOR_TXT[2]}</Tag>
</Descriptions.Item>
</Descriptions>
</PageHeader>
</>
}
>
<div
style={{
marginBottom: 24,
}}
>
<AuditProcess />
</div>
<BasicInfo />
</PageHeaderWrapper>
);
};
export default auditPr;
export default auditPr1;
import React from 'react';
import AuditDetail from '../components/auditDetail';
import React, { useState, useEffect } from 'react';
import { history } from 'umi';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { PageHeader, Tag, Descriptions, Button } from 'antd';
import { FormOutlined, StopOutlined } from '@ant-design/icons';
import { STATUS_COLOR_MAP, STATUS_COLOR_TXT } from '../constant';
import { usePageStatus } from '@/hooks/usePageStatus';
import { PublicApi } from '@/services/api';
import MellowCard from '@/components/MellowCard';
import HeadInfo from '../components/HeadInfo';
import AuditProcess from '../components/AuditProcess';
import BasicInfo from '../components/BasicInfo';
import styles from './index.less';
const auditPr = (props: any) => {
return <AuditDetail auditType="3" routeParams={props.location.query} />;
const auditPr2: React.FC<{}> = () => {
const { pageStatus, id, validateId } = usePageStatus();
const [detailed, setDetailed] = useState<any>({});
useEffect(() => {
}, []);
return (
<PageHeaderWrapper
title={
<>
<PageHeader
style={{ padding: 0 }}
onBack={() => history.goBack()}
title={
<HeadInfo
info={{
name: '广州市极致皮具有限公司',
level: 1,
}}
/>
}
extra={(
<>
<Button
icon={<StopOutlined />}
onClick={() => {}}
>
审核不通过
</Button>
<Button
type="primary"
icon={<FormOutlined />}
onClick={() => {}}
>
提交审核
</Button>
</>
)}
>
<Descriptions
size="small"
column={3}
style={{
padding: '0 32px',
}}
>
<Descriptions.Item label="会员类型">{123}</Descriptions.Item>
<Descriptions.Item label="会员角色" span={2}>{123}</Descriptions.Item>
<Descriptions.Item label="会员状态">
<Tag color={STATUS_COLOR_MAP[1]}>{STATUS_COLOR_TXT[1]}</Tag>
</Descriptions.Item>
<Descriptions.Item label="外部状态">
<Tag color={STATUS_COLOR_MAP[2]}>{STATUS_COLOR_TXT[2]}</Tag>
</Descriptions.Item>
</Descriptions>
</PageHeader>
</>
}
>
<div
style={{
marginBottom: 24,
}}
>
<AuditProcess />
</div>
<BasicInfo />
</PageHeaderWrapper>
);
};
export default auditPr;
export default auditPr2;
import React from 'react';
import AuditDetail from '../components/auditDetail';
import React, { useState, useEffect } from 'react';
import { history } from 'umi';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { PageHeader, Tag, Descriptions, Button } from 'antd';
import { FormOutlined, StopOutlined } from '@ant-design/icons';
import { STATUS_COLOR_MAP, STATUS_COLOR_TXT } from '../constant';
import { usePageStatus } from '@/hooks/usePageStatus';
import { PublicApi } from '@/services/api';
import MellowCard from '@/components/MellowCard';
import HeadInfo from '../components/HeadInfo';
import AuditProcess from '../components/AuditProcess';
import BasicInfo from '../components/BasicInfo';
import styles from './index.less';
const auditPrConfirm = props => {
return <AuditDetail auditType="4" routeParams={props.location.query} />;
const auditPrComfirm: React.FC<{}> = () => {
const { pageStatus, id, validateId } = usePageStatus();
const [detailed, setDetailed] = useState<any>({});
useEffect(() => {
}, []);
return (
<PageHeaderWrapper
title={
<>
<PageHeader
style={{ padding: '0' }}
onBack={() => history.goBack()}
title={
<HeadInfo
info={{
name: '广州市极致皮具有限公司',
level: 1,
}}
/>
}
extra={(
<>
<Button
icon={<StopOutlined />}
onClick={() => {}}
>
审核不通过
</Button>
<Button
type="primary"
icon={<FormOutlined />}
onClick={() => {}}
>
审核通过
</Button>
</>
)}
>
<Descriptions
size="small"
column={3}
style={{
padding: '0 32px',
}}
>
<Descriptions.Item label="会员类型">{123}</Descriptions.Item>
<Descriptions.Item label="会员角色" span={2}>{123}</Descriptions.Item>
<Descriptions.Item label="会员状态">
<Tag color={STATUS_COLOR_MAP[1]}>{STATUS_COLOR_TXT[1]}</Tag>
</Descriptions.Item>
<Descriptions.Item label="外部状态">
<Tag color={STATUS_COLOR_MAP[2]}>{STATUS_COLOR_TXT[2]}</Tag>
</Descriptions.Item>
</Descriptions>
</PageHeader>
</>
}
>
<div
style={{
marginBottom: 24,
}}
>
<AuditProcess />
</div>
<BasicInfo />
</PageHeaderWrapper>
);
};
export default auditPrConfirm;
export default auditPrComfirm;
......@@ -2,7 +2,7 @@ import React from 'react';
import AuditList from '../components/auditList';
const memberPrConfirm = () => {
return <AuditList pageType="3" />;
return <AuditList pageType="4" />;
};
export default memberPrConfirm;
import React from 'react';
import AuditDetail from '../components/auditDetail';
import React, { useState, useEffect } from 'react';
import { history } from 'umi';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { PageHeader, Tag, Descriptions, Button } from 'antd';
import { FormOutlined } from '@ant-design/icons';
import { STATUS_COLOR_MAP, STATUS_COLOR_TXT } from '../constant';
import { usePageStatus } from '@/hooks/usePageStatus';
import { PublicApi } from '@/services/api';
import MellowCard from '@/components/MellowCard';
import HeadInfo from '../components/HeadInfo';
import AuditProcess from '../components/AuditProcess';
import BasicInfo from '../components/BasicInfo';
import styles from './index.less';
const auditPrSubmit = props => {
return <AuditDetail auditType="1" routeParams={props.location.query} />;
const auditPrSubmit: React.FC<{}> = () => {
const { pageStatus, id, validateId } = usePageStatus();
const [detailed, setDetailed] = useState<any>({});
useEffect(() => {
}, []);
return (
<PageHeaderWrapper
title={
<>
<PageHeader
style={{ padding: 0 }}
onBack={() => history.goBack()}
title={
<HeadInfo
info={{
name: '广州市极致皮具有限公司',
level: 1,
}}
/>
}
extra={(
<Button
type="primary"
icon={<FormOutlined />}
onClick={() => {}}
>
提交审核
</Button>
)}
>
<Descriptions
size="small"
column={3}
style={{
padding: '0 32px',
}}
>
<Descriptions.Item label="会员类型">{123}</Descriptions.Item>
<Descriptions.Item label="会员角色" span={2}>{123}</Descriptions.Item>
<Descriptions.Item label="会员状态">
<Tag color={STATUS_COLOR_MAP[1]}>{STATUS_COLOR_TXT[1]}</Tag>
</Descriptions.Item>
<Descriptions.Item label="外部状态">
<Tag color={STATUS_COLOR_MAP[2]}>{STATUS_COLOR_TXT[2]}</Tag>
</Descriptions.Item>
</Descriptions>
</PageHeader>
</>
}
>
<div
style={{
marginBottom: 24,
}}
>
<AuditProcess />
</div>
<BasicInfo />
</PageHeaderWrapper>
);
};
export default auditPrSubmit;
import React from 'react';
import { Steps } from 'antd';
import MellowCard from '@/components/MellowCard';
import BasicInfo from '../../components/BasicInfo';
const MemberBasicInfo: React.FC<{}> = () => {
return (
<div>
<MellowCard
title="外部审核流程"
style={{
marginBottom: 24,
}}
>
<Steps style={{ marginTop: 30 }} progressDot current={2}>
<Steps.Step title="业务角色" description="申请审核" />
<Steps.Step title="业务角色" description="审核会员" />
<Steps.Step title="完成" description="" />
</Steps>
</MellowCard>
<BasicInfo />
</div>
);
};
export default MemberBasicInfo;
\ No newline at end of file
import React from 'react';
import Info from '../../components/EquityInfo';
const EquityInfo: React.FC<{}> = () => {
return (
<div>
<Info />
</div>
);
};
export default EquityInfo;
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import { history } from 'umi';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { PageHeader, Tag, Descriptions, Steps } from 'antd';
import { STATUS_COLOR_MAP, STATUS_COLOR_TXT } from '../../constant';
import { usePageStatus } from '@/hooks/usePageStatus';
import { PublicApi } from '@/services/api';
import HeadInfo from '../../components/HeadInfo';
import styles from './index.less';
interface QueryProps {
match: {
url: string;
path: string;
};
location: {
pathname: string;
};
}
const MemberQueryDetailed: React.FC<QueryProps> = props => {
const { children } = props;
const { pageStatus, id, validateId } = usePageStatus();
const [detailed, setDetailed] = useState<any>({});
useEffect(() => {
}, []);
const tabList = [
{
key: 'basicInfo',
tab: '基本信息',
},
{
key: 'powerInfo',
tab: '权限信息',
},
{
key: 'levelInfo',
tab: '等级信息',
},
{
key: 'equityInfo',
tab: '权益信息',
},
{
key: 'sincerityInfo',
tab: '诚信信息',
},
];
const handleTabChange = (val: string) => {
const { match } = props;
const url = match.url === '/' ? '' : match.url;
switch (val) {
case 'basicInfo':
history.push(`${url}/basicInfo`);
break;
case 'powerInfo':
history.push(`${url}/powerInfo`);
break;
case 'levelInfo':
history.push(`${url}/levelInfo`);
break;
case 'equityInfo':
history.push(`${url}/equityInfo`);
break;
case 'sincerityInfo':
history.push(`${url}/sincerityInfo`);
break;
default:
break;
}
};
const getTabKey = () => {
const { match, location } = props;
const url = match.path === '/' ? '' : match.path;
const tabKey = location.pathname.replace(`${url}/`, '');
if (tabKey && tabKey !== '/') {
return tabKey;
}
return 'basicInfo';
};
return (
<PageHeaderWrapper
title={
<>
<PageHeader
style={{ padding: '0' }}
onBack={() => history.goBack()}
title={
<HeadInfo
info={{
name: '广州市极致皮具有限公司',
level: 1,
}}
/>
}
>
<Descriptions
size="small"
column={2}
style={{
padding: '0 32px',
}}
>
<Descriptions.Item label="会员类型">{123}</Descriptions.Item>
<Descriptions.Item label="会员角色">{123}</Descriptions.Item>
<Descriptions.Item label="会员状态">
<Tag color={STATUS_COLOR_MAP[1]}>{STATUS_COLOR_TXT[1]}</Tag>
</Descriptions.Item>
<Descriptions.Item label="外部状态">
<Tag color={STATUS_COLOR_MAP[2]}>{STATUS_COLOR_TXT[2]}</Tag>
</Descriptions.Item>
</Descriptions>
</PageHeader>
</>
}
tabList={tabList}
tabActiveKey={getTabKey()}
onTabChange={handleTabChange}
>
{children}
</PageHeaderWrapper>
);
};
export default MemberQueryDetailed;
\ No newline at end of file
import React from 'react';
import Info from '../../components/LevelInfo';
const LevelInfo: React.FC<{}> = () => {
return (
<div>
<Info />
</div>
);
};
export default LevelInfo;
\ No newline at end of file
import React from 'react';
const PowerInfo: React.FC<{}> = () => {
return (
<div>123</div>
);
};
export default PowerInfo;
\ No newline at end of file
import React from 'react';
import Info from '../../components/SincerityInfo';
const SincerityInfo: React.FC<{}> = () => {
return (
<div>
<Info />
</div>
);
};
export default SincerityInfo;
\ No newline at end of file
import React, { ReactNode, useState, useRef } from 'react';
import { history } from 'umi';
import {
Card,
Space,
Button,
Menu,
Popconfirm,
Dropdown,
Badge,
Modal,
} from 'antd';
import {
PlusOutlined,
DeleteOutlined,
ClockCircleOutlined,
DownOutlined,
} from '@ant-design/icons';
import { StandardTable } from 'god';
import { ColumnType } from 'antd/lib/table/interface';
import { createFormActions, FormEffectHooks } from '@formily/antd';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import EyePreview from '@/components/EyePreview';
import StatusSwitch from '@/components/StatusSwitch';
import NiceForm from '@/components/NiceForm';
import LevelBrand from '../components/LevelBrand';
import { maintianSchema } from './schema';
import { PublicApi } from '@/services/api';
const mock = [
{
memberId: 1,
validateId: 1,
name: '模拟会员1',
memberTypeName: '模拟会员类型1',
roleName: '模拟角色',
sourceName: '2020.08.28 15:14:00',
memberStatus: '正常',
status: 1,
outerStatusName: '待审核',
innerStatusName: '审核通过',
},
{
memberId: 2,
validateId: 2,
name: '模拟会员1',
memberTypeName: '模拟会员类型1',
roleName: '模拟角色',
sourceName: '2020.08.28 15:14:00',
memberStatus: '正常',
status: 0,
outerStatusName: '待审核',
innerStatusName: '待提交审核',
},
];
const formActions = createFormActions();
const fetchData = async (params: any) => {
let res = await PublicApi.getMemberMaintenancePage(params);
return res.data;
};
const memberQuery: React.FC<[]> = () => {
const ref = useRef<any>({});
const [selectedRowKeys, setSelectedRowKeys] = useState<Array<string>>([]);
const defaultColumns: ColumnType<any>[] = [
{
title: 'ID',
dataIndex: 'memberId',
align: 'center',
},
{
title: '会员归属',
dataIndex: 'name',
align: 'center',
render: (text, record) => (
<EyePreview
url={`/memberCenter/memberAbility/query/detailed?id=${record.memberId}&validateId=${record.validateId}&preview=1`}
>
{text}
</EyePreview>
),
},
{
title: '会员类型',
dataIndex: 'memberTypeName',
align: 'center',
render: (text, record) => <>{text}</>,
},
{
title: '会员角色',
dataIndex: 'roleName',
align: 'center',
render: (text, record) => <>{text}</>,
},
{
title: '所属会员等级',
dataIndex: 'level',
align: 'center',
render: (text, record) => <LevelBrand level={2} />,
},
{
title: '操作时间',
dataIndex: 'sourceName',
align: 'center',
},
{
title: '会员状态',
dataIndex: 'outerStatusName',
align: 'center',
filters: [],
// filteredValue: searchForm.outerStatus || ['0'],
filterMultiple: false,
render: (text, record) => <span>{text}</span>,
},
{
title: '审核状态',
dataIndex: 'innerStatusName',
align: 'center',
filters: [],
// filteredValue: searchForm.innerStatus || ['0'],
filterMultiple: false,
render: (text, record) => <Badge color="#FFC400" text={text} />,
},
{
title: '操作',
dataIndex: 'option',
align: 'center',
render: (text, record) => (
<Button
type="link"
onClick={() => {}}
style={{ color: '#00B37A' }}
>
变更信息
</Button>
),
},
];
const rowSelection = {
onChange: (selectedRowKeys: any, selectedRows: any) => {
setSelectedRowKeys(selectedRowKeys);
},
selectedRowKeys: selectedRowKeys,
};
const [columns, setColumns] = useState<any[]>(defaultColumns);
// 更改会员状态
const handleModify = record => {
PublicApi.postMemberMaintenanceStatus({
memberId: record.memberId,
validateId: record.validateId,
status: record.status === 1 ? 0 : 1,
}).then(res => {
if (res.code === 1000) return ref.current.reload();
});
};
// 初始化高级筛选选项
const fetchSelectOptions = async () => {
const res = await PublicApi.getMemberValidateCommitPageitems();
if (res.code === 1000) {
const { data } = res;
return {
memberType: fetchFilterOptions(data.memberTypes),
roleId: fetchFilterOptions(data.memberRoles),
level: fetchFilterOptions(data.memberLevels),
source: fetchFilterOptions(data.memberSource),
};
}
return {};
};
const fetchFilterOptions = data => {
return data.map(v => ({ label: v.text, value: v.id }));
};
return (
<Card>
<StandardTable
tableProps={{
rowKey: 'memberId',
// onChange: (pagination: any, filter: any) => handleSearch(filter),
dataSource: mock,
}}
columns={columns}
currentRef={ref}
fetchTableData={(params: any) => fetchData(params)}
rowSelection={rowSelection}
controlRender={
<NiceForm
actions={formActions}
onSubmit={values => ref.current.reload(values)}
effects={($, actions) => {
useStateFilterSearchLinkageEffect(
$,
actions,
'name',
FORM_FILTER_PATH,
);
// useAsyncInitSelect(
// ['memberType', 'roleId', 'level', 'source'],
// fetchSelectOptions,
// );
}}
schema={maintianSchema}
/>
}
/>
</Card>
);
};
export default memberQuery;
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { UPLOAD_TYPE } from '@/constants'
export const maintianSchema: ISchema = {
type: 'object',
properties: {
megaLayout: {
type: 'object',
'x-component': 'mega-layout',
properties: {
name: {
type: 'string',
'x-component': 'Search',
'x-component-props': {
placeholder: '搜索',
align: 'flex-left',
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
grid: true,
full: true,
autoRow: true,
columns: 6,
},
properties: {
memberType: {
type: 'string',
'x-component-props': {
placeholder: '请选择',
defaultValue: undefined,
},
enum: [],
},
roleId: {
type: 'string',
'x-component-props': {
placeholder: '请选择',
defaultValue: undefined,
},
enum: [],
},
level: {
type: 'string',
'x-component-props': {
placeholder: '请选择',
defaultValue: undefined,
},
enum: [],
},
source: {
type: 'string',
'x-component-props': {
placeholder: '请选择',
defaultValue: undefined,
},
enum: [],
},
timeRange: {
type: 'string',
'x-component-props': {
placeholder: '请选择',
defaultValue: undefined,
},
enum: [
{ label: '时间范围(全部)', value: 0 },
{ label: '今天', value: 1 },
{ label: '一周内', value: 2 },
{ label: '一个月内', value: 3 },
{ label: '三个月内', value: 4 },
{ label: '六个月内', value: 5 },
{ label: '一年内', value: 6 },
{ label: '一年前', value: 7 },
],
},
submit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: '查询',
},
},
},
},
},
},
},
};
/*
* @Author: LeeJiancong
* @Date: 2020-08-28 10:07:45
* @LastEditors: LeeJiancong
* @Copyright: 1549414730@qq.com
* @LastEditTime: 2020-08-29 10:16:45
*/
import React, { Component, useState, useEffect } from 'react';
import { Modal, Button, Form, Radio, Tabs, Input, Select,Checkbox } from 'antd'
import { PublicApi } from '@/services/api'
const { TabPane } = Tabs
const { Option } = Select
const {TextArea} = Input
export interface Params {
sourceData: Array<any>[],
id?: any,
mode: number,
type?: number | string,
dialogVisible: boolean;
onCancel: Function;
onOK?: Function;
initialValues?: any;
dontReceive?: boolean; //默认展示
}
const layout = {
labelCol: {
span: 4
},
wrapperCol: {
span: 20
}
}
/**
* @description: 保存 提交表单
* @param {type}
* @return {type}
*/
const comfirmDialog: React.FC<Params> = (props) => {
console.log('数据',props.sourceData)
const [form] = Form.useForm()
const [placeOfOriginList, setplaceOfOriginList] = useState([])//产地
const handleCancel = () => {
}
const handletOk = () => {
form.validateFields().then(v => {
console.log('表单', v)
props.onOK(v)
})
// if(props.type){
// value.type = props.type
// }
// console.log('列表',value)
}
useEffect(() => {
return () => {
}
}, [])
const onChange = (value, attrItem) => {
}
const renderTabPanchildren = (item: any) => {
console.log('子项',item)
return (
<>
{
item.attributeList.map((attrItem:any) => {
return (
<>
{
attrItem.type === 1 &&
<Form.Item
name={attrItem.name}
label={attrItem.name}
rules={attrItem.isEmpty && [{
required: true,
message: '此项为必填项'
}]}
>
<Select
placeholder="请选择"
allowClear
onChange={(v)=>onChange(v, attrItem)}
>
{
attrItem.attributeValueList && attrItem.attributeValueList.map((item: any) => (
<Option key={item.id} value={item.id}>{item.value}</Option>
))
}
</Select>
</Form.Item>
}
{
attrItem.type === 2 &&
<Form.Item
label={attrItem.name}
name={attrItem.id}
rules={attrItem.isEmpty && [{
required: true,
message: '此项为必填项'
}]}
>
{/* <Checkbox.Group onChange={(v)=>onChange(v, attrItem)}>
{
attrItem.customerAttributeValueList.length && attrItem.customerAttributeValueList.map((item: any, index: string) => (
<Checkbox key={item.id} value={item.id}>{item.value}</Checkbox>
))
}
</Checkbox.Group> */}
</Form.Item>
}
{
attrItem.type === 3 &&
<Form.Item
name={attrItem.id}
label={attrItem.name}
rules={attrItem.isEmpty && [{
required: true,
message: '此项为必填项'
}]}
>
{/* <TextArea onChange={(v)=>onChange(v, attrItem)} maxLength={100} placeholder="最多输入100个字符" rows={4} /> */}
</Form.Item>
}
</>
)
})
}
</>
)
}
return (
<>
<Modal
title={props.mode === 0 ? '新增商品' : '查看商品'}
width={800}
visible={props.dialogVisible}
onOk={() => handletOk()}
onCancel={() => props.onCancel()}
destroyOnClose
afterClose={() => { }}
okText={`确定`}
cancelText='取消'
>
<Form
{...layout}
colon={false}
labelAlign="left"
form={form}
autoComplete="off"
>
<Tabs defaultActiveKey='tab1'
tabPosition="left"
>
<Tabs.TabPane tab='基本信息' key="tab-1">
<Form.Item
label='规格型号'
name='model'
required
>
<Input placeholder='' />
</Form.Item>
<Form.Item
label='商品品牌'
name='brand'
required
>
<Input placeholder='' />
</Form.Item>
</Tabs.TabPane>
{
/**
* @description: 动态循环
* @param {type}
* @return {type}
*/
}
{
props.sourceData.length > 0 && props.sourceData.map((attributeItem:any) => <>
<TabPane tab={attributeItem.name} key={attributeItem.id}>
{
renderTabPanchildren(attributeItem)
}
</TabPane>
</>
)
}
<Tabs.TabPane tab='采购数量' key="tab-7">
<Form.Item
label='单位'
name='purchaseNuit'
required
>
<Input placeholder='' />
</Form.Item>
<Form.Item
label='采购数量'
name='purchaseQuantity'
required
>
<Input placeholder='' />
</Form.Item>
</Tabs.TabPane>
</Tabs>
</Form>
</Modal>
</>
)
}
comfirmDialog.defaultProps = {
dontReceive: true,
type: 1 //1.支付宝 2.支付宝转账到银行卡参数配置 3.微信
}
export default comfirmDialog
\ No newline at end of file
......@@ -3,7 +3,7 @@
* @Date: 2020-08-27 16:27:53
* @LastEditors: LeeJiancong
* @Copyright: 1549414730@qq.com
* @LastEditTime: 2020-08-27 16:34:59
* @LastEditTime: 2020-08-29 14:29:40
*/
import { ColumnType } from 'antd/lib/table/interface'
export const equiryColumns: ColumnType<any>[] = [
......@@ -69,52 +69,49 @@ export const equiryColumns: ColumnType<any>[] = [
export const dockingList: ColumnType<any>[] = [
{
title: '序号',
dataIndex: 'memberId',
dataIndex: 'id',
align: 'center',
key: 'memberId',
key: 'id',
},
{
title: '公司名称',
dataIndex: 'name',
key: 'name',
title: '会员名称',
dataIndex: 'memberName',
key: 'memberName',
align: 'left'
},
{
title: '公司地址',
dataIndex: 'roleName',
key: 'roleName',
align: 'center'
},
{
title: '成立日期',
dataIndex: 'roleName',
key: 'roleName',
title: '会员类型',
dataIndex: 'memberTypeName',
key: 'memberTypeName',
align: 'center'
},
{
title: '公司规模',
title: '会员角色',
dataIndex: 'roleName',
key: 'roleName',
align: 'center'
},
{
title: '诚信度',
dataIndex: 'roleName',
key: 'roleName',
title: '会员等级',
dataIndex: 'levelTag',
key: 'levelTag',
align: 'center'
},
{
title: '是否归属会员',
dataIndex: 'roleName',
key: 'roleName',
align: 'center'
dataIndex: 'membershipOrNot',
key: 'membershipOrNot',
align: 'center',
render:(text:any) => (
text == 0 ?'否':'是'
)
},
{
title: '状态',
dataIndex: 'levelTag',
key: 'levelTag',
dataIndex: 'state',
key: 'state',
align: 'center'
},
{
......
......@@ -388,27 +388,8 @@ export const getQueryStringParams = (url?: string) => {
return queryString.parse(searchParam)
}
/**
* 节流函数
* @param {func} func 需要执行的函数
* @param {number} delay 间隔
*/
export function debounce(func: (any?) => void, delay: number) {
let timer = null;
return function (...args) {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
func.apply(this, args);
}, delay);
}
}
export default {
isArray,
isObject,
omit,
debounce,
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment