feat: P1 合盘/星座/问答与测测完整设计包及模拟器取证工具
落地 synastry/star/ask API 与 H5 页面,补齐 cece-frontend-re complete-design 证据文档,并加入 Android 模拟器截图抓取脚本。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<main class="yxg-page">
|
||||
<div class="yxg-hero">
|
||||
<BackButton />
|
||||
<PageTitle feature="growth" title="成长计划" sub="小目标 · 每日打卡(生活成长,非运势)" />
|
||||
</div>
|
||||
|
||||
<div class="yxg-sheet">
|
||||
<div class="yxg-card">
|
||||
<label class="yxg-label">新计划标题</label>
|
||||
<input class="yxg-input" v-model="title" maxlength="40" placeholder="例如:每晚 11 点前放下手机" />
|
||||
<label class="yxg-label">焦点(可选)</label>
|
||||
<input class="yxg-input" v-model="focus" maxlength="80" placeholder="例如:保护睡眠与情绪" />
|
||||
<button class="yxg-btn" type="button" :disabled="saving || !title.trim()" @click="create">创建计划</button>
|
||||
<p v-if="err" class="yxg-err">{{ err }}</p>
|
||||
</div>
|
||||
|
||||
<p v-if="loading" class="yxg-hint pad">加载中…</p>
|
||||
<ul v-else class="yxg-list plans">
|
||||
<li v-for="p in plans" :key="p.id" class="plan">
|
||||
<strong>▽ {{ p.title }}</strong>
|
||||
<p v-if="p.focus" class="focus">{{ p.focus }}</p>
|
||||
<button type="button" class="yxg-btn yxg-btn-ghost" :disabled="checking === p.id" @click="checkin(p.id)">
|
||||
{{ checking === p.id ? '记录中…' : '今日打卡' }}
|
||||
</button>
|
||||
<ul v-if="checkins[p.id]?.length" class="cks">
|
||||
<li v-for="c in checkins[p.id]" :key="c.id">{{ c.day }}{{ c.note ? ' · ' + c.note : '' }}</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li v-if="!plans.length" class="empty">还没有计划,先创建一个小目标吧。</li>
|
||||
</ul>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { api } from '../api/client'
|
||||
import BackButton from '../components/BackButton.vue'
|
||||
import PageTitle from '../components/PageTitle.vue'
|
||||
|
||||
const plans = ref<{ id: string; title: string; focus: string }[]>([])
|
||||
const checkins = ref<Record<string, { id: string; day: string; note?: string }[]>>({})
|
||||
const title = ref('')
|
||||
const focus = ref('')
|
||||
const loading = ref(true)
|
||||
const saving = ref(false)
|
||||
const checking = ref('')
|
||||
const err = ref('')
|
||||
|
||||
async function load() {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await api.listGrowthPlans()
|
||||
plans.value = res.items || []
|
||||
for (const p of plans.value) {
|
||||
const ck = await api.listGrowthCheckins(p.id)
|
||||
checkins.value[p.id] = ck.items || []
|
||||
}
|
||||
} catch (e) {
|
||||
err.value = e instanceof Error ? e.message : '加载失败'
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function create() {
|
||||
saving.value = true
|
||||
err.value = ''
|
||||
try {
|
||||
await api.createGrowthPlan({ title: title.value.trim(), focus: focus.value.trim() || undefined })
|
||||
title.value = ''
|
||||
focus.value = ''
|
||||
await load()
|
||||
} catch (e) {
|
||||
err.value = e instanceof Error ? e.message : '创建失败'
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function checkin(id: string) {
|
||||
checking.value = id
|
||||
err.value = ''
|
||||
try {
|
||||
await api.growthCheckin(id, {})
|
||||
const ck = await api.listGrowthCheckins(id)
|
||||
checkins.value[id] = ck.items || []
|
||||
} catch (e) {
|
||||
err.value = e instanceof Error ? e.message : '打卡失败'
|
||||
} finally {
|
||||
checking.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(load)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.yxg-card{margin-top:8px}
|
||||
.yxg-card .yxg-label:first-child{margin-top:0}
|
||||
.yxg-btn{margin-top:12px}
|
||||
.pad{padding:0 16px}
|
||||
.plans{list-style:none}
|
||||
.plan{display:block}
|
||||
.plan strong{font-size:15px;color:#222}
|
||||
.focus{font-size:13px;color:#888;margin:6px 0}
|
||||
.cks{margin-top:8px;padding-left:16px;font-size:12px;color:#999}
|
||||
.empty{color:#999;font-size:13px;padding:8px 4px}
|
||||
</style>
|
||||
Reference in New Issue
Block a user