forked from admin/PlantAI-rag-new
feat(ui): 右上角生信跳转按钮+四按钮文字标签
- TopBar 新增「生信」按钮(仅生信模块不可用时显示):点击开新窗访问 PlantAI-dev(当前主机名:9017,公网/内网自适应) - 扩展/生信/设置/主题四按钮配文字标签(图标+文字并排,宽度自适应) - 新增 deploy/toggle_bioflow_176.sh <off|on>:一键开关 176 生信模块 (改 BIOFLOW_ENABLED + 重启 BFF;off 时 /api/bioflow/health 404, 前端生信 TAB 自动隐藏) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
# deploy/toggle_bioflow_176.sh —— 176 生信模块快速开关(off/on)
|
||||
# 用法(在 176 上执行,或从 175 ssh 过去执行):
|
||||
# bash /srv/plantai/toggle_bioflow_176.sh off # 关生信:env=false + 重启 BFF → 生信 TAB/入口消失
|
||||
# bash /srv/plantai/toggle_bioflow_176.sh on # 开生信:env=true + 重启 BFF → 生信 TAB 恢复
|
||||
# 原理:BFF main.py 按 BIOFLOW_ENABLED 决定是否注册 bioflow 反代路由;
|
||||
# 不注册时 /api/bioflow/health 返回 404,前端 probe 落 offline,生信 TAB 自动隐藏。
|
||||
set -uo pipefail
|
||||
|
||||
ACTION="${1:-}"
|
||||
ENV_FILE="/srv/plantai/install/sdk/.env"
|
||||
PY="/srv/plantai/install/venv/bin/python"
|
||||
|
||||
if [ "$ACTION" != "off" ] && [ "$ACTION" != "on" ]; then
|
||||
echo "用法: $0 <off|on>" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
VAL="true"
|
||||
[ "$ACTION" = "off" ] && VAL="false"
|
||||
|
||||
# 1. 改 env
|
||||
if grep -q "^BIOFLOW_ENABLED=" "$ENV_FILE"; then
|
||||
sed -i "s/^BIOFLOW_ENABLED=.*/BIOFLOW_ENABLED=$VAL/" "$ENV_FILE"
|
||||
else
|
||||
echo "BIOFLOW_ENABLED=$VAL" >> "$ENV_FILE"
|
||||
fi
|
||||
echo "BIOFLOW_ENABLED -> $VAL"
|
||||
|
||||
# 2. 重启 BFF 8090(仅取 LISTEN 者;venv 必须绝对路径,cd sdk 后才能 import app.main)
|
||||
kill $(lsof -ti tcp:8090 -sTCP:LISTEN) 2>/dev/null
|
||||
sleep 2
|
||||
cd /srv/plantai/install && set -a && . sdk/.env && set +a
|
||||
( cd sdk && setsid "$PY" -m uvicorn app.main:app --host 127.0.0.1 --port 8090 \
|
||||
> /tmp/plantai-sdk.log 2>&1 < /dev/null & ) && disown -a
|
||||
|
||||
# 3. 自检
|
||||
for i in $(seq 1 20); do
|
||||
sleep 2
|
||||
curl -s -m 3 http://127.0.0.1:8090/api/health >/dev/null 2>&1 && break
|
||||
done
|
||||
curl -s -m 10 http://127.0.0.1:8090/api/health | head -c 150
|
||||
echo
|
||||
if [ "$ACTION" = "off" ]; then
|
||||
CODE=$(curl -s -o /dev/null -w "%{http_code}" -m 8 http://127.0.0.1:8090/api/bioflow/health)
|
||||
echo "bioflow/health HTTP $CODE (off 期望 404)"
|
||||
[ "$CODE" = "404" ] && echo "OFF_OK" || echo "OFF_CHECK_FAIL"
|
||||
else
|
||||
curl -s -m 8 http://127.0.0.1:8090/api/bioflow/health | head -c 150
|
||||
echo
|
||||
fi
|
||||
@@ -13,6 +13,7 @@ import { computed, onMounted, ref } from 'vue';
|
||||
import { APP_NAME, STATUS_LABEL, T } from '../../i18n/labels.js';
|
||||
import { BF } from '../../i18n/bioflow.js';
|
||||
import { useThemeStore } from '../../stores/theme.js';
|
||||
import { useBioflowStore } from '../../stores/bioflow.js';
|
||||
|
||||
const props = defineProps({
|
||||
/** 当前会话标题(无会话为 null → 显示「就绪」徽章) */
|
||||
@@ -34,6 +35,11 @@ const emit = defineEmits(['menu', 'bench', 'close-bench', 'goto-extensions', 'go
|
||||
/* ---------- 主题 ---------- */
|
||||
const themeStore = useThemeStore();
|
||||
|
||||
/* ---------- 生信可用性(右上角生信跳转按钮显隐;=== 'online' 避免 unknown 闪现) ---------- */
|
||||
const bioflowStore = useBioflowStore();
|
||||
const bioflowOnline = computed(() => bioflowStore.availability === 'online');
|
||||
const bioflowStatus = computed(() => bioflowStore.availability);
|
||||
|
||||
/* ---------- B2/B3 store 数据(动态导入 + 空值守卫) ---------- */
|
||||
const chatStore = ref(null);
|
||||
const benchStore = ref(null);
|
||||
@@ -134,6 +140,12 @@ function onMenu() {
|
||||
function onBench() {
|
||||
emit('bench');
|
||||
}
|
||||
/** 生信跳转(2026-09-16):开新窗口访问 PlantAI-dev(9017);主机名跟随当前访问地址自适应 */
|
||||
function openBioflowDev() {
|
||||
const devUrl = window.location.protocol + '//' + window.location.hostname + ':9017/';
|
||||
window.open(devUrl, '_blank', 'noopener');
|
||||
}
|
||||
|
||||
function onToggleTheme() {
|
||||
themeStore.toggle();
|
||||
}
|
||||
@@ -147,6 +159,7 @@ const iconClose = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" st
|
||||
// 右上角快捷按钮图标(2026-09-15:会话/扩展/知识图谱/设置 自侧栏迁移)
|
||||
const iconRailExt = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2l2.4 4.9 5.4.8-3.9 3.8.9 5.4-4.8-2.5-4.8 2.5.9-5.4L4.2 7.7l5.4-.8z"/><path d="M20 14v5a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-5"/></svg>';
|
||||
const iconRailSettings = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .34 1.87l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.7 1.7 0 0 0-1.87-.34 1.7 1.7 0 0 0-1 1.55V21a2 2 0 1 1-4 0v-.09a1.7 1.7 0 0 0-1-1.55 1.7 1.7 0 0 0-1.87.34l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.7 1.7 0 0 0 .34-1.87 1.7 1.7 0 0 0-1.55-1H3a2 2 0 1 1 0-4h.09a1.7 1.7 0 0 0 1.55-1 1.7 1.7 0 0 0-.34-1.87l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.7 1.7 0 0 0 1.87.34h0a1.7 1.7 0 0 0 1-1.55V3a2 2 0 1 1 4 0v.09a1.7 1.7 0 0 0 1 1.55h0a1.7 1.7 0 0 0 1.87-.34l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.7 1.7 0 0 0-.34 1.87v0a1.7 1.7 0 0 0 1.55 1H21a2 2 0 1 1 0 4h-.09a1.7 1.7 0 0 0-1.55 1z"/></svg>';
|
||||
const iconRailBio = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 3c0 4-1.2 8.6-5 11"/><path d="M7 3c0 4 1.2 8.6 5 11"/><path d="M17 3c0 4 1.2 8.6 5 11"/><path d="M17 3c0 4-1.2 8.6-5 11"/><path d="M8.5 8h7"/><path d="M8 13.5h8"/><path d="M10.5 18h3"/></svg>';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -197,21 +210,29 @@ const iconRailSettings = '<svg viewBox="0 0 24 24" fill="none" stroke="currentCo
|
||||
<span v-if="!benchOverlayOpen && sourceCount != null" class="bench-btn-count">{{ sourceCount }}</span>
|
||||
</button>
|
||||
|
||||
<!-- 右上角快捷按钮(2026-09-15 自侧栏迁移;仅 desktop/laptop;三按钮同行右对齐) -->
|
||||
<!-- 右上角快捷按钮(2026-09-15 自侧栏迁移;仅 desktop/laptop;图标+文字同行右对齐) -->
|
||||
<template v-if="tier === 'desktop' || tier === 'laptop'">
|
||||
<button class="icon-btn top-rail-btn" type="button" :title="BF.extRailTitle" :aria-label="BF.extRailTitle"
|
||||
@click="$emit('goto-extensions')">
|
||||
<span v-html="iconRailExt"></span>
|
||||
<span class="rail-label">{{ BF.extRailTitle }}</span>
|
||||
</button>
|
||||
<!-- 生信跳转(2026-09-16:仅无生信模块时显示,开新窗访问 PlantAI-dev 9017) -->
|
||||
<button v-if="!bioflowOnline" class="icon-btn top-rail-btn" type="button" title="生信" aria-label="生信"
|
||||
@click="openBioflowDev">
|
||||
<span v-html="iconRailBio"></span>
|
||||
<span class="rail-label">生信</span>
|
||||
</button>
|
||||
<button class="icon-btn top-rail-btn" type="button" :title="T.railSettings" :aria-label="T.railSettings"
|
||||
@click="$emit('goto-settings')">
|
||||
<span v-html="iconRailSettings"></span>
|
||||
<span class="rail-label">{{ T.railSettings }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<!-- 主题切换(日月 SVG + rotate 180° 400ms,FR-THEME-002) -->
|
||||
<button
|
||||
class="icon-btn"
|
||||
class="icon-btn top-rail-btn"
|
||||
type="button"
|
||||
:title="themeStore.theme === 'dark' ? '切换到浅色主题' : '切换到深色主题'"
|
||||
:aria-label="themeStore.theme === 'dark' ? '切换到浅色主题' : '切换到深色主题'"
|
||||
@@ -220,6 +241,7 @@ const iconRailSettings = '<svg viewBox="0 0 24 24" fill="none" stroke="currentCo
|
||||
<span class="theme-toggle-anim" :class="{ flipped: themeStore.theme === 'dark' }">
|
||||
<span v-html="themeStore.theme === 'dark' ? iconSun : iconMoon"></span>
|
||||
</span>
|
||||
<span class="rail-label">主题</span>
|
||||
</button>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
+11
-1
@@ -119,8 +119,18 @@ html.drawer-open { overflow: hidden; }
|
||||
}
|
||||
.icon-btn svg { width: 16px; height: 16px; }
|
||||
.icon-btn:disabled { opacity: .45; cursor: not-allowed; }
|
||||
.top-rail-btn { margin-left: 2px; }
|
||||
.top-rail-btn {
|
||||
margin-left: 2px;
|
||||
width: auto;
|
||||
padding: 0 10px;
|
||||
gap: 6px;
|
||||
}
|
||||
.top-rail-btn > span { display: flex; align-items: center; justify-content: center; }
|
||||
.top-rail-btn .rail-label {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 状态徽章(pill,三编码:颜色+图标+文字,UI_SPEC §4.1 / PRD §2.1) */
|
||||
.badge {
|
||||
|
||||
Reference in New Issue
Block a user