This commit is contained in:
eleanor.mao 2025-05-29 01:04:31 +08:00
parent fa30ec2988
commit ed99c7b1ae
6 changed files with 93 additions and 55 deletions

View File

@ -3,12 +3,12 @@ import classNames from 'classnames';
import { useCallback, useEffect, useRef, useState } from 'react';
import ListPlaceholder from '@/components/list-placeholder';
import { ProfitStatusDescriptions } from '@/constants/partner';
import { GetProfitRequest, PartnerProfitItem, ProfitType } from '@/types/partner';
import { logWithPrefix } from '@/utils/common';
import { formatMoney, formatTimestamp, getProfitList as requestData } from '@/utils/partner';
import './index.less';
import { PROFIT_STATUS_MAP, PROFIT_TYPE_MAP } from '@/constants/partner';
export interface IPartnerProfitListProps extends GetProfitRequest {
visible?: boolean;
@ -22,7 +22,7 @@ const PREFIX = 'partner-profit';
const log = logWithPrefix(PREFIX);
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 [loadingMore, setLoadingMore] = useState(false);
const [loadMoreError, setLoadMoreError] = useState(false);
@ -34,7 +34,7 @@ function ProfitList(props: IPartnerProfitListProps) {
try {
setRefreshing(true);
setLoadMoreError(false);
const list = await requestData({ profitType });
const list = await requestData({ type });
setDataList(list);
!list.length && onListEmptyRef.current?.();
log('pull refresh success');
@ -65,7 +65,7 @@ function ProfitList(props: IPartnerProfitListProps) {
setDataList([]);
setLoadingMore(true);
setLoadMoreError(false);
const list = await requestData({ profitType });
const list = await requestData({ type });
setDataList(list);
!list.length && onListEmptyRef.current?.();
} catch (e) {
@ -77,7 +77,7 @@ function ProfitList(props: IPartnerProfitListProps) {
}
};
refresh();
}, [visible, profitType]);
}, [visible, type]);
return (
<div className={`${PREFIX}__tab-content`}>
@ -95,18 +95,21 @@ function ProfitList(props: IPartnerProfitListProps) {
fixedHeight={typeof listHeight !== 'undefined'}
style={listHeight ? { height: `${listHeight}px` } : undefined}
>
{dataList.map(item => (
<div className={`${PREFIX}__row`} key={item.id}>
<div className={`${PREFIX}__row-content`}>
<div className={`${PREFIX}__item time`}>{formatTimestamp(item.created)}</div>
<div className={`${PREFIX}__item project`}>{PROFIT_TYPE_MAP[profitType]}</div>
<div className={`${PREFIX}__item status`}>
{profitType === ProfitType.Anchor ? '已结算' : PROFIT_STATUS_MAP[item.status]}
{dataList.map(item => {
const isChat = type === ProfitType.CHAT_SHARE || item.earnType.toString().toLowerCase().indexOf('chat');
return (
<div className={`${PREFIX}__row`} key={item.id}>
<div className={`${PREFIX}__row-content`}>
<div className={`${PREFIX}__item time`}>{formatTimestamp(item.created)}</div>
<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 className={`${PREFIX}__item income`}>+{formatMoney(item.profit)}</div>
</div>
</div>
))}
);
})}
<ListPlaceholder hasMore={false} loadingMore={loadingMore} loadMoreError={loadMoreError} />
</List>
</PullRefresh>

View File

@ -30,15 +30,15 @@ export default function PartnerProfit() {
<Tabs className={`${PREFIX}__tabs`}>
<Tabs.TabPane title="推荐主播收益">
<TableTitle />
<ProfitList profitType={ProfitType.Anchor} />
<ProfitList type={ProfitType.CHAT_SHARE} />
</Tabs.TabPane>
<Tabs.TabPane title="推荐会员权益">
<TableTitle />
<ProfitList profitType={ProfitType.Member} />
<ProfitList type={ProfitType.PAYMENT_SHARE} />
</Tabs.TabPane>
<Tabs.TabPane title="推荐合伙人收益">
<TableTitle />
<ProfitList profitType={ProfitType.Partner} />
<ProfitList type={ProfitType.INDIRECT_MEMBER_REFERRAL} />
</Tabs.TabPane>
</Tabs>
</div>

View File

@ -1,21 +1,54 @@
export enum ProfitType {
Anchor = '1',
Member = '2',
Partner = '3',
}
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]: '主播被开聊',
[ProfitType.Member]: '会员支付',
[ProfitType.Partner]: '合伙人收益分成',
};
export const PROFIT_STATUS_MAP = {
[ProfitStatus.AVAILABLE]: '可提现',
[ProfitStatus.WITHDRAWING]: '提现中',
[ProfitStatus.WITHDRAW]: '已提现',
// 如果需要为每个枚举值添加描述,可以使用一个单独的映射对象
export const ProfitStatusDescriptions: { [key in ProfitStatus]: string } = {
[ProfitStatus.PENDING_CALCULATION]: '',
[ProfitStatus.DIRECT_SETTLEMENT_PENDING]: '待分账',
[ProfitStatus.DIRECT_SETTLEMENT_PROCESSING]: '',
[ProfitStatus.INDIRECT_SETTLED_TO_BALANCE]: '',
[ProfitStatus.CANCELLED]: '',
[ProfitStatus.FAILED]: '',
[ProfitStatus.OTHER]: '',
[ProfitStatus.FINISHED]: '已分账',
};

View File

@ -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 BASE_URL = `${DOMAIN}/api`;
@ -80,6 +80,6 @@ export enum API {
GET_INVITE_CODE = '/user/getUserInviteCode',
GET_INVITE_LIST = '/user/inviteUsers',
BECOME_PARTNER = '/user/becomePartner',
GET_PROFIT_LIST = '/profit/profits',
GET_PROFIT_LIST = '/user/profit/list',
GET_PROFIT_STAT = '/user/profits',
}

View File

@ -36,9 +36,9 @@ export interface InviteUserInfo {
roleType: string; // 角色类型,可选
}
export enum ProfitType {
Anchor = '1',
Member = '2',
Partner = '3',
PAYMENT_SHARE = 'PAYMENT_SHARE',
CHAT_SHARE = 'CHAT_SHARE',
INDIRECT_MEMBER_REFERRAL = 'INDIRECT_MEMBER_REFERRAL',
}
export enum ProfitStatus {
AVAILABLE = '1',
@ -46,18 +46,21 @@ export enum ProfitStatus {
WITHDRAW = '3',
}
export interface GetProfitRequest {
profitType: ProfitType;
type: ProfitType;
}
export interface PartnerProfitItem {
id: number; // 唯一标识
userId: string; // 用户ID
profit: number; // 利润
profitType: ProfitType; // 利润类型
partnerId: string;
sourceUserId: string;
originatingUserId: string; // 用户ID
relatedEntityId: string;
relatedEntityType: string;
amount: number; // 利润
earnType: ProfitType; // 利润类型
status: ProfitStatus; // 状态
relatedId: string; // 相关ID
remark: string; // 备注
created: string; // 创建时间
updated: string; // 更新时间
profitTypeEnum: string; // 利润类型枚举
statusEnum: string; // 状态枚举
expectedSettlementDate: string;
actualSettlementDate: string;
}

View File

@ -61,8 +61,11 @@ export const getInviteCode = async () => {
return inviteCode;
};
export const getProfitList = async (data: GetProfitRequest) => {
// const result = await http.post<PartnerProfitItem[]>(API.GET_PROFIT_LIST, { data });
// return Array.isArray(result) ? result : [];
const result = await http.post<PartnerProfitItem[]>(API.GET_PROFIT_LIST, {
data,
contentType: 'application/x-www-form-urlencoded',
});
return Array.isArray(result) ? result : [];
return [];
};
export const formatMoney = (cents: number) => {
@ -73,11 +76,8 @@ export const formatMoney = (cents: number) => {
return yuan.toFixed(2);
};
export function formatTimestamp(timestamp: string): string {
// 将字符串时间戳转换为数字类型
const time = Number(timestamp);
// 创建 Date 对象
const date = new Date(time);
const date = new Date(timestamp);
// 获取年、月、日、时、分、秒
const YYYY = date.getFullYear();
@ -85,10 +85,9 @@ export function formatTimestamp(timestamp: string): string {
const DD = String(date.getDate()).padStart(2, '0');
const HH = String(date.getHours()).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 {