复用 admin.explore.write、POST/PUT+审计、C端 GET /cards/decks、 H5 无 active 空态/失败回退;migration 000054。无牌面内容编辑。 ExploreConfig Loop STOP,禁自动 ECR-046。 Co-authored-by: Cursor <cursoragent@cursor.com>
164 lines
3.7 KiB
Vue
164 lines
3.7 KiB
Vue
<template>
|
||
<PageShell>
|
||
<template #hero>
|
||
<div class="head">
|
||
<HomeToolIcon name="cards" :size="48" />
|
||
<div>
|
||
<h1 class="title">意象卡片</h1>
|
||
<p class="sub">投射整理 · 自我反思</p>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<div class="body" :class="{ 'has-results': cards.length }">
|
||
<div v-if="!configAvailable && !cards.length" class="empty-gate">
|
||
<HomeToolIcon name="cards" :size="56" />
|
||
<p class="empty-title">意象牌组暂未开放</p>
|
||
<p class="empty-sub">运营尚未启用意象牌组,请稍后再来</p>
|
||
<button class="cta-off" type="button" disabled>抽取意象卡</button>
|
||
</div>
|
||
|
||
<template v-else>
|
||
<ImageCardGreeting
|
||
:boot-error="bootError"
|
||
:quota-label="quotaLabel"
|
||
:scene="scene"
|
||
/>
|
||
|
||
<ImageCardLanding
|
||
v-if="!cards.length"
|
||
v-model:want-depth="wantDepth"
|
||
v-model:show-birth="showBirth"
|
||
v-model:year="year"
|
||
v-model:month="month"
|
||
v-model:day="day"
|
||
:drawing="drawing"
|
||
@prompt-click="onPromptClick"
|
||
@draw="draw"
|
||
/>
|
||
|
||
<ImageCardResults
|
||
v-if="cards.length"
|
||
:cards="cards"
|
||
:report="report"
|
||
:summary="summary"
|
||
:detail="detail"
|
||
:want-depth="wantDepth"
|
||
:paying="paying"
|
||
@buy-deep="buyDeep"
|
||
/>
|
||
</template>
|
||
|
||
<p class="yxg-disc ai-note">意象卡片用于投射与自我反思,不判定好坏,也不预测未来。部分内容由 AI 生成,仅供参考。</p>
|
||
<p v-if="error" class="yxg-err err-float">{{ error }}</p>
|
||
</div>
|
||
|
||
<ImageCardInputBar
|
||
v-if="configAvailable && !cards.length"
|
||
v-model:question-input="questionInput"
|
||
:drawing="drawing"
|
||
@send="sendDraw"
|
||
/>
|
||
</PageShell>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import PageShell from '../components/PageShell.vue'
|
||
import HomeToolIcon from '../components/HomeToolIcon.vue'
|
||
import ImageCardGreeting from '../components/imagecard/ImageCardGreeting.vue'
|
||
import ImageCardInputBar from '../components/imagecard/ImageCardInputBar.vue'
|
||
import ImageCardLanding from '../components/imagecard/ImageCardLanding.vue'
|
||
import ImageCardResults from '../components/imagecard/ImageCardResults.vue'
|
||
import { useImageCardPage } from '../composables/useImageCardPage'
|
||
|
||
const {
|
||
scene,
|
||
configAvailable,
|
||
quotaLabel,
|
||
year,
|
||
month,
|
||
day,
|
||
wantDepth,
|
||
drawing,
|
||
paying,
|
||
error,
|
||
bootError,
|
||
cards,
|
||
report,
|
||
questionInput,
|
||
showBirth,
|
||
summary,
|
||
detail,
|
||
onPromptClick,
|
||
sendDraw,
|
||
draw,
|
||
buyDeep,
|
||
} = useImageCardPage()
|
||
</script>
|
||
|
||
<style scoped>
|
||
.head {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
margin-top: 8px;
|
||
padding-bottom: 8px;
|
||
}
|
||
.title {
|
||
font-family: var(--font-display);
|
||
font-size: 22px;
|
||
font-weight: 700;
|
||
letter-spacing: 0.06em;
|
||
color: var(--color-text-primary);
|
||
}
|
||
.sub {
|
||
margin-top: 2px;
|
||
font-size: 12px;
|
||
color: rgba(0, 0, 0, 0.38);
|
||
letter-spacing: 0.04em;
|
||
}
|
||
.body {
|
||
padding: 0 16px 88px;
|
||
}
|
||
.body.has-results {
|
||
padding-bottom: 24px;
|
||
}
|
||
.ai-note {
|
||
margin-top: 16px;
|
||
}
|
||
.err-float {
|
||
margin-top: 8px;
|
||
}
|
||
.empty-gate {
|
||
text-align: center;
|
||
padding: 28px 16px 12px;
|
||
}
|
||
.empty-title {
|
||
font-family: var(--font-display);
|
||
font-size: 20px;
|
||
font-weight: 700;
|
||
margin-top: 10px;
|
||
letter-spacing: 0.06em;
|
||
}
|
||
.empty-sub {
|
||
font-size: 13px;
|
||
color: rgba(0, 0, 0, 0.42);
|
||
margin-top: 8px;
|
||
line-height: 1.5;
|
||
}
|
||
.cta-off {
|
||
margin-top: 16px;
|
||
width: 100%;
|
||
max-width: 320px;
|
||
padding: 13px;
|
||
border: none;
|
||
border-radius: 22px;
|
||
color: #fff;
|
||
font-size: 15px;
|
||
font-weight: 600;
|
||
background: linear-gradient(135deg, #ff7a6e, var(--color-primary));
|
||
opacity: 0.45;
|
||
cursor: not-allowed;
|
||
}
|
||
</style>
|