v1.1 - Added question context analysis and spread story features

This commit is contained in:
huanglimeng 2026-02-04 22:34:27 +08:00
parent d9edbf0562
commit 71a73908fa
5 changed files with 175 additions and 1 deletions

View File

@ -4,6 +4,8 @@ const DEEPSEEK_BASE_URL = 'https://api.deepseek.com/chat/completions';
// --- 数据导入 ---
const { minorArcana } = require('../../data/tarot/index');
const { getQuestionType } = require('../../utils/questionType');
const { generateSpreadStory } = require('../../utils/spreadStory');
// --- Prompt 模板定义 ---
@ -179,6 +181,8 @@ Page({
// 1. 状态管理: spread_select, idle, shuffling, drawing, flipping, revealed
state: 'spread_select', // 初始进入牌阵选择
selectedSpread: null,
question: '', // 用户输入的问题
questionType: '综合问题', // 问题类型
drawnCardIndices: [], // 用户选中的牌索引
drawnCards: [], // 实际抽到的牌对象
revealedCount: 0, // 已翻开的数量
@ -195,6 +199,7 @@ Page({
// AI 相关
isAiLoading: false,
aiExplanation: '',
spreadStory: '', // 综合故事线
// 3. 前缀文案列表(随机抽取)
prefixList: [
@ -410,6 +415,17 @@ Page({
const spread = this.data.spreads.find(s => s.id === id);
this.setData({
selectedSpread: spread,
state: 'asking' // 先进入提问状态
});
},
// --- 1.5 确认问题并开始洗牌 ---
confirmQuestion: function () {
const question = this.data.question.trim();
const questionType = getQuestionType(question);
this.setData({
questionType: questionType,
state: 'shuffling'
});
@ -419,6 +435,13 @@ Page({
}, 2500);
},
// 输入问题
onQuestionInput: function (e) {
this.setData({
question: e.detail.value
});
},
// --- 2. 抽牌逻辑 ---
onCardTap: function (e) {
const index = e.currentTarget.dataset.index;
@ -524,8 +547,10 @@ Page({
if (res.data && res.data.choices && res.data.choices[0]) {
try {
const aiResult = JSON.parse(res.data.choices[0].message.content);
const spreadStory = generateSpreadStory(drawnCards);
this.setData({
aiResult,
spreadStory: spreadStory,
isAiLoading: false
});
} catch (e) {

View File

@ -18,6 +18,26 @@
</view>
</view>
<!-- 1.5 提问状态 -->
<view class="asking-area" wx:if="{{state === 'asking'}}">
<view class="title-area">
<text class="app-title">请输入你想询问的问题</text>
<text class="instruction">心中默念问题,塔罗牌将为你指引方向</text>
</view>
<view class="input-area">
<textarea
class="question-input"
placeholder="例如:我们的关系会如何发展?我是否应该换工作?这个合作值得继续吗?"
placeholder-class="placeholder-style"
bindinput="onQuestionInput"
value="{{question}}"
maxlength="200"
></textarea>
<text class="char-count">{{question.length}}/200</text>
</view>
<button class="start-btn" bindtap="confirmQuestion" hover-class="btn-hover">开始抽牌</button>
</view>
<!-- 2. 洗牌状态 (展示动画) -->
<view class="ritual-area" wx:if="{{state === 'shuffling'}}">
<view class="shuffling-container">
@ -143,10 +163,16 @@
</view>
</view>
<!-- 整体趋势 -->
<view class="story-box" wx:if="{{spreadStory}}">
<text class="label">整体趋势</text>
<text class="content">{{spreadStory}}</text>
</view>
<view class="pos-meanings">
<view class="pos-meaning-item" wx:for="{{aiResult.positions}}" wx:key="posName">
<text class="pos-title">{{item.posName}}</text>
<text class="pos-text">{{item.posMeaning}}</text>
<text class="pos-text">在【{{questionType}}】来看:{{item.posMeaning}}</text>
</view>
</view>

View File

@ -442,3 +442,82 @@ page {
0%, 100% { opacity: 0.3; transform: scale(0.9); }
50% { opacity: 1; transform: scale(1.1); }
}
/* 整体趋势故事框 */
.story-box {
background: linear-gradient(135deg, rgba(201, 160, 220, 0.1), rgba(138, 138, 157, 0.05));
padding: 30rpx;
border-radius: 16rpx;
margin-bottom: 30rpx;
border-left: 4rpx solid #c9a0dc;
}
.story-box .label {
display: block;
font-size: 24rpx;
color: #c9a0dc;
margin-bottom: 15rpx;
font-weight: 600;
letter-spacing: 2rpx;
}
.story-box .content {
font-size: 28rpx;
color: #e0e0e0;
line-height: 1.8;
}
/* 提问区域样式 */
.asking-area {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
padding: 60rpx 40rpx;
}
.input-area {
width: 100%;
background: rgba(255, 255, 255, 0.05);
border-radius: 20rpx;
padding: 30rpx;
margin-bottom: 60rpx;
border: 1px solid rgba(201, 160, 220, 0.2);
position: relative;
}
.question-input {
width: 100%;
height: 300rpx;
font-size: 30rpx;
color: #ffffff;
line-height: 1.6;
}
.placeholder-style {
color: rgba(255, 255, 255, 0.3);
}
.char-count {
position: absolute;
bottom: 20rpx;
right: 30rpx;
font-size: 22rpx;
color: #8a8a9d;
}
.start-btn {
background: #c9a0dc;
color: #1a1a2e;
font-size: 32rpx;
font-weight: 600;
padding: 24rpx 100rpx;
border-radius: 50rpx;
box-shadow: 0 4rpx 20rpx rgba(201, 160, 220, 0.3);
transition: all 0.3s ease;
}
.btn-hover {
transform: scale(0.98);
opacity: 0.9;
}

29
utils/questionType.js Normal file
View File

@ -0,0 +1,29 @@
function getQuestionType(question) {
if (!question) return "综合问题";
if (/爱|恋|关系|复合|分手|对象|感情|桃花|结婚|老公|老婆|男友|女友/.test(question)) {
return "感情关系";
}
if (/工作|事业|面试|跳槽|职场|公司|升职|离职|创业|项目/.test(question)) {
return "事业工作";
}
if (/钱|收入|财务|投资|赚钱|债|工资|薪水|理财/.test(question)) {
return "金钱财务";
}
if (/学习|考试|上岸|成绩|学校|考研|留学|进修/.test(question)) {
return "学业成长";
}
if (/健康|身体|状态|焦虑|压力|睡眠|精神/.test(question)) {
return "健康状态";
}
return "综合问题";
}
module.exports = {
getQuestionType: getQuestionType
};

15
utils/spreadStory.js Normal file
View File

@ -0,0 +1,15 @@
function generateSpreadStory(cards) {
if (!cards || cards.length < 2) {
return "";
}
const names = cards.map(c => c.name).join("、");
return "从整体牌阵来看,你当前的经历更像是一个逐步发展的过程。" +
"这些牌(" + names + ")并不是孤立存在的,而是在描述一个连续的变化。" +
"它提示你关注事情的发展方向,而不仅仅是单一阶段。";
}
module.exports = {
generateSpreadStory: generateSpreadStory
};