From a9b583fd37c3bb28ec98f7073b4f4f48f06d7996 Mon Sep 17 00:00:00 2001
From: huanglimeng <627513797@qq.com>
Date: Tue, 3 Feb 2026 22:41:30 +0800
Subject: [PATCH] feat: optimize tarot functionality, navigation, ritual
experience and standardized spreads
---
app.json | 3 +-
backup_zodiac/pages/zodiac/index.js | 341 +++++++++++++++
backup_zodiac/pages/zodiac/index.json | 3 +
backup_zodiac/pages/zodiac/index.wxml | 78 ++++
backup_zodiac/pages/zodiac/index.wxss | 247 +++++++++++
pages/home/home.js | 6 -
pages/home/home.wxml | 8 -
pages/index/index.js | 322 +++++++++-----
pages/index/index.json | 4 +
pages/index/index.wxml | 175 +++++---
pages/index/index.wxss | 590 ++++++++++++++++----------
project.config.json | 2 +-
project.private.config.json | 2 +-
13 files changed, 1383 insertions(+), 398 deletions(-)
create mode 100644 backup_zodiac/pages/zodiac/index.js
create mode 100644 backup_zodiac/pages/zodiac/index.json
create mode 100644 backup_zodiac/pages/zodiac/index.wxml
create mode 100644 backup_zodiac/pages/zodiac/index.wxss
create mode 100644 pages/index/index.json
diff --git a/app.json b/app.json
index 5d43c07..1c052d0 100644
--- a/app.json
+++ b/app.json
@@ -1,8 +1,7 @@
{
"pages": [
"pages/home/home",
- "pages/index/index",
- "pages/zodiac/index"
+ "pages/index/index"
],
"window": {
"navigationBarTitleText": "我的第一个小程序"
diff --git a/backup_zodiac/pages/zodiac/index.js b/backup_zodiac/pages/zodiac/index.js
new file mode 100644
index 0000000..94b383a
--- /dev/null
+++ b/backup_zodiac/pages/zodiac/index.js
@@ -0,0 +1,341 @@
+Page({
+ data: {
+ selectedZodiac: null,
+ currentFortune: null, // { keyword, today, lucky, notice, match, action, summary }
+ isMatchExpanded: false, // 控制关系提示的展开状态
+
+ // 12星座数据 - 增加 summary 字段
+ zodiacList: [
+ {
+ name: '白羊座',
+ symbol: '♈',
+ range: '3.21 – 4.19',
+ fortunes: [
+ {
+ keyword: '开启',
+ today: '感觉能量在一点点回升,像温柔的晨光,正如适合开启一个小计划。',
+ lucky: '试着做一件从未做过的小事,哪怕只是换条路漫步回家。',
+ notice: '稍微慢下来也没关系,深呼吸,给自己一点缓冲的时间。',
+ action: '也许可以尝试一项简单的运动,或者把那个想了很久的小决定做了。',
+ match: '狮子座',
+ summary: '整体氛围积极向上,适宜迈出新的一步。'
+ },
+ {
+ keyword: '直觉',
+ today: '直觉敏锐的一天,内心的声音会温柔地指引你去对的地方。',
+ lucky: '流一点汗,让身体的能量自由流动起来。',
+ notice: '倾听也是一种力量,试着先听听别人的想法。',
+ action: '相信你的第一反应,今天不需要过度分析,跟着感觉走就好。',
+ match: '射手座',
+ summary: '这是一个依靠感性而非逻辑的时刻,信任直觉。'
+ }
+ ]
+ },
+ {
+ name: '金牛座',
+ symbol: '♉',
+ range: '4.20 – 5.20',
+ fortunes: [
+ {
+ keyword: '安稳',
+ today: '享受当下的安稳就好,物质的触感能带给你实实在在的安全感。',
+ lucky: '一杯温热的茶,或是一顿用心准备的晚餐,都是很好的滋养。',
+ notice: '柔软一点,你会发现世界比想象中更宽阔。',
+ action: '花点时间整理一下钱包或书桌,有序的环境会让你感到平静。',
+ match: '处女座',
+ summary: '平稳是今日的主基调,无需向外过多索求。'
+ },
+ {
+ keyword: '秩序',
+ today: '按部就班也很好,秩序感会让你感到踏实和放松。',
+ lucky: '在整理收纳中梳理思绪,享受物品归位的快乐。',
+ notice: '试着松开手,有时候放手反而能拥有更多。',
+ action: '去做一次舒缓的按摩,或者仅仅是静静地听一段白噪音。',
+ match: '摩羯座',
+ summary: '在规则与秩序中能找到内心的宁静。'
+ }
+ ]
+ },
+ {
+ name: '双子座',
+ symbol: '♊',
+ range: '5.21 – 6.21',
+ fortunes: [
+ {
+ keyword: '灵感',
+ today: '思维很活跃,灵感像小火花一样在闪烁。',
+ lucky: '翻翻新书的目录,或和陌生人简单聊几句。',
+ notice: '试着一次只做一件事情,专注会让你更舒服。',
+ action: '随身带一个小本子,记录下今天那些有趣的小念头。',
+ match: '水瓶座',
+ summary: '思维跳跃的一天,由于灵感的迸发而显得生动。'
+ },
+ {
+ keyword: '表达',
+ today: '沟通的桥梁已经架好,适合真实而轻松地表达自己。',
+ lucky: '记录下脑海中一闪而过的念头,它们很珍贵。',
+ notice: '有时候稍微沉默一下,给自己留点空间。',
+ action: '给许久未见的老朋友发个信息,简单的问候就很好。',
+ match: '天秤座',
+ summary: '适宜交流与分享,信息的流动会带来新的机会。'
+ }
+ ]
+ },
+ {
+ name: '巨蟹座',
+ symbol: '♋',
+ range: '6.22 – 7.22',
+ fortunes: [
+ {
+ keyword: '疗愈',
+ today: '情感细腻丰富,适合向内探索,疗愈旧日的伤口。',
+ lucky: '去水边走走,水的包容会让你感到平静。',
+ notice: '保护好自己的情绪边界,不用对所有人的话都太在意。',
+ action: '今晚给自己做一顿暖胃的食物,或者泡一个舒服的热水澡。',
+ match: '双鱼座',
+ summary: '向内关注自我,是一个适合自我修复的温和日子。'
+ },
+ {
+ keyword: '关怀',
+ today: '温柔是你的铠甲,你对他人的关怀也会回流到自己身上。',
+ lucky: '给家人打个电话,或者照顾一株植物。',
+ notice: '过去已去,当下才是最真实的,试着活在此时此刻。',
+ action: '整理一下旧照片,保留快乐的记忆就好。',
+ match: '天蝎座',
+ summary: '被温柔的情绪包围,付出与接受都自然发生。'
+ }
+ ]
+ },
+ {
+ name: '狮子座',
+ symbol: '♌',
+ range: '7.23 – 8.22',
+ fortunes: [
+ {
+ keyword: '舞台',
+ today: '自信的光芒很美,你本身就是舞台的中心。',
+ lucky: '穿一件喜欢的亮色衣服,或者大方地接受别人的赞美。',
+ notice: '真正的王者懂得示弱的艺术,柔软也是一种力量。',
+ action: '对着镜子里的自己微笑,肯定自己的一个优点。',
+ match: '白羊座',
+ summary: '光芒外露,适宜展示自我,但也需张弛有度。'
+ },
+ {
+ keyword: '创造',
+ today: '创造力在涌动,与其等待机会,不如自己创造一个小舞台。',
+ lucky: '像孩子一样去玩耍,画画或者唱歌都很棒。',
+ notice: '保持谦逊,你会看到更多不一样的风景。',
+ action: '尝试一种新的娱乐方式,或者去一个从未去过的店。',
+ match: '射手座',
+ summary: '创造力充沛,是表达个性和释放天性的好时机。'
+ }
+ ]
+ },
+ {
+ name: '处女座',
+ symbol: '♍',
+ range: '8.23 – 9.22',
+ fortunes: [
+ {
+ keyword: '清晰',
+ today: '逻辑很清晰,能看透事物的本质,混乱将离你而去。',
+ lucky: '列一张简单的清单,每划掉一项都是一种治愈。',
+ notice: '对自己宽容一点,完美是一个方向,而不是必须到达的终点。',
+ action: '清理手机里无用的截图和APP,数字极简也能带来清爽。',
+ match: '金牛座',
+ summary: '条理清晰,事半功倍,适合处理复杂的细节事务。'
+ },
+ {
+ keyword: '服务',
+ today: '助人的愿望很美好,你的细心能帮到很多人。',
+ lucky: '做一次深度的清洁,无论是环境还是心灵。',
+ notice: '偶尔也要抬头看看森林,不要总是盯着细节看。',
+ action: '在这个周末,尝试“一次只做一件事”,体验专注的快乐。',
+ match: '摩羯座',
+ summary: '在付出中获得满足感,但也需注意微观与宏观的平衡。'
+ }
+ ]
+ },
+ {
+ name: '天秤座',
+ symbol: '♎',
+ range: '9.23 – 10.23',
+ fortunes: [
+ {
+ keyword: '平衡',
+ today: '追求和谐与美,在平衡中找到内心的宁静。',
+ lucky: '去美术馆逛逛,或者欣赏一首优美的乐曲。',
+ notice: '不要为了取悦他人而委屈自己,温和地拒绝也是可以的。',
+ action: '更换一下手机或电脑的壁纸,换成一张让你觉得美的图片。',
+ match: '双子座',
+ summary: '适宜在审美与艺术中寻找平衡,享受片刻的优雅。'
+ },
+ {
+ keyword: '连接',
+ today: '人际关系很顺畅,适合化解误会,建立新的连接。',
+ lucky: '买一束花插在瓶中,为生活增添一点仪式感。',
+ notice: '犹豫不决时,抛硬币也是一种把命运交给天意的智慧。',
+ action: '主动赞美身边的一个人,真诚的赞美会让大家都很开心。',
+ match: '水瓶座',
+ summary: '良性的互动会带来好运,人际关系是今日的重点。'
+ }
+ ]
+ },
+ {
+ name: '天蝎座',
+ symbol: '♏',
+ range: '10.24 – 11.22',
+ fortunes: [
+ {
+ keyword: '洞察',
+ today: '洞察力很强,能看穿表象,直达事物的核心。',
+ lucky: '在日记本里写下秘密,或者进行一次深刻的冥想。',
+ notice: '放下执念,学会像蛇蜕皮一样重生。',
+ action: '读一本悬疑小说或者看一部深度电影,满足你的探索欲。',
+ match: '巨蟹座',
+ summary: '直觉与洞察力并存,适合深入思考而非浅尝辄止。'
+ },
+ {
+ keyword: '坚定',
+ today: '意志力坚定,现在是攻克难题的好时机。',
+ lucky: '独处,享受一个人的高质量时光。',
+ notice: '试着交付一点信任,你会发现没有那么多需要防备的事。',
+ action: '尝试与一个信任的人进行一次深度谈话,不设防的那种。',
+ match: '双鱼座'
+ }
+ ]
+ },
+ {
+ name: '射手座',
+ symbol: '♐',
+ range: '11.23 – 12.21',
+ fortunes: [
+ {
+ keyword: '自由',
+ today: '视野开阔,心向远方,自由的感觉真好。',
+ lucky: '规划一次未来的旅行,或者看一部异国电影。',
+ notice: '承诺之前先想一下,不要因为一时兴起而许下诺言。',
+ action: '去户外走走,甚至只是去楼下公园转一圈,看看天空。',
+ match: '白羊座',
+ summary: '心向自由,适合拓展视野,不宜被琐事困住眼界。'
+ },
+ {
+ keyword: '乐观',
+ today: '乐观的精神很有感染力,你是身边人的开心果。',
+ lucky: '去户外奔跑,去接触大自然和新鲜空气。',
+ notice: '检查一下随身物品,细心一点能避免小麻烦。',
+ action: '学习一个全新的冷知识,或者尝试一种异国料理。',
+ match: '狮子座',
+ summary: '积极乐观的一天,行动力是好运的来源。'
+ }
+ ]
+ },
+ {
+ name: '摩羯座',
+ symbol: '♑',
+ range: '12.22 – 1.19',
+ fortunes: [
+ {
+ keyword: '踏实',
+ today: '脚踏实地,每一步都算数,成就感源于自律。',
+ lucky: '制定一个长期的目标,并迈出第一步。',
+ notice: '不要把自己逼得太紧,工作之余也要学会“虚度时光”。',
+ action: '复盘一下本周的计划,把完成的事项画上大大的勾。',
+ match: '金牛座',
+ summary: '耕耘即有收获,适合专注于当下脚踏实地的积累。'
+ },
+ {
+ keyword: '权威',
+ today: '权威感提升,你的专业度会得到大家的认可。',
+ lucky: '向一位长辈或导师请教,汲取传统的智慧。',
+ notice: '给生活加点糖,不用总是那么严肃。',
+ action: '给自己泡一杯好茶或好咖啡,在工作间隙享受片刻宁静。',
+ match: '处女座',
+ summary: '专业与稳重是今日的通行证,但也需适度放松。'
+ }
+ ]
+ },
+ {
+ name: '水瓶座',
+ symbol: '♒',
+ range: '1.20 – 2.18',
+ fortunes: [
+ {
+ keyword: '创意',
+ today: '特立独行的一天,你的怪念头也许就是天才的创意。',
+ lucky: '尝试一种新的科技产品,或者研究一个小众领域。',
+ notice: '给身边人一点温度,理智之外也需要温情。',
+ action: '去浏览一些前沿科技或艺术资讯,给大脑“充充电”。',
+ match: '双子座',
+ summary: '思维活跃且独特,适合进行创造性的脑力活动。'
+ },
+ {
+ keyword: '理想',
+ today: '为了理想而战,你的视野超越了当下,看向未来。',
+ lucky: '参加一个社群活动,寻找志同道合的伙伴。',
+ notice: '保持开放的心态,固执己见和坚持真理只有一线之隔。',
+ action: '换一条平时不走的路去上班/回家,观察沿途的新风景。',
+ match: '天秤座',
+ summary: '目光长远,适合规划未来,不宜纠结于眼前的小节。'
+ }
+ ]
+ },
+ {
+ name: '双鱼座',
+ symbol: '♓',
+ range: '2.19 – 3.20',
+ fortunes: [
+ {
+ keyword: '灵感',
+ today: '梦幻与现实的边界模糊,灵感如潮水般涌来。',
+ lucky: '听海浪的声音,或者在睡前读一首诗。',
+ notice: '勇敢面对现实问题,比躲进幻想更有效。',
+ action: '听一首纯音乐,闭上眼睛想象一个完美的场景。',
+ match: '巨蟹座',
+ summary: '感受力极强的一天,适合艺术创作与精神探索。'
+ },
+ {
+ keyword: '同理心',
+ today: '同理心爆棚,你能轻易感知他人的悲喜。',
+ lucky: '做一件善事,哪怕只是给流浪猫一点食物。',
+ notice: '学会自我净化,不要做情绪的海绵。',
+ action: '写下一件让你感到焦虑的事,然后把纸条撕碎扔掉。',
+ match: '天蝎座',
+ summary: '情感流动充沛,在关怀他人的同时也需照顾好自己。'
+ }
+ ]
+ }
+ ]
+ },
+
+ // 选择星座
+ selectZodiac: function (e) {
+ const index = e.currentTarget.dataset.index;
+ const zodiac = this.data.zodiacList[index];
+
+ const randomIdx = Math.floor(Math.random() * zodiac.fortunes.length);
+ const fortuneData = zodiac.fortunes[randomIdx];
+
+ this.setData({
+ selectedZodiac: zodiac,
+ currentFortune: fortuneData,
+ isMatchExpanded: false // 重置展开状态
+ });
+ },
+
+ // 切换关系提示展开状态
+ toggleMatch: function () {
+ this.setData({
+ isMatchExpanded: !this.data.isMatchExpanded
+ });
+ },
+
+ // 返回列表
+ backToList: function () {
+ this.setData({
+ selectedZodiac: null,
+ currentFortune: null,
+ isMatchExpanded: false // 重置展开状态
+ });
+ }
+})
diff --git a/backup_zodiac/pages/zodiac/index.json b/backup_zodiac/pages/zodiac/index.json
new file mode 100644
index 0000000..a329c48
--- /dev/null
+++ b/backup_zodiac/pages/zodiac/index.json
@@ -0,0 +1,3 @@
+{
+ "navigationBarTitleText": "星座运势"
+}
\ No newline at end of file
diff --git a/backup_zodiac/pages/zodiac/index.wxml b/backup_zodiac/pages/zodiac/index.wxml
new file mode 100644
index 0000000..2d07997
--- /dev/null
+++ b/backup_zodiac/pages/zodiac/index.wxml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+ {{item.symbol}}
+ {{item.name}}
+ {{item.range}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ✨ 今日关键词
+ {{currentFortune.keyword}}
+
+
+
+
+ ✨ 今日运势
+ {{currentFortune.today}}
+
+
+
+
+ 🍀 幸运提示
+ {{currentFortune.lucky}}
+
+
+
+
+ 💡 注意事项
+ {{currentFortune.notice}}
+
+
+
+
+ 🌱 今日行动建议
+ {{currentFortune.action}}
+
+
+
+
+
+ {{isMatchExpanded ? '收起关系提示' : '🌸 今日关系提示(点击查看)'}}
+
+
+ 今天,与你能量更顺的星座是:
+ {{currentFortune.match}}
+
+
+
+
+
+
+ {{currentFortune.summary}}
+
+
+ ⬅ 选其他星座
+
+
+
+
diff --git a/backup_zodiac/pages/zodiac/index.wxss b/backup_zodiac/pages/zodiac/index.wxss
new file mode 100644
index 0000000..02434f1
--- /dev/null
+++ b/backup_zodiac/pages/zodiac/index.wxss
@@ -0,0 +1,247 @@
+/* 保持与整体风格一致的暗色背景 */
+page {
+ background-color: #1a1a2e;
+ height: 100%;
+ color: #fff;
+}
+
+.container {
+ padding: 30px 20px;
+ box-sizing: border-box;
+ min-height: 100%;
+ display: flex;
+ flex-direction: column;
+}
+
+/* --- 列表状态样式 --- */
+.header-tip {
+ font-size: 20px;
+ margin-bottom: 30px;
+ text-align: center;
+ opacity: 0.9;
+ letter-spacing: 1px;
+}
+
+.grid-container {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+}
+
+.zodiac-item {
+ width: 30%; /* 三列布局 */
+ background-color: rgba(255, 255, 255, 0.05);
+ margin-bottom: 20px;
+ padding: 20px 0;
+ border-radius: 12px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ border: 1px solid rgba(255, 255, 255, 0.05);
+ cursor: pointer;
+}
+
+.zodiac-symbol {
+ font-size: 28px;
+ margin-bottom: 5px;
+}
+
+.zodiac-name {
+ font-size: 14px;
+ opacity: 0.8;
+}
+
+.zodiac-range {
+ font-size: 10px;
+ opacity: 0.5;
+ margin-top: 3px;
+}
+
+/* --- 结果状态样式 --- */
+.result-container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-top: 20px;
+ flex: 1;
+ width: 100%;
+}
+
+.result-header {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-bottom: 30px;
+ animation: fadeIn 0.8s ease;
+}
+
+.result-symbol {
+ font-size: 50px;
+ margin-bottom: 10px;
+ color: #e94560;
+}
+
+.today-title {
+ font-size: 18px;
+ opacity: 0.8;
+}
+
+.fortune-card {
+ width: 100%;
+ padding: 25px;
+ background-color: rgba(255, 255, 255, 0.05);
+ border-radius: 16px;
+ box-sizing: border-box;
+ margin-bottom: 40px;
+ border: 1px solid rgba(233, 69, 96, 0.3);
+ animation: slideUp 0.8s ease;
+ display: flex;
+ flex-direction: column;
+}
+
+/* 0. 关键词卡片样式 */
+.keyword-card {
+ background-color: rgba(0, 0, 0, 0.2);
+ border-radius: 12px;
+ padding: 15px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-bottom: 25px;
+ border: 1px solid rgba(255, 255, 255, 0.05);
+}
+
+.keyword-label {
+ font-size: 12px;
+ color: #a29bfe;
+ margin-bottom: 5px;
+ opacity: 0.8;
+}
+
+.keyword-text {
+ font-size: 32px; /* 进一步加大关键词字号 */
+ color: #fff;
+ font-weight: bold;
+ letter-spacing: 4px;
+ margin-top: 5px;
+ text-shadow: 0 2px 10px rgba(0,0,0,0.3);
+}
+
+/* 三段式内容的样式 */
+.section {
+ display: flex;
+ flex-direction: column;
+ margin-bottom: 25px;
+ border-bottom: 1px dashed rgba(255, 255, 255, 0.1); /* 分隔线 */
+ padding-bottom: 15px;
+}
+
+.last-section {
+ margin-bottom: 0;
+ border-bottom: none;
+ padding-bottom: 0;
+}
+
+.section-label {
+ font-size: 14px;
+ color: #a29bfe; /* 浅紫色标签 */
+ margin-bottom: 8px;
+ font-weight: bold;
+}
+
+.section-content {
+ font-size: 14px; /* 二级信息字号调小 */
+ line-height: 1.6;
+ color: #fff;
+ opacity: 0.75; /* 二级信息透明度降低 */
+ text-align: left;
+}
+
+/* 一级信息强调样式 */
+.primary-section .section-content {
+ font-size: 17px;
+ opacity: 1;
+ font-weight: 500;
+ line-height: 1.7;
+ letter-spacing: 0.5px;
+}
+
+.primary-section .section-label {
+ font-size: 15px;
+ color: #e94560; /* 稍微强调标题颜色 */
+ opacity: 1;
+}
+
+.back-btn {
+ font-size: 14px;
+ opacity: 0.6;
+ text-decoration: underline;
+ padding: 10px;
+}
+
+/* 简单的动效 */
+@keyframes fadeIn {
+ from { opacity: 0; }
+ to { opacity: 1; }
+}
+
+@keyframes slideUp {
+ from { opacity: 0; transform: translateY(20px); }
+ to { opacity: 1; transform: translateY(0); }
+}
+
+/* 关系模块样式 */
+.status-divider {
+ width: 100%;
+ height: 1px;
+ background-color: rgba(255, 255, 255, 0.05);
+ margin: 15px 0;
+}
+
+.match-module {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 10px 0;
+ cursor: pointer;
+}
+
+.match-trigger {
+ font-size: 14px;
+ color: #fbaceb; /* 淡淡的粉色 */
+ opacity: 0.8;
+ text-decoration: underline;
+ margin-bottom: 5px;
+}
+
+.match-content {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-top: 15px;
+ animation: fadeIn 0.5s ease;
+}
+
+.match-intro {
+ font-size: 12px;
+ color: #fff;
+ opacity: 0.6;
+ margin-bottom: 8px;
+}
+
+.match-name {
+ font-size: 18px;
+ color: #fff;
+ font-weight: bold;
+}
+
+/* 总体结论样式 */
+.summary-text {
+ font-size: 13px;
+ color: rgba(255, 255, 255, 0.5); /* 中性灰 */
+ margin-top: -20px; /* 调整间距 */
+ margin-bottom: 30px;
+ text-align: center;
+ max-width: 80%;
+ line-height: 1.5;
+}
diff --git a/pages/home/home.js b/pages/home/home.js
index 6c062d4..6f77b34 100644
--- a/pages/home/home.js
+++ b/pages/home/home.js
@@ -3,11 +3,5 @@ Page({
wx.navigateTo({
url: '/pages/index/index'
})
- },
-
- goToZodiac: function () {
- wx.navigateTo({
- url: '/pages/zodiac/index'
- })
}
})
diff --git a/pages/home/home.wxml b/pages/home/home.wxml
index 956f657..677121b 100644
--- a/pages/home/home.wxml
+++ b/pages/home/home.wxml
@@ -16,14 +16,6 @@
-
-
- ♒
-
- 星座运势
- 解析星体给你的启示
-
-
diff --git a/pages/index/index.js b/pages/index/index.js
index 8778f15..2acd471 100644
--- a/pages/index/index.js
+++ b/pages/index/index.js
@@ -2,6 +2,9 @@
const DEEPSEEK_API_KEY = 'sk-f659b4c3aa954baaa6cbdbd5cae0b7d1'; // 请在此处替换您的 API Key
const DEEPSEEK_BASE_URL = 'https://api.deepseek.com/chat/completions';
+// --- 数据导入 ---
+const { minorArcana } = require('../../data/tarot/index');
+
// --- Prompt 模板定义 ---
// 1. 基础版模板:平静、清晰、节制
@@ -45,19 +48,95 @@ const TAROT_PROMPT_NIGHT = `你是一位安静、克制、不制造依赖的塔
3. 用一句轻微、可停住的句子结束,不指向下一步
【输出要求】
-- 总字数 100–160 字
-- 不使用感叹号,不使用列表、解释性语句
- 只输出解读文本`;
+// 3. 增强版模板:结构化深度解读
+const TAROT_PROMPT_ENHANCED = `你是一位专业、温和且具有洞察力的塔罗解读者。
+你的任务是根据选定的牌阵,为用户提供有深度、有层次且具有陪伴感的解读。
+
+【解读边界】
+- 不预测具体事件、不给绝对结论、不使用恐吓性语言
+- 保持温和的引导口气,像是在进行一场心灵对话
+
+【解读结构】
+请严格按照以下 JSON 格式输出解读内容,不要包含任何其他说明性文字:
+{
+ "theme": "用一句话概括本次解读的核心主题",
+ "status": "描述用户当下的情绪或处境状态",
+ "influence": "分析当前局面背后的潜在影响因素(内在或外在)",
+ "advice": "给出具体、温和且具有操作性的行动建议",
+ "positions": [
+ {
+ "posName": "位置名称",
+ "posMeaning": "由你结合牌面对该位置的详细解读(约 60-100 字)"
+ }
+ ]
+}`;
+
+// --- 牌阵定义 ---
+const SPREADS = [
+ {
+ "id": "one_card_guidance",
+ "name": "单张指引",
+ "cardCount": 1,
+ "positions": ["当下的指引"],
+ "description": "为你此刻的状态提供一个温和而清晰的方向提示。",
+ "aiSchema": ["core_theme", "current_state", "action_advice"]
+ },
+ {
+ "id": "three_time_flow",
+ "name": "过去 · 现在 · 未来",
+ "cardCount": 3,
+ "positions": ["过去", "现在", "未来"],
+ "description": "帮助你理解事情的发展过程与可能走向。",
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ },
+ {
+ "id": "three_problem_solution",
+ "name": "问题 · 阻碍 · 建议",
+ "cardCount": 3,
+ "positions": ["问题核心", "当前阻碍", "行动建议"],
+ "description": "聚焦关键问题,找出当下最可行的应对方式。",
+ "aiSchema": ["core_theme", "current_state", "action_advice"]
+ },
+ {
+ "id": "five_situation_analysis",
+ "name": "现状分析",
+ "cardCount": 5,
+ "positions": ["现状", "内在因素", "外在影响", "行动方向", "可能结果"],
+ "description": "从内外层面拆解局势,明确下一步行动。",
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ },
+ {
+ "id": "two_choice_decision",
+ "name": "二选一抉择",
+ "cardCount": 4,
+ "positions": ["选择A的发展", "选择A的结果", "选择B的发展", "选择B的结果"],
+ "description": "对比两种选择的潜在走向,辅助理性决策。",
+ "aiSchema": ["core_theme", "potential_influence", "action_advice"]
+ },
+ {
+ "id": "relationship_spread",
+ "name": "关系洞察",
+ "cardCount": 5,
+ "positions": ["你的位置", "对方的位置", "关系现状", "隐藏影响", "未来趋势"],
+ "description": "理解一段关系中的互动模式与发展方向。",
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ }
+];
+
Page({
data: {
todayDate: '', // 用于存储今天的日期
- // 1. 状态管理: idle, focusing, flipping, revealed
- state: 'idle',
- currentCard: null,
- isRevealed: false,
- explanation: '',
+ // 1. 状态管理: spread_select, idle, shuffling, drawing, flipping, revealed
+ state: 'spread_select', // 初始进入牌阵选择
+ selectedSpread: null,
+ drawnCardIndices: [], // 用户选中的牌索引
+ drawnCards: [], // 实际抽到的牌对象
+ revealedCount: 0, // 已翻开的数量
+
cardBackImage: '/images/beimian.png',
+ spreads: SPREADS,
// 动画数据
deckAnimation: {},
@@ -253,11 +332,12 @@ Page({
meaning: "一段旅程的完美终点,成就感与整合,准备开始新的循环。",
reversedMeaning: "机遇还没完全成熟,再耐心一点点。检查一下还有什么细节没完成?",
energy: "圆融",
- meaning: "一段旅程的完美终点,成就感与整合,准备开始新的循环。",
- reversedMeaning: "机遇还没完全成熟,再耐心一点点。检查一下还有什么细节没完成?",
image: "/images/shijie.png"
}
- ]
+ ],
+ // 合并大牌和小牌
+ allCards: [],
+ aiResult: null
},
onLoad: function () {
@@ -269,95 +349,78 @@ Page({
const dateStr = `${year}-${month}-${day}`;
this.setData({
- todayDate: dateStr
+ todayDate: dateStr,
+ allCards: [...this.data.cardList, ...minorArcana]
});
- this.startIdleAnimation();
- console.log('塔罗牌(完整版 22 张 + 逆位文案)已经洗好了...')
+ console.log(`塔罗牌已就位,共 ${this.data.allCards.length} 张。`)
},
- // --- 待机呼吸动画 ---
- startIdleAnimation: function () {
- const animation = wx.createAnimation({
- duration: 2000,
- timingFunction: 'ease-in-out',
- });
-
- const next = () => {
- if (this.data.state !== 'idle' && this.data.state !== 'focusing') return;
- animation.translateY(4).step();
- animation.translateY(0).step();
- this.setData({
- deckAnimation: animation.export()
- });
- };
-
- next();
- this.idleTimer = setInterval(next, 4000);
- },
-
- // --- 抽一张牌:进入 focusing 状态 ---
- drawCard: function () {
- if (this.data.state !== 'idle' && this.data.state !== 'revealed') return;
-
- // 停止之前的呼吸动画计时器(如果有)
- if (this.idleTimer) clearInterval(this.idleTimer);
-
+ // --- 1. 选择牌阵 ---
+ selectSpread: function (e) {
+ const id = e.currentTarget.dataset.id;
+ const spread = this.data.spreads.find(s => s.id === id);
this.setData({
- state: 'focusing',
- currentCard: null,
- isRevealed: false,
- explanation: ''
+ selectedSpread: spread,
+ state: 'shuffling'
});
- // 引导文案淡入
- const guideAnim = wx.createAnimation({ duration: 500, timingFunction: 'ease' });
- guideAnim.opacity(1).step();
- this.setData({ guideAnimation: guideAnim.export() });
-
- // 停顿 500-800ms 后进入 flipping
+ // 模拟洗牌感应 2.5s
setTimeout(() => {
- this.startFlipping();
- }, 800);
+ this.setData({ state: 'drawing' });
+ }, 2500);
},
- // --- 开始翻牌流程 ---
- startFlipping: function () {
- const allCards = this.data.cardList;
- const randomIndex = Math.floor(Math.random() * allCards.length);
- const selected = Object.assign({}, allCards[randomIndex]);
- selected.isReversed = Math.random() >= 0.5;
+ // --- 2. 抽牌逻辑 ---
+ onCardTap: function (e) {
+ const index = e.currentTarget.dataset.index;
+ let { drawnCardIndices, selectedSpread } = this.data;
- const prefixes = this.data.prefixList;
- const randomPrefixIndex = Math.floor(Math.random() * prefixes.length);
- const selectedPrefix = prefixes[randomPrefixIndex];
+ if (drawnCardIndices.includes(index)) {
+ drawnCardIndices = drawnCardIndices.filter(i => i !== index);
+ } else if (drawnCardIndices.length < selectedSpread.cardCount) {
+ drawnCardIndices.push(index);
+ }
+
+ this.setData({ drawnCardIndices });
+ },
+
+ // --- 3. 确认开启 ---
+ confirmDraw: function () {
+ const { drawnCardIndices, allCards } = this.data;
+ const drawnCards = drawnCardIndices.map(() => {
+ const randomIndex = Math.floor(Math.random() * allCards.length);
+ const card = Object.assign({}, allCards[randomIndex]);
+ card.isReversed = Math.random() >= 0.5;
+ // 如果这张牌没有图片(如小牌),使用背面图作为占位符,或保持原有逻辑
+ if (!card.image) {
+ card.image = this.data.cardBackImage;
+ }
+ return card;
+ });
this.setData({
+ drawnCards,
state: 'flipping',
- currentCard: selected,
- explanation: `${selectedPrefix}${selected.isReversed ? selected.reversedMeaning : selected.meaning}`
+ revealedCount: 0
});
+ },
- // 卡牌抬起并旋转的动画
- const cardAnim = wx.createAnimation({
- duration: 500,
- timingFunction: 'ease-in-out'
- });
+ // --- 4. 逐一翻牌 ---
+ revealNext: function (e) {
+ const index = e.currentTarget.dataset.index;
+ if (index === this.data.revealedCount) {
+ const nextCount = index + 1;
+ this.setData({
+ revealedCount: nextCount
+ });
- // 轻微抬起 (Y -10~-15px) 和旋转 (≤ 3°)
- cardAnim.translateY(-12).rotate(Math.random() * 6 - 3).step();
- this.setData({ cardAnimation: cardAnim.export() });
-
- // 翻转动画是在 WXML 中通过 CSS 类控制的,这里保持一致
- setTimeout(() => {
- this.setData({ isRevealed: true });
-
- // 翻牌完成后留白 300-500ms
- setTimeout(() => {
+ // 如果全部翻开,触发解读
+ if (nextCount === this.data.selectedSpread.cardCount) {
this.setData({ state: 'revealed' });
this.showInterpretation();
- }, 500);
- }, 500);
+ }
+ }
},
// --- 展示解读内容 ---
@@ -373,33 +436,25 @@ Page({
this.fetchAiInterpretation();
},
- // --- 获取 AI 解读主逻辑 (DeepSeek 直接调用版) ---
+ // --- 获取 AI 解读主逻辑 ---
fetchAiInterpretation: function () {
- const card = this.data.currentCard;
- if (!card) return;
+ const { drawnCards, selectedSpread } = this.data;
+ if (!drawnCards.length) return;
this.setData({
isAiLoading: true,
- aiExplanation: ''
+ aiResult: null
});
- // 1. 构建结构化 Prompt
- const position = card.isReversed ? '逆位' : '正位';
- const core = card.isReversed ? card.reversedMeaning : card.meaning;
+ // 1. 构建卡牌信息
+ const cardDetails = drawnCards.map((card, index) => {
+ return `位置[${selectedSpread.positions[index]}]:${card.name} (${card.isReversed ? '逆位' : '正位'}),关键词:${card.keyword || (card.keywords ? card.keywords.join(',') : '')}`;
+ }).join('\n');
- // 当前版本统一使用基础解读 Prompt (TAROT_PROMPT_BASE)
- const systemPrompt = TAROT_PROMPT_BASE;
+ const userPrompt = `牌阵:${selectedSpread.name}\n${cardDetails}`;
- const userPrompt = `请基于以下信息给出解读:
-牌名:${card.name}
-位置:${position}
-关键词:${card.keyword}
-一句话核心解读:${core}
-能量倾向:${card.energy}`;
+ console.log("正在获取深度解读...");
- console.log("正在通过 DeepSeek 生成解读...");
-
- // 2. 调用 DeepSeek API
wx.request({
url: DEEPSEEK_BASE_URL,
method: 'POST',
@@ -410,37 +465,82 @@ Page({
data: {
model: "deepseek-chat",
messages: [
- { role: "system", content: systemPrompt },
+ { role: "system", content: TAROT_PROMPT_ENHANCED },
{ role: "user", content: userPrompt }
],
stream: false,
- temperature: 0.7
+ response_format: { type: "json_object" }
},
- timeout: 15000,
+ timeout: 20000,
success: (res) => {
if (res.data && res.data.choices && res.data.choices[0]) {
- const aiResult = res.data.choices[0].message.content;
- this.setData({
- aiExplanation: aiResult,
- isAiLoading: false
- });
+ try {
+ const aiResult = JSON.parse(res.data.choices[0].message.content);
+ this.setData({
+ aiResult,
+ isAiLoading: false
+ });
+ } catch (e) {
+ console.error("JSON 解析失败", e);
+ this.handleAiFallback();
+ }
} else {
- console.warn("DeepSeek 返回异常,执行回退");
this.handleAiFallback();
}
},
fail: (err) => {
- console.error("DeepSeek 请求失败:", err);
+ console.error("请求失败", err);
this.handleAiFallback();
}
});
},
- // --- AI 解读失败后的回退处理 ---
handleAiFallback: function () {
+ // 构建一个基础的回退对象
+ const fallback = {
+ theme: "能量感应受阻",
+ status: "当前思绪可能较为杂乱",
+ influence: "外界干扰或网络波动",
+ advice: "建议深呼吸,稍后再次尝试开启心灵对话",
+ positions: this.data.drawnCards.map((card, index) => ({
+ posName: this.data.selectedSpread.positions[index],
+ posMeaning: `${card.name}${card.isReversed ? '(逆位)' : '(正位)'}:${card.isReversed ? (card.reversedMeaning || card.description) : (card.meaning || card.description)}`
+ }))
+ };
this.setData({
- aiExplanation: this.data.explanation,
+ aiResult: fallback,
isAiLoading: false
});
},
-})
\ No newline at end of file
+
+ resetSpread: function () {
+ this.setData({
+ state: 'spread_select',
+ selectedSpread: null,
+ drawnCardIndices: [],
+ drawnCards: [],
+ revealedCount: 0,
+ aiResult: null
+ });
+ },
+
+ // --- 导航优化:统一返回逻辑 ---
+ handleBack: function () {
+ const pages = getCurrentPages();
+ if (pages.length > 1) {
+ wx.navigateBack({
+ delta: 1
+ });
+ } else {
+ // 兜底逻辑:如果是在第一层,则跳转回首页
+ wx.switchTab({
+ url: '/pages/home/home'
+ }).catch(() => {
+ // 如果不是 tabBar,则使用 reLaunch
+ wx.reLaunch({
+ url: '/pages/home/home'
+ });
+ });
+ }
+ }
+})
diff --git a/pages/index/index.json b/pages/index/index.json
new file mode 100644
index 0000000..f6beb02
--- /dev/null
+++ b/pages/index/index.json
@@ -0,0 +1,4 @@
+{
+ "navigationBarTitleText": "塔罗指引",
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/pages/index/index.wxml b/pages/index/index.wxml
index 87ce550..cb20e70 100644
--- a/pages/index/index.wxml
+++ b/pages/index/index.wxml
@@ -1,76 +1,141 @@
-
- 塔罗 · 今日指引
- 📅 今日指引 · {{todayDate}}
- 当你需要一个答案时
-
-
-
-