优化: miniapp 设置页支持编辑 + 移除 Ideas 批量删除功能

This commit is contained in:
lxy
2026-08-08 14:19:59 +08:00
parent 92903702e2
commit 795e05f42d
4 changed files with 135 additions and 119 deletions
+134 -12
View File
@@ -1,13 +1,14 @@
<script setup lang="ts">
import { computed } from 'vue'
import { getConfig } from '@/config'
import { computed, ref } from 'vue'
import { getConfig, setConfig } from '@/config'
import { useAiChat } from '@/composables/useAiChat'
/**
* 设置页(只读查看,不编辑)。
* 设置页(连接配置查看/编辑 + 连接状态 + 连接操作)。
*
* 展示当前连接配置 + 连接状态,用户据此核对/排查问题。
* 编辑功能后续做(relayHost/deviceId/token 手填)或走二维码配对(分发阶段)。
* 默认查看模式(只读展示 relayHost/deviceId/token,token 脱敏);点「编辑」进入编辑模式,
* 保存时 setConfig 持久化并 resumeIfDisconnected 用新配置重连。连接态可「断开」,
* 断开态可「重连」,另展示最近状态详情(wsStatusDetail)辅助排查。
*
* 数据源:
* - 连接配置:config.ts getConfig()(storage 持久化,含默认值合并)
@@ -21,6 +22,7 @@ const cfg = computed(() => getConfig())
// 连接状态(实时,useAiChat 单例 ref 直接响应)
const ai = useAiChat()
const wsStatus = computed(() => ai.wsStatus.value)
const wsStatusDetail = computed(() => ai.wsStatusDetail.value)
const deviceOnline = computed(() => ai.deviceOnline.value)
const isWsConnected = computed(() => ai.isWsConnected.value)
@@ -58,11 +60,56 @@ function fmtMs(ms: number): string {
/** 版本号(对齐 manifest.json versionName,改版时同步) */
const APP_VERSION = '0.1.0'
/** 手动重连(断开/重连中可点,复用 ai.resumeIfDisconnected) */
/** 手动重连(断开态可点)。用 ai.connect() 而非 resumeIfDisconnected:
* 用户先点「断开」(manualClose=true)后 resumeIfDisconnected 会因 manualClose 早退,
* connect() 复位 manualClose 强制开新连接(非连接态才生效,连接态自动幂等跳过)。 */
function onReconnect(): void {
if (wsStatus.value === 'disconnected' || wsStatus.value === 'reconnecting') {
ai.resumeIfDisconnected()
ai.connect()
}
/** 手动断开(连接态可点,disconnect 置 manualClose 后不再自动重连) */
function onDisconnect(): void {
ai.disconnect()
uni.showToast({ title: '已断开连接', icon: 'none' })
}
/** 连接操作按钮入口(连接态→断开,断开态→重连) */
function onConnOp(): void {
if (isWsConnected.value) onDisconnect()
else onReconnect()
}
/** 编辑态(false=查看模式,true=编辑模式;草稿保存时才 setConfig,取消丢弃) */
const editing = ref(false)
const draftRelayHost = ref('')
const draftDeviceId = ref('')
const draftToken = ref('')
/** 进入编辑模式:以当前配置填充草稿 */
function enterEdit(): void {
draftRelayHost.value = cfg.value.relayHost
draftDeviceId.value = cfg.value.deviceId
draftToken.value = cfg.value.token
editing.value = true
}
/** 取消编辑:丢弃草稿回查看模式(不保存) */
function cancelEdit(): void {
editing.value = false
}
/** 保存编辑:setConfig 持久化 + 提示 + resumeIfDisconnected 用新配置重连 */
function saveEdit(): void {
const relayHost = draftRelayHost.value.trim()
const deviceId = draftDeviceId.value.trim()
if (!relayHost || !deviceId) {
uni.showToast({ title: '中继地址和设备 ID 不能为空', icon: 'none' })
return
}
setConfig({ relayHost, deviceId, token: draftToken.value.trim() })
editing.value = false
uni.showToast({ title: '已保存,正在重连…', icon: 'none' })
ai.resumeIfDisconnected()
}
</script>
@@ -81,21 +128,41 @@ function onReconnect(): void {
<text class="row-label">中继地址</text>
<text class="row-value mono">{{ cfg.relayHost }}</text>
</view>
<view class="row" v-if="wsStatusDetail">
<text class="row-label">最近状态</text>
<text class="row-value">{{ wsStatusDetail }}</text>
</view>
<view class="ops">
<view class="btn btn-block" :class="isWsConnected ? 'btn-danger' : 'btn-primary'" @tap="onConnOp">
{{ isWsConnected ? '断开' : '重连' }}
</view>
</view>
</view>
<!-- 连接配置(只读展示,编辑后续做) -->
<!-- 连接配置(查看/编辑双模式:编辑可改 relayHost/deviceId/token) -->
<view class="card">
<view class="card-head">
<text class="card-title">连接配置</text>
<text class="card-sub">只读 · 编辑后续开放</text>
<view v-if="editing" class="card-actions">
<text class="btn btn-sm btn-ghost" @tap="cancelEdit">取消</text>
<text class="btn btn-sm btn-primary" @tap="saveEdit">保存</text>
</view>
<text v-else class="btn btn-sm btn-ghost" @tap="enterEdit">编辑</text>
</view>
<view class="row">
<text class="row-label">中继地址</text>
<input v-if="editing" v-model="draftRelayHost" class="row-input" placeholder="ws://…/ws/miniapp" placeholder-class="row-ph" />
<text v-else class="row-value mono">{{ cfg.relayHost }}</text>
</view>
<view class="row">
<text class="row-label">设备 ID</text>
<text class="row-value mono">{{ cfg.deviceId }}</text>
<input v-if="editing" v-model="draftDeviceId" class="row-input" placeholder="桌面端设备 ID" placeholder-class="row-ph" />
<text v-else class="row-value mono">{{ cfg.deviceId }}</text>
</view>
<view class="row">
<text class="row-label">配对 Token</text>
<text class="row-value mono">{{ maskToken(cfg.token) }}</text>
<input v-if="editing" v-model="draftToken" class="row-input" placeholder="配对 token" placeholder-class="row-ph" />
<text v-else class="row-value mono">{{ maskToken(cfg.token) }}</text>
</view>
</view>
@@ -197,4 +264,59 @@ function onReconnect(): void {
.st-wait { color: $uni-color-primary; }
.st-warn { color: #f0c75e; }
.st-err { color: #e85a4f; }
/* 连接操作按钮(连接状态卡:重连/断开) */
.ops {
margin-top: 8rpx;
}
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 8rpx 24rpx;
font-size: $uni-font-size-sm;
line-height: 1.6;
border-radius: 10rpx;
}
.btn-block {
display: block;
padding: 20rpx 32rpx;
text-align: center;
}
.btn-primary {
background-color: $uni-color-primary;
color: #fff;
}
.btn-danger {
background-color: #e85a4f;
color: #fff;
}
.btn-ghost {
color: $uni-color-primary;
border: 1rpx solid $uni-color-primary;
background-color: transparent;
}
/* 卡片头部按钮组(编辑/取消/保存) */
.card-actions {
display: flex;
flex-direction: row;
align-items: center;
}
.card-actions .btn {
margin-left: 16rpx;
}
.btn-sm {
padding: 4rpx 20rpx;
}
/* 编辑态输入(label 左 + input 右,横向一行对齐 .row-value) */
.row-input {
flex: 1;
margin-left: 24rpx;
font-size: $uni-font-size-sm;
color: $uni-text-color;
text-align: right;
}
.row-ph {
color: $uni-text-color-disable;
}
</style>