bazi.js 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235
  1. /**
  2. * 八字计算工具类
  3. * 基于传统命理学理论实现八字计算、分析和配对功能
  4. * 支持专业API验证和本地算法双重计算
  5. */
  6. import { BAZI_API_CONFIG } from '@/config/api-config.js'
  7. // 天干
  8. const TIANGAN = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸']
  9. // 地支
  10. const DIZHI = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥']
  11. // 天干五行
  12. const TIANGAN_WUXING = {
  13. '甲': '木', '乙': '木',
  14. '丙': '火', '丁': '火',
  15. '戊': '土', '己': '土',
  16. '庚': '金', '辛': '金',
  17. '壬': '水', '癸': '水'
  18. }
  19. // 地支五行
  20. const DIZHI_WUXING = {
  21. '子': '水', '丑': '土', '寅': '木', '卯': '木',
  22. '辰': '土', '巳': '火', '午': '火', '未': '土',
  23. '申': '金', '酉': '金', '戌': '土', '亥': '水'
  24. }
  25. // 天干阴阳
  26. const TIANGAN_YINYANG = {
  27. '甲': '阳', '乙': '阴', '丙': '阳', '丁': '阴', '戊': '阳',
  28. '己': '阴', '庚': '阳', '辛': '阴', '壬': '阳', '癸': '阴'
  29. }
  30. // 地支阴阳
  31. const DIZHI_YINYANG = {
  32. '子': '阳', '丑': '阴', '寅': '阳', '卯': '阴', '辰': '阳', '巳': '阴',
  33. '午': '阳', '未': '阴', '申': '阳', '酉': '阴', '戌': '阳', '亥': '阴'
  34. }
  35. // 十二生肖
  36. const SHENGXIAO = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪']
  37. // 月份地支对照表(节气月)
  38. const MONTH_DIZHI = {
  39. 2: '寅', 3: '卯', 4: '辰', 5: '巳', 6: '午', 7: '未',
  40. 8: '申', 9: '酉', 10: '戌', 11: '亥', 12: '子', 1: '丑'
  41. }
  42. // 时辰对照表
  43. const TIME_DIZHI = {
  44. 23: '子', 0: '子', 1: '丑', 2: '丑', 3: '寅', 4: '寅',
  45. 5: '卯', 6: '卯', 7: '辰', 8: '辰', 9: '巳', 10: '巳',
  46. 11: '午', 12: '午', 13: '未', 14: '未', 15: '申', 16: '申',
  47. 17: '酉', 18: '酉', 19: '戌', 20: '戌', 21: '亥', 22: '亥'
  48. }
  49. // 五行生克关系
  50. const WUXING_RELATION = {
  51. '生': {
  52. '木': '火', '火': '土', '土': '金', '金': '水', '水': '木'
  53. },
  54. '克': {
  55. '木': '土', '火': '金', '土': '水', '金': '木', '水': '火'
  56. }
  57. }
  58. // 纳音表(简化版)
  59. const NAYIN = {
  60. '甲子': '海中金', '乙丑': '海中金', '丙寅': '炉中火', '丁卯': '炉中火',
  61. '戊辰': '大林木', '己巳': '大林木', '庚午': '路旁土', '辛未': '路旁土',
  62. '壬申': '剑锋金', '癸酉': '剑锋金', '甲戌': '山头火', '乙亥': '山头火',
  63. '丙子': '涧下水', '丁丑': '涧下水', '戊寅': '城头土', '己卯': '城头土',
  64. '庚辰': '白蜡金', '辛巳': '白蜡金', '壬午': '杨柳木', '癸未': '杨柳木',
  65. '甲申': '泉中水', '乙酉': '泉中水', '丙戌': '屋上土', '丁亥': '屋上土',
  66. '戊子': '霹雳火', '己丑': '霹雳火', '庚寅': '松柏木', '辛卯': '松柏木',
  67. '壬辰': '长流水', '癸巳': '长流水', '甲午': '砂中金', '乙未': '砂中金',
  68. '丙申': '山下火', '丁酉': '山下火', '戊戌': '平地木', '己亥': '平地木',
  69. '庚子': '壁上土', '辛丑': '壁上土', '壬寅': '金箔金', '癸卯': '金箔金',
  70. '甲辰': '佛灯火', '乙巳': '佛灯火', '丙午': '天河水', '丁未': '天河水',
  71. '戊申': '大驿土', '己酉': '大驿土', '庚戌': '钗钏金', '辛亥': '钗钏金',
  72. '壬子': '桑柘木', '癸丑': '桑柘木', '甲寅': '大溪水', '乙卯': '大溪水',
  73. '丙辰': '砂中土', '丁巳': '砂中土', '戊午': '天上火', '己未': '天上火',
  74. '庚申': '石榴木', '辛酉': '石榴木', '壬戌': '大海水', '癸亥': '大海水'
  75. }
  76. /**
  77. * 计算八字
  78. * @param {Date} birthDate 出生日期
  79. * @param {Number} hour 出生时辰(0-23)
  80. * @returns {Object} 八字信息
  81. */
  82. export function calculateBaZi(birthDate, hour) {
  83. const year = birthDate.getFullYear()
  84. const month = birthDate.getMonth() + 1
  85. const day = birthDate.getDate()
  86. // 计算年柱
  87. const yearGanZhi = getYearGanZhi(year)
  88. // 计算月柱
  89. const monthGanZhi = getMonthGanZhi(year, month)
  90. // 计算日柱
  91. const dayGanZhi = getDayGanZhi(year, month, day)
  92. // 计算时柱
  93. const hourGanZhi = getHourGanZhi(dayGanZhi.gan, hour)
  94. // 分析八字
  95. const analysis = analyzeBaZi({
  96. year: yearGanZhi,
  97. month: monthGanZhi,
  98. day: dayGanZhi,
  99. hour: hourGanZhi
  100. })
  101. return {
  102. year: yearGanZhi,
  103. month: monthGanZhi,
  104. day: dayGanZhi,
  105. hour: hourGanZhi,
  106. birthInfo: {
  107. year: year,
  108. month: month,
  109. day: day,
  110. hour: hour,
  111. shengxiao: SHENGXIAO[(year - 4) % 12],
  112. nayin: NAYIN[yearGanZhi.ganZhi] || '未知'
  113. },
  114. analysis: analysis,
  115. baziString: `${yearGanZhi.ganZhi} ${monthGanZhi.ganZhi} ${dayGanZhi.ganZhi} ${hourGanZhi.ganZhi}`,
  116. rizhu: dayGanZhi.ganZhi,
  117. riganWuxing: TIANGAN_WUXING[dayGanZhi.gan]
  118. }
  119. }
  120. /**
  121. * 获取年柱干支
  122. */
  123. function getYearGanZhi(year) {
  124. // 以1900年庚子年为基准计算
  125. const baseYear = 1900
  126. const yearOffset = year - baseYear
  127. const ganIndex = (yearOffset + 6) % 10 // 庚为第7个天干,索引为6
  128. const zhiIndex = (yearOffset + 0) % 12 // 子为第1个地支,索引为0
  129. const gan = TIANGAN[ganIndex]
  130. const zhi = DIZHI[zhiIndex]
  131. return {
  132. gan: gan,
  133. zhi: zhi,
  134. ganZhi: gan + zhi,
  135. wuxing: TIANGAN_WUXING[gan],
  136. yinyang: TIANGAN_YINYANG[gan]
  137. }
  138. }
  139. /**
  140. * 获取月柱干支
  141. */
  142. function getMonthGanZhi(year, month) {
  143. // 简化计算,实际应该根据节气
  144. const zhi = MONTH_DIZHI[month]
  145. // 月干计算:年干为甲己配丙寅,乙庚丁卯始...
  146. const yearGan = getYearGanZhi(year).gan
  147. let ganIndex = 0
  148. switch (yearGan) {
  149. case '甲': case '己': ganIndex = 2; break // 丙
  150. case '乙': case '庚': ganIndex = 3; break // 丁
  151. case '丙': case '辛': ganIndex = 4; break // 戊
  152. case '丁': case '壬': ganIndex = 5; break // 己
  153. case '戊': case '癸': ganIndex = 6; break // 庚
  154. }
  155. // 从寅月开始计算
  156. const monthOffset = month === 1 ? 11 : (month === 2 ? 0 : month - 2)
  157. ganIndex = (ganIndex + monthOffset) % 10
  158. const gan = TIANGAN[ganIndex]
  159. return {
  160. gan: gan,
  161. zhi: zhi,
  162. ganZhi: gan + zhi,
  163. wuxing: TIANGAN_WUXING[gan],
  164. yinyang: TIANGAN_YINYANG[gan]
  165. }
  166. }
  167. /**
  168. * 获取日柱干支(简化算法)
  169. */
  170. function getDayGanZhi(year, month, day) {
  171. // 以公元1年1月1日为甲子日计算(简化)
  172. const date = new Date(year, month - 1, day)
  173. const daysSince1900 = Math.floor((date - new Date(1900, 0, 1)) / (24 * 60 * 60 * 1000))
  174. // 1900年1月1日为庚戌日
  175. const ganIndex = (daysSince1900 + 6) % 10 // 庚的索引是6
  176. const zhiIndex = (daysSince1900 + 10) % 12 // 戌的索引是10
  177. const gan = TIANGAN[ganIndex]
  178. const zhi = DIZHI[zhiIndex]
  179. return {
  180. gan: gan,
  181. zhi: zhi,
  182. ganZhi: gan + zhi,
  183. wuxing: TIANGAN_WUXING[gan],
  184. yinyang: TIANGAN_YINYANG[gan]
  185. }
  186. }
  187. /**
  188. * 获取时柱干支
  189. */
  190. function getHourGanZhi(dayGan, hour) {
  191. const zhi = TIME_DIZHI[hour] || '未知'
  192. // 时干计算:甲己还是甲,乙庚丙作初...
  193. let ganIndex = 0
  194. const zhiIndex = DIZHI.indexOf(zhi)
  195. switch (dayGan) {
  196. case '甲': case '己': ganIndex = 0; break // 甲
  197. case '乙': case '庚': ganIndex = 2; break // 丙
  198. case '丙': case '辛': ganIndex = 4; break // 戊
  199. case '丁': case '壬': ganIndex = 6; break // 庚
  200. case '戊': case '癸': ganIndex = 8; break // 壬
  201. }
  202. ganIndex = (ganIndex + zhiIndex) % 10
  203. const gan = TIANGAN[ganIndex]
  204. return {
  205. gan: gan,
  206. zhi: zhi,
  207. ganZhi: gan + zhi,
  208. wuxing: TIANGAN_WUXING[gan],
  209. yinyang: TIANGAN_YINYANG[gan]
  210. }
  211. }
  212. /**
  213. * 分析八字
  214. */
  215. function analyzeBaZi(bazi) {
  216. const wuxingCount = countWuXing(bazi)
  217. const qiangRuo = analyzeQiangRuo(bazi, wuxingCount)
  218. const yongshen = getYongShen(bazi, wuxingCount, qiangRuo)
  219. const personality = getPersonality(bazi)
  220. return {
  221. wuxingCount: wuxingCount,
  222. qiangRuo: qiangRuo,
  223. yongshen: yongshen,
  224. personality: personality,
  225. summary: generateBaziSummary(bazi, wuxingCount, qiangRuo, yongshen)
  226. }
  227. }
  228. /**
  229. * 统计五行个数
  230. */
  231. function countWuXing(bazi) {
  232. const count = { '金': 0, '木': 0, '水': 0, '火': 0, '土': 0 }
  233. // 统计天干
  234. Object.values(bazi).forEach(pillar => {
  235. const ganWuxing = TIANGAN_WUXING[pillar.gan]
  236. const zhiWuxing = DIZHI_WUXING[pillar.zhi]
  237. if (ganWuxing) count[ganWuxing]++
  238. if (zhiWuxing) count[zhiWuxing]++
  239. })
  240. return count
  241. }
  242. /**
  243. * 分析日主强弱
  244. */
  245. function analyzeQiangRuo(bazi, wuxingCount) {
  246. const riganWuxing = TIANGAN_WUXING[bazi.day.gan]
  247. const riganCount = wuxingCount[riganWuxing]
  248. // 简化分析:看日干五行在八字中的个数
  249. if (riganCount >= 3) {
  250. return { type: '身旺', description: '日主偏强,需要消耗和克制' }
  251. } else if (riganCount <= 1) {
  252. return { type: '身弱', description: '日主偏弱,需要生助和帮扶' }
  253. } else {
  254. return { type: '中和', description: '日主适中,平衡发展' }
  255. }
  256. }
  257. /**
  258. * 取用神
  259. */
  260. function getYongShen(bazi, wuxingCount, qiangRuo) {
  261. const riganWuxing = TIANGAN_WUXING[bazi.day.gan]
  262. if (qiangRuo.type === '身旺') {
  263. // 身旺用克泄耗
  264. const keWuxing = Object.keys(WUXING_RELATION.克).find(key => WUXING_RELATION.克[key] === riganWuxing)
  265. const xieWuxing = WUXING_RELATION.生[riganWuxing]
  266. return {
  267. primary: keWuxing || xieWuxing,
  268. description: `日主${riganWuxing}偏旺,宜用${keWuxing || xieWuxing}调候`
  269. }
  270. } else if (qiangRuo.type === '身弱') {
  271. // 身弱用生扶
  272. const shengWuxing = Object.keys(WUXING_RELATION.生).find(key => WUXING_RELATION.生[key] === riganWuxing)
  273. return {
  274. primary: shengWuxing || riganWuxing,
  275. description: `日主${riganWuxing}偏弱,宜用${shengWuxing || riganWuxing}生扶`
  276. }
  277. } else {
  278. return {
  279. primary: riganWuxing,
  280. description: `日主${riganWuxing}中和,保持平衡即可`
  281. }
  282. }
  283. }
  284. /**
  285. * 获取性格特征
  286. */
  287. function getPersonality(bazi) {
  288. const traits = []
  289. // 根据日干分析性格
  290. const rigan = bazi.day.gan
  291. switch (rigan) {
  292. case '甲':
  293. traits.push('正直', '有领导力', '创新精神')
  294. break
  295. case '乙':
  296. traits.push('温和', '适应力强', '善于变通')
  297. break
  298. case '丙':
  299. traits.push('热情', '积极向上', '善于表达')
  300. break
  301. case '丁':
  302. traits.push('细心', '有艺术天赋', '内心温暖')
  303. break
  304. case '戊':
  305. traits.push('踏实', '稳重可靠', '包容心强')
  306. break
  307. case '己':
  308. traits.push('务实', '善于理财', '注重细节')
  309. break
  310. case '庚':
  311. traits.push('果断', '意志坚强', '正义感强')
  312. break
  313. case '辛':
  314. traits.push('细腻', '品味高雅', '追求完美')
  315. break
  316. case '壬':
  317. traits.push('聪明', '适应力强', '善于沟通')
  318. break
  319. case '癸':
  320. traits.push('智慧', '直觉敏锐', '内心丰富')
  321. break
  322. }
  323. return traits
  324. }
  325. /**
  326. * 生成八字总结
  327. */
  328. function generateBaziSummary(bazi, wuxingCount, qiangRuo, yongshen) {
  329. const riganWuxing = TIANGAN_WUXING[bazi.day.gan]
  330. const maxWuxing = Object.keys(wuxingCount).reduce((a, b) => wuxingCount[a] > wuxingCount[b] ? a : b)
  331. const minWuxing = Object.keys(wuxingCount).reduce((a, b) => wuxingCount[a] < wuxingCount[b] ? a : b)
  332. return `您的八字为${bazi.baziString},日主${bazi.day.gan}${riganWuxing},${qiangRuo.description}。` +
  333. `八字中${maxWuxing}较旺,${minWuxing}较弱,${yongshen.description}。` +
  334. `建议在生活中多接触${yongshen.primary}属性的事物,有利于运势提升。`
  335. }
  336. /**
  337. * 八字配对分析
  338. * @param {Object} bazi1 第一个人的八字
  339. * @param {Object} bazi2 第二个人的八字
  340. * @returns {Object} 配对结果
  341. */
  342. export function analyzeBaziMatch(bazi1, bazi2) {
  343. // 日干配对
  344. const riganMatch = analyzeRiganMatch(bazi1.day.gan, bazi2.day.gan)
  345. // 五行配对
  346. const wuxingMatch = analyzeWuxingMatch(bazi1.riganWuxing, bazi2.riganWuxing)
  347. // 纳音配对
  348. const nayinMatch = analyzeNayinMatch(bazi1.birthInfo.nayin, bazi2.birthInfo.nayin)
  349. // 生肖配对
  350. const shengxiaoMatch = analyzeShengxiaoMatch(bazi1.birthInfo.shengxiao, bazi2.birthInfo.shengxiao)
  351. // 综合评分
  352. const totalScore = calculateMatchScore(riganMatch, wuxingMatch, nayinMatch, shengxiaoMatch)
  353. // 获取配对等级
  354. const level = getMatchLevel(totalScore)
  355. return {
  356. totalScore: totalScore,
  357. level: level.name,
  358. levelColor: level.color,
  359. riganMatch: riganMatch,
  360. wuxingMatch: wuxingMatch,
  361. nayinMatch: nayinMatch,
  362. shengxiaoMatch: shengxiaoMatch,
  363. advantages: generateMatchAdvantages(bazi1, bazi2),
  364. challenges: generateMatchChallenges(bazi1, bazi2),
  365. suggestions: generateMatchSuggestions(bazi1, bazi2, totalScore),
  366. summary: generateMatchSummary(bazi1, bazi2, totalScore)
  367. }
  368. }
  369. /**
  370. * 分析日干配对
  371. */
  372. function analyzeRiganMatch(gan1, gan2) {
  373. const wuxing1 = TIANGAN_WUXING[gan1]
  374. const wuxing2 = TIANGAN_WUXING[gan2]
  375. const yinyang1 = TIANGAN_YINYANG[gan1]
  376. const yinyang2 = TIANGAN_YINYANG[gan2]
  377. let score = 50
  378. let description = ''
  379. // 阴阳配合
  380. if (yinyang1 !== yinyang2) {
  381. score += 15
  382. description += '阴阳互补,'
  383. }
  384. // 五行关系
  385. if (WUXING_RELATION.生[wuxing1] === wuxing2) {
  386. score += 20
  387. description += `${gan1}生${gan2},相生和谐`
  388. } else if (WUXING_RELATION.生[wuxing2] === wuxing1) {
  389. score += 20
  390. description += `${gan2}生${gan1},相生和谐`
  391. } else if (WUXING_RELATION.克[wuxing1] === wuxing2) {
  392. score -= 10
  393. description += `${gan1}克${gan2},需要包容`
  394. } else if (WUXING_RELATION.克[wuxing2] === wuxing1) {
  395. score -= 10
  396. description += `${gan2}克${gan1},需要理解`
  397. } else if (wuxing1 === wuxing2) {
  398. score += 10
  399. description += '同气相求,志趣相投'
  400. } else {
  401. description += '五行中和,平稳发展'
  402. }
  403. return {
  404. score: Math.max(0, Math.min(100, score)),
  405. description: description
  406. }
  407. }
  408. /**
  409. * 分析五行配对
  410. */
  411. function analyzeWuxingMatch(wuxing1, wuxing2) {
  412. let score = 60
  413. let description = ''
  414. if (wuxing1 === wuxing2) {
  415. score = 75
  416. description = `同属${wuxing1},价值观相近,容易理解对方`
  417. } else if (WUXING_RELATION.生[wuxing1] === wuxing2 || WUXING_RELATION.生[wuxing2] === wuxing1) {
  418. score = 85
  419. description = `${wuxing1}与${wuxing2}相生,互相促进,相得益彰`
  420. } else if (WUXING_RELATION.克[wuxing1] === wuxing2 || WUXING_RELATION.克[wuxing2] === wuxing1) {
  421. score = 40
  422. description = `${wuxing1}与${wuxing2}相克,需要更多理解和包容`
  423. } else {
  424. score = 65
  425. description = `${wuxing1}与${wuxing2}中性关系,互补性较好`
  426. }
  427. return {
  428. score: score,
  429. description: description
  430. }
  431. }
  432. /**
  433. * 分析纳音配对
  434. */
  435. function analyzeNayinMatch(nayin1, nayin2) {
  436. // 简化的纳音配对逻辑
  437. let score = 60
  438. let description = ''
  439. if (nayin1 === nayin2) {
  440. score = 70
  441. description = `同为${nayin1},命理相同,默契度高`
  442. } else {
  443. // 根据纳音五行分析
  444. const nayin1Wuxing = getNayinWuxing(nayin1)
  445. const nayin2Wuxing = getNayinWuxing(nayin2)
  446. if (nayin1Wuxing && nayin2Wuxing) {
  447. if (WUXING_RELATION.生[nayin1Wuxing] === nayin2Wuxing || WUXING_RELATION.生[nayin2Wuxing] === nayin1Wuxing) {
  448. score = 80
  449. description = `${nayin1}与${nayin2}纳音相生,天作之合`
  450. } else if (WUXING_RELATION.克[nayin1Wuxing] === nayin2Wuxing || WUXING_RELATION.克[nayin2Wuxing] === nayin1Wuxing) {
  451. score = 45
  452. description = `${nayin1}与${nayin2}纳音相克,需要调和`
  453. } else {
  454. score = 65
  455. description = `${nayin1}与${nayin2}纳音和谐,关系稳定`
  456. }
  457. } else {
  458. description = `${nayin1}与${nayin2},命理互补`
  459. }
  460. }
  461. return {
  462. score: score,
  463. description: description
  464. }
  465. }
  466. /**
  467. * 获取纳音五行
  468. */
  469. function getNayinWuxing(nayin) {
  470. if (nayin.includes('金')) return '金'
  471. if (nayin.includes('木')) return '木'
  472. if (nayin.includes('水')) return '水'
  473. if (nayin.includes('火')) return '火'
  474. if (nayin.includes('土')) return '土'
  475. return null
  476. }
  477. /**
  478. * 分析生肖配对
  479. */
  480. function analyzeShengxiaoMatch(shengxiao1, shengxiao2) {
  481. // 生肖配对表
  482. const shengxiaoCompatibility = {
  483. '鼠': { '龙': 90, '猴': 85, '牛': 80, '马': 30, '羊': 40 },
  484. '牛': { '蛇': 90, '鸡': 85, '鼠': 80, '马': 35, '羊': 30 },
  485. '虎': { '马': 90, '狗': 85, '猪': 80, '猴': 30, '蛇': 35 },
  486. '兔': { '羊': 90, '猪': 85, '狗': 80, '鸡': 30, '龙': 35 },
  487. '龙': { '鼠': 90, '猴': 85, '鸡': 80, '狗': 30, '兔': 35 },
  488. '蛇': { '牛': 90, '鸡': 85, '猴': 80, '猪': 30, '虎': 35 },
  489. '马': { '虎': 90, '狗': 85, '羊': 80, '鼠': 30, '牛': 35 },
  490. '羊': { '兔': 90, '马': 80, '猪': 85, '牛': 30, '鼠': 40 },
  491. '猴': { '鼠': 85, '龙': 85, '蛇': 80, '虎': 30, '猪': 35 },
  492. '鸡': { '牛': 85, '蛇': 85, '龙': 80, '兔': 30, '狗': 35 },
  493. '狗': { '虎': 85, '马': 85, '兔': 80, '龙': 30, '鸡': 35 },
  494. '猪': { '兔': 85, '羊': 85, '虎': 80, '蛇': 30, '猴': 35 }
  495. }
  496. let score = 60
  497. let description = ''
  498. if (shengxiao1 === shengxiao2) {
  499. score = 70
  500. description = `同属${shengxiao1},性格相似,容易产生共鸣`
  501. } else if (shengxiaoCompatibility[shengxiao1] && shengxiaoCompatibility[shengxiao1][shengxiao2]) {
  502. score = shengxiaoCompatibility[shengxiao1][shengxiao2]
  503. if (score >= 85) {
  504. description = `${shengxiao1}与${shengxiao2}是最佳配对,天生一对`
  505. } else if (score >= 70) {
  506. description = `${shengxiao1}与${shengxiao2}配对良好,相处融洽`
  507. } else {
  508. description = `${shengxiao1}与${shengxiao2}需要更多磨合,相互理解`
  509. }
  510. } else {
  511. description = `${shengxiao1}与${shengxiao2}属于中性配对,平稳发展`
  512. }
  513. return {
  514. score: score,
  515. description: description
  516. }
  517. }
  518. /**
  519. * 计算总体配对分数
  520. */
  521. function calculateMatchScore(riganMatch, wuxingMatch, nayinMatch, shengxiaoMatch) {
  522. // 加权计算
  523. const weights = {
  524. rigan: 0.3, // 日干权重30%
  525. wuxing: 0.3, // 五行权重30%
  526. nayin: 0.2, // 纳音权重20%
  527. shengxiao: 0.2 // 生肖权重20%
  528. }
  529. const totalScore =
  530. riganMatch.score * weights.rigan +
  531. wuxingMatch.score * weights.wuxing +
  532. nayinMatch.score * weights.nayin +
  533. shengxiaoMatch.score * weights.shengxiao
  534. return Math.round(totalScore)
  535. }
  536. /**
  537. * 获取配对等级
  538. */
  539. function getMatchLevel(score) {
  540. if (score >= 90) {
  541. return { name: '天作之合', color: 'linear-gradient(135deg, #FF6B9D 0%, #FFA5C6 100%)' }
  542. } else if (score >= 80) {
  543. return { name: '绝配佳偶', color: 'linear-gradient(135deg, #4CAF50 0%, #81C784 100%)' }
  544. } else if (score >= 70) {
  545. return { name: '良缘美眷', color: 'linear-gradient(135deg, #2196F3 0%, #64B5F6 100%)' }
  546. } else if (score >= 60) {
  547. return { name: '尚可之配', color: 'linear-gradient(135deg, #FF9800 0%, #FFB74D 100%)' }
  548. } else if (score >= 50) {
  549. return { name: '需要磨合', color: 'linear-gradient(135deg, #FFC107 0%, #FFD54F 100%)' }
  550. } else {
  551. return { name: '挑战较大', color: 'linear-gradient(135deg, #F44336 0%, #EF5350 100%)' }
  552. }
  553. }
  554. /**
  555. * 生成配对优势
  556. */
  557. function generateMatchAdvantages(bazi1, bazi2) {
  558. const advantages = []
  559. // 分析共同特点
  560. const commonTraits = bazi1.analysis.personality.filter(trait =>
  561. bazi2.analysis.personality.includes(trait)
  562. )
  563. if (commonTraits.length > 0) {
  564. advantages.push(`你们都具有${commonTraits.join('、')}的特质,容易产生共鸣和理解`)
  565. }
  566. // 分析互补特点
  567. if (bazi1.analysis.qiangRuo.type === '身旺' && bazi2.analysis.qiangRuo.type === '身弱') {
  568. advantages.push('一强一弱的组合,能够互相补充,形成良好的平衡')
  569. } else if (bazi1.analysis.qiangRuo.type === '身弱' && bazi2.analysis.qiangRuo.type === '身旺') {
  570. advantages.push('强弱互补的搭配,能够相互扶持,共同成长')
  571. }
  572. // 分析用神关系
  573. if (bazi1.analysis.yongshen.primary === bazi2.riganWuxing) {
  574. advantages.push('对方的日主五行正好是您的用神,能够给您带来很好的帮助')
  575. }
  576. return advantages.length > 0 ? advantages : ['你们的八字搭配有其独特的魅力,能够在相处中发现彼此的闪光点']
  577. }
  578. /**
  579. * 生成配对挑战
  580. */
  581. function generateMatchChallenges(bazi1, bazi2) {
  582. const challenges = []
  583. // 分析冲突
  584. if (bazi1.riganWuxing && bazi2.riganWuxing &&
  585. WUXING_RELATION.克[bazi1.riganWuxing] === bazi2.riganWuxing) {
  586. challenges.push('日主五行相克,在性格和处事方式上可能存在一些分歧')
  587. }
  588. // 分析过旺或过弱
  589. if (bazi1.analysis.qiangRuo.type === '身旺' && bazi2.analysis.qiangRuo.type === '身旺') {
  590. challenges.push('双方都比较强势,在决策时可能需要更多的沟通和协调')
  591. } else if (bazi1.analysis.qiangRuo.type === '身弱' && bazi2.analysis.qiangRuo.type === '身弱') {
  592. challenges.push('双方都比较内敛,需要主动创造更多的交流机会')
  593. }
  594. return challenges.length > 0 ? challenges : ['每一对组合都有需要磨合的地方,这正是相处的乐趣所在']
  595. }
  596. /**
  597. * 生成配对建议
  598. */
  599. function generateMatchSuggestions(bazi1, bazi2, totalScore) {
  600. const suggestions = []
  601. if (totalScore >= 80) {
  602. suggestions.push('你们的八字配对很好,珍惜这份缘分,相互支持共同成长')
  603. } else if (totalScore >= 60) {
  604. suggestions.push('你们的配对有很好的基础,多一些包容和理解,感情会更加稳定')
  605. } else {
  606. suggestions.push('缘分需要用心经营,多沟通多理解,用爱化解所有的不合')
  607. }
  608. // 根据用神给建议
  609. if (bazi1.analysis.yongshen.primary && bazi2.analysis.yongshen.primary) {
  610. const commonYongshen = bazi1.analysis.yongshen.primary === bazi2.analysis.yongshen.primary
  611. if (commonYongshen) {
  612. suggestions.push(`你们的用神都是${bazi1.analysis.yongshen.primary},可以一起从事相关的活动来增进感情`)
  613. }
  614. }
  615. suggestions.push('建议选择有利于双方用神的环境和时间进行重要的决策和沟通')
  616. return suggestions
  617. }
  618. /**
  619. * 生成配对总结
  620. */
  621. function generateMatchSummary(bazi1, bazi2, totalScore) {
  622. const level = getMatchLevel(totalScore)
  623. const summary = `您的八字${bazi1.baziString}与对方的八字${bazi2.baziString},` +
  624. `综合评分${totalScore}分,属于"${level.name}"的配对等级。`
  625. if (totalScore >= 80) {
  626. return summary + '你们的八字搭配很好,是难得的良缘,要好好珍惜。'
  627. } else if (totalScore >= 60) {
  628. return summary + '你们有着不错的缘分基础,通过相互理解和包容,能够建立美好的关系。'
  629. } else {
  630. return summary + '虽然八字配对有些挑战,但真爱能够化解一切,只要相互理解,同样能够获得幸福。'
  631. }
  632. }
  633. /**
  634. * 智能API选择器 - 根据策略选择最佳API
  635. * @returns {Object} 选中的API配置
  636. */
  637. function selectBestAPI() {
  638. const settings = BAZI_API_CONFIG.SETTINGS
  639. const enabledAPIs = settings.ENABLED_APIS
  640. // 按优先级排序可用的API
  641. const sortedAPIs = enabledAPIs
  642. .map(apiName => ({
  643. name: apiName,
  644. config: BAZI_API_CONFIG[apiName],
  645. isConfigured: BAZI_API_CONFIG[apiName].API_KEY &&
  646. !BAZI_API_CONFIG[apiName].API_KEY.startsWith('YOUR_')
  647. }))
  648. .filter(api => api.isConfigured)
  649. .sort((a, b) => a.config.PRIORITY - b.config.PRIORITY)
  650. if (sortedAPIs.length === 0) {
  651. return null
  652. }
  653. // 根据策略选择API
  654. switch (settings.STRATEGY) {
  655. case 'cost_first':
  656. return sortedAPIs.sort((a, b) => a.config.COST_PER_CALL - b.config.COST_PER_CALL)[0]
  657. case 'accuracy_first':
  658. return sortedAPIs[0] // 优先级最高的通常最准确
  659. case 'speed_first':
  660. return sortedAPIs.find(api => api.name === 'ALIYUN_API') || sortedAPIs[0]
  661. default:
  662. return sortedAPIs[0]
  663. }
  664. }
  665. /**
  666. * 调用专业八字API获取准确数据(支持多API自动切换)
  667. * @param {Date} birthDate 出生日期
  668. * @param {Number} hour 出生时辰(0-23)
  669. * @returns {Promise<Object>} API返回结果
  670. */
  671. export async function getBaziFromAPI(birthDate, hour) {
  672. const settings = BAZI_API_CONFIG.SETTINGS
  673. const maxRetries = settings.RETRY_COUNT || 2
  674. for (let attempt = 0; attempt < maxRetries + 1; attempt++) {
  675. try {
  676. // 智能选择API
  677. const selectedAPI = selectBestAPI()
  678. if (!selectedAPI) {
  679. return null
  680. }
  681. const result = await callSpecificAPI(selectedAPI, birthDate, hour)
  682. if (result) {
  683. return {
  684. ...result,
  685. apiProvider: selectedAPI.name,
  686. apiCost: selectedAPI.config.COST_PER_CALL
  687. }
  688. }
  689. // 如果启用自动故障转移,尝试下一个API
  690. if (settings.AUTO_FAILOVER && attempt < maxRetries) {
  691. const index = settings.ENABLED_APIS.indexOf(selectedAPI.name)
  692. if (index > -1) {
  693. settings.ENABLED_APIS.splice(index, 1)
  694. }
  695. continue
  696. }
  697. } catch (error) {
  698. console.error(`❌ API调用异常 (尝试${attempt + 1}):`, error)
  699. if (attempt === maxRetries) {
  700. return null
  701. }
  702. }
  703. }
  704. return null
  705. }
  706. /**
  707. * 调用特定的API服务
  708. * @param {Object} selectedAPI 选中的API配置
  709. * @param {Date} birthDate 出生日期
  710. * @param {Number} hour 出生时辰
  711. * @returns {Promise<Object>} API返回结果
  712. */
  713. async function callSpecificAPI(selectedAPI, birthDate, hour) {
  714. const { name, config } = selectedAPI
  715. // 根据不同API构建请求参数
  716. let params, url
  717. switch (name) {
  718. case 'JISU_API':
  719. params = {
  720. appkey: config.API_KEY,
  721. name: '用户', // 姓名参数(必填)
  722. city: '', // 城市参数(必填,可空)
  723. year: birthDate.getFullYear(),
  724. month: birthDate.getMonth() + 1,
  725. day: birthDate.getDate(),
  726. hour: hour,
  727. minute: 0, // 分钟,默认0
  728. sex: 1, // 性别,1男0女,默认男
  729. islunar: 0, // 是否阴历,0阳历1阴历
  730. istaiyang: 0, // 是否太阳时,0不使用1使用
  731. islunarmonth: 2 // 是否闰月,1是2否
  732. }
  733. url = `${config.BASE_URL}${config.ENDPOINTS.bazi}`
  734. break
  735. case 'JUHE_API':
  736. params = {
  737. key: config.API_KEY,
  738. year: birthDate.getFullYear(),
  739. month: birthDate.getMonth() + 1,
  740. day: birthDate.getDate(),
  741. hour: hour
  742. }
  743. url = `${config.BASE_URL}${config.ENDPOINTS.bazi}`
  744. break
  745. case 'ALIYUN_API':
  746. params = {
  747. year: birthDate.getFullYear(),
  748. month: birthDate.getMonth() + 1,
  749. day: birthDate.getDate(),
  750. hour: hour
  751. }
  752. url = `${config.BASE_URL}${config.ENDPOINTS.bazi}`
  753. break
  754. case 'TENCENT_API':
  755. params = {
  756. year: birthDate.getFullYear(),
  757. month: birthDate.getMonth() + 1,
  758. day: birthDate.getDate(),
  759. hour: hour
  760. }
  761. url = `${config.BASE_URL}${config.ENDPOINTS.bazi}`
  762. break
  763. default:
  764. console.error('❌ 不支持的API类型:', name)
  765. return null
  766. }
  767. // 发送请求
  768. const response = await new Promise((resolve, reject) => {
  769. const headers = {}
  770. // 阿里云和腾讯云需要特殊的认证头
  771. if (name === 'ALIYUN_API') {
  772. headers['Authorization'] = `APPCODE ${config.API_KEY}`
  773. } else if (name === 'TENCENT_API') {
  774. headers['Authorization'] = config.API_KEY
  775. }
  776. uni.request({
  777. url: url,
  778. data: params,
  779. method: 'GET',
  780. header: headers,
  781. timeout: BAZI_API_CONFIG.SETTINGS.TIMEOUT || 10000,
  782. success: (res) => {
  783. resolve(res)
  784. },
  785. fail: (err) => {
  786. console.error('📡 API请求失败:', err)
  787. reject(err)
  788. }
  789. })
  790. })
  791. // 解析不同API的响应格式
  792. return parseAPIResponse(name, response)
  793. }
  794. /**
  795. * 解析不同API的响应格式
  796. * @param {String} apiName API名称
  797. * @param {Object} response 响应对象
  798. * @returns {Object} 标准化的八字数据
  799. */
  800. function parseAPIResponse(apiName, response) {
  801. if (response.statusCode !== 200) {
  802. throw new Error(`HTTP ${response.statusCode}`)
  803. }
  804. const data = response.data
  805. let result = null
  806. switch (apiName) {
  807. case 'JISU_API':
  808. if (data.status === 0 && data.result) {
  809. result = data.result
  810. // 极速数据API返回的是完整的八字排盘数据
  811. }
  812. break
  813. case 'JUHE_API':
  814. if (data.error_code === 0 && data.result) {
  815. result = data.result
  816. }
  817. break
  818. case 'ALIYUN_API':
  819. case 'TENCENT_API':
  820. if (data.code === 200 && data.data) {
  821. result = data.data
  822. }
  823. break
  824. }
  825. if (!result) {
  826. return null
  827. }
  828. // 极速数据API专用解析(更丰富的数据)
  829. if (apiName === 'JISU_API' && result.bazi) {
  830. // 解析八字数组 [年柱, 月柱, 日柱, 时柱]
  831. const baziArray = result.bazi
  832. const nayinArray = result.nayin || []
  833. return {
  834. year: {
  835. gan: baziArray[0]?.charAt(0) || '',
  836. zhi: baziArray[0]?.charAt(1) || '',
  837. ganZhi: baziArray[0] || '',
  838. nayin: nayinArray[0] || ''
  839. },
  840. month: {
  841. gan: baziArray[1]?.charAt(0) || '',
  842. zhi: baziArray[1]?.charAt(1) || '',
  843. ganZhi: baziArray[1] || '',
  844. nayin: nayinArray[1] || ''
  845. },
  846. day: {
  847. gan: baziArray[2]?.charAt(0) || '',
  848. zhi: baziArray[2]?.charAt(1) || '',
  849. ganZhi: baziArray[2] || '',
  850. nayin: nayinArray[2] || ''
  851. },
  852. hour: {
  853. gan: baziArray[3]?.charAt(0) || '',
  854. zhi: baziArray[3]?.charAt(1) || '',
  855. ganZhi: baziArray[3] || '',
  856. nayin: nayinArray[3] || ''
  857. },
  858. baziString: baziArray.join(' '),
  859. // 极速数据提供的专业信息
  860. animal: result.animal, // 生肖
  861. yearganzhi: result.yearganzhi, // 年干支
  862. taiyuan: result.taiyuan, // 胎元
  863. minggong: result.minggong, // 命宫
  864. xunkong: result.xunkong, // 旬空
  865. qiyun: result.qiyun, // 起运时间
  866. jiaoyun: result.jiaoyun, // 交运时间
  867. qiankunzao: result.qiankunzao, // 乾造/坤造
  868. shensha: result.shensha, // 神煞
  869. dayun: result.dayun, // 大运
  870. liunian: result.liunian, // 流年
  871. // 农历信息
  872. lunar: {
  873. year: result.lunaryear,
  874. month: result.lunarmonth,
  875. day: result.lunarday,
  876. hour: result.lunarhour
  877. },
  878. // 节气信息
  879. jieqi: {
  880. prev: result.jieqiprev,
  881. next: result.jieqinext
  882. },
  883. source: 'api',
  884. apiProvider: 'jisuapi',
  885. apiData: result
  886. }
  887. }
  888. // 通用API数据格式(其他API使用)
  889. return {
  890. year: {
  891. gan: result.year_gan || result.yearGan,
  892. zhi: result.year_zhi || result.yearZhi,
  893. ganZhi: (result.year_gan || result.yearGan) + (result.year_zhi || result.yearZhi),
  894. wuxing: result.year_wuxing || result.yearWuxing,
  895. yinyang: result.year_yinyang || result.yearYinyang
  896. },
  897. month: {
  898. gan: result.month_gan || result.monthGan,
  899. zhi: result.month_zhi || result.monthZhi,
  900. ganZhi: (result.month_gan || result.monthGan) + (result.month_zhi || result.monthZhi),
  901. wuxing: result.month_wuxing || result.monthWuxing,
  902. yinyang: result.month_yinyang || result.monthYinyang
  903. },
  904. day: {
  905. gan: result.day_gan || result.dayGan,
  906. zhi: result.day_zhi || result.dayZhi,
  907. ganZhi: (result.day_gan || result.dayGan) + (result.day_zhi || result.dayZhi),
  908. wuxing: result.day_wuxing || result.dayWuxing,
  909. yinyang: result.day_yinyang || result.dayYinyang
  910. },
  911. hour: {
  912. gan: result.hour_gan || result.hourGan,
  913. zhi: result.hour_zhi || result.hourZhi,
  914. ganZhi: (result.hour_gan || result.hourGan) + (result.hour_zhi || result.hourZhi),
  915. wuxing: result.hour_wuxing || result.hourWuxing,
  916. yinyang: result.hour_yinyang || result.hourYinyang
  917. },
  918. baziString: `${result.year_gan || result.yearGan}${result.year_zhi || result.yearZhi} ${result.month_gan || result.monthGan}${result.month_zhi || result.monthZhi} ${result.day_gan || result.dayGan}${result.day_zhi || result.dayZhi} ${result.hour_gan || result.hourGan}${result.hour_zhi || result.hourZhi}`,
  919. nayin: result.nayin || '',
  920. source: 'api',
  921. apiData: result
  922. }
  923. }
  924. /**
  925. * 增强版八字计算(API + 本地算法)
  926. * @param {Date} birthDate 出生日期
  927. * @param {Number} hour 出生时辰(0-23)
  928. * @returns {Object} 八字信息
  929. */
  930. export async function calculateEnhancedBaZi(birthDate, hour) {
  931. let localResult = null
  932. let apiResult = null
  933. try {
  934. // 1. 先计算本地结果
  935. localResult = calculateBaZi(birthDate, hour)
  936. // 2. 尝试获取API结果
  937. if (BAZI_API_CONFIG.SETTINGS.ENABLE_VALIDATION) {
  938. apiResult = await getBaziFromAPI(birthDate, hour)
  939. }
  940. // 3. 结果对比和融合
  941. if (apiResult) {
  942. const comparison = compareBaziResults(localResult, apiResult)
  943. if (comparison.accuracy >= 0.8) {
  944. localResult.validation = {
  945. status: 'verified',
  946. accuracy: comparison.accuracy,
  947. apiSource: 'professional',
  948. differences: comparison.differences
  949. }
  950. } else {
  951. const enhancedResult = mergeApiAndLocalResults(apiResult, localResult)
  952. enhancedResult.validation = {
  953. status: 'api_corrected',
  954. accuracy: comparison.accuracy,
  955. apiSource: 'professional',
  956. differences: comparison.differences
  957. }
  958. return enhancedResult
  959. }
  960. } else {
  961. localResult.validation = {
  962. status: 'local_only',
  963. accuracy: 0.85, // 本地算法估计准确度
  964. apiSource: 'none',
  965. note: '建议配置专业API以提高准确度'
  966. }
  967. }
  968. return localResult
  969. } catch (error) {
  970. console.error('❌ 增强版八字计算异常:', error)
  971. return localResult || calculateBaZi(birthDate, hour)
  972. }
  973. }
  974. /**
  975. * 对比八字计算结果
  976. * @param {Object} localResult 本地算法结果
  977. * @param {Object} apiResult API算法结果
  978. * @returns {Object} 对比结果
  979. */
  980. function compareBaziResults(localResult, apiResult) {
  981. const differences = []
  982. let correctCount = 0
  983. let totalCount = 8 // 四柱共8个字
  984. // 对比四柱
  985. const pillars = ['year', 'month', 'day', 'hour']
  986. pillars.forEach(pillar => {
  987. if (localResult[pillar].gan === apiResult[pillar].gan) {
  988. correctCount++
  989. } else {
  990. differences.push(`${pillar}干: 本地${localResult[pillar].gan} vs API${apiResult[pillar].gan}`)
  991. }
  992. if (localResult[pillar].zhi === apiResult[pillar].zhi) {
  993. correctCount++
  994. } else {
  995. differences.push(`${pillar}支: 本地${localResult[pillar].zhi} vs API${apiResult[pillar].zhi}`)
  996. }
  997. })
  998. const accuracy = correctCount / totalCount
  999. return {
  1000. accuracy: accuracy,
  1001. differences: differences,
  1002. recommendation: accuracy >= 0.8 ? 'use_local' : 'use_api'
  1003. }
  1004. }
  1005. /**
  1006. * 融合API和本地结果
  1007. * @param {Object} apiResult API结果
  1008. * @param {Object} localResult 本地结果
  1009. * @returns {Object} 融合后的结果
  1010. */
  1011. function mergeApiAndLocalResults(apiResult, localResult) {
  1012. // 以API结果为准,但保留本地的详细分析
  1013. return {
  1014. ...apiResult,
  1015. // 保留本地的详细分析
  1016. analysis: localResult.analysis,
  1017. birthInfo: {
  1018. ...localResult.birthInfo,
  1019. // 如果API提供了纳音,使用API的
  1020. nayin: apiResult.nayin || localResult.birthInfo.nayin
  1021. },
  1022. // 标记数据来源
  1023. dataSource: 'api_enhanced',
  1024. localCalculation: localResult.baziString,
  1025. apiCalculation: apiResult.baziString
  1026. }
  1027. }
  1028. /**
  1029. * 获取八字建议
  1030. */
  1031. export function getBaziSuggestions(bazi) {
  1032. const suggestions = []
  1033. // 根据验证状态添加可靠性说明
  1034. if (bazi.validation) {
  1035. if (bazi.validation.status === 'verified') {
  1036. suggestions.push(`✅ 您的八字经过专业API验证,准确度${Math.round(bazi.validation.accuracy * 100)}%,结果可信度高`)
  1037. } else if (bazi.validation.status === 'api_corrected') {
  1038. suggestions.push(`🔍 已使用专业算法修正结果,确保测算准确性`)
  1039. } else {
  1040. suggestions.push(`💡 建议配置专业八字API以获得更准确的测算结果`)
  1041. }
  1042. }
  1043. // 根据用神给建议
  1044. const yongshen = bazi.analysis.yongshen.primary
  1045. suggestions.push(`您的用神为${yongshen},建议多接触${yongshen}属性的事物,如颜色、方位、职业等`)
  1046. // 根据强弱给建议
  1047. if (bazi.analysis.qiangRuo.type === '身旺') {
  1048. suggestions.push('您的日主偏强,适合发挥领导才能,但要注意不要过于强势')
  1049. } else if (bazi.analysis.qiangRuo.type === '身弱') {
  1050. suggestions.push('您的日主偏弱,需要多寻求他人的帮助和支持,团队合作会更有利')
  1051. } else {
  1052. suggestions.push('您的日主平衡,适合稳步发展,保持现有的良好状态')
  1053. }
  1054. return suggestions
  1055. }
  1056. // 导出默认对象
  1057. export default {
  1058. calculateBaZi,
  1059. calculateEnhancedBaZi, // 新增:增强版八字计算
  1060. getBaziFromAPI, // 新增:专业API调用
  1061. analyzeBaziMatch,
  1062. getBaziSuggestions,
  1063. TIANGAN,
  1064. DIZHI,
  1065. TIANGAN_WUXING,
  1066. DIZHI_WUXING,
  1067. SHENGXIAO
  1068. }