Files
digital-psychology/apps/user-h5/src/pages/ImageCardPage.vue
T
jackyu66gitandCursor 0158036341 feat(ECR-045): ImageCardDeck 写面闭环并 Closed
复用 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>
2026-08-13 21:29:43 +08:00

164 lines
3.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>