zodiac-enhanced.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. /**
  2. * 增强版生肖工具 - 接入天行数据API
  3. */
  4. import TIANAPI_CONFIG, { validateConfig } from '@/config/api-config.js'
  5. import zodiacUtil from './zodiac.js'
  6. /**
  7. * 从天行数据API获取生肖运势
  8. * @param {String} zodiac - 生肖名称
  9. * @returns {Promise<Object>} 运势数据
  10. */
  11. export async function getZodiacFortuneFromAPI(zodiac) {
  12. // 直接返回本地数据
  13. return {
  14. ...zodiacUtil.getTodayFortune(zodiac),
  15. source: 'local_no_api',
  16. dataFrom: '本地数据(天行数据暂无运势接口)',
  17. updateTime: new Date().toLocaleString('zh-CN')
  18. }
  19. }
  20. /**
  21. * 🆕 生肖配对查询(使用天行数据API)
  22. * @param {String} myZodiac - 我的生肖
  23. * @param {String} targetZodiac - 对方生肖
  24. * @returns {Promise<Object>} 配对结果
  25. */
  26. export async function getZodiacMatch(myZodiac, targetZodiac) {
  27. try {
  28. // 使用Promise包装uni.request以更好地处理错误
  29. const response = await new Promise((resolve, reject) => {
  30. uni.request({
  31. url: `${TIANAPI_CONFIG.BASE_URL}${TIANAPI_CONFIG.ENDPOINTS.zodiacMatch}`,
  32. method: 'GET',
  33. data: {
  34. key: TIANAPI_CONFIG.API_KEY,
  35. me: myZodiac,
  36. he: targetZodiac
  37. },
  38. timeout: 10000,
  39. success: (res) => {
  40. resolve(res)
  41. },
  42. fail: (err) => {
  43. console.error('🌐 网络请求失败,错误信息:', err)
  44. reject(new Error(`网络请求失败: ${err.errMsg || err.message || '未知网络错误'}`))
  45. }
  46. })
  47. })
  48. // 检查响应是否存在
  49. if (!response) {
  50. console.error('❌ 响应对象为空')
  51. throw new Error('网络响应为空,可能是域名配置或网络问题')
  52. }
  53. // 检查HTTP状态码
  54. if (response.statusCode !== 200) {
  55. console.error('❌ HTTP状态码错误:', response.statusCode)
  56. throw new Error(`HTTP错误: ${response.statusCode}`)
  57. }
  58. // 检查响应数据是否存在
  59. if (!response.data) {
  60. console.error('❌ API响应数据为空')
  61. throw new Error('API响应数据为空')
  62. }
  63. // 检查API业务状态码
  64. if (response.data.code !== 200) {
  65. console.error('❌ API业务错误:', {
  66. code: response.data.code,
  67. msg: response.data.msg || '未知错误'
  68. })
  69. throw new Error(response.data.msg || `API错误(code: ${response.data.code})`)
  70. }
  71. // 检查result数据
  72. const result = response.data.result
  73. if (!result) {
  74. console.error('❌ API返回结果为空')
  75. throw new Error('API返回结果为空')
  76. }
  77. return {
  78. title: result.title || '配对分析',
  79. malePerspective: result.mcontent || '', // 男性视角
  80. femalePerspective: result.fcontent || '', // 女性视角
  81. malePerspective2: result.mcontent1 || '', // 男性视角2
  82. femalePerspective2: result.fcontent1 || '', // 女性视角2
  83. source: 'tianapi',
  84. updateTime: new Date().toLocaleString('zh-CN')
  85. }
  86. } catch (error) {
  87. console.error('❌ 生肖配对查询失败')
  88. console.error('错误类型:', error.name || 'Unknown')
  89. console.error('错误信息:', error.message || error.errMsg || '未知错误')
  90. console.error('完整错误:', error)
  91. // 友好的用户提示
  92. uni.showToast({
  93. title: '配对查询失败,使用本地数据',
  94. icon: 'none',
  95. duration: 2000
  96. })
  97. return null
  98. }
  99. }
  100. /**
  101. * 解析运势文本为分数
  102. * 根据关键词判断分数
  103. */
  104. function parseFortune(text) {
  105. if (!text) return 75
  106. // 正面关键词
  107. const positiveWords = ['佳', '好', '旺', '顺', '吉', '高', '升', '涨', '强']
  108. // 负面关键词
  109. const negativeWords = ['差', '弱', '低', '降', '凶', '衰', '险', '忌']
  110. let score = 75 // 基础分数
  111. // 检查正面词
  112. for (let word of positiveWords) {
  113. if (text.includes(word)) {
  114. score += 5
  115. }
  116. }
  117. // 检查负面词
  118. for (let word of negativeWords) {
  119. if (text.includes(word)) {
  120. score -= 5
  121. }
  122. }
  123. // 限制分数范围 60-95
  124. return Math.max(60, Math.min(95, score))
  125. }
  126. /**
  127. * 统一的获取运势接口
  128. * 优先使用API,失败则降级到本地
  129. */
  130. export async function getTodayFortune(zodiac) {
  131. return await getZodiacFortuneFromAPI(zodiac)
  132. }
  133. /**
  134. * 获取星座运势(如果需要)
  135. */
  136. export async function getConstellationFortune(constellation) {
  137. if (!validateConfig()) {
  138. return null
  139. }
  140. try {
  141. const response = await uni.request({
  142. url: `${TIANAPI_CONFIG.BASE_URL}${TIANAPI_CONFIG.ENDPOINTS.constellation}`,
  143. method: 'GET',
  144. data: {
  145. key: TIANAPI_CONFIG.API_KEY,
  146. astro: constellation
  147. },
  148. timeout: 5000
  149. })
  150. if (response.statusCode === 200 && response.data.code === 200) {
  151. return response.data.result
  152. }
  153. } catch (error) {
  154. console.error('获取星座运势失败:', error)
  155. }
  156. return null
  157. }
  158. /**
  159. * 测试API连接
  160. */
  161. export async function testAPIConnection() {
  162. if (!validateConfig()) {
  163. return {
  164. success: false,
  165. message: '请先配置API Key'
  166. }
  167. }
  168. try {
  169. const result = await getZodiacFortuneFromAPI('鼠')
  170. // 检查是否真的是API数据
  171. if (result.source === 'tianapi') {
  172. return {
  173. success: true,
  174. message: 'API连接成功!',
  175. data: result
  176. }
  177. } else {
  178. return {
  179. success: false,
  180. message: 'API调用失败,已降级到本地数据',
  181. data: result
  182. }
  183. }
  184. } catch (error) {
  185. return {
  186. success: false,
  187. message: 'API连接失败:' + (error.message || error.errMsg || '未知错误'),
  188. error: error
  189. }
  190. }
  191. }
  192. /**
  193. * 🔧 网络连接诊断工具
  194. */
  195. export async function diagnoseNetwork() {
  196. const diagnostics = {
  197. timestamp: new Date().toLocaleString('zh-CN'),
  198. environment: {
  199. platform: uni.getSystemInfoSync().platform,
  200. version: uni.getSystemInfoSync().version,
  201. SDKVersion: uni.getSystemInfoSync().SDKVersion
  202. },
  203. tests: {}
  204. }
  205. // 测试1: 基础网络连接
  206. try {
  207. const testResponse = await new Promise((resolve, reject) => {
  208. uni.request({
  209. url: 'https://www.baidu.com',
  210. method: 'GET',
  211. timeout: 5000,
  212. success: resolve,
  213. fail: reject
  214. })
  215. })
  216. diagnostics.tests.basicNetwork = {
  217. success: true,
  218. statusCode: testResponse.statusCode,
  219. message: '网络连接正常'
  220. }
  221. } catch (error) {
  222. diagnostics.tests.basicNetwork = {
  223. success: false,
  224. error: error.errMsg || error.message,
  225. message: '基础网络连接失败'
  226. }
  227. console.error('❌ 基础网络连接失败:', error)
  228. }
  229. // 测试2: HTTPS协议测试
  230. try {
  231. const httpsResponse = await new Promise((resolve, reject) => {
  232. uni.request({
  233. url: 'https://httpbin.org/get',
  234. method: 'GET',
  235. timeout: 8000,
  236. success: resolve,
  237. fail: reject
  238. })
  239. })
  240. diagnostics.tests.httpsSupport = {
  241. success: true,
  242. statusCode: httpsResponse.statusCode,
  243. message: 'HTTPS协议支持正常'
  244. }
  245. } catch (error) {
  246. diagnostics.tests.httpsSupport = {
  247. success: false,
  248. error: error.errMsg || error.message,
  249. message: 'HTTPS协议测试失败'
  250. }
  251. console.error('❌ HTTPS协议测试失败:', error)
  252. }
  253. // 测试3: 天行数据域名连通性
  254. try {
  255. const tianApiResponse = await new Promise((resolve, reject) => {
  256. uni.request({
  257. url: 'https://apis.tianapi.com',
  258. method: 'GET',
  259. timeout: 8000,
  260. success: resolve,
  261. fail: reject
  262. })
  263. })
  264. diagnostics.tests.tianApiDomain = {
  265. success: true,
  266. statusCode: tianApiResponse.statusCode,
  267. message: '天行数据域名可访问'
  268. }
  269. } catch (error) {
  270. diagnostics.tests.tianApiDomain = {
  271. success: false,
  272. error: error.errMsg || error.message,
  273. message: '天行数据域名无法访问'
  274. }
  275. console.error('❌ 天行数据域名无法访问:', error)
  276. }
  277. return diagnostics
  278. }
  279. /**
  280. * 详细的API诊断工具
  281. */
  282. export async function diagnoseAPI() {
  283. const diagnostics = {
  284. config: {
  285. hasApiKey: !!TIANAPI_CONFIG.API_KEY,
  286. apiKey: TIANAPI_CONFIG.API_KEY ? TIANAPI_CONFIG.API_KEY.substring(0, 8) + '...' : '未配置',
  287. baseUrl: TIANAPI_CONFIG.BASE_URL,
  288. endpoint: TIANAPI_CONFIG.ENDPOINTS.zodiac
  289. },
  290. network: {},
  291. apiResponse: {}
  292. }
  293. // 测试基础网络连接
  294. try {
  295. const testUrl = `${TIANAPI_CONFIG.BASE_URL}${TIANAPI_CONFIG.ENDPOINTS.zodiac}`
  296. diagnostics.network.testUrl = testUrl
  297. const response = await uni.request({
  298. url: testUrl,
  299. method: 'GET',
  300. data: {
  301. key: TIANAPI_CONFIG.API_KEY,
  302. name: '鼠'
  303. },
  304. timeout: 10000
  305. })
  306. diagnostics.network.success = true
  307. diagnostics.network.statusCode = response.statusCode
  308. diagnostics.apiResponse = response.data
  309. } catch (error) {
  310. diagnostics.network.success = false
  311. diagnostics.network.error = error.errMsg || error.message
  312. console.error('❌ 网络连接失败:', error)
  313. }
  314. return diagnostics
  315. }
  316. export default {
  317. getTodayFortune,
  318. getZodiacFortuneFromAPI,
  319. getZodiacMatch,
  320. getConstellationFortune,
  321. testAPIConnection,
  322. diagnoseAPI,
  323. diagnoseNetwork
  324. }