refactor(ECR-005): 再拆 Ask/Decode/Portrait 与 composable,补强 OpenAPI
ci / h5 (push) Canceled after 0s
ci / api (push) Canceled after 0s
ci / ess-docs (push) Canceled after 0s

压低贴线 SFC/composable;报告/档案/量表/意象卡 path 挂 Envelope $ref;CI ESS 门禁跟到 ECR-005。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-05 22:38:32 +08:00
co-authored by Cursor
parent 7034c92de7
commit 00fc7f82b9
31 changed files with 2017 additions and 1251 deletions
@@ -0,0 +1,95 @@
<template>
<div class="composer-wrap">
<p v-if="quota" class="quota">
剩余 {{ quota.remaining }}
<span v-if="!quota.active_membership">免费 {{ quota.free_limit }}</span>
</p>
<form class="composer" @submit.prevent="$emit('send')">
<textarea
class="ta"
:value="draft"
rows="2"
placeholder="让我来解答你的问题吧"
:disabled="sending || (quota !== null && quota.remaining <= 0)"
@input="$emit('update:draft', ($event.target as HTMLTextAreaElement).value)"
/>
<button
class="send"
type="submit"
:disabled="sending || !draft.trim() || (quota !== null && quota.remaining <= 0)"
>
发送
</button>
</form>
<p class="ai-note">部分内容由 AI 生成仅供参考</p>
</div>
</template>
<script setup lang="ts">
import type { AskQuota } from '@yuxingu/types'
defineProps<{
draft: string
sending: boolean
quota: AskQuota | null
}>()
defineEmits<{
'update:draft': [v: string]
send: []
}>()
</script>
<style scoped>
.composer-wrap {
position: sticky;
bottom: 72px;
padding-top: 8px;
background: linear-gradient(180deg, transparent, var(--color-bg-sheet) 24%);
}
.quota {
font-size: 11px;
color: #aaa;
margin-bottom: 6px;
}
.composer {
display: flex;
gap: 8px;
align-items: flex-end;
}
.ta {
flex: 1;
resize: none;
min-height: 44px;
padding: 11px 14px;
border-radius: 16px;
border: 1.5px solid #eee;
background: #fff;
font-size: 14px;
font-family: inherit;
outline: none;
}
.ta:focus {
border-color: #f0b8b0;
}
.send {
flex-shrink: 0;
padding: 11px 16px;
border: none;
border-radius: 22px;
color: #fff;
font-size: 14px;
font-weight: 600;
background: linear-gradient(135deg, #ff7a6e, var(--color-primary));
box-shadow: 0 6px 16px rgba(229, 77, 66, 0.28);
}
.send:disabled {
opacity: 0.45;
}
.ai-note {
margin-top: 8px;
font-size: 10px;
color: #ccc;
text-align: center;
}
</style>