Commit 47a57c30 authored by wuting's avatar wuting

feat: 业务员业绩相关

parent b8beb880
......@@ -74,7 +74,7 @@ const memberCenterRoute = {
},
// ShopRoute,
// CommodityRoute,
// TranactionRoute,
TranactionRoute,
// ChannelRoute,
// ShopRoute,
// ProcurementRoute,
......
......@@ -431,12 +431,14 @@ const TranactionRoute = {
path: '/memberCenter/tranactionAbility/salesPerformanceStatistics/statisticsDetail',
name: 'statisticsDetail',
component: '@/pages/transaction/salesPerformanceStatistics/statisticsDetail',
hideInMenu: true,
},
// 业绩订单明细
{
path: '/memberCenter/tranactionAbility/salesPerformanceStatistics/performanceDetail',
name: 'performanceDetail',
component: '@/pages/transaction/salesPerformanceStatistics/performanceDetail',
hideInMenu: true,
}
],
};
......
......@@ -10,7 +10,7 @@ export default {
'salesPerformanceStatistics.currency':'¥',
'salesPerformanceStatistics.view':'View performance details',
'salesPerformanceStatistics.orderDetail':'View order details',
'salesPerformanceStatistics.export':'Export EXCEL',
'salesPerformanceStatistics.export':'Export',
'salesPerformanceStatistics.placeholder.time': 'Please select a statistical month',
'salesPerformanceStatistics.placeholder.organization': 'Please select the organization',
'salesPerformanceStatistics.placeholder.name': 'Please enter a name',
......@@ -50,4 +50,5 @@ export default {
'salesPerformanceStatistics.subordinateSalesman': 'Subordinate salesman',
'salesPerformanceStatistics.orderMemberName': 'Order Member Name',
'salesPerformanceStatistics.orderCompletionTime': 'Order Completion Time',
'salesPerformanceStatistics.performanceOrderDetails': 'performance order details',
}
\ No newline at end of file
......@@ -10,7 +10,7 @@ export default {
'salesPerformanceStatistics.currency': '¥',
'salesPerformanceStatistics.view':'실적 세부 정보 보기',
'salesPerformanceStatistics.orderDetail':'주문 세부정보 보기',
'salesPerformanceStatistics.export': '엑셀 내보내기',
'salesPerformanceStatistics.export': '엑셀',
'salesPerformanceStatistics.placeholder.time': '통계 월을 선택하세요',
'salesPerformanceStatistics.placeholder.organization': '조직을 선택하십시오',
'salesPerformanceStatistics.placeholder.name': '이름을 입력하세요',
......@@ -50,4 +50,5 @@ export default {
'salesPerformanceStatistics.subordinateSalesman': '하위 판매원',
'salesPerformanceStatistics.orderMemberName': '주문 회원 이름',
'salesPerformanceStatistics.orderCompletionTime': '주문 완료 시간',
'salesPerformanceStatistics.performanceOrderDetails': '실적 주문 세부정보',
}
\ No newline at end of file
......@@ -10,7 +10,7 @@ export default {
'salesPerformanceStatistics.currency':'¥',
'salesPerformanceStatistics.view':'查看业绩详情',
'salesPerformanceStatistics.orderDetail':'查看订单明细',
'salesPerformanceStatistics.export':'导出EXCEL',
'salesPerformanceStatistics.export':'导出',
'salesPerformanceStatistics.placeholder.time':'请选择统计月份',
'salesPerformanceStatistics.placeholder.organization':'请选择所属机构',
'salesPerformanceStatistics.placeholder.name':'请输入姓名',
......@@ -50,4 +50,5 @@ export default {
'salesPerformanceStatistics.subordinateSalesman': '所属业务员',
'salesPerformanceStatistics.orderMemberName': '下单会员名称',
'salesPerformanceStatistics.orderCompletionTime': '订单完成时间',
'salesPerformanceStatistics.performanceOrderDetails': '业绩订单明细',
}
\ No newline at end of file
/*
* @Author: XieZhiXiong
* @Date: 2021-01-06 11:36:35
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-12 14:03:15
* @Description:
*/
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { GlobalConfig } from '@/global/config';
import { getIntl } from 'umi';
const intl = getIntl();
const orderTypeArr = GlobalConfig.web.orderType.map((item) => ({
label: item.platformWayName,
value: item.id,
}));
export const listSearchSchema: ISchema = {
type: 'object',
properties: {
megaLayout: {
type: 'object',
'x-component': 'mega-layout',
properties: {
orderNo: {
type: 'string',
// 'x-component': 'Search',
// enum:[
// {value:'2021-10-10',label:'2222'}
// ],
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.sousuo'}),
align: 'flex-left',
tip: intl.formatMessage({id: 'supplierEvaluation.shurudingdanhao'}),
style: { width: '174px' },
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
grid: true,
full: true,
autoRow: true,
columns: 6,
},
properties: {
digest: {
type: 'string',
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.dingdanzhaiyao'}),
allowClear: true,
},
},
memberName: {
type: 'string',
default: undefined,
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.caigouhuiyuan'}),
allowClear: true,
},
},
'[createTimeStart, createTimeEnd]': {
type: 'string',
default: '',
'x-component': 'dateSelect',
// enum:[
// {value:'2021-10-10',label:'2222'}
// ],
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.xiadanshijian'}),
allowClear: true,
},
},
orderType: {
type: 'string',
default: undefined,
enum: orderTypeArr,
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.dingdanleixing'}),
allowClear: true,
},
},
submit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: intl.formatMessage({id: 'supplierEvaluation.chaxun'}),
},
},
},
},
},
},
},
};
/*
* @Author: XieZhiXiong
* @Date: 2021-01-06 11:36:35
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-12 14:03:15
* @Description:
*/
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { GlobalConfig } from '@/global/config';
import { getIntl } from 'umi';
const intl = getIntl();
const orderTypeArr = GlobalConfig.web.orderType.map((item) => ({
label: item.platformWayName,
value: item.id,
}));
export const listSearchSchema: ISchema = {
type: 'object',
properties: {
megaLayout: {
type: 'object',
'x-component': 'mega-layout',
properties: {
orderNo: {
type: 'string',
// 'x-component': 'Search',
// enum:[
// {value:'2021-10-10',label:'2222'}
// ],
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.sousuo'}),
align: 'flex-left',
tip: intl.formatMessage({id: 'supplierEvaluation.shurudingdanhao'}),
style: { width: '174px' },
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
grid: true,
full: true,
autoRow: true,
columns: 6,
},
properties: {
digest: {
type: 'string',
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.dingdanzhaiyao'}),
allowClear: true,
},
},
memberName: {
type: 'string',
default: undefined,
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.caigouhuiyuan'}),
allowClear: true,
},
},
'[createTimeStart, createTimeEnd]': {
type: 'string',
default: '',
'x-component': 'dateSelect',
// enum:[
// {value:'2021-10-10',label:'2222'}
// ],
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.xiadanshijian'}),
allowClear: true,
},
},
orderType: {
type: 'string',
default: undefined,
enum: orderTypeArr,
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.dingdanleixing'}),
allowClear: true,
},
},
submit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: intl.formatMessage({id: 'supplierEvaluation.chaxun'}),
},
},
},
},
},
},
},
};
/*
* @Author: XieZhiXiong
* @Date: 2021-05-18 16:27:14
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-12-04 14:16:15
* @Description: 会员基础信息
*/
import React from 'react';
import { useIntl } from 'umi';
// import { MEMBER_OUTER_STATUS_TYPE } from '../../constant';
import CustomizeColumn from '@/components/CustomizeColumn';
import StatusTag from '@/components/StatusTag';
......@@ -17,57 +10,33 @@ export type BasicInfoProps = {
*/
dataSource: {
/**
* 会员id
*/
memberId: number,
/**
* 会员类型
*/
memberTypeName: string,
/**
* 登录账号
*/
account: string,
/**
* 会员名称
*/
name: string,
/**
* 会员角色
*/
roleName: string,
/**
* 注册手机号
*/
phone: string,
/**
* 外部状态
*/
outerStatus: number,
/**
* 外部状态名称
*/
outerStatusName: string,
/**
* 等级
*/
level?: number,
/**
* 会员等级
*/
levelTag: string,
/**
* 注册邮箱
*/
email: string,
/**
* 申请时间
*/
createTime: string,
/**
* 会员类型枚举,前端不展示,当值为3或4时,展示渠道信息
*/
memberTypeEnum?: number,
* 业务员Id
*/
userId: number
/**
* 业务员姓名
*/
name: string
/**
* 所属机构
*/
title: string
/**
* 职位
*/
position: string
/**
* 所属角色
*/
roleName: string
/**
* 城市Code
*/
countryCode: string
/**
* 绑定手机号
*/
phone: string
},
}
......@@ -79,23 +48,23 @@ const BasicInfo: React.FC<BasicInfoProps> = (props: BasicInfoProps) => {
const basicInfo = [
{
title: intl.formatMessage({ id: 'salesPerformanceStatistics.basicInfo.name' }),
value: dataSource.memberId !== undefined ? dataSource.memberId : '',
value: dataSource.name ||'',
},
{
title: intl.formatMessage({ id: 'salesPerformanceStatistics.basicInfo.organization' }),
value: dataSource.memberTypeName || '',
value: dataSource.title || '',
},
{
title: intl.formatMessage({ id: 'salesPerformanceStatistics.basicInfo.position' }),
value: dataSource.account || '',
value: dataSource.position || '',
},
{
title: intl.formatMessage({ id: 'salesPerformanceStatistics.basicInfo.role' }),
value: dataSource.name || '',
value: dataSource.roleName || '',
},
{
title: intl.formatMessage({ id: 'salesPerformanceStatistics.basicInfo.phone' }),
value: dataSource.roleName || '',
value: (dataSource.countryCode + ' ' + dataSource.phone) || '',
},
];
......
/*
* @Author: XieZhiXiong
* @Date: 2021-01-06 11:36:35
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-12 14:03:15
* @Description:
*/
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { GlobalConfig } from '@/global/config';
import { getIntl } from 'umi';
const intl = getIntl();
const orderTypeArr = GlobalConfig.web.orderType.map((item) => ({
label: item.platformWayName,
value: item.id,
}));
export const listSearchSchema: ISchema = {
type: 'object',
properties: {
megaLayout: {
type: 'object',
'x-component': 'mega-layout',
properties: {
orderNo: {
type: 'string',
// 'x-component': 'Search',
// enum:[
// {value:'2021-10-10',label:'2222'}
// ],
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.sousuo'}),
align: 'flex-left',
tip: intl.formatMessage({id: 'supplierEvaluation.shurudingdanhao'}),
style: { width: '174px' },
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
grid: true,
full: true,
autoRow: true,
columns: 6,
},
properties: {
digest: {
type: 'string',
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.dingdanzhaiyao'}),
allowClear: true,
},
},
memberName: {
type: 'string',
default: undefined,
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.caigouhuiyuan'}),
allowClear: true,
},
},
'[createTimeStart, createTimeEnd]': {
type: 'string',
default: '',
'x-component': 'dateSelect',
// enum:[
// {value:'2021-10-10',label:'2222'}
// ],
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.xiadanshijian'}),
allowClear: true,
},
},
orderType: {
type: 'string',
default: undefined,
enum: orderTypeArr,
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.dingdanleixing'}),
allowClear: true,
},
},
submit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: intl.formatMessage({id: 'supplierEvaluation.chaxun'}),
},
},
},
},
},
},
},
};
.tableStyle {
:global {
.ant-row {
width: 100%;
justify-content: space-between;
}
.ant-col-order-2{
flex:1;
}
.ant-col-order-3{
.ant-row {
width: auto;
justify-content: space-between;
}
}
}
.info{
width: 100%;
display: flex;
justify-content: space-between;
}
.title{
font-size: 16px;
font-weight: 500;
color: #343031;
}
}
/*
* @Author: XieZhiXiong
* @Date: 2021-06-04 11:31:48
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-11-29 17:56:21
* @Description: 会员冻结
*/
import React, { useState, useEffect } from 'react';
import {
Button,
Modal,
Row,
Col,
Spin,
} from 'antd';
import { history, useIntl } from 'umi';
import { StopOutlined } from '@ant-design/icons';
import {
createFormActions,
FormEffectHooks,
} from '@formily/antd';
import { Row, Col, Spin } from 'antd';
import { useIntl } from 'umi';
import { usePageStatus } from '@/hooks/usePageStatus';
import { getMemberAbilityMaintenanceDetail, GetMemberAbilityMaintenanceDetailResponse, postMemberAbilityMaintenanceFreeze } from '@/services/MemberV2Api';
import {
MEMBER_TYPE_CHANNEL_CORPORATE,
MEMBER_TYPE_CHANNEL_INDIVIDUAL,
} from '@/constants/member';
import AnchorPage from '@/components/AnchorPage';
import AvatarWrap from '@/components/AvatarWrap';
import LevelBrand from '@/components/LevelBrand';
import FlowRecords from '@/components/FlowRecords';
import CustomizeColumn from '@/components/CustomizeColumn';
import NiceForm from '@/components/NiceForm';
import { freezeSchema } from './schema';
// import {
// MEMBER_OUTER_COLUMNS,
// MEMBER_INNER_COLUMNS,
// } from '../../constant';
import { getMemberFeignAbilitySalesChannelInformation } from '@/services/MemberV2Api';
import BasicInfo from './components/basicInfo';
import MemberStatisticsList from './components/memberStatisticsList';
// import MemberChannelInfo from '../../components/MemberChannelInfo';
// import PicWrap from '../../components/PicWrap';
import StatisticsList from './components/statisticsList';
type ValueType = {
/**
* 理由
*/
reason: string,
}
const formActions = createFormActions();
const MemberFrozen: React.FC<{}> = () => {
const { validateId = 1792 } = usePageStatus();
const [memberInfo, setMemberInfo] = useState<GetMemberAbilityMaintenanceDetailResponse>(null);
const [modalVisible, setModalVisible] = useState(false);
const { id } = usePageStatus();
const [memberInfo, setMemberInfo] = useState<any>({
name:'',
title:'',
position:'',
roleName:'',
countryCode:'',
phone:''
});
const [infoLoading, setInfoLoaading] = useState(false);
const [confirmLoading, setConfirmLoading] = useState(false);
const intl = useIntl();
const getBasicInfo = () => {
if (!validateId) {
if (!id) {
return;
}
setInfoLoaading(true);
getMemberAbilityMaintenanceDetail({
validateId,
}).then(res => {
if (res.code === 1000) {
setMemberInfo(res.data);
}
}).catch((err) => {
console.warn(err);
}).finally(() => {
setInfoLoaading(false);
});
getMemberFeignAbilitySalesChannelInformation({
userId: id,
})
.then(res => {
if (res.code === 1000) {
setMemberInfo(res.data);
}
})
.catch(err => {
console.warn(err);
})
.finally(() => {
setInfoLoaading(false);
});
};
useEffect(() => {
getBasicInfo();
}, []);
// 冻结与解冻
const handleSubmit = (values: ValueType) => {
setConfirmLoading(true);
return postMemberAbilityMaintenanceFreeze({
validateId: validateId,
status: 2,
reason: values.reason || '',
}).then(res => {
if (res.code !== 1000) {
return;
}
setModalVisible(false);
setTimeout(() => {
history.goBack();
}, 800);
}).finally(() => {
setConfirmLoading(false);
});
};
const anchorsArr = [
{
key: 'basicInfo',
......@@ -109,77 +55,52 @@ const MemberFrozen: React.FC<{}> = () => {
},
{
key: 'membershipStatistics',
name: intl.formatMessage({ id: 'salesPerformanceStatistics.membershipStatistics' }),
name: intl.formatMessage({
id: 'salesPerformanceStatistics.membershipStatistics',
}),
},
{
key: 'CommodityStatistics',
name: intl.formatMessage({ id: 'salesPerformanceStatistics.CommodityStatistics' }),
name: intl.formatMessage({
id: 'salesPerformanceStatistics.CommodityStatistics',
}),
},
].filter(Boolean);
return (
<Spin spinning={infoLoading}>
<AnchorPage
title={(
title={
<AvatarWrap
info={{
name: memberInfo?.name,
}}
// extra={(
// <LevelBrand level={2} />
// )}
/>
)}
}
anchors={anchorsArr}
// extra={(
// <Button
// icon={<StopOutlined />}
// onClick={() => setModalVisible(true)}
// >
// {intl.formatMessage({ id: 'member.management.maintain.query.freeze' })}
// </Button>
// )}
>
<Row gutter={[16, 16]}>
{/* 基本信息 */}
<Col span={24}>
<AnchorPage.Item itemKey="basicInfo">
<BasicInfo
dataSource={{
memberId: memberInfo?.memberId,
memberTypeName: memberInfo?.memberTypeName,
account: memberInfo?.account,
name: memberInfo?.name,
roleName: memberInfo?.roleName,
phone: memberInfo?.phone,
outerStatus: memberInfo?.outerStatus,
outerStatusName: memberInfo?.outerStatusName,
levelTag: memberInfo?.levelTag,
email: memberInfo?.email,
createTime: memberInfo?.registerTime,
}}
/>
<BasicInfo dataSource={memberInfo} />
</AnchorPage.Item>
</Col>
{/* 查看下级会员统计信息 */}
<Col span={24}>
<AnchorPage.Item itemKey="membershipStatistics">
<MemberStatisticsList searchType='membership'/>
<StatisticsList id={Number(id)} searchType="membership" />
</AnchorPage.Item>
</Col>
{/* 查看商品统计信息 */}
<Col span={24}>
<AnchorPage.Item itemKey="CommodityStatistics">
<MemberStatisticsList searchType='commodity'/>
<StatisticsList id={Number(id)} searchType="commodity" />
</AnchorPage.Item>
</Col>
</Row>
</AnchorPage>
</Spin>
);
......
/*
* @Author: XieZhiXiong
* @Date: 2021-06-04 11:27:42
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-11-29 18:17:12
* @Description:
*/
import { getIntl } from 'umi';
import { ISchema } from '@formily/antd';
const intl = getIntl();
export const freezeSchema: ISchema = {
type: 'object',
properties: {
MEGA_LAYOUT: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
labelAlign: 'top',
},
properties: {
reason: {
type: 'string',
title: intl.formatMessage({ id: 'member.management.maintain.freeze.freeze.form.reason' }),
'x-component': 'Textarea',
'x-component-props': {
placeholder: intl.formatMessage({ id: 'member.management.maintain.freeze.freeze.form.reason.placeholder' }),
maxLength: 60,
rows: 5,
},
'x-rules': [
{
required: true,
message: intl.formatMessage({ id: 'member.management.maintain.freeze.freeze.form.reason.rules-required' }),
},
{
limitByte: true, // 自定义校验规则
maxByte: 120,
}
],
},
},
},
},
};
\ No newline at end of file
import { getIntl } from "umi";
const intl = getIntl();
/**
* 获取近几个月的时间数组 包含当前月份
* @param maxNum 数值 1、2、3、4、5......
* @returns {arr[{label:,value:''}]}
*/
export function getDateTimeListCurrentMonth(maxNum){
var timeArray = new Array();
//获取时间对象
var date = new Date();
var year = date.getFullYear();
//js的月份 是从0~11 ,所以要加1
var month = date.getMonth()+1;
for(var i = 0; i < maxNum; i++){
if(month <= 0){
month = 12;
year = year-1;
}
if(month < 10){
timeArray[i] = year+ intl.formatMessage({ id: 'salesPerformanceStatistics.year' }) +"0"+month + intl.formatMessage({ id: 'salesPerformanceStatistics.month' });
} else {
timeArray[i] = year+intl.formatMessage({ id: 'salesPerformanceStatistics.year' }) +month + intl.formatMessage({ id: 'salesPerformanceStatistics.month' }) ;
}
month = month-1;
}
let list = timeArray.map(item => ({
label: item,
value: item.replace(intl.formatMessage({ id: 'salesPerformanceStatistics.year' }),'-').replace(intl.formatMessage({ id: 'salesPerformanceStatistics.month' }),''),
}))
return list;
}
\ 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