Commit 6b7c9463 authored by XieZhiXiong's avatar XieZhiXiong

对接会员维护相关接口

parent da792376
......@@ -58,6 +58,13 @@ const memberAbility =
component: '@/pages/member/memberMaintain/detailed/sincerityInfo',
hideInMenu: true,
},
{
path: '/memberAbility/manage/maintainDetail/powerInfo',
name: 'powerInfo',
key: 'powerInfo',
component: '@/pages/member/memberMaintain/detailed/powerInfo',
hideInMenu: true,
},
],
},
{
......
......@@ -58,9 +58,11 @@ const CheckboxTree: React.FC<CheckboxTreeProps> = props => {
<div className="flex-bet">
<div>{props.title}</div>
<div>
<Button onClick={toggleSelectAll} type="link" disabled={disabled}>
{allSelected ? '取消全选' : '全选'}
</Button>
{!disabled && (
<Button onClick={toggleSelectAll} type="link">
{allSelected ? '取消全选' : '全选'}
</Button>
)}
{showSave && (
<Button onClick={handleSubmit} type="link" disabled={disabled}>
保存
......
......@@ -15,7 +15,9 @@ const Search = props => {
const [state, setState] = useFieldState({
filterSearch: false,
});
const justifyAlign = props.props['x-component-props'].align || 'flex-end';
const { align, advanced = true, ...rest } = props.props['x-component-props'];
const justifyAlign = align || 'flex-end';
const changeFilterVisible = () => {
if (state.filterSearch) {
props.form.reset({
......@@ -36,12 +38,14 @@ const Search = props => {
e.preventDefault();
props.form.submit();
}}
{...props.props['x-component-props']}
{...rest}
/>
<Button onClick={changeFilterVisible}>
高级筛选
{state.filterSearch ? <CaretUpOutlined /> : <CaretDownOutlined />}
</Button>
{advanced && (
<Button onClick={changeFilterVisible}>
高级筛选
{state.filterSearch ? <CaretUpOutlined /> : <CaretDownOutlined />}
</Button>
)}
<Button
onClick={() => {
props.form.reset();
......
......@@ -298,7 +298,7 @@ const TabTree: React.FC<TabTreeProps> = props => {
{title && (
<div className="god-tabtree-header">
<div>{title}</div>
{checkable && (
{checkable && !disabled && (
<Button onClick={toggleSelectAll} disabled={disabled} type="link">
{allSelected ? '取消全选' : '全选'}
</Button>
......
......@@ -39,4 +39,24 @@
/* autoprefixer: on */
-webkit-line-clamp: @line;
overflow: hidden;
}
.silkyScrollbar() {
&::-webkit-scrollbar {
height: 8px;
width: 6px;
background: #f0f2f5;
border-radius: 5px;
}
&::-webkit-scrollbar-button {
display: none;
}
&::-webkit-scrollbar-thumb {
width: 8px;
min-height: 15px;
background: rgba(0,0,0,.2);
border-radius: 5px;
}
}
\ No newline at end of file
......@@ -66,6 +66,7 @@ export default {
'menu.memberAbility.maintainDetail.levelInfo': '会员等级信息',
'menu.memberAbility.maintainDetail.equityInfo': '权益信息',
'menu.memberAbility.maintainDetail.sincerityInfo': '诚信信息',
'menu.memberAbility.maintainDetail.powerInfo': '权限信息',
'menu.memberAbility.maintainFrozen': '会员冻结',
'menu.memberAbility.memberPrSubmit': '待提交审核',
'menu.memberAbility.auditPrSubmit': '待提交审核详情',
......
@import '../../../../global/styles/utils.less';
.equityInfo {
.container {
display: flex;
......@@ -9,7 +11,7 @@
border-radius: 8px;
&-title {
margin-bottom: 24px;
margin-bottom: 20px;
line-height: 24px;
font-size: 16px;
font-weight: 500;
......@@ -23,11 +25,14 @@
.tofo {
display: flex;
padding: 0;
padding: 0 0 4px;
margin: 0;
min-height: 101px;
overflow-x: auto;
.silkyScrollbar();
&-item {
flex: 1;
flex: 0 0 33.333%;
list-style: none;
&-logo {
......
......@@ -3,17 +3,13 @@ import {
Row,
Col,
Tabs,
Tooltip,
} 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 '@/asserts/equity-1.png';
import equity2 from '@/asserts/equity-2.png';
import equity3 from '@/asserts/equity-3.png';
import equity4 from '@/asserts/equity-4.png';
import equity5 from '@/asserts/equity-5.png';
import styles from './index.less';
const { TabPane } = Tabs;
......@@ -47,12 +43,28 @@ export interface EquityInfoProps {
sumReturnMoney?: number, // 累计返现金额
sumUsedPoint?: number, // 已用积分
sumPoint?: number, // 累计积分
rights?: {
acquireWay: string,
id: number,
name: string,
paramWay: string,
parameter: string,
remark: string,
rightTypeEnum: number,
status: number,
}[];
};
fetchReceivedList?: (params: FetchParams) => Promise<{ data: ReceivedData[] , totalCount: number }>;
fetchUsageList?: (params: FetchParams) => Promise<{ data: UsageData[] , totalCount: number }>;
}
const equityTxtMap = {
1: '折扣',
2: '返现',
3: '积分',
};
const EquityInfo: React.FC<EquityInfoProps> = ({
equityInfo = {},
fetchReceivedList,
......@@ -216,44 +228,26 @@ const EquityInfo: React.FC<EquityInfoProps> = ({
<div className={styles['container-content']}>
<ul className={styles.tofo}>
<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-price'])}>95% 折扣</span>
</div>
</li>
<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-recurrence'])}>0.1% 返现</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-integral'])}>1% 积分</span>
</div>
</li>
{equityInfo.rights ? equityInfo.rights.map(item => (
<li key={item.id} className={styles['tofo-item']}>
<div className={styles['tofo-item-logo']}>
<img src={require(`@/asserts/equity-${item.rightTypeEnum}.png`)} />
</div>
<div className={styles['tofo-item-title']}>
{item.name}
<Tooltip title={item.remark}>
<QuestionCircleOutlined />
</Tooltip>
</div>
<div className={styles['tofo-item-extra']}>
<span
className={classNames(styles['tofo-item-tag'], styles['tofo-item-tag-price'])}
>
{item.parameter} {equityTxtMap[item.rightTypeEnum] || ''}
</span>
</div>
</li>
)) : null}
</ul>
</div>
</div>
......@@ -275,7 +269,7 @@ const EquityInfo: React.FC<EquityInfoProps> = ({
<div className={styles['exhibition-right']}>
<div className={styles['exhibition-logo']}>
<img src={equity4} />
<img src={require(`@/asserts/equity-4.png`)} />
</div>
</div>
</div>
......@@ -298,7 +292,7 @@ const EquityInfo: React.FC<EquityInfoProps> = ({
<div className={styles['exhibition-right']}>
<div className={styles['exhibition-logo']}>
<img src={equity5} />
<img src={require(`@/asserts/equity-5.png`)} />
</div>
</div>
</div>
......
import React, { useState, useRef } from 'react';
import { Row, Col, Modal } from 'antd';
import { useTreeTabs, FormState } from '@/hooks/useTreeTabs';
import MellowCard from '@/components/MellowCard';
import TabTree, { createTreeActions } from '@/components/TabTree';
import CheckboxTree from '@/components/CheckBoxTree';
import styles from './index.less';
const treeActions = createTreeActions();
const PowerInfo: React.FC<{}> = () => {
const [powerLoading, setPowerLoading] = useState(false);
const [buttonInfos, setButtonInfos] = useState<any>([]);
const actionRef = useRef<any>({});
// 获取左侧已选择的项
const getMenuSelectData = async () => {
setPowerLoading(true);
const res = await PublicApi.getMemberValidateTreeCheckids({
memberId: id,
validateId: validateId,
});
setPowerLoading(false);
if (res.code === 1000) {
const { checkIds } = res.data;
return { data: { ids: checkIds } };
}
return {
data: {
ids: [],
},
};
};
// 获取左边菜单
const fetchMenuData = async () => {
const res = await PublicApi.getMemberValidateTree({
memberId: id,
validateId: validateId,
});
return res;
};
// 点击左侧菜单获取右侧按钮菜单、及已勾选的信息
const handleFindDetail = menuId => {
PublicApi.getMemberValidateCommitGetbutton({
menuId: menuId,
memberId: id,
validateId: validateId,
}).then(res => {
const { data } = res;
let buttons = data.buttons.map(v => ({ id: v.id, buttonName: v.name }));
setButtonInfos(buttons || []);
if (actionRef.current.setSelected) {
actionRef.current.setSelected(data.checkIds);
}
});
};
const customSelect = (selectKey?, node?) => {
// 首次新增菜单的时候没有节点信息
if (!node) {
setNodeRecord(null);
setTreeStatus(FormState.ADD);
return;
}
// key相等时 不刷新右侧表单
if (nodeRecord && nodeRecord.key === selectKey) {
setNodeRecord(node);
setTreeStatus(FormState.EDIT);
} else {
if (isEditForm) {
// 有填写过表单
return new Promise((resolve, reject) => {
Modal.confirm({
content: '确认要离开当前页面吗,您提交的数据尚未保存',
onOk() {
// 确认离开当前页, 需改变node state
setNodeRecord(node);
setTreeStatus(FormState.EDIT);
// 点击菜单,请求数据重置
handleFindDetail(selectKey);
setIsEditForm(false);
resolve();
},
onCancel() {
reject();
},
});
});
} else {
// 编辑页, 需回显
handleFindDetail(selectKey);
setNodeRecord(node);
setTreeStatus(FormState.EDIT);
}
}
};
const {
treeData,
handleSelect,
nodeRecord,
setNodeRecord,
setTreeStatus,
setIsEditForm,
isEditForm,
} = useTreeTabs({
fetchMenuData,
selectCallback: customSelect,
});
// 更新右侧按钮
const handleSubmitAuth = async () => {
const buttonIds = [...actionRef.current.selected];
if (!nodeRecord) {
return;
}
if (isEditForm) {
// 更新右侧按钮
await PublicApi.postMemberValidateCommitUpdatebutton({
memberId: id,
validateId,
menuId: nodeRecord.id,
buttonIds: buttonIds,
});
}
setIsEditForm(false);
};
return (
<Row>
<Col span={15}>
<MellowCard>
<TabTree
title="菜单列表"
getMenuSelectData={getMenuSelectData}
customKey="id"
actions={treeActions}
treeData={treeData}
handleSelect={handleSelect}
disabled={true}
checkable
/>
</MellowCard>
</Col>
<Col span={8} offset={1}>
<MellowCard>
<CheckboxTree
actions={actionRef}
disabled={true}
handleChange={e => setIsEditForm(true)}
checkedNodes={buttonInfos}
title="菜单按钮访问权限"
handleSubmit={handleSubmitAuth}
showSave
/>
</MellowCard>
</Col>
</Row>
);
};
export default PowerInfo
\ No newline at end of file
......@@ -6,6 +6,7 @@ import {
Card,
Tooltip,
Radio,
Button,
Spin,
} from 'antd';
import {
......@@ -416,12 +417,13 @@ const SincerityInfo: React.FC<SincerityInfoProps> = ({
};
// 获取交易评价记录列表
const getSalesRecordList = () => {
const getSalesRecordList = (extraParams: {[key: string]: any} = {}) => {
if (fetchSalesList) {
setSalesListLoading(true);
fetchSalesList({
current: salesPage,
pageSize: salesSize,
...extraParams,
}).then(res => {
const { data = [], totalCount = 0 } = (res || {});
setSalesList(data);
......@@ -433,12 +435,13 @@ const SincerityInfo: React.FC<SincerityInfoProps> = ({
};
// 获取售后评价记录列表
const getAfterRecordList = () => {
const getAfterRecordList = (extraParams: {[key: string]: any} = {}) => {
if (fetchAfterList) {
setAfterListLoading(true);
fetchAfterList({
current: afterPage,
pageSize: afterSize,
...extraParams,
}).then(res => {
const { data = [], totalCount = 0 } = (res || {});
setAfterList(data);
......@@ -520,6 +523,20 @@ const SincerityInfo: React.FC<SincerityInfoProps> = ({
getComplaintList();
};
const handleSalesRadioChange = value => {
setSalesPage(1);
getSalesRecordList({
starLevel: value,
});
};
const handleAfterRadioChange = value => {
setAfterPage(1);
getAfterRecordList({
starLevel: value,
});
};
return (
<div className={styles.sincerityInfo}>
<Row gutter={[0, 24]}>
......@@ -573,12 +590,12 @@ const SincerityInfo: React.FC<SincerityInfoProps> = ({
onChange={handleSalesTabChange}
tabBarExtraContent={
salesTabKey === 'evaluateRecord' ? (
<Radio.Group onChange={() => { }}>
<Radio.Button value="good">好评</Radio.Button>
<Radio.Button value="notBad">中评</Radio.Button>
<Radio.Button value="bad">差评</Radio.Button>
<Radio.Button value="all">全部</Radio.Button>
</Radio.Group>
<>
<Button type="text" onClick={() => handleSalesRadioChange(3)}>好评</Button>
<Button type="text" onClick={() => handleSalesRadioChange(2)}>中评</Button>
<Button type="text" onClick={() => handleSalesRadioChange(1)}>差评</Button>
<Button type="text" onClick={() => handleSalesRadioChange(0)}>全部</Button>
</>
) : null
}
>
......@@ -637,12 +654,12 @@ const SincerityInfo: React.FC<SincerityInfoProps> = ({
onChange={handleAfterTabChange}
tabBarExtraContent={
afterTabKey === 'evaluateRecord' ? (
<Radio.Group onChange={() => { }}>
<Radio.Button value="good">好评</Radio.Button>
<Radio.Button value="notBad">中评</Radio.Button>
<Radio.Button value="bad">差评</Radio.Button>
<Radio.Button value="all">全部</Radio.Button>
</Radio.Group>
<>
<Button type="text" onClick={() => handleAfterRadioChange(3)}>好评</Button>
<Button type="text" onClick={() => handleAfterRadioChange(2)}>中评</Button>
<Button type="text" onClick={() => handleAfterRadioChange(1)}>差评</Button>
<Button type="text" onClick={() => handleAfterRadioChange(0)}>全部</Button>
</>
) : null
}
>
......@@ -700,11 +717,11 @@ const SincerityInfo: React.FC<SincerityInfoProps> = ({
buttonStyle="solid"
onChange={() => { }}
>
<Radio.Button value="all">全部({complaintSumData?.sum})</Radio.Button>
<Radio.Button value="day7">最近7天({complaintSumData?.last7days})</Radio.Button>
<Radio.Button value="day30">最近30天({complaintSumData?.last30days})</Radio.Button>
<Radio.Button value="day180">最近180天({complaintSumData?.last180days})</Radio.Button>
<Radio.Button value="day180+">180天前({complaintSumData?.before180days})</Radio.Button>
<Button type="text">全部({complaintSumData?.sum})</Button>
<Button type="text">最近7天({complaintSumData?.last7days})</Button>
<Button type="text">最近30天({complaintSumData?.last30days})</Button>
<Button type="text">最近180天({complaintSumData?.last180days})</Button>
<Button type="text">180天前({complaintSumData?.before180days})</Button>
</Radio.Group>
</div>
......
......@@ -34,7 +34,7 @@ const AddMember: React.FC<any> = props => {
const getDetailedInfo = async () => {
if (id && validateId) {
setInfoLoading(true);
const infoRes = await PublicApi.getMemberAbilitySubGet({
const infoRes = await PublicApi.getMemberMaintenanceGetmember({
memberId: id,
validateId,
});
......@@ -45,11 +45,8 @@ const AddMember: React.FC<any> = props => {
const {
memberTypeEnum,
groups = [],
areaCodes,
account,
channelLevelTag,
channelTypeName,
countryCode,
createTime,
currentStep,
......@@ -78,8 +75,6 @@ const AddMember: React.FC<any> = props => {
setMemberInfo({
memberTypeId: memberTypeEnum,
...rest,
areas: areaCodes,
channelLevel: channelLevelTag,
...detail,
});
......@@ -88,7 +83,7 @@ const AddMember: React.FC<any> = props => {
};
useEffect(() => {
// getDetailedInfo();
getDetailedInfo();
}, []);
const handleSubmit = (values: any) => {
......@@ -103,6 +98,11 @@ const AddMember: React.FC<any> = props => {
outerStatus,
status,
statusName,
currentOuterStep,
level,
outerVerifySteps,
validateId,
...rest
} = values;
......@@ -124,6 +124,7 @@ const AddMember: React.FC<any> = props => {
if (res.code !== 1000) {
return;
}
setUnsaved(false);
setTimeout(() => {
history.goBack();
}, 800);
......@@ -137,30 +138,28 @@ const AddMember: React.FC<any> = props => {
content: '正在保存,请稍候...',
duration: 0,
});
// PublicApi.postMemberAbilitySubUpdate({
// memberId: id,
// validateId,
// memberTypeId,
// roleId,
// levelId,
// countryCodeId,
// phone,
// email,
// channelTypeId,
// remark,
// detail: rest,
// }).then(res => {
// if (res.code !== 1000) {
// return;
// }
// setUnsaved(false);
// setTimeout(() => {
// history.replace('/memberCenter/memberAbility/manage/import');
// }, 800);
// }).finally(() => {
// msg();
// setSubmitLoading(false);
// });
PublicApi.postMemberMaintenanceUpdatemember({
memberId: id,
validateId,
memberTypeId,
roleId,
levelId,
countryCodeId,
phone,
email,
detail: rest,
}).then(res => {
if (res.code !== 1000) {
return;
}
setUnsaved(false);
setTimeout(() => {
history.goBack();
}, 800);
}).finally(() => {
msg();
setSubmitLoading(false);
});
}
};
......@@ -222,14 +221,14 @@ const AddMember: React.FC<any> = props => {
if (!fieldState.value) {
return;
}
// PublicApi.getMemberAbilitySubPageitemsDetail({
// roleId: fieldState.value,
// }).then(res => {
// if (res.code === 1000) {
// const { data = [] } = res;
// setMemberItems(data);
// }
// });
PublicApi.getMemberMaintenanceAddpageitemsDetail({
roleId: fieldState.value,
}).then(res => {
if (res.code === 1000) {
const { data = [] } = res;
setMemberItems(data);
}
});
});
// 手动触发改变的话重置等级下拉框
......@@ -243,26 +242,29 @@ const AddMember: React.FC<any> = props => {
const selfName = fieldState.name;
const selfValue = fieldState.value;
const otherName = selfName == 'memberTypeId' ? 'roleId' : 'memberTypeId';
const otherValue = formActions.getFieldState(otherName, state => state.value);
if (selfValue && otherValue) {
linkage.loading('levelId');
PublicApi.getMemberMaintenanceAddpageitemsLevel({
memberTypeId: selfName == 'memberTypeId' ? selfValue : otherValue,
roleId: selfName == 'memberTypeId' ? otherValue : selfValue,
}, {
useCache: true,
}).then(res => {
if (res.code === 1000) {
const { data = [] } = res;
const options = data.map(item => ({ label: item.levelTag, value: item.levelId }));
linkage.enum('levelId', options);
}
}).finally(() => {
linkage.loaded('levelId');
});
}
setTimeout(() => {
const otherValue = formActions.getFieldState(otherName, state => state.value);
if (selfValue && otherValue) {
linkage.loading('levelId');
PublicApi.getMemberMaintenanceAddpageitemsLevel({
memberTypeId: selfName == 'memberTypeId' ? selfValue : otherValue,
roleId: selfName == 'memberTypeId' ? otherValue : selfValue,
}, {
useCache: true,
}).then(res => {
if (res.code === 1000) {
const { data = [] } = res;
const options = data.map(item => ({ label: item.levelTag, value: item.levelId }));
linkage.enum('levelId', options);
}
}).finally(() => {
linkage.loaded('levelId');
});
}
}, 0);
});
}
......
import React, { useState, useRef, useEffect } from 'react';
import { usePageStatus, PageStatus } from '@/hooks/usePageStatus';
import { Row, Col, Tabs, Steps, Badge } from 'antd';
import TabTree, {
useTreeActions,
createTreeActions,
} from '@/components/TabTree';
import CheckboxTree from '@/components/CheckBoxTree';
import { useTreeTabs } from '@/hooks/useTreeTabs';
import styles from '../index.less';
interface PageProps {
detailData: any;
}
const { TabPane } = Tabs;
const { Step } = Steps;
const treeActions = createTreeActions();
const AuthDetail: React.FC<PageProps> = (props: any) => {
const { detailData } = props;
const { pageStatus, id } = usePageStatus();
const {
treeData,
handleSelect,
nodeRecord,
getTreeMaps,
setIsEditForm,
isEditForm,
setTreeData,
} = useTreeTabs({
// fetchItemDetailData: Promise.resolve({data: detailData})
});
useEffect(() => {
setTreeData(detailData?.auths);
}, []);
const actionRef = useRef({});
const formInitValue = nodeRecord ? getTreeMaps(nodeRecord.key) : null;
const [formValue, setFormValue] = useState<any>(null);
// 编辑和预览模式下需回显数据
const fetchRoleDetail = id => {
// 10秒缓存
// const res = await PublicApi.getRoleDetails(
// { id },
// { useCache: true, ttl: 10 * 1000 },
// );
// return res;
};
// 储存的按钮数据
const [buttonInfos, setButtonInfos] = useState<any>([]);
useEffect(() => {
if (!id) return;
// fetchRoleDetail(id).then(res => {
// const { data } = res;
// setFormValue(data);
// });
}, []);
useEffect(() => {
if (formInitValue) {
// 显示右侧checkbox
setButtonInfos(formInitValue.buttons || []);
// 回显右侧checkbox的值
// if (actionRef.current.setSelected) {
// PublicApi.getMenuRoleButtonList({
// memberId: id,
// menuId: formInitValue.id,
// }).then(res => {
// const { data } = res;
// actionRef.current.setSelected(data.ids);
// });
// }
}
}, [getTreeMaps]);
return (
<Row>
<Col className={styles['authCol']} span={15}>
<TabTree
title="菜单列表"
customKey="id"
checkable
actions={treeActions}
treeData={treeData}
handleSelect={handleSelect}
disabled={pageStatus === PageStatus.PREVIEW}
/>
</Col>
<Col className={styles['authCol']} span={8} offset={1}>
<CheckboxTree
actions={actionRef}
disabled={pageStatus === PageStatus.PREVIEW}
handleChange={e => setIsEditForm(true)}
checkedNodes={buttonInfos}
title="菜单按钮访问权限"
/>
</Col>
</Row>
);
};
export default AuthDetail;
import React, { useState } from 'react';
import { Row, Col, Tabs, Steps, Badge } from 'antd';
import { StandardTable } from 'god';
import { ColumnType } from 'antd/lib/table/interface';
import styles from '../index.less';
interface PageProps {
detailData: any;
}
const { TabPane } = Tabs;
const { Step } = Steps;
const BaseDetail: React.FC<PageProps> = props => {
const { detailData } = props;
const [fActived, setfActived] = useState('1');
const [lActived, setlActived] = useState('1');
const columns: ColumnType<any>[] = [
{
title: '序号',
dataIndex: 'id',
align: 'center',
key: 'id',
},
{
title: '操作角色',
dataIndex: 'roleName',
align: 'center',
key: 'roleName',
},
{
title: '状态',
dataIndex: 'statusName',
align: 'center',
key: 'statusName',
render: (text: any, record: any) => <Badge color="#FFC400" text={text} />,
},
{
title: '操作',
dataIndex: 'operation',
align: 'center',
key: 'operation',
},
{
title: '操作时间',
dataIndex: 'operateTime',
align: 'center',
key: 'operateTime',
},
{
title: '审核意见',
dataIndex: 'reason',
align: 'center',
key: 'reason',
},
];
const innerColumns: ColumnType<any>[] = [
{
title: '序号',
dataIndex: 'id',
align: 'center',
key: 'id',
},
{
title: '操作人',
dataIndex: 'operator',
align: 'center',
key: 'operator',
},
{
title: '部门',
dataIndex: 'org',
align: 'center',
key: 'org',
},
{
title: '职位',
dataIndex: 'jobTitle',
align: 'center',
key: 'jobTitle',
},
{
title: '状态',
dataIndex: 'innerStatusName',
align: 'center',
key: 'innerStatusName',
render: (text: any, record: any) => <Badge color="#FFC400" text={text} />,
},
{
title: '操作',
dataIndex: 'operation',
align: 'center',
key: 'operation',
},
{
title: '操作时间',
dataIndex: 'operateTime',
align: 'center',
key: 'operateTime',
},
{
title: '审核意见',
dataIndex: 'reason',
align: 'center',
key: 'reason',
},
];
const renderInfoTemplate = (params: any) => {
const { type, item } = params;
return (
<>
<div className={styles['mainCol-title']}>{item.groupName}</div>
<div className={styles['mainCol-row']}>
{item.elements.map((items: any, indexs: string) => {
return (
<div className={styles['mainCol-row-col']} key={indexs}>
<div className={styles['mainCol-row-col-option']}>
{items.fieldCNName}
</div>
<div className={styles['mainCol-row-col-option']}>
{items.fieldValue}
</div>
</div>
);
})}
</div>
</>
);
};
return (
<Row>
<Col className={styles['mainCol']} span={24}>
<Tabs activeKey={fActived} onChange={val => setfActived(val)}>
<TabPane tab="外部审核流程" key="1">
<Steps
style={{ padding: '34px 0' }}
progressDot
current={detailData?.currentOuterStep - 1}
>
{detailData?.outerVerifySteps?.map((item, index) => {
return (
<Step
key={index}
title={item.roleName}
description={item.stepName}
/>
);
})}
</Steps>
</TabPane>
<TabPane tab="内部审核流程" key="2">
<Steps
style={{ padding: '34px 0' }}
progressDot
current={detailData?.currentInnerStep - 1}
>
{detailData?.innerVerifySteps?.map((item, index) => {
return (
<Step
key={index}
title={item.roleName}
description={item.stepName}
/>
);
})}
</Steps>
</TabPane>
</Tabs>
</Col>
{detailData?.groups?.map((item, index) => {
return (
<Col className={styles['mainCol']} span={24} key={index}>
{renderInfoTemplate({ type: '1', item })}
</Col>
);
})}
<Col className={styles['mainCol']} span={24}>
<Tabs activeKey={lActived} onChange={val => setlActived(val)}>
<TabPane tab="流转记录" key="1">
<div style={{ marginBottom: '40px' }}>
<StandardTable
tableProps={{
pagination: false,
rowKey: 'id',
}}
columns={columns}
fetchTableData={(params: any) =>
Promise.resolve({ data: detailData?.history })
}
/>
</div>
</TabPane>
<TabPane tab="内部单据流转记录" key="2">
<div style={{ marginBottom: '40px' }}>
<StandardTable
tableProps={{
pagination: false,
rowKey: 'id',
}}
columns={innerColumns}
fetchTableData={(params: any) =>
Promise.resolve({ data: detailData?.innerHistory })
}
/>
</div>
</TabPane>
</Tabs>
</Col>
</Row>
);
};
export default BaseDetail;
import React, { useState } from 'react';
import { Row, Col, Tabs, Steps, Badge } from 'antd';
import { StandardTable } from 'god';
import { ColumnType } from 'antd/lib/table/interface';
import styles from '../index.less';
interface PageProps {
detailData: any;
}
const EquitiesDetail: React.FC<PageProps> = props => {
return <>123</>;
};
export default EquitiesDetail;
import React, { useState } from 'react';
import { Row, Col, Tabs, Steps, Badge } from 'antd';
import { StandardTable } from 'god';
import { ColumnType } from 'antd/lib/table/interface';
import styles from '../index.less';
interface PageProps {
detailData: any;
}
const IntegrityDetail: React.FC<PageProps> = props => {
return <>123</>;
};
export default IntegrityDetail;
import React, { useState } from 'react';
import { Row, Col, Progress, Form, Input } from 'antd';
import { StandardTable } from 'god';
import { ColumnType } from 'antd/lib/table/interface';
import { Chart, LineAdvance } from 'bizcharts';
import styles from '../index.less';
interface PageProps {
detailData: any;
}
const LevelDetail: React.FC<PageProps> = props => {
const { detailData } = props;
// 数据源
const data = [
{
month: 'Jan',
city: 'Tokyo',
temperature: 7,
},
{
month: 'Feb',
city: 'Tokyo',
temperature: 13,
},
{
month: 'Mar',
city: 'Tokyo',
temperature: 16.5,
},
{
month: 'Apr',
city: 'Tokyo',
temperature: 14.5,
},
{
month: 'May',
city: 'Tokyo',
temperature: 10,
},
{
month: 'Jun',
city: 'Tokyo',
temperature: 7.5,
},
{
month: 'Jul',
city: 'Tokyo',
temperature: 9.2,
},
{
month: 'Aug',
city: 'Tokyo',
temperature: 14.5,
},
{
month: 'Sep',
city: 'Tokyo',
temperature: 9.3,
},
{
month: 'Oct',
city: 'Tokyo',
temperature: 8.3,
},
{
month: 'Nov',
city: 'Tokyo',
temperature: 8.9,
},
{
month: 'Dec',
city: 'Tokyo',
temperature: 5.6,
},
];
return (
<Row>
<Col className={styles['mainCol']} span={24}>
<div className={styles['mainCol-title']}>会员等级</div>
<div className={styles['mainCol-chart']}>
<div className={styles['mainCol-chart-main']}>
<div
className={
styles[`mainCol-chart-main-card${detailData.level || '4'}`]
}
>
<h2>青铜会员</h2>
<div className={styles['progress']}>
<Progress
style={{ height: '4px' }}
strokeLinecap="square"
strokeColor={
detailData.level === '1'
? '#A47268'
: detailData.level === '2'
? '#576C8F'
: detailData.level === '3'
? '#B28525'
: '#595B71'
}
trailColor={
detailData.level === '1'
? '#E9BFA9'
: detailData.level === '2'
? '#ABC0DC'
: detailData.level === '3'
? '#D6C39D'
: '#A7AAC6'
}
showInfo={false}
percent={75}
/>
<div className={styles['progress-score']}>
<span>5000/15000</span>
<span>白银会员</span>
</div>
<div>当前活跃分</div>
</div>
</div>
</div>
<div className={styles['mainCol-chart-main']}>
<div className={styles['mainCol-chart-main-line']}>
<Chart
padding={[10, 20, 50, 40]}
autoFit
height={300}
data={data}
>
<LineAdvance
shape="smooth"
point
area
position="month*temperature"
color="city"
/>
</Chart>
</div>
</div>
</div>
</Col>
<Col className={styles['mainCol']} span={24}>
<div className={styles['mainCol-title']}>活跃分获取记录</div>
</Col>
</Row>
);
};
export default LevelDetail;
......@@ -66,6 +66,7 @@ const EquityInfo: React.FC<{}> = () => {
sumReturnMoney: equityInfo?.sumReturnMoney,
sumUsedPoint: equityInfo?.sumUsedPoint,
sumPoint: equityInfo?.sumPoint,
rights: equityInfo?.rights,
}}
fetchReceivedList={getReceivedList}
fetchUsageList={getUsageList}
......
......@@ -73,6 +73,10 @@ const MemberMaintainDetailed: React.FC<QueryProps> = props => {
tab: '基本信息',
},
{
key: 'powerInfo',
tab: '权限信息',
},
{
key: 'levelInfo',
tab: '等级信息',
},
......
import React, { useState, useRef } from 'react';
import { Row, Col, Modal } from 'antd';
import { usePageStatus, PageStatus } from '@/hooks/usePageStatus';
import { useTreeTabs, FormState } from '@/hooks/useTreeTabs';
import { PublicApi } from '@/services/api';
import MellowCard from '@/components/MellowCard';
import TabTree, { createTreeActions } from '@/components/TabTree';
import CheckboxTree from '@/components/CheckBoxTree';
import styles from './index.less';
const treeActions = createTreeActions();
const PowerInfo: React.FC<{}> = () => {
const { id, validateId, pageStatus } = usePageStatus();
const [powerLoading, setPowerLoading] = useState(false);
const [buttonInfos, setButtonInfos] = useState<any>([]);
const actionRef = useRef<any>({});
// 获取左侧已选择的项
const getMenuSelectData = async () => {
setPowerLoading(true);
const res = await PublicApi.getMemberMaintenanceDetailAuthMenuCheck({
memberId: id,
validateId: validateId,
});
setPowerLoading(false);
if (res.code === 1000) {
const { checkIds } = res.data;
return { data: { ids: checkIds } };
}
return {
data: {
ids: [],
},
};
};
// 获取左边菜单
const fetchMenuData = async () => {
const res = await PublicApi.getMemberMaintenanceDetailAuthMenu({
memberId: id,
validateId: validateId,
});
return res;
};
// 点击左侧菜单获取右侧按钮菜单、及已勾选的信息
const handleFindDetail = async menuId => {
// 右侧对应按钮
const authButtonRes = await PublicApi.getMemberMaintenanceDetailAuthButton({
menuId: menuId,
memberId: id,
validateId: validateId,
});
if (authButtonRes.code === 1000) {
const { data } = authButtonRes;
let buttons = data.map(v => ({ id: v.id, buttonName: v.name }));
setButtonInfos(buttons || []);
}
// 右侧选中按钮
const authButtonCheckRes = await PublicApi.getMemberMaintenanceDetailAuthButtonCheck({
menuId: menuId,
memberId: id,
validateId: validateId,
});
if (authButtonCheckRes.code === 1000) {
if (actionRef.current.setSelected) {
actionRef.current.setSelected(authButtonCheckRes.data.checkIds);
}
}
};
const customSelect = (selectKey?, node?) => {
// 首次新增菜单的时候没有节点信息
if (!node) {
setNodeRecord(null);
setTreeStatus(FormState.ADD);
return;
}
// key相等时 不刷新右侧表单
if (nodeRecord && nodeRecord.key === selectKey) {
setNodeRecord(node);
setTreeStatus(FormState.EDIT);
} else {
if (isEditForm) {
// 有填写过表单
return new Promise((resolve, reject) => {
Modal.confirm({
content: '确认要离开当前页面吗,您提交的数据尚未保存',
onOk() {
// 确认离开当前页, 需改变node state
setNodeRecord(node);
setTreeStatus(FormState.EDIT);
// 点击菜单,请求数据重置
handleFindDetail(selectKey);
setIsEditForm(false);
resolve();
},
onCancel() {
reject();
},
});
});
} else {
// 编辑页, 需回显
handleFindDetail(selectKey);
setNodeRecord(node);
setTreeStatus(FormState.EDIT);
}
}
};
const {
treeData,
handleSelect,
nodeRecord,
setNodeRecord,
setTreeStatus,
setIsEditForm,
isEditForm,
} = useTreeTabs({
fetchMenuData,
selectCallback: customSelect,
});
// 更新右侧按钮
const handleSubmitAuth = async () => {
const buttonIds = [...actionRef.current.selected];
if (!nodeRecord) {
return;
}
if (isEditForm) {
// 更新右侧按钮
await PublicApi.postMemberValidateCommitUpdatebutton({
memberId: id,
validateId,
menuId: nodeRecord.id,
buttonIds: buttonIds,
});
}
setIsEditForm(false);
};
return (
<Row>
<Col span={15}>
<MellowCard>
<TabTree
title="菜单列表"
getMenuSelectData={getMenuSelectData}
customKey="id"
actions={treeActions}
treeData={treeData}
handleSelect={handleSelect}
disabled={true}
checkable
/>
</MellowCard>
</Col>
<Col span={8} offset={1}>
<MellowCard>
<CheckboxTree
actions={actionRef}
disabled={true}
handleChange={e => setIsEditForm(true)}
checkedNodes={buttonInfos}
title="菜单按钮访问权限"
handleSubmit={handleSubmitAuth}
/>
</MellowCard>
</Col>
</Row>
);
};
export default PowerInfo;
\ No newline at end of file
......@@ -32,8 +32,8 @@ import {
MEMBER_STATUS_NORMAL,
MEMBER_INNER_STATUS_SUCCESS,
MEMBER_OUTER_STATUS_SUCCESS,
MEMBER_OUTER_STATUS_UNCOMMITTED,
MEMBER_OUTER_STATUS_FAILED,
MEMBER_INNER_STATUS_UNCOMMITTED,
MEMBER_INNER_STATUS_FAILED,
} from '@/constants';
import { importSchema, auditModalSchema } from './schema';
import {
......@@ -56,18 +56,21 @@ const memberMaintain: React.FC<[]> = () => {
};
const handleDelete = (memberId: number, validateId: number) => {
const mesInstance = message.loading('功能暂时没有,敬请期待');
// PublicApi.postMemberAbilitySubDelete({
// memberId,
// validateId,
// }).then(res => {
// if (res.code !== 1000) {
// return;
// }
// ref.current.reload();
// }).finally(() => {
// mesInstance();
// });
const mesInstance = message.loading({
content: '正在删除',
duration: 0,
});
PublicApi.postMemberMaintenanceDelete({
memberId,
validateId,
}).then(res => {
if (res.code !== 1000) {
return;
}
ref.current.reload();
}).finally(() => {
mesInstance();
});
};
const defaultColumns: ColumnType<any>[] = [
......@@ -170,8 +173,8 @@ const memberMaintain: React.FC<[]> = () => {
)}
{/* 外部审核状态等于 待提交 或者 审核失败 可进行编辑操作 */}
{(
record.outerStatus === MEMBER_OUTER_STATUS_UNCOMMITTED ||
record.outerStatus === MEMBER_OUTER_STATUS_FAILED
record.outerStatus === MEMBER_INNER_STATUS_UNCOMMITTED ||
record.outerStatus === MEMBER_INNER_STATUS_FAILED
) && (
<>
<Button
......
import React, { useState, useEffect, useRef, ReactNode } from 'react';
import { history } from 'umi';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { PageHeader, Tag, Badge, Tabs, Steps, Descriptions } from 'antd';
import { StandardTable } from 'god';
import { ColumnType } from 'antd/lib/table/interface';
import { usePageStatus, PageStatus } from '@/hooks/usePageStatus';
import { PublicApi } from '@/services/api';
import styles from './index.less';
import BaseDetail from './component/baseDetail';
import AuthDetail from './component/authDetail';
import LevelDetail from './component/levelDetail';
import EquitiesDetail from './component/equitiesDetail';
import IntegrityDetail from './component/integrityDetail';
const { TabPane } = Tabs;
const { Step } = Steps;
const MemberDetail: React.FC<{}> = () => {
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: id,
validateId,
});
setDetailData(data);
};
fetchDetailData();
}, []);
return (
<PageHeaderWrapper
title={
<>
<PageHeader
style={{ padding: '0' }}
onBack={() => window.history.back()}
title={
<>
<div className={styles['headerTop']}>
<div className={styles['headerTop-prefix']}>广</div>
<div className={styles['headerTop-name']}>
广州市极致皮具有限公司
</div>
<div className={styles[`levelIcon${'1'}`]}></div>
</div>
</>
}
footer={
<Tabs activeKey={hActived} onChange={val => setHActived(val)}>
<TabPane tab="基本信息" key="1" />
<TabPane tab="权限信息" key="2" />
<TabPane tab="等级信息" key="3" />
<TabPane tab="权益信息" key="4" />
<TabPane tab="诚信信息" key="5" />
</Tabs>
}
>
<Descriptions size="small" column={3} style={{ padding: '0 32px' }}>
<Descriptions.Item label="会员类型">{123}</Descriptions.Item>
<Descriptions.Item label="会员角色">{123}</Descriptions.Item>
<Descriptions.Item label="会员状态">
<Tag color="green"></Tag>
</Descriptions.Item>
<Descriptions.Item label="外部状态">
<Tag color="gold"></Tag>
</Descriptions.Item>
<Descriptions.Item label="内部状态">
<Badge color="#669EDE" text={123} />
</Descriptions.Item>
</Descriptions>
</PageHeader>
</>
}
>
{hActived === '1' ? (
<BaseDetail detailData={detailData} />
) : hActived === '2' ? (
<AuthDetail detailData={detailData} />
) : hActived === '3' ? (
<LevelDetail detailData={detailData} />
) : hActived === '4' ? (
<EquitiesDetail detailData={detailData} />
) : (
<IntegrityDetail detailData={detailData} />
)}
</PageHeaderWrapper>
);
};
export default MemberDetail;
......@@ -365,7 +365,6 @@ const AuditPr1: React.FC<QueryProps> = props => {
checkedNodes={buttonInfos}
title="菜单按钮访问权限"
handleSubmit={handleSubmitAuth}
showSave
/>
</MellowCard>
</Col>
......
......@@ -365,7 +365,6 @@ const AuditPr2: React.FC<QueryProps> = props => {
checkedNodes={buttonInfos}
title="菜单按钮访问权限"
handleSubmit={handleSubmitAuth}
showSave
/>
</MellowCard>
</Col>
......
......@@ -365,7 +365,6 @@ const AuditPrComfirm: React.FC<QueryProps> = props => {
checkedNodes={buttonInfos}
title="菜单按钮访问权限"
handleSubmit={handleSubmitAuth}
showSave
/>
</MellowCard>
</Col>
......
......@@ -365,7 +365,7 @@ const AuditPrSubmit: React.FC<QueryProps> = props => {
checkedNodes={buttonInfos}
title="菜单按钮访问权限"
handleSubmit={handleSubmitAuth}
showSave
showSave={pageStatus !== PageStatus.PREVIEW}
/>
</MellowCard>
</Col>
......
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