feat: AI 打字机流式输出、小程序脚本主页布局及灵感卡片优化

- life-script: 新增 aiRuntime 打字机流式服务,PathView/ScriptView/TimelineView 接入打字机效果
- mini-program: ScriptView 重构为打字机输出 + 卡片式灵感列表,主页布局优化
- web: aiRuntime 服务新增流式输出支持
- chat store: 消息状态管理和打字机流式渲染支持

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-24 18:35:33 +08:00
parent c900f56174
commit 64476eee6d
21 changed files with 1474 additions and 205 deletions
+6 -6
View File
@@ -1,9 +1,9 @@
<template>
<view class="profile-page">
<view class="space-bg"></view>
<view class="status-space" :style="{ height: statusBarHeight + 'px' }"></view>
<view class="status-space" :style="{ height: capsuleTopReservePx + 'px' }"></view>
<view class="topbar">
<view class="topbar" :style="topbarStyle">
<text class="back" @click="goBack"></text>
<text class="title">编辑资料 <text class="gold"></text></text>
<text class="save" @click="saveProfile">保存</text>
@@ -185,9 +185,10 @@
<script setup>
import { computed, onMounted, reactive, ref } from 'vue'
import { useAppStore } from '../../stores/app.js'
import { useMenuButtonSafeArea } from '../../composables/useMenuButtonSafeArea.js'
const store = useAppStore()
const statusBarHeight = ref(20)
const { capsuleTopReservePx, topbarStyle } = useMenuButtonSafeArea({ extraTopPx: 10 })
const isEdit = ref(false)
const saving = ref(false)
const birthday = ref('')
@@ -321,17 +322,16 @@ const saveProfile = async () => {
uni.showToast({ title: '已保存', icon: 'success' })
setTimeout(() => {
if (isEdit.value) uni.navigateBack()
else uni.reLaunch({ url: '/pages/main/index' })
else uni.reLaunch({ url: '/pages/main/index?tab=script' })
}, 350)
}
const goBack = () => {
if (isEdit.value) uni.navigateBack()
else uni.reLaunch({ url: '/pages/main/index' })
else uni.reLaunch({ url: '/pages/main/index?tab=script' })
}
onMounted(() => {
statusBarHeight.value = uni.getStorageSync('statusBarHeight') || 20
const pages = getCurrentPages()
isEdit.value = pages[pages.length - 1]?.options?.edit === '1'
syncFromStore()