rwadurian/backend/services/referral-service/src/domain/value-objects/province-city-distribution....

109 lines
2.8 KiB
TypeScript

export interface ProvinceCityCount {
provinceCode: string;
cityCode: string;
count: number;
}
/**
* 省市分布统计值对象
* 用于计算用户团队在各省/市的认种分布
*/
export class ProvinceCityDistribution {
private constructor(private readonly distribution: Map<string, Map<string, number>>) {}
static empty(): ProvinceCityDistribution {
return new ProvinceCityDistribution(new Map());
}
static fromJson(json: Record<string, Record<string, number>> | null): ProvinceCityDistribution {
if (!json) {
return ProvinceCityDistribution.empty();
}
const map = new Map<string, Map<string, number>>();
for (const [province, cities] of Object.entries(json)) {
const cityMap = new Map<string, number>();
for (const [city, count] of Object.entries(cities)) {
cityMap.set(city, count);
}
map.set(province, cityMap);
}
return new ProvinceCityDistribution(map);
}
/**
* 添加认种记录 (返回新实例,不可变)
*/
add(provinceCode: string, cityCode: string, count: number): ProvinceCityDistribution {
const newDist = new Map(this.distribution);
if (!newDist.has(provinceCode)) {
newDist.set(provinceCode, new Map());
}
const cityMap = new Map(newDist.get(provinceCode)!);
cityMap.set(cityCode, (cityMap.get(cityCode) ?? 0) + count);
newDist.set(provinceCode, cityMap);
return new ProvinceCityDistribution(newDist);
}
/**
* 获取某省的总认种量
*/
getProvinceTotal(provinceCode: string): number {
const cities = this.distribution.get(provinceCode);
if (!cities) return 0;
let total = 0;
for (const count of cities.values()) {
total += count;
}
return total;
}
/**
* 获取某市的总认种量
*/
getCityTotal(provinceCode: string, cityCode: string): number {
return this.distribution.get(provinceCode)?.get(cityCode) ?? 0;
}
/**
* 获取所有省市的统计
*/
getAll(): ProvinceCityCount[] {
const result: ProvinceCityCount[] = [];
for (const [provinceCode, cities] of this.distribution) {
for (const [cityCode, count] of cities) {
result.push({ provinceCode, cityCode, count });
}
}
return result;
}
/**
* 获取总数
*/
getTotal(): number {
let total = 0;
for (const cities of this.distribution.values()) {
for (const count of cities.values()) {
total += count;
}
}
return total;
}
toJson(): Record<string, Record<string, number>> {
const result: Record<string, Record<string, number>> = {};
for (const [province, cities] of this.distribution) {
result[province] = {};
for (const [city, count] of cities) {
result[province][city] = count;
}
}
return result;
}
}