feat: 小程序统一走 Go 后台,咨询与登录切到 /api/v1

去掉协会 WebView 和魔方账密页,微信登录与咨询接口共用同一 token 和拦截器。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-09-15 00:26:28 +08:00
co-authored by Cursor
parent 6e97f01378
commit b09d82df8d
40 changed files with 3852 additions and 285 deletions
+77
View File
@@ -0,0 +1,77 @@
<template>
<yxg-page :title="cat?.title || '分类'">
<view class="head">
<yxg-tool-icon :name="heroIcon" :size="40" />
<view>
<text class="title">{{ cat?.title || '分类' }}</text>
<text v-if="cat" class="sub">{{ cat.description }}</text>
</view>
</view>
<text v-if="loading" class="hint">加载中</text>
<text v-else-if="error" class="err">{{ error }}</text>
<view v-else-if="cat" class="list">
<view v-for="it in cat.items" :key="it.key" class="row" @click="yxgGo(it.path)">
<yxg-tool-icon :name="toolIconFor(it.path || it.key)" :size="36" />
<view class="row-body">
<text class="row-t">{{ it.title }}</text>
<text class="row-d">{{ it.description }}</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 { toolIconFor } from '@/util/yxgCatalog.js'
import { yxgGo } from '@/util/yxgNav.js'
const category = ref('')
const cat = ref(null)
const loading = ref(true)
const error = ref('')
const heroIcon = computed(() => toolIconFor(cat.value?.key || category.value || 'explore'))
async function load() {
loading.value = true
error.value = ''
if (!(await ensureAccount(`/explore/${category.value}`))) {
loading.value = false
return
}
try {
cat.value = await yxgApi.getExploreCategory(category.value)
} catch (e) {
error.value = e instanceof Error ? e.message : '加载失败'
} finally {
loading.value = false
}
}
onLoad((q) => {
category.value = q.category || ''
load()
})
</script>
<style>
page { background-color: #ffd1c7; }
</style>
<style scoped>
.head { display: flex; align-items: center; gap: 12px; padding: 8px 16px; }
.title { display: block; font-size: 20px; font-weight: 700; color: #333; }
.sub { display: block; font-size: 12px; color: #999; margin-top: 2px; }
.list { margin: 8px 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; }
.row-body { flex: 1; min-width: 0; }
.row-t { display: block; font-size: 15px; font-weight: 650; color: #222; }
.row-d { display: block; font-size: 12px; color: #999; margin-top: 2px; }
.chev { color: #ccc; }
.hint, .err { display: block; padding: 16px; font-size: 13px; color: #999; }
.err { color: #e54d42; }
</style>