@mymcp-fun/bazi
Version:
专业的八字计算MCP服务器
121 lines (120 loc) • 4.08 kB
JavaScript
import { Solar } from 'lunar-javascript';
export class MCPBaziService {
async calculateBazi(input) {
try {
this.validateInput(input);
const solar = Solar.fromYmdHms(input.year, input.month, input.day, input.hour, 0, 0);
const lunar = solar.getLunar();
const baZi = lunar.getEightChar();
return this.formatResult(solar, lunar, baZi);
}
catch (error) {
throw this.handleError(error);
}
}
validateInput(input) {
if (!input.year || input.year < 1900 || input.year > 2100) {
throw new Error('年份必须在1900-2100之间');
}
if (!input.month || input.month < 1 || input.month > 12) {
throw new Error('月份必须在1-12之间');
}
if (!input.day || input.day < 1 || input.day > 31) {
throw new Error('日期必须在1-31之间');
}
if (input.hour === undefined || input.hour < 0 || input.hour > 23) {
throw new Error('小时必须在0-23之间');
}
}
formatResult(solar, lunar, baZi) {
const yearGanZhi = baZi.getYear();
const monthGanZhi = baZi.getMonth();
const dayGanZhi = baZi.getDay();
const hourGanZhi = baZi.getTime();
const lunarMonthNames = [
'', '正月', '二月', '三月', '四月', '五月', '六月',
'七月', '八月', '九月', '十月', '冬月', '腊月'
];
const result = {
四柱: {
年柱: yearGanZhi,
月柱: monthGanZhi,
日柱: dayGanZhi,
时柱: hourGanZhi
},
五行: {
木: 0,
火: 0,
土: 0,
金: 0,
水: 0
},
生肖: lunar.getYearShengXiao(),
星座: solar.getXingZuo(),
农历: {
农历年: lunar.getYear(),
农历月: lunar.getMonth(),
农历日: lunar.getDay(),
是否闰月: false,
农历月名: lunarMonthNames[lunar.getMonth()] || `${lunar.getMonth()}月`
},
日主: dayGanZhi[0]
};
this.calculateElements(result, [yearGanZhi, monthGanZhi, dayGanZhi, hourGanZhi]);
return result;
}
calculateElements(result, ganZhiList) {
const ganWuXing = {
'甲': '木', '乙': '木',
'丙': '火', '丁': '火',
'戊': '土', '己': '土',
'庚': '金', '辛': '金',
'壬': '水', '癸': '水'
};
const zhiWuXing = {
'子': '水', '亥': '水',
'寅': '木', '卯': '木',
'巳': '火', '午': '火',
'申': '金', '酉': '金',
'辰': '土', '戌': '土', '丑': '土', '未': '土'
};
ganZhiList.forEach(ganZhi => {
if (ganZhi && ganZhi.length >= 2) {
const gan = ganZhi[0];
const zhi = ganZhi[1];
if (gan && ganWuXing[gan]) {
this.addElement(result, ganWuXing[gan]);
}
if (zhi && zhiWuXing[zhi]) {
this.addElement(result, zhiWuXing[zhi]);
}
}
});
}
addElement(result, element) {
switch (element) {
case '木':
result.五行.木 += 1;
break;
case '火':
result.五行.火 += 1;
break;
case '土':
result.五行.土 += 1;
break;
case '金':
result.五行.金 += 1;
break;
case '水':
result.五行.水 += 1;
break;
}
}
handleError(error) {
return {
code: 'CALCULATION_ERROR',
message: error.message || '八字计算失败',
details: error
};
}
}