feat: 小程序统一走 Go 后台,咨询与登录切到 /api/v1
去掉协会 WebView 和魔方账密页,微信登录与咨询接口共用同一 token 和拦截器。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<yxg-page title="成长报告">
|
||||
<scroll-view class="chips" scroll-x>
|
||||
<view v-for="f in filters" :key="f.key" class="chip" :class="{ on: filter === f.key }" @click="filter = f.key">
|
||||
<text>{{ f.label }}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="vip" @click="yxgGo('/membership')">
|
||||
<text class="vip-t">成长会员</text>
|
||||
<text class="vip-s">解锁全部深度报告与节气陪伴 ›</text>
|
||||
</view>
|
||||
<text v-if="loading" class="hint">加载中…</text>
|
||||
<text v-else-if="error" class="err" @click="load">{{ error }} · 重试</text>
|
||||
<view v-else-if="!filtered.length" class="empty">
|
||||
<text>还没有{{ filter === 'all' ? '' : '该类' }}成长报告</text>
|
||||
<view class="btn" @click="yxgGo('/explore')"><text>去探索</text></view>
|
||||
</view>
|
||||
<view v-else class="list">
|
||||
<view v-for="r in filtered" :key="r.id" class="row" @click="yxgGo(`/reports/${r.id}`)">
|
||||
<yxg-tool-icon :name="toolIconFor(r.type)" :size="36" />
|
||||
<view class="body">
|
||||
<text class="t">{{ typeLabel(r.type) }}</text>
|
||||
<text class="d">{{ headlineOf(r) }}</text>
|
||||
<text class="m">{{ formatDate(r.created_at) }}</text>
|
||||
</view>
|
||||
<text class="chev">›</text>
|
||||
</view>
|
||||
</view>
|
||||
</yxg-page>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import YxgPage from '@/components/yxg/yxg-page.vue'
|
||||
import YxgToolIcon from '@/components/yxg/yxg-tool-icon.vue'
|
||||
import { yxgApi } from '@/util/yxgApi.js'
|
||||
import { ensureAccount } from '@/util/yxgAuth.js'
|
||||
import { formatDate, headlineOf, toolIconFor, typeLabel } from '@/util/yxgCatalog.js'
|
||||
import { yxgGo } from '@/util/yxgNav.js'
|
||||
|
||||
const filters = [
|
||||
{ key: 'all', label: '全部' },
|
||||
{ key: 'portrait', label: '解码' },
|
||||
{ key: 'star', label: '星座' },
|
||||
{ key: 'rhythm', label: '节律' },
|
||||
{ key: 'synastry', label: '合盘' },
|
||||
]
|
||||
const filter = ref('all')
|
||||
const items = ref([])
|
||||
const loading = ref(true)
|
||||
const error = ref('')
|
||||
const filtered = computed(() =>
|
||||
filter.value === 'all' ? items.value : items.value.filter((r) => r.type === filter.value),
|
||||
)
|
||||
|
||||
async function load() {
|
||||
loading.value = true
|
||||
error.value = ''
|
||||
if (!(await ensureAccount('/reports'))) {
|
||||
loading.value = false
|
||||
return
|
||||
}
|
||||
try {
|
||||
const res = await yxgApi.listReports()
|
||||
items.value = res.items || []
|
||||
} catch (e) {
|
||||
error.value = e instanceof Error ? e.message : '加载失败'
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onShow(load)
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page { background-color: #ffd1c7; }
|
||||
</style>
|
||||
<style scoped>
|
||||
.chips { white-space: nowrap; padding: 8px 16px; }
|
||||
.chip {
|
||||
display: inline-block; margin-right: 8px; padding: 6px 12px; border-radius: 999px;
|
||||
background: #fff; font-size: 13px; color: #666;
|
||||
}
|
||||
.chip.on { background: #e54d42; color: #fff; }
|
||||
.vip {
|
||||
margin: 0 16px 8px; padding: 12px 14px; border-radius: 14px;
|
||||
background: linear-gradient(145deg, #fff4e0, #ffd98a);
|
||||
}
|
||||
.vip-t { display: block; font-weight: 700; color: #8a5a18; }
|
||||
.vip-s { display: block; font-size: 12px; color: #a07838; margin-top: 2px; }
|
||||
.list { margin: 0 16px; background: #fff; border-radius: 16px; }
|
||||
.row { display: flex; align-items: center; gap: 12px; padding: 14px; border-bottom: 1px solid #f5f5f5; }
|
||||
.row:last-child { border-bottom: none; }
|
||||
.body { flex: 1; min-width: 0; }
|
||||
.t { display: block; font-size: 15px; font-weight: 650; color: #222; }
|
||||
.d { display: block; font-size: 12px; color: #666; margin-top: 2px; }
|
||||
.m { display: block; font-size: 11px; color: #bbb; margin-top: 2px; }
|
||||
.chev { color: #ccc; }
|
||||
.hint, .err, .empty { display: block; padding: 16px; font-size: 13px; color: #999; text-align: center; }
|
||||
.err { color: #e54d42; }
|
||||
.btn {
|
||||
margin: 12px auto 0; width: 140px; height: 40px; border-radius: 999px; background: #e54d42; color: #fff;
|
||||
display: flex; align-items: center; justify-content: center; font-weight: 700;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user