feat:n
This commit is contained in:
parent
fa30ec2988
commit
ed99c7b1ae
@ -3,12 +3,12 @@ import classNames from 'classnames';
|
|||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
import ListPlaceholder from '@/components/list-placeholder';
|
import ListPlaceholder from '@/components/list-placeholder';
|
||||||
|
import { ProfitStatusDescriptions } from '@/constants/partner';
|
||||||
import { GetProfitRequest, PartnerProfitItem, ProfitType } from '@/types/partner';
|
import { GetProfitRequest, PartnerProfitItem, ProfitType } from '@/types/partner';
|
||||||
import { logWithPrefix } from '@/utils/common';
|
import { logWithPrefix } from '@/utils/common';
|
||||||
import { formatMoney, formatTimestamp, getProfitList as requestData } from '@/utils/partner';
|
import { formatMoney, formatTimestamp, getProfitList as requestData } from '@/utils/partner';
|
||||||
|
|
||||||
import './index.less';
|
import './index.less';
|
||||||
import { PROFIT_STATUS_MAP, PROFIT_TYPE_MAP } from '@/constants/partner';
|
|
||||||
|
|
||||||
export interface IPartnerProfitListProps extends GetProfitRequest {
|
export interface IPartnerProfitListProps extends GetProfitRequest {
|
||||||
visible?: boolean;
|
visible?: boolean;
|
||||||
@ -22,7 +22,7 @@ const PREFIX = 'partner-profit';
|
|||||||
const log = logWithPrefix(PREFIX);
|
const log = logWithPrefix(PREFIX);
|
||||||
|
|
||||||
function ProfitList(props: IPartnerProfitListProps) {
|
function ProfitList(props: IPartnerProfitListProps) {
|
||||||
const { className, listHeight, refreshDisabled, visible = true, profitType, onListEmpty } = props;
|
const { className, listHeight, refreshDisabled, visible = true, type, onListEmpty } = props;
|
||||||
const [refreshing, setRefreshing] = useState(false);
|
const [refreshing, setRefreshing] = useState(false);
|
||||||
const [loadingMore, setLoadingMore] = useState(false);
|
const [loadingMore, setLoadingMore] = useState(false);
|
||||||
const [loadMoreError, setLoadMoreError] = useState(false);
|
const [loadMoreError, setLoadMoreError] = useState(false);
|
||||||
@ -34,7 +34,7 @@ function ProfitList(props: IPartnerProfitListProps) {
|
|||||||
try {
|
try {
|
||||||
setRefreshing(true);
|
setRefreshing(true);
|
||||||
setLoadMoreError(false);
|
setLoadMoreError(false);
|
||||||
const list = await requestData({ profitType });
|
const list = await requestData({ type });
|
||||||
setDataList(list);
|
setDataList(list);
|
||||||
!list.length && onListEmptyRef.current?.();
|
!list.length && onListEmptyRef.current?.();
|
||||||
log('pull refresh success');
|
log('pull refresh success');
|
||||||
@ -65,7 +65,7 @@ function ProfitList(props: IPartnerProfitListProps) {
|
|||||||
setDataList([]);
|
setDataList([]);
|
||||||
setLoadingMore(true);
|
setLoadingMore(true);
|
||||||
setLoadMoreError(false);
|
setLoadMoreError(false);
|
||||||
const list = await requestData({ profitType });
|
const list = await requestData({ type });
|
||||||
setDataList(list);
|
setDataList(list);
|
||||||
!list.length && onListEmptyRef.current?.();
|
!list.length && onListEmptyRef.current?.();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -77,7 +77,7 @@ function ProfitList(props: IPartnerProfitListProps) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
refresh();
|
refresh();
|
||||||
}, [visible, profitType]);
|
}, [visible, type]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`${PREFIX}__tab-content`}>
|
<div className={`${PREFIX}__tab-content`}>
|
||||||
@ -95,18 +95,21 @@ function ProfitList(props: IPartnerProfitListProps) {
|
|||||||
fixedHeight={typeof listHeight !== 'undefined'}
|
fixedHeight={typeof listHeight !== 'undefined'}
|
||||||
style={listHeight ? { height: `${listHeight}px` } : undefined}
|
style={listHeight ? { height: `${listHeight}px` } : undefined}
|
||||||
>
|
>
|
||||||
{dataList.map(item => (
|
{dataList.map(item => {
|
||||||
<div className={`${PREFIX}__row`} key={item.id}>
|
const isChat = type === ProfitType.CHAT_SHARE || item.earnType.toString().toLowerCase().indexOf('chat');
|
||||||
<div className={`${PREFIX}__row-content`}>
|
return (
|
||||||
<div className={`${PREFIX}__item time`}>{formatTimestamp(item.created)}</div>
|
<div className={`${PREFIX}__row`} key={item.id}>
|
||||||
<div className={`${PREFIX}__item project`}>{PROFIT_TYPE_MAP[profitType]}</div>
|
<div className={`${PREFIX}__row-content`}>
|
||||||
<div className={`${PREFIX}__item status`}>
|
<div className={`${PREFIX}__item time`}>{formatTimestamp(item.created)}</div>
|
||||||
{profitType === ProfitType.Anchor ? '已结算' : PROFIT_STATUS_MAP[item.status]}
|
<div className={`${PREFIX}__item project`}>{isChat ? '主播被开聊' : '会员支付'}</div>
|
||||||
|
<div className={`${PREFIX}__item status`}>
|
||||||
|
{isChat ? '已结算' : ProfitStatusDescriptions[item.status]}
|
||||||
|
</div>
|
||||||
|
<div className={`${PREFIX}__item income`}>+{formatMoney(item.amount)}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={`${PREFIX}__item income`}>+{formatMoney(item.profit)}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
);
|
||||||
))}
|
})}
|
||||||
<ListPlaceholder hasMore={false} loadingMore={loadingMore} loadMoreError={loadMoreError} />
|
<ListPlaceholder hasMore={false} loadingMore={loadingMore} loadMoreError={loadMoreError} />
|
||||||
</List>
|
</List>
|
||||||
</PullRefresh>
|
</PullRefresh>
|
||||||
|
@ -30,15 +30,15 @@ export default function PartnerProfit() {
|
|||||||
<Tabs className={`${PREFIX}__tabs`}>
|
<Tabs className={`${PREFIX}__tabs`}>
|
||||||
<Tabs.TabPane title="推荐主播收益">
|
<Tabs.TabPane title="推荐主播收益">
|
||||||
<TableTitle />
|
<TableTitle />
|
||||||
<ProfitList profitType={ProfitType.Anchor} />
|
<ProfitList type={ProfitType.CHAT_SHARE} />
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
<Tabs.TabPane title="推荐会员权益">
|
<Tabs.TabPane title="推荐会员权益">
|
||||||
<TableTitle />
|
<TableTitle />
|
||||||
<ProfitList profitType={ProfitType.Member} />
|
<ProfitList type={ProfitType.PAYMENT_SHARE} />
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
<Tabs.TabPane title="推荐合伙人收益">
|
<Tabs.TabPane title="推荐合伙人收益">
|
||||||
<TableTitle />
|
<TableTitle />
|
||||||
<ProfitList profitType={ProfitType.Partner} />
|
<ProfitList type={ProfitType.INDIRECT_MEMBER_REFERRAL} />
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,21 +1,54 @@
|
|||||||
export enum ProfitType {
|
|
||||||
Anchor = '1',
|
|
||||||
Member = '2',
|
|
||||||
Partner = '3',
|
|
||||||
}
|
|
||||||
export enum ProfitStatus {
|
export enum ProfitStatus {
|
||||||
AVAILABLE = '1',
|
/**
|
||||||
WITHDRAWING = '2',
|
* 待处理/待计算 (例如,等待上游数据或条件满足)
|
||||||
WITHDRAW = '3',
|
*/
|
||||||
|
PENDING_CALCULATION = 0,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 待直接结算/待直接分账 (例如,T+7 到账)
|
||||||
|
* 这种类型的佣金会计入银行账户,而非平台余额
|
||||||
|
*/
|
||||||
|
DIRECT_SETTLEMENT_PENDING = 1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直接结算已完成/直接分账已完成
|
||||||
|
*/
|
||||||
|
DIRECT_SETTLEMENT_PROCESSING = 2,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 间接收益已结算到合伙人余额 (例如,主播推荐奖金进入可提现余额)
|
||||||
|
*/
|
||||||
|
INDIRECT_SETTLED_TO_BALANCE = 3,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 佣金已取消 (例如,订单退款,不满足条件等)
|
||||||
|
*/
|
||||||
|
CANCELLED = 4,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 佣金处理失败
|
||||||
|
*/
|
||||||
|
FAILED = 5,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 其他状态
|
||||||
|
*/
|
||||||
|
OTHER = 6,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已完成
|
||||||
|
*/
|
||||||
|
FINISHED = 7,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PROFIT_TYPE_MAP = {
|
// 如果需要为每个枚举值添加描述,可以使用一个单独的映射对象
|
||||||
[ProfitType.Anchor]: '主播被开聊',
|
export const ProfitStatusDescriptions: { [key in ProfitStatus]: string } = {
|
||||||
[ProfitType.Member]: '会员支付',
|
[ProfitStatus.PENDING_CALCULATION]: '',
|
||||||
[ProfitType.Partner]: '合伙人收益分成',
|
[ProfitStatus.DIRECT_SETTLEMENT_PENDING]: '待分账',
|
||||||
};
|
[ProfitStatus.DIRECT_SETTLEMENT_PROCESSING]: '',
|
||||||
export const PROFIT_STATUS_MAP = {
|
[ProfitStatus.INDIRECT_SETTLED_TO_BALANCE]: '',
|
||||||
[ProfitStatus.AVAILABLE]: '可提现',
|
[ProfitStatus.CANCELLED]: '',
|
||||||
[ProfitStatus.WITHDRAWING]: '提现中',
|
[ProfitStatus.FAILED]: '',
|
||||||
[ProfitStatus.WITHDRAW]: '已提现',
|
[ProfitStatus.OTHER]: '',
|
||||||
|
[ProfitStatus.FINISHED]: '已分账',
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// export const DOMAIN = 'http://192.168.60.120:8082';
|
// export const DOMAIN = 'http://192.168.60.148:8082';
|
||||||
export const DOMAIN = 'https://neighbourhood.cn';
|
export const DOMAIN = 'https://neighbourhood.cn';
|
||||||
export const BASE_URL = `${DOMAIN}/api`;
|
export const BASE_URL = `${DOMAIN}/api`;
|
||||||
|
|
||||||
@ -80,6 +80,6 @@ export enum API {
|
|||||||
GET_INVITE_CODE = '/user/getUserInviteCode',
|
GET_INVITE_CODE = '/user/getUserInviteCode',
|
||||||
GET_INVITE_LIST = '/user/inviteUsers',
|
GET_INVITE_LIST = '/user/inviteUsers',
|
||||||
BECOME_PARTNER = '/user/becomePartner',
|
BECOME_PARTNER = '/user/becomePartner',
|
||||||
GET_PROFIT_LIST = '/profit/profits',
|
GET_PROFIT_LIST = '/user/profit/list',
|
||||||
GET_PROFIT_STAT = '/user/profits',
|
GET_PROFIT_STAT = '/user/profits',
|
||||||
}
|
}
|
||||||
|
@ -36,9 +36,9 @@ export interface InviteUserInfo {
|
|||||||
roleType: string; // 角色类型,可选
|
roleType: string; // 角色类型,可选
|
||||||
}
|
}
|
||||||
export enum ProfitType {
|
export enum ProfitType {
|
||||||
Anchor = '1',
|
PAYMENT_SHARE = 'PAYMENT_SHARE',
|
||||||
Member = '2',
|
CHAT_SHARE = 'CHAT_SHARE',
|
||||||
Partner = '3',
|
INDIRECT_MEMBER_REFERRAL = 'INDIRECT_MEMBER_REFERRAL',
|
||||||
}
|
}
|
||||||
export enum ProfitStatus {
|
export enum ProfitStatus {
|
||||||
AVAILABLE = '1',
|
AVAILABLE = '1',
|
||||||
@ -46,18 +46,21 @@ export enum ProfitStatus {
|
|||||||
WITHDRAW = '3',
|
WITHDRAW = '3',
|
||||||
}
|
}
|
||||||
export interface GetProfitRequest {
|
export interface GetProfitRequest {
|
||||||
profitType: ProfitType;
|
type: ProfitType;
|
||||||
}
|
}
|
||||||
export interface PartnerProfitItem {
|
export interface PartnerProfitItem {
|
||||||
id: number; // 唯一标识
|
id: number; // 唯一标识
|
||||||
userId: string; // 用户ID
|
partnerId: string;
|
||||||
profit: number; // 利润
|
sourceUserId: string;
|
||||||
profitType: ProfitType; // 利润类型
|
originatingUserId: string; // 用户ID
|
||||||
|
relatedEntityId: string;
|
||||||
|
relatedEntityType: string;
|
||||||
|
amount: number; // 利润
|
||||||
|
earnType: ProfitType; // 利润类型
|
||||||
status: ProfitStatus; // 状态
|
status: ProfitStatus; // 状态
|
||||||
relatedId: string; // 相关ID
|
|
||||||
remark: string; // 备注
|
remark: string; // 备注
|
||||||
created: string; // 创建时间
|
created: string; // 创建时间
|
||||||
updated: string; // 更新时间
|
updated: string; // 更新时间
|
||||||
profitTypeEnum: string; // 利润类型枚举
|
expectedSettlementDate: string;
|
||||||
statusEnum: string; // 状态枚举
|
actualSettlementDate: string;
|
||||||
}
|
}
|
||||||
|
@ -61,8 +61,11 @@ export const getInviteCode = async () => {
|
|||||||
return inviteCode;
|
return inviteCode;
|
||||||
};
|
};
|
||||||
export const getProfitList = async (data: GetProfitRequest) => {
|
export const getProfitList = async (data: GetProfitRequest) => {
|
||||||
// const result = await http.post<PartnerProfitItem[]>(API.GET_PROFIT_LIST, { data });
|
const result = await http.post<PartnerProfitItem[]>(API.GET_PROFIT_LIST, {
|
||||||
// return Array.isArray(result) ? result : [];
|
data,
|
||||||
|
contentType: 'application/x-www-form-urlencoded',
|
||||||
|
});
|
||||||
|
return Array.isArray(result) ? result : [];
|
||||||
return [];
|
return [];
|
||||||
};
|
};
|
||||||
export const formatMoney = (cents: number) => {
|
export const formatMoney = (cents: number) => {
|
||||||
@ -73,11 +76,8 @@ export const formatMoney = (cents: number) => {
|
|||||||
return yuan.toFixed(2);
|
return yuan.toFixed(2);
|
||||||
};
|
};
|
||||||
export function formatTimestamp(timestamp: string): string {
|
export function formatTimestamp(timestamp: string): string {
|
||||||
// 将字符串时间戳转换为数字类型
|
|
||||||
const time = Number(timestamp);
|
|
||||||
|
|
||||||
// 创建 Date 对象
|
// 创建 Date 对象
|
||||||
const date = new Date(time);
|
const date = new Date(timestamp);
|
||||||
|
|
||||||
// 获取年、月、日、时、分、秒
|
// 获取年、月、日、时、分、秒
|
||||||
const YYYY = date.getFullYear();
|
const YYYY = date.getFullYear();
|
||||||
@ -85,10 +85,9 @@ export function formatTimestamp(timestamp: string): string {
|
|||||||
const DD = String(date.getDate()).padStart(2, '0');
|
const DD = String(date.getDate()).padStart(2, '0');
|
||||||
const HH = String(date.getHours()).padStart(2, '0');
|
const HH = String(date.getHours()).padStart(2, '0');
|
||||||
const mm = String(date.getMinutes()).padStart(2, '0');
|
const mm = String(date.getMinutes()).padStart(2, '0');
|
||||||
const ss = String(date.getSeconds()).padStart(2, '0');
|
|
||||||
|
|
||||||
// 拼接成所需的格式
|
// 拼接成所需的格式
|
||||||
return `${YYYY}.${MM}.${DD} ${HH}:${mm}:${ss}`;
|
return `${YYYY}.${MM}.${DD} ${HH}:${mm}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatUserId(input: string): string {
|
export function formatUserId(input: string): string {
|
||||||
|
Loading…
Reference in New Issue
Block a user