业务功能开发指南
业务功能开发指南
新增功能先复用同一业务模块中的页面、API 和组件。平台能力通过契约使用,业务逻辑留在 Saber-AI。
1. 确定页面形态
| 形态 | 现有实现 |
|---|---|
| 卡片或表格列表 | basic-container 与对应 Avue 配置 |
| 多页签工作区 | components/workspace/detail |
| 对话页面 | components/chat 与协议、提供者 |
| 流程设计器 | components/canvas 与 engine/canvas |
| 创作项目 | 对应 studio 工作区与领域模块 |
2. 补齐模块文件
按实际需要添加 types、const、api、option 和 views,保持一级业务目录一致。跨模块公共组件进入 components,单页私有模块留在页面目录。
页面采用 <script setup lang="ts">。实体和表单使用实际字段类型,方法按本工程现有风格声明。可复用字典集中放在 const,不在多处重复维护。
3. 注册入口与权限
在 src/remote.ts 增加懒加载路由,为中英文语言包补齐标题。同步 src/dev/menus.json 和所需开发按钮清单。宿主菜单与后端权限码按 路由菜单与权限控制 配置。
4. 示例:新增提示词速查页
该页面复用现有提示词列表与详情接口,提供名称检索、分页和正文预览,不新增后端实体或写入操作。
4.1 复用类型与接口
类型使用 src/types/model.ts 中的 Prompt。接口使用 src/api/model/prompt.ts 已有函数,形状如下,无需另外创建请求实例:
import request from '@saber/micro/http';
export const getList = (current: number, size: number, params?: object) =>
request({
url: '/blade-ai/prompt/list',
method: 'get',
params: { ...params, current, size },
});
export const getDetail = (id: string) =>
request({ url: '/blade-ai/prompt/detail', method: 'get', params: { id } });getList 的分页数据位于 res.data.data,包含 records 和 total;详情数据同样位于 res.data.data。管理接口使用宿主会话,与开放接口的 Bearer API 密钥分别处理。
4.2 编写页面
新增 src/views/model/promptreview/promptreview.vue:
<template>
<basic-container>
<el-form inline @submit.prevent="search">
<el-form-item :label="t.promptReview.name()">
<el-input v-model="name" clearable />
</el-form-item>
<el-form-item>
<el-button type="primary" native-type="submit" :loading="loading">
{{ $t('button.search') }}
</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="rows">
<el-table-column prop="name" :label="t.promptReview.name()" min-width="180" />
<el-table-column prop="type" :label="t.promptReview.type()" width="140" />
<el-table-column :label="t.promptReview.preview()" width="100">
<template #default="{ row }">
<el-button
v-if="hasPermission('ai_prompt_view')"
link
type="primary"
@click="preview(row)"
>{{ t.promptReview.preview() }}</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
v-model:current-page="current"
:page-size="size"
:total="total"
layout="prev, pager, next, total"
@current-change="load"
/>
<el-dialog v-model="visible" :title="detail?.name" width="720">
<pre class="ai-prompt-review__content">{{ detail?.content }}</pre>
</el-dialog>
</basic-container>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { getDetail, getList } from '@/api/model/prompt';
import type { Prompt } from '@/types/model';
import { t } from '@/lang';
defineOptions({ name: 'aiPromptReview' });
const name = ref('');
const rows = ref<Prompt[]>([]);
const current = ref(1);
const size = 12;
const total = ref(0);
const loading = ref(false);
const detail = ref<Prompt>();
const visible = ref(false);
const load = async () => {
loading.value = true;
try {
const response = await getList(current.value, size, { name: name.value.trim() });
const page: { records: Prompt[]; total: number | string } = response.data.data;
rows.value = page.records;
total.value = Number(page.total);
} finally {
loading.value = false;
}
};
const search = () => {
current.value = 1;
load();
};
const preview = async (row: Prompt) => {
const response = await getDetail(row.id);
detail.value = response.data.data;
visible.value = true;
};
onMounted(load);
</script>
<style scoped>
.ai-prompt-review__content {
margin: 0;
white-space: pre-wrap;
overflow-wrap: anywhere;
color: var(--blade-text-primary);
font: inherit;
}
</style>错误提示由平台请求拦截链统一处理,finally 只负责复位加载状态。提示词以文本插值展示,正文中的 HTML 不执行。
4.3 注册路由与语言包
在 src/remote.ts 的路由数组中增加叶子路由,沿用已有 leaf 帮助函数:
leaf(
`${p}/model/prompt-review`,
'ai-prompt-review',
() => import('./views/model/promptreview/promptreview.vue'),
'ai_prompt_view'
),leaf 统一写入 meta.remote、meta.i18n 与查看权限码。远端通过 routes 返回路由数组,由宿主统一创建路由并注册;页面以懒加载方式导入。
在语言包对应对象中分别合并以下键,保留其他字段:
// src/lang/zh.ts
route: { 'ai-prompt-review': '提示词速查' },
promptReview: { name: '名称', type: '分类', preview: '预览' },
// src/lang/en.ts
route: { 'ai-prompt-review': 'Prompt Reference' },
promptReview: { name: 'Name', type: 'Category', preview: 'Preview' },4.4 配置菜单与权限
在 src/dev/menus.json 的“模型中心”子菜单中增加:
{"name":"提示词速查","path":"/ai/model/prompt-review","source":"iconfont icon-yinyong"}示例复用已有的 ai_prompt_view,开发外壳的权限清单已包含此项。宿主环境在后端菜单中登记同一路径、配置排序并授权角色后,页面出现在宿主侧栏。新功能若增加独立操作,同步定义按钮码、开发权限清单与后端授权检查;按钮隐藏只影响界面展示,访问控制以后端授权检查为准。
5. 执行工程检查
首次检查或宿主依赖变化后,先在 Saber 执行:
pnpm run matrix在 Saber-AI 执行:
pnpm run verify该命令依次执行类型检查、ESLint 与 Stylelint、单元测试、依赖方向与资源地址检查、共享版本检查、联邦及分享构建、产物检查。
| 检查范围 | 核心要求 |
|---|---|
| 路由与契约 | 远端标识、标题、查看权限和菜单匹配 |
| 共享依赖 | 与宿主矩阵一致,契约运行时单例 |
| 联邦产物 | 唯一出口 ./remote,manifest 带版本和 buildId,无开发 index.html |
| 分享产物 | 单独生成 dist/share/ |
6. 复查实际页面
先在 1881 开发外壳中验证页面,再装入 1888 宿主检查菜单、高亮、标签、详情刷新和返回。涉及模型、知识或媒体服务的页面连接真实服务核对结果;持有流式连接、定时器或事件订阅的页面,检查离开后是否释放。
