rwadurian/backend/services/planting-service/src/infrastructure/external/authorization-service.clien...

299 lines
8.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { HttpService } from '@nestjs/axios';
import { firstValueFrom } from 'rxjs';
// 省市公司授权信息
export interface RegionAuthorization {
authorizationId: string;
userId: string;
roleType: string;
regionCode: string;
regionName: string;
benefitActive: boolean;
// 算力百分比(正式省公司 1%,正式市公司 2%
hashpowerPercent: number;
}
// 社区授权信息
export interface CommunityAuthorization {
authorizationId: string;
userId: string;
communityName: string;
benefitActive: boolean;
}
// 系统账户信息
export interface SystemAccountInfo {
accountId: string;
accountType: string;
regionCode: string | null;
walletAddress: string | null;
}
// 分配上下文 - 包含授权查询结果
export interface AllocationContext {
// 省公司授权(区域权益 15U + 1% 算力)
provinceCompanyAuth: RegionAuthorization | null;
// 授权省公司(团队权益 20U
authProvinceCompanyAuth: RegionAuthorization | null;
// 市公司授权(区域权益 35U + 2% 算力)
cityCompanyAuth: RegionAuthorization | null;
// 授权市公司(团队权益 40U
authCityCompanyAuth: RegionAuthorization | null;
// 社区授权80U
communityAuth: CommunityAuthorization | null;
// 系统账户用于无授权时的fallback
systemAccounts: {
costAccount: SystemAccountInfo;
operationAccount: SystemAccountInfo;
hqCommunityAccount: SystemAccountInfo;
rwadPoolAccount: SystemAccountInfo;
systemProvinceAccount: SystemAccountInfo;
systemCityAccount: SystemAccountInfo;
};
}
@Injectable()
export class AuthorizationServiceClient {
private readonly logger = new Logger(AuthorizationServiceClient.name);
private readonly baseUrl: string;
constructor(
private readonly configService: ConfigService,
private readonly httpService: HttpService,
) {
this.baseUrl =
this.configService.get<string>('AUTHORIZATION_SERVICE_URL') ||
'http://localhost:3005';
}
/**
* 获取分配上下文 - 查询省市社区授权状态和系统账户
*/
async getAllocationContext(
planterId: string,
provinceCode: string,
cityCode: string,
): Promise<AllocationContext> {
try {
const response = await firstValueFrom(
this.httpService.get<AllocationContext>(
`${this.baseUrl}/api/v1/allocations/context`,
{
params: {
planterId,
provinceCode,
cityCode,
},
},
),
);
return response.data;
} catch (error) {
this.logger.error(
`Failed to get allocation context for planter ${planterId}`,
error,
);
// 开发环境返回默认数据
if (this.configService.get('NODE_ENV') === 'development') {
this.logger.warn(
'Development mode: returning default allocation context',
);
return this.getDefaultAllocationContext(provinceCode, cityCode);
}
throw error;
}
}
/**
* 获取省区域权益接收方
*/
async getProvinceAreaRightsRecipient(
provinceCode: string,
): Promise<{ recipientType: 'USER' | 'SYSTEM'; recipientId: string; hashpowerPercent: number }> {
try {
const response = await firstValueFrom(
this.httpService.get(
`${this.baseUrl}/api/v1/authorizations/province/${provinceCode}/area-rights`,
),
);
return response.data;
} catch (error) {
this.logger.error(`Failed to get province area rights recipient for ${provinceCode}`, error);
// 返回系统省账户作为默认
return {
recipientType: 'SYSTEM',
recipientId: `SYSTEM_PROVINCE:${provinceCode}`,
hashpowerPercent: 0,
};
}
}
/**
* 获取省团队权益接收方
*/
async getProvinceTeamRightsRecipient(
provinceCode: string,
): Promise<{ recipientType: 'USER' | 'SYSTEM'; recipientId: string }> {
try {
const response = await firstValueFrom(
this.httpService.get(
`${this.baseUrl}/api/v1/authorizations/province/${provinceCode}/team-rights`,
),
);
return response.data;
} catch (error) {
this.logger.error(`Failed to get province team rights recipient for ${provinceCode}`, error);
return {
recipientType: 'SYSTEM',
recipientId: `SYSTEM_PROVINCE:${provinceCode}`,
};
}
}
/**
* 获取市区域权益接收方
*/
async getCityAreaRightsRecipient(
cityCode: string,
): Promise<{ recipientType: 'USER' | 'SYSTEM'; recipientId: string; hashpowerPercent: number }> {
try {
const response = await firstValueFrom(
this.httpService.get(
`${this.baseUrl}/api/v1/authorizations/city/${cityCode}/area-rights`,
),
);
return response.data;
} catch (error) {
this.logger.error(`Failed to get city area rights recipient for ${cityCode}`, error);
return {
recipientType: 'SYSTEM',
recipientId: `SYSTEM_CITY:${cityCode}`,
hashpowerPercent: 0,
};
}
}
/**
* 获取市团队权益接收方
*/
async getCityTeamRightsRecipient(
cityCode: string,
): Promise<{ recipientType: 'USER' | 'SYSTEM'; recipientId: string }> {
try {
const response = await firstValueFrom(
this.httpService.get(
`${this.baseUrl}/api/v1/authorizations/city/${cityCode}/team-rights`,
),
);
return response.data;
} catch (error) {
this.logger.error(`Failed to get city team rights recipient for ${cityCode}`, error);
return {
recipientType: 'SYSTEM',
recipientId: `SYSTEM_CITY:${cityCode}`,
};
}
}
/**
* 获取社区权益接收方
*/
async getCommunityRightsRecipient(
planterId: string,
): Promise<{ recipientType: 'USER' | 'SYSTEM'; recipientId: string } | null> {
try {
const response = await firstValueFrom(
this.httpService.get(
`${this.baseUrl}/api/v1/authorizations/user/${planterId}/community-rights`,
),
);
return response.data;
} catch (error) {
this.logger.error(`Failed to get community rights recipient for ${planterId}`, error);
return null;
}
}
/**
* 通知认种完成,更新考核进度
*/
async notifyPlantingCompleted(params: {
planterId: string;
treeCount: number;
provinceCode: string;
cityCode: string;
orderId: string;
}): Promise<void> {
try {
await firstValueFrom(
this.httpService.post(
`${this.baseUrl}/api/v1/allocations/planting-completed`,
params,
),
);
} catch (error) {
this.logger.error('Failed to notify planting completed', error);
// 不抛出错误,允许继续执行
}
}
/**
* 获取默认分配上下文(开发环境用)
*/
private getDefaultAllocationContext(
provinceCode: string,
cityCode: string,
): AllocationContext {
return {
provinceCompanyAuth: null,
authProvinceCompanyAuth: null,
cityCompanyAuth: null,
authCityCompanyAuth: null,
communityAuth: null,
systemAccounts: {
costAccount: {
accountId: '1',
accountType: 'COST_ACCOUNT',
regionCode: null,
walletAddress: null,
},
operationAccount: {
accountId: '2',
accountType: 'OPERATION_ACCOUNT',
regionCode: null,
walletAddress: null,
},
hqCommunityAccount: {
accountId: '3',
accountType: 'HQ_COMMUNITY',
regionCode: null,
walletAddress: null,
},
rwadPoolAccount: {
accountId: '4',
accountType: 'RWAD_POOL_PENDING',
regionCode: null,
walletAddress: null,
},
systemProvinceAccount: {
accountId: `PROVINCE:${provinceCode}`,
accountType: 'SYSTEM_PROVINCE',
regionCode: provinceCode,
walletAddress: null,
},
systemCityAccount: {
accountId: `CITY:${cityCode}`,
accountType: 'SYSTEM_CITY',
regionCode: cityCode,
walletAddress: null,
},
},
};
}
}