@liujitcn/kratos-admin-system 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +137 -0
- package/dist/package/declarations/index.d.ts +1 -0
- package/dist/package/declarations/src/ai.d.ts +10 -0
- package/dist/package/declarations/src/api/base/ai_message.d.ts +27 -0
- package/dist/package/declarations/src/api/base/ai_session.d.ts +17 -0
- package/dist/package/declarations/src/api/base/ai_tool.d.ts +7 -0
- package/dist/package/declarations/src/api/base/oauth.d.ts +13 -0
- package/dist/package/declarations/src/api/base/sse.d.ts +31 -0
- package/dist/package/declarations/src/api/system/auth.d.ts +17 -0
- package/dist/package/declarations/src/api/system/base_api.d.ts +22 -0
- package/dist/package/declarations/src/api/system/base_area.d.ts +19 -0
- package/dist/package/declarations/src/api/system/base_config.d.ts +20 -0
- package/dist/package/declarations/src/api/system/base_dept.d.ts +21 -0
- package/dist/package/declarations/src/api/system/base_dict.d.ts +32 -0
- package/dist/package/declarations/src/api/system/base_job.d.ts +28 -0
- package/dist/package/declarations/src/api/system/base_log.d.ts +9 -0
- package/dist/package/declarations/src/api/system/base_menu.d.ts +21 -0
- package/dist/package/declarations/src/api/system/base_migration.d.ts +10 -0
- package/dist/package/declarations/src/api/system/base_post.d.ts +21 -0
- package/dist/package/declarations/src/api/system/base_role.d.ts +23 -0
- package/dist/package/declarations/src/api/system/base_tenant.d.ts +21 -0
- package/dist/package/declarations/src/api/system/base_user.d.ts +23 -0
- package/dist/package/declarations/src/api/system/code_gen.d.ts +14 -0
- package/dist/package/declarations/src/api/system/code_gen_column.d.ts +12 -0
- package/dist/package/declarations/src/api/system/code_gen_proto.d.ts +10 -0
- package/dist/package/declarations/src/api/system/code_gen_sse.d.ts +8 -0
- package/dist/package/declarations/src/api/system/code_gen_table.d.ts +18 -0
- package/dist/package/declarations/src/api/system/project_document.d.ts +9 -0
- package/dist/package/declarations/src/components/Ai.vue.d.ts +3 -0
- package/dist/package/declarations/src/index.d.ts +3 -0
- package/dist/package/declarations/src/module.d.ts +2 -0
- package/dist/package/declarations/src/rpc/base/v1/ai_message.d.ts +82 -0
- package/dist/package/declarations/src/rpc/base/v1/ai_session.d.ts +176 -0
- package/dist/package/declarations/src/rpc/base/v1/ai_tool.d.ts +59 -0
- package/dist/package/declarations/src/rpc/base/v1/oauth.d.ts +167 -0
- package/dist/package/declarations/src/rpc/base/v1/sse.d.ts +13 -0
- package/dist/package/declarations/src/rpc/common/v1/common.d.ts +57 -0
- package/dist/package/declarations/src/rpc/common/v1/enum.d.ts +58 -0
- package/dist/package/declarations/src/rpc/common/v1/types.d.ts +60 -0
- package/dist/package/declarations/src/rpc/google/protobuf/empty.d.ts +11 -0
- package/dist/package/declarations/src/rpc/google/protobuf/timestamp.d.ts +107 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/auth.d.ts +156 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_api.d.ts +193 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_area.d.ts +82 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_config.d.ts +112 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_dept.d.ts +112 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_dict.d.ts +215 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_job.d.ts +177 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_log.d.ts +87 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_menu.d.ts +151 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_migration.d.ts +64 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_post.d.ts +112 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_role.d.ts +128 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_tenant.d.ts +112 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_user.d.ts +161 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/code_gen.d.ts +155 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_column.d.ts +143 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_proto.d.ts +86 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_table.d.ts +149 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/project_document.d.ts +64 -0
- package/dist/package/declarations/src/rpc/system/common/v1/enum.d.ts +67 -0
- package/dist/package/declarations/src/views/ai/chat/attachment.d.ts +14 -0
- package/dist/package/declarations/src/views/ai/chat/components/AiMarkdown.vue.d.ts +13 -0
- package/dist/package/declarations/src/views/ai/chat/components/ChatPanel.vue.d.ts +45 -0
- package/dist/package/declarations/src/views/ai/chat/components/SessionPanel.vue.d.ts +34 -0
- package/dist/package/declarations/src/views/ai/chat/components/XSender.vue.d.ts +12 -0
- package/dist/package/declarations/src/views/ai/chat/index.vue.d.ts +4 -0
- package/dist/package/declarations/src/views/ai/chat/message.d.ts +59 -0
- package/dist/package/declarations/src/views/ai/chat/stream.d.ts +10 -0
- package/dist/package/declarations/src/views/ai/chat/types.d.ts +115 -0
- package/dist/package/declarations/src/views/base/api/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/area/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/config/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/dept/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/dict/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/dict/item.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/job/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/job/log.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/log/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/menu/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/migration/index.vue.d.ts +4 -0
- package/dist/package/declarations/src/views/base/post/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/role/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/tenant/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/user/components/dept-tree.vue.d.ts +19 -0
- package/dist/package/declarations/src/views/base/user/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/profile/components/base.vue.d.ts +13 -0
- package/dist/package/declarations/src/views/profile/components/password.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/profile/components/security.vue.d.ts +15 -0
- package/dist/package/declarations/src/views/profile/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/tool/api-doc/index.vue.d.ts +4 -0
- package/dist/package/declarations/src/views/tool/code-gen/code-preview/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/tool/code-gen/columns/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/tool/code-gen/columns/option-copy.d.ts +25 -0
- package/dist/package/declarations/src/views/tool/code-gen/components/CodeGenProgressDialog.vue.d.ts +16 -0
- package/dist/package/declarations/src/views/tool/code-gen/components/CodePreviewPane.vue.d.ts +9 -0
- package/dist/package/declarations/src/views/tool/code-gen/config.d.ts +32 -0
- package/dist/package/declarations/src/views/tool/code-gen/preview/capabilities.d.ts +20 -0
- package/dist/package/declarations/src/views/tool/code-gen/preview/data.d.ts +42 -0
- package/dist/package/declarations/src/views/tool/code-gen/preview/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/tool/code-gen/proto/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/tool/code-gen/table/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/tool/project-doc/index.vue.d.ts +4 -0
- package/dist/package/src/ai.ts +16 -0
- package/dist/package/src/api/base/ai_message.ts +139 -0
- package/dist/package/src/api/base/ai_session.ts +77 -0
- package/dist/package/src/api/base/ai_tool.ts +22 -0
- package/dist/package/src/api/base/oauth.ts +47 -0
- package/dist/package/src/api/base/sse.ts +192 -0
- package/dist/package/src/api/system/auth.ts +65 -0
- package/dist/package/src/api/system/base_api.ts +95 -0
- package/dist/package/src/api/system/base_area.ts +73 -0
- package/dist/package/src/api/system/base_config.ts +82 -0
- package/dist/package/src/api/system/base_dept.ts +83 -0
- package/dist/package/src/api/system/base_dict.ts +144 -0
- package/dist/package/src/api/system/base_job.ts +125 -0
- package/dist/package/src/api/system/base_log.ts +32 -0
- package/dist/package/src/api/system/base_menu.ts +83 -0
- package/dist/package/src/api/system/base_migration.ts +35 -0
- package/dist/package/src/api/system/base_post.ts +83 -0
- package/dist/package/src/api/system/base_role.ts +93 -0
- package/dist/package/src/api/system/base_tenant.ts +83 -0
- package/dist/package/src/api/system/base_user.ts +93 -0
- package/dist/package/src/api/system/code_gen.ts +56 -0
- package/dist/package/src/api/system/code_gen_column.ts +43 -0
- package/dist/package/src/api/system/code_gen_proto.ts +32 -0
- package/dist/package/src/api/system/code_gen_sse.ts +33 -0
- package/dist/package/src/api/system/code_gen_table.ts +74 -0
- package/dist/package/src/api/system/project_document.ts +33 -0
- package/dist/package/src/components/Ai.vue +57 -0
- package/dist/package/src/index.ts +3 -0
- package/dist/package/src/module.ts +17 -0
- package/dist/package/src/rpc/base/v1/ai_message.ts +98 -0
- package/dist/package/src/rpc/base/v1/ai_session.ts +214 -0
- package/dist/package/src/rpc/base/v1/ai_tool.ts +74 -0
- package/dist/package/src/rpc/base/v1/oauth.ts +199 -0
- package/dist/package/src/rpc/base/v1/sse.ts +22 -0
- package/dist/package/src/rpc/common/v1/common.ts +71 -0
- package/dist/package/src/rpc/common/v1/enum.ts +71 -0
- package/dist/package/src/rpc/common/v1/types.ts +77 -0
- package/dist/package/src/rpc/google/protobuf/empty.ts +19 -0
- package/dist/package/src/rpc/google/protobuf/timestamp.ts +115 -0
- package/dist/package/src/rpc/system/admin/v1/auth.ts +208 -0
- package/dist/package/src/rpc/system/admin/v1/base_api.ts +241 -0
- package/dist/package/src/rpc/system/admin/v1/base_area.ts +105 -0
- package/dist/package/src/rpc/system/admin/v1/base_config.ts +140 -0
- package/dist/package/src/rpc/system/admin/v1/base_dept.ts +140 -0
- package/dist/package/src/rpc/system/admin/v1/base_dict.ts +249 -0
- package/dist/package/src/rpc/system/admin/v1/base_job.ts +206 -0
- package/dist/package/src/rpc/system/admin/v1/base_log.ts +101 -0
- package/dist/package/src/rpc/system/admin/v1/base_menu.ts +195 -0
- package/dist/package/src/rpc/system/admin/v1/base_migration.ts +81 -0
- package/dist/package/src/rpc/system/admin/v1/base_post.ts +134 -0
- package/dist/package/src/rpc/system/admin/v1/base_role.ts +151 -0
- package/dist/package/src/rpc/system/admin/v1/base_tenant.ts +134 -0
- package/dist/package/src/rpc/system/admin/v1/base_user.ts +190 -0
- package/dist/package/src/rpc/system/admin/v1/code_gen.ts +176 -0
- package/dist/package/src/rpc/system/admin/v1/code_gen_column.ts +170 -0
- package/dist/package/src/rpc/system/admin/v1/code_gen_proto.ts +104 -0
- package/dist/package/src/rpc/system/admin/v1/code_gen_table.ts +179 -0
- package/dist/package/src/rpc/system/admin/v1/project_document.ts +79 -0
- package/dist/package/src/rpc/system/common/v1/enum.ts +80 -0
- package/dist/package/src/typings/swagger-ui-dist.d.ts +28 -0
- package/dist/package/src/typings/x-markdown-vue.d.ts +1 -0
- package/dist/package/src/views/ai/chat/attachment.ts +65 -0
- package/dist/package/src/views/ai/chat/components/AiMarkdown.vue +162 -0
- package/dist/package/src/views/ai/chat/components/ChatPanel.vue +1861 -0
- package/dist/package/src/views/ai/chat/components/SessionPanel.vue +316 -0
- package/dist/package/src/views/ai/chat/components/XSender.vue +554 -0
- package/dist/package/src/views/ai/chat/index.vue +848 -0
- package/dist/package/src/views/ai/chat/message.ts +416 -0
- package/dist/package/src/views/ai/chat/stream.ts +115 -0
- package/dist/package/src/views/ai/chat/types.ts +126 -0
- package/dist/package/src/views/base/api/index.vue +455 -0
- package/dist/package/src/views/base/area/index.vue +269 -0
- package/dist/package/src/views/base/config/index.vue +530 -0
- package/dist/package/src/views/base/dept/index.vue +461 -0
- package/dist/package/src/views/base/dict/index.vue +304 -0
- package/dist/package/src/views/base/dict/item.vue +373 -0
- package/dist/package/src/views/base/job/index.vue +535 -0
- package/dist/package/src/views/base/job/log.vue +202 -0
- package/dist/package/src/views/base/log/index.vue +317 -0
- package/dist/package/src/views/base/menu/index.vue +944 -0
- package/dist/package/src/views/base/migration/index.vue +791 -0
- package/dist/package/src/views/base/post/index.vue +324 -0
- package/dist/package/src/views/base/role/index.vue +684 -0
- package/dist/package/src/views/base/tenant/index.vue +328 -0
- package/dist/package/src/views/base/user/components/dept-tree.vue +75 -0
- package/dist/package/src/views/base/user/index.vue +783 -0
- package/dist/package/src/views/profile/components/base.vue +320 -0
- package/dist/package/src/views/profile/components/password.vue +269 -0
- package/dist/package/src/views/profile/components/security.vue +443 -0
- package/dist/package/src/views/profile/index.vue +199 -0
- package/dist/package/src/views/tool/api-doc/index.vue +275 -0
- package/dist/package/src/views/tool/code-gen/code-preview/index.vue +233 -0
- package/dist/package/src/views/tool/code-gen/columns/index.vue +1456 -0
- package/dist/package/src/views/tool/code-gen/columns/option-copy.ts +125 -0
- package/dist/package/src/views/tool/code-gen/components/CodeGenProgressDialog.vue +328 -0
- package/dist/package/src/views/tool/code-gen/components/CodePreviewPane.vue +42 -0
- package/dist/package/src/views/tool/code-gen/config.ts +175 -0
- package/dist/package/src/views/tool/code-gen/preview/capabilities.ts +34 -0
- package/dist/package/src/views/tool/code-gen/preview/data.ts +331 -0
- package/dist/package/src/views/tool/code-gen/preview/index.vue +831 -0
- package/dist/package/src/views/tool/code-gen/proto/index.vue +703 -0
- package/dist/package/src/views/tool/code-gen/table/index.vue +864 -0
- package/dist/package/src/views/tool/project-doc/index.vue +561 -0
- package/package.json +60 -0
- package/tsconfig.json +13 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { CodeGenColumnOptionConfig } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/code_gen_column";
|
|
2
|
+
/** 字段选项配置所属范围。 */
|
|
3
|
+
export type CodeGenOptionScope = "query" | "list" | "form";
|
|
4
|
+
/** 单个范围内参与选项复刻的配置。 */
|
|
5
|
+
export interface CodeGenOptionContainer {
|
|
6
|
+
enabled: boolean;
|
|
7
|
+
component: string;
|
|
8
|
+
option: CodeGenColumnOptionConfig;
|
|
9
|
+
}
|
|
10
|
+
/** 查询、列表和表单三范围的选项配置集合。 */
|
|
11
|
+
export interface CodeGenOptionCopyColumn {
|
|
12
|
+
query_config: CodeGenOptionContainer;
|
|
13
|
+
list_config: CodeGenOptionContainer;
|
|
14
|
+
form_config: CodeGenOptionContainer;
|
|
15
|
+
}
|
|
16
|
+
/** 返回指定范围的选项配置容器。 */
|
|
17
|
+
export declare function getCodeGenOptionContainer(column: CodeGenOptionCopyColumn, scope: CodeGenOptionScope): CodeGenOptionContainer;
|
|
18
|
+
/** 判断选项配置是否满足当前保存规则并可作为复刻来源。 */
|
|
19
|
+
export declare function isCompleteCodeGenOptionConfig(option: CodeGenColumnOptionConfig): boolean;
|
|
20
|
+
/** 从第一个相同组件的完整范围复刻选项配置。 */
|
|
21
|
+
export declare function copyFirstMatchingCodeGenOption(column: CodeGenOptionCopyColumn, targetScope: CodeGenOptionScope): boolean;
|
|
22
|
+
/** 用当前范围补齐相同组件中尚未完整配置的其他范围。 */
|
|
23
|
+
export declare function copyCodeGenOptionToEmptyMatches(column: CodeGenOptionCopyColumn, sourceScope: CodeGenOptionScope): CodeGenOptionScope[];
|
|
24
|
+
/** 页面加载时按固定优先级补齐相同组件的空配置。 */
|
|
25
|
+
export declare function fillMissingCodeGenOptionConfigs(column: CodeGenOptionCopyColumn): CodeGenOptionScope[];
|
package/dist/package/declarations/src/views/tool/code-gen/components/CodeGenProgressDialog.vue.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** 代码生成进度弹窗属性。 */
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
modelValue: boolean;
|
|
4
|
+
taskId: string;
|
|
5
|
+
};
|
|
6
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
7
|
+
"update:modelValue": (value: boolean) => any;
|
|
8
|
+
completed: () => any;
|
|
9
|
+
unavailable: () => any;
|
|
10
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
11
|
+
"onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
|
|
12
|
+
onCompleted?: (() => any) | undefined;
|
|
13
|
+
onUnavailable?: (() => any) | undefined;
|
|
14
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
15
|
+
declare const _default: typeof __VLS_export;
|
|
16
|
+
export default _default;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CodeGenPreviewFile } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/code_gen";
|
|
2
|
+
/** 代码预览面板属性。 */
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
files: CodeGenPreviewFile[];
|
|
5
|
+
loading: boolean;
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
8
|
+
declare const _default: typeof __VLS_export;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { FormRules } from "element-plus";
|
|
2
|
+
import type { ProFormOption } from "@liujitcn/kratos-admin-core/components/ProForm/interface";
|
|
3
|
+
import type { CodeGenColumnFormConfig, CodeGenColumnListConfig, CodeGenColumnOptionConfig, CodeGenColumnQueryConfig } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/code_gen_column";
|
|
4
|
+
import type { CodeGenLeftTreeConfig, CodeGenTableForm } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/code_gen_table";
|
|
5
|
+
/** 代码生成表配置页面类型选项。 */
|
|
6
|
+
export declare const codeGenPageTypeOptions: ProFormOption[];
|
|
7
|
+
/** 判断页面类型是否使用树形表格配置。 */
|
|
8
|
+
export declare function isCodeGenTreePageType(pageType?: string): pageType is "tree" | "tree_lazy";
|
|
9
|
+
/** 左树数据源类型选项。 */
|
|
10
|
+
export declare const codeGenSourceTypeOptions: ProFormOption[];
|
|
11
|
+
/** 查询操作符选项。 */
|
|
12
|
+
export declare const codeGenQueryOperatorOptions: ProFormOption[];
|
|
13
|
+
/** 查询组件选项。 */
|
|
14
|
+
export declare const codeGenQueryComponentOptions: ProFormOption[];
|
|
15
|
+
/** 列表展示组件选项。 */
|
|
16
|
+
export declare const codeGenListComponentOptions: ProFormOption[];
|
|
17
|
+
/** 表单录入组件选项,保持与 ProForm 支持类型完整一致。 */
|
|
18
|
+
export declare const codeGenFormComponentOptions: ProFormOption[];
|
|
19
|
+
/** 代码生成表配置校验规则。 */
|
|
20
|
+
export declare const codeGenTableRules: FormRules;
|
|
21
|
+
/** 创建默认左树右表页面配置。 */
|
|
22
|
+
export declare function createDefaultCodeGenLeftTreeConfig(): CodeGenLeftTreeConfig;
|
|
23
|
+
/** 创建代码生成表配置默认表单。 */
|
|
24
|
+
export declare function createDefaultCodeGenTableForm(): CodeGenTableForm;
|
|
25
|
+
/** 创建默认字段查询配置。 */
|
|
26
|
+
export declare function createDefaultCodeGenQueryConfig(): CodeGenColumnQueryConfig;
|
|
27
|
+
/** 创建默认字段列表配置。 */
|
|
28
|
+
export declare function createDefaultCodeGenListConfig(): CodeGenColumnListConfig;
|
|
29
|
+
/** 创建默认字段表单配置。 */
|
|
30
|
+
export declare function createDefaultCodeGenFormConfig(): CodeGenColumnFormConfig;
|
|
31
|
+
/** 创建一份独立的字段选项配置。 */
|
|
32
|
+
export declare function createDefaultCodeGenOptionConfig(): CodeGenColumnOptionConfig;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** 预览能力判断所需的 Proto 检查项。 */
|
|
2
|
+
export interface CodeGenPreviewProtoCheck {
|
|
3
|
+
/** Proto 方法名。 */
|
|
4
|
+
method_name: string;
|
|
5
|
+
/** 接口是否已经存在。 */
|
|
6
|
+
exists: boolean;
|
|
7
|
+
/** 接口缺失时是否已选择生成。 */
|
|
8
|
+
generate_when_missing: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** 代码生成页面预览支持的维护能力。 */
|
|
11
|
+
export interface CodeGenPreviewCapabilities {
|
|
12
|
+
/** 是否支持新增。 */
|
|
13
|
+
create: boolean;
|
|
14
|
+
/** 是否支持更新。 */
|
|
15
|
+
update: boolean;
|
|
16
|
+
/** 是否支持删除。 */
|
|
17
|
+
delete: boolean;
|
|
18
|
+
}
|
|
19
|
+
/** 根据当前实体可用的 Proto 方法解析预览维护能力。 */
|
|
20
|
+
export declare function resolveCodeGenPreviewCapabilities(entityName: string, protoChecks: CodeGenPreviewProtoCheck[]): CodeGenPreviewCapabilities;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ProFormOption } from "@liujitcn/kratos-admin-core/components/ProForm/interface";
|
|
2
|
+
import type { OptionBaseDictResponse_BaseDict } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_dict";
|
|
3
|
+
import type { CodeGenColumn } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/code_gen_column";
|
|
4
|
+
import type { CodeGenLeftTreeConfig, CodeGenTableForm } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/code_gen_table";
|
|
5
|
+
/** 页面预览中的字段配置范围。 */
|
|
6
|
+
export type CodeGenPreviewScope = "query" | "list" | "form";
|
|
7
|
+
/** 页面预览模拟记录。 */
|
|
8
|
+
export type CodeGenPreviewRow = Record<string, any> & {
|
|
9
|
+
/** 树形表格子记录。 */
|
|
10
|
+
children?: CodeGenPreviewRow[];
|
|
11
|
+
/** 树形懒加载表格是否存在子记录。 */
|
|
12
|
+
has_children?: boolean;
|
|
13
|
+
};
|
|
14
|
+
/** 代码生成页面预览快照。 */
|
|
15
|
+
export interface CodeGenPagePreviewSnapshot {
|
|
16
|
+
/** 当前代码生成表配置。 */
|
|
17
|
+
table: CodeGenTableForm;
|
|
18
|
+
/** 当前已经保存的字段配置。 */
|
|
19
|
+
columns: CodeGenColumn[];
|
|
20
|
+
}
|
|
21
|
+
/** 页面预览中按字段和范围隔离的模拟选项。 */
|
|
22
|
+
export type CodeGenPreviewOptionMap = Record<string, ProFormOption[]>;
|
|
23
|
+
/** 创建字段指定配置范围的预览选项缓存键。 */
|
|
24
|
+
export declare function createCodeGenPreviewOptionKey(columnName: string, scope: CodeGenPreviewScope): string;
|
|
25
|
+
/** 根据当前字段配置和字典数据创建查询、列表和表单各自的模拟选项。 */
|
|
26
|
+
export declare function createCodeGenPreviewOptionMap(columns: CodeGenColumn[], dictionaries: OptionBaseDictResponse_BaseDict[]): CodeGenPreviewOptionMap;
|
|
27
|
+
/** 根据左树配置创建结构相符的模拟树节点。 */
|
|
28
|
+
export declare function createCodeGenLeftTreeOptions(config?: CodeGenLeftTreeConfig): ProFormOption[];
|
|
29
|
+
/** 创建页面列表所需的模拟业务记录。 */
|
|
30
|
+
export declare function createCodeGenPreviewRows(snapshot: CodeGenPagePreviewSnapshot, optionMap: CodeGenPreviewOptionMap, leftTreeOptions: ProFormOption[]): CodeGenPreviewRow[];
|
|
31
|
+
/** 按查询配置过滤页面模拟记录。 */
|
|
32
|
+
export declare function filterCodeGenPreviewRows(rows: CodeGenPreviewRow[], columns: CodeGenColumn[], params: Record<string, any>): CodeGenPreviewRow[];
|
|
33
|
+
/** 将扁平模拟记录转换成 Element Plus 表格树。 */
|
|
34
|
+
export declare function buildCodeGenPreviewTree(rows: CodeGenPreviewRow[], primaryColumn: string, parentColumn: string): CodeGenPreviewRow[];
|
|
35
|
+
/** 将树形选项扁平化,供模拟记录赋值和标签匹配使用。 */
|
|
36
|
+
export declare function flattenCodeGenPreviewOptions(options: ProFormOption[]): ProFormOption[];
|
|
37
|
+
/** 返回当前表的真实主键字段,缺少主键时使用预览内部编号。 */
|
|
38
|
+
export declare function resolveCodeGenPrimaryColumn(columns: CodeGenColumn[]): string;
|
|
39
|
+
/** 返回指定字段范围的模拟选项。 */
|
|
40
|
+
export declare function resolveCodeGenPreviewOptions(optionMap: CodeGenPreviewOptionMap, columnName: string, scope: CodeGenPreviewScope): ProFormOption[];
|
|
41
|
+
/** 判断字段是否为数值类型。 */
|
|
42
|
+
export declare function isNumericColumn(column: CodeGenColumn): boolean;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import "x-markdown-vue/style";
|
|
2
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
3
|
+
declare const _default: typeof __VLS_export;
|
|
4
|
+
export default _default;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Component } from "vue";
|
|
2
|
+
import { getAdminModuleExtension } from "@liujitcn/kratos-admin-core";
|
|
3
|
+
|
|
4
|
+
/** ADMIN_AI_EXTENSION AI 助手扩展名称。 */
|
|
5
|
+
export const ADMIN_AI_EXTENSION = "admin.ai";
|
|
6
|
+
|
|
7
|
+
/** AdminAiExtension AI 助手可扩展能力。 */
|
|
8
|
+
export interface AdminAiExtension {
|
|
9
|
+
/** 结构化流程卡片组件。 */
|
|
10
|
+
flowBlocks?: Component;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** getAdminAiExtension 获取当前宿主注册的 AI 助手扩展。 */
|
|
14
|
+
export function getAdminAiExtension(): AdminAiExtension {
|
|
15
|
+
return getAdminModuleExtension<AdminAiExtension>(ADMIN_AI_EXTENSION) ?? {};
|
|
16
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import service, {
|
|
2
|
+
getRequestAccessToken,
|
|
3
|
+
handleAuthExpired,
|
|
4
|
+
requestBaseURL
|
|
5
|
+
} from "@liujitcn/kratos-admin-core/request";
|
|
6
|
+
import type {
|
|
7
|
+
ListAiMessageRequest,
|
|
8
|
+
ListAiMessageResponse
|
|
9
|
+
} from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_session";
|
|
10
|
+
import type {
|
|
11
|
+
AiMessageService,
|
|
12
|
+
DeleteAiMessageRequest,
|
|
13
|
+
DeleteAiMessageResponse,
|
|
14
|
+
RegenerateAiMessageRequest,
|
|
15
|
+
RetryAiUserMessageRequest,
|
|
16
|
+
SendAiMessageRequest,
|
|
17
|
+
SendAiMessageResponse,
|
|
18
|
+
UpdateAiMessageRequest
|
|
19
|
+
} from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_message";
|
|
20
|
+
|
|
21
|
+
const AI_SESSION_URL = "/v1/base/ai/session";
|
|
22
|
+
|
|
23
|
+
/** direct stream 请求控制选项。 */
|
|
24
|
+
export type AiMessageStreamOptions = {
|
|
25
|
+
/** 外部取消信号,用于页面卸载或会话删除时终止流式请求。 */
|
|
26
|
+
signal?: AbortSignal;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/** 从 direct stream 错误响应中提取后端业务提示。 */
|
|
30
|
+
async function resolveStreamErrorMessage(response: Response): Promise<string> {
|
|
31
|
+
const fallbackMessage = `AI 助手请求失败(${response.status})`;
|
|
32
|
+
const contentType = response.headers.get("Content-Type") ?? "";
|
|
33
|
+
if (contentType.includes("application/json")) {
|
|
34
|
+
try {
|
|
35
|
+
const payload = await response.json();
|
|
36
|
+
return String(payload?.message || payload?.error || fallbackMessage);
|
|
37
|
+
} catch {
|
|
38
|
+
return fallbackMessage;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const text = (await response.text()).trim();
|
|
43
|
+
return text || fallbackMessage;
|
|
44
|
+
} catch {
|
|
45
|
+
return fallbackMessage;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** 使用 direct stream 发送 AI 助手消息,并返回原始 Fetch Response 供调用方消费。 */
|
|
50
|
+
export async function SendAiMessageStream(request: SendAiMessageRequest, options?: AiMessageStreamOptions): Promise<Response> {
|
|
51
|
+
const accessToken = await getRequestAccessToken();
|
|
52
|
+
const headers: Record<string, string> = {
|
|
53
|
+
Accept: "text/event-stream",
|
|
54
|
+
"Content-Type": "application/json;charset=utf-8"
|
|
55
|
+
};
|
|
56
|
+
if (accessToken) headers.Authorization = accessToken;
|
|
57
|
+
|
|
58
|
+
const response = await fetch(`${requestBaseURL}${AI_SESSION_URL}/${request.session_id}/message`, {
|
|
59
|
+
method: "POST",
|
|
60
|
+
headers,
|
|
61
|
+
body: JSON.stringify(request),
|
|
62
|
+
signal: options?.signal
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// direct stream 不经过 axios 响应拦截器,需要在这里补齐登录失效处理。
|
|
66
|
+
if (response.status === 401 || response.status === 403) {
|
|
67
|
+
handleAuthExpired();
|
|
68
|
+
throw new Error("登录状态已失效,请重新登录");
|
|
69
|
+
}
|
|
70
|
+
if (!response.ok) {
|
|
71
|
+
throw new Error(await resolveStreamErrorMessage(response));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return response;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** AI 助手消息服务。 */
|
|
78
|
+
export class AiMessageServiceImpl implements AiMessageService {
|
|
79
|
+
/** 查询 AI 助手消息列表。 */
|
|
80
|
+
ListAiMessage(request: ListAiMessageRequest): Promise<ListAiMessageResponse> {
|
|
81
|
+
return service<ListAiMessageRequest, ListAiMessageResponse>({
|
|
82
|
+
url: `${AI_SESSION_URL}/${request.session_id}/message`,
|
|
83
|
+
method: "get",
|
|
84
|
+
params: request
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** 发送 AI 助手消息并等待完整响应。 */
|
|
89
|
+
SendAiMessage(request: SendAiMessageRequest): Promise<SendAiMessageResponse> {
|
|
90
|
+
return service<SendAiMessageRequest, SendAiMessageResponse>({
|
|
91
|
+
url: `${AI_SESSION_URL}/${request.session_id}/message`,
|
|
92
|
+
method: "post",
|
|
93
|
+
data: request
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** 删除 AI 助手消息。 */
|
|
98
|
+
DeleteAiMessage(request: DeleteAiMessageRequest): Promise<DeleteAiMessageResponse> {
|
|
99
|
+
return service<DeleteAiMessageRequest, DeleteAiMessageResponse>({
|
|
100
|
+
url: `${AI_SESSION_URL}/${request.session_id}/message/${request.message_id}`,
|
|
101
|
+
method: "delete",
|
|
102
|
+
params: request
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** 更新 AI 助手消息文本并重新生成输出。 */
|
|
107
|
+
UpdateAiMessage(request: UpdateAiMessageRequest): Promise<SendAiMessageResponse> {
|
|
108
|
+
return service<UpdateAiMessageRequest, SendAiMessageResponse>({
|
|
109
|
+
url: `${AI_SESSION_URL}/${request.session_id}/message/${request.message_id}`,
|
|
110
|
+
method: "put",
|
|
111
|
+
data: request
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** 重试失败的 AI 助手消息。 */
|
|
116
|
+
RetryAiUserMessage(request: RetryAiUserMessageRequest): Promise<SendAiMessageResponse> {
|
|
117
|
+
return service<RetryAiUserMessageRequest, SendAiMessageResponse>({
|
|
118
|
+
url: `${AI_SESSION_URL}/${request.session_id}/message/${request.message_id}/retry`,
|
|
119
|
+
method: "post",
|
|
120
|
+
data: request
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** 重新生成 AI 助手输出。 */
|
|
125
|
+
RegenerateAiMessage(request: RegenerateAiMessageRequest): Promise<SendAiMessageResponse> {
|
|
126
|
+
return service<RegenerateAiMessageRequest, SendAiMessageResponse>({
|
|
127
|
+
url: `${AI_SESSION_URL}/${request.session_id}/message/${request.message_id}/regeneration`,
|
|
128
|
+
method: "post",
|
|
129
|
+
data: request
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** 使用 direct stream 发送 AI 助手消息,并返回原始 Fetch Response 供调用方消费。 */
|
|
134
|
+
async StreamAiMessage(request: SendAiMessageRequest, options?: AiMessageStreamOptions): Promise<Response> {
|
|
135
|
+
return SendAiMessageStream(request, options);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export const defAiMessageService = new AiMessageServiceImpl();
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import service from "@liujitcn/kratos-admin-core/request";
|
|
2
|
+
import type {
|
|
3
|
+
AiSessionService,
|
|
4
|
+
CreateAiSessionBranchRequest,
|
|
5
|
+
CreateAiSessionBranchResponse,
|
|
6
|
+
CreateAiSessionRequest,
|
|
7
|
+
CreateAiSessionResponse,
|
|
8
|
+
DeleteAiSessionRequest,
|
|
9
|
+
DeleteAiSessionResponse,
|
|
10
|
+
ListAiMessageRequest,
|
|
11
|
+
ListAiMessageResponse,
|
|
12
|
+
ListAiSessionRequest,
|
|
13
|
+
ListAiSessionResponse,
|
|
14
|
+
UpdateAiSessionRequest,
|
|
15
|
+
UpdateAiSessionResponse
|
|
16
|
+
} from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_session";
|
|
17
|
+
|
|
18
|
+
const AI_SESSION_URL = "/v1/base/ai/session";
|
|
19
|
+
|
|
20
|
+
/** AI 助手会话服务。 */
|
|
21
|
+
export class AiSessionServiceImpl implements AiSessionService {
|
|
22
|
+
/** 查询 AI 助手会话列表。 */
|
|
23
|
+
ListAiSession(request: ListAiSessionRequest): Promise<ListAiSessionResponse> {
|
|
24
|
+
return service<ListAiSessionRequest, ListAiSessionResponse>({
|
|
25
|
+
url: `${AI_SESSION_URL}`,
|
|
26
|
+
method: "get",
|
|
27
|
+
params: request
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** 创建 AI 助手会话。 */
|
|
32
|
+
CreateAiSession(request: CreateAiSessionRequest): Promise<CreateAiSessionResponse> {
|
|
33
|
+
return service<CreateAiSessionRequest, CreateAiSessionResponse>({
|
|
34
|
+
url: `${AI_SESSION_URL}`,
|
|
35
|
+
method: "post",
|
|
36
|
+
data: request
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** 更新 AI 助手会话。 */
|
|
41
|
+
UpdateAiSession(request: UpdateAiSessionRequest): Promise<UpdateAiSessionResponse> {
|
|
42
|
+
return service<UpdateAiSessionRequest, UpdateAiSessionResponse>({
|
|
43
|
+
url: `${AI_SESSION_URL}/${request.id}`,
|
|
44
|
+
method: "put",
|
|
45
|
+
data: request
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** 删除 AI 助手会话。 */
|
|
50
|
+
DeleteAiSession(request: DeleteAiSessionRequest): Promise<DeleteAiSessionResponse> {
|
|
51
|
+
return service<DeleteAiSessionRequest, DeleteAiSessionResponse>({
|
|
52
|
+
url: `${AI_SESSION_URL}/${request.id}`,
|
|
53
|
+
method: "delete",
|
|
54
|
+
params: request
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** 查询 AI 助手消息列表。 */
|
|
59
|
+
ListAiMessage(request: ListAiMessageRequest): Promise<ListAiMessageResponse> {
|
|
60
|
+
return service<ListAiMessageRequest, ListAiMessageResponse>({
|
|
61
|
+
url: `${AI_SESSION_URL}/${request.session_id}/message`,
|
|
62
|
+
method: "get",
|
|
63
|
+
params: request
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** 从指定消息创建 AI 助手分支会话。 */
|
|
68
|
+
CreateAiSessionBranch(request: CreateAiSessionBranchRequest): Promise<CreateAiSessionBranchResponse> {
|
|
69
|
+
return service<CreateAiSessionBranchRequest, CreateAiSessionBranchResponse>({
|
|
70
|
+
url: `${AI_SESSION_URL}/${request.source_session_id}/branch`,
|
|
71
|
+
method: "post",
|
|
72
|
+
data: request
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export const defAiSessionService = new AiSessionServiceImpl();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import service from "@liujitcn/kratos-admin-core/request";
|
|
2
|
+
import type {
|
|
3
|
+
AiToolService,
|
|
4
|
+
ListAiShortcutRequest,
|
|
5
|
+
ListAiShortcutResponse
|
|
6
|
+
} from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_tool";
|
|
7
|
+
|
|
8
|
+
const AI_SHORTCUT_URL = "/v1/base/ai/shortcut";
|
|
9
|
+
|
|
10
|
+
/** AI 助手工具服务。 */
|
|
11
|
+
export class AiToolServiceImpl implements AiToolService {
|
|
12
|
+
/** 查询 AI 助手快捷入口列表。 */
|
|
13
|
+
ListAiShortcut(request: ListAiShortcutRequest): Promise<ListAiShortcutResponse> {
|
|
14
|
+
return service<ListAiShortcutRequest, ListAiShortcutResponse>({
|
|
15
|
+
url: AI_SHORTCUT_URL,
|
|
16
|
+
method: "get",
|
|
17
|
+
params: request
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const defAiToolService = new AiToolServiceImpl();
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import service from "@liujitcn/kratos-admin-core/request";
|
|
2
|
+
import type {
|
|
3
|
+
CreateOauthBindingAuthorizationRequest,
|
|
4
|
+
CreateOauthBindingAuthorizationResponse,
|
|
5
|
+
ListOauthBindingRequest,
|
|
6
|
+
ListOauthBindingResponse,
|
|
7
|
+
UnbindOauthAccountRequest
|
|
8
|
+
} from "@liujitcn/kratos-admin-system/rpc/base/v1/oauth";
|
|
9
|
+
import type { Empty } from "@liujitcn/kratos-admin-system/rpc/google/protobuf/empty";
|
|
10
|
+
|
|
11
|
+
const OAUTH_BINDING_URL = "/v1/base/oauth/binding";
|
|
12
|
+
const OAUTH_BINDING_AUTHORIZATION_URL = "/v1/base/oauth/binding/authorization";
|
|
13
|
+
|
|
14
|
+
/** ProfileOauthServiceImpl 个人中心三方账号服务。 */
|
|
15
|
+
export class ProfileOauthServiceImpl {
|
|
16
|
+
/** 查询个人中心三方账号绑定列表。 */
|
|
17
|
+
ListOauthBinding(request: ListOauthBindingRequest): Promise<ListOauthBindingResponse> {
|
|
18
|
+
return service<ListOauthBindingRequest, ListOauthBindingResponse>({
|
|
19
|
+
url: OAUTH_BINDING_URL,
|
|
20
|
+
method: "get",
|
|
21
|
+
params: request
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** 创建个人中心三方账号绑定授权地址。 */
|
|
26
|
+
CreateOauthBindingAuthorization(
|
|
27
|
+
request: CreateOauthBindingAuthorizationRequest
|
|
28
|
+
): Promise<CreateOauthBindingAuthorizationResponse> {
|
|
29
|
+
return service<CreateOauthBindingAuthorizationRequest, CreateOauthBindingAuthorizationResponse>({
|
|
30
|
+
url: OAUTH_BINDING_AUTHORIZATION_URL,
|
|
31
|
+
method: "post",
|
|
32
|
+
data: request
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** 解绑个人中心三方账号。 */
|
|
37
|
+
UnbindOauthAccount(request: UnbindOauthAccountRequest): Promise<Empty> {
|
|
38
|
+
return service<UnbindOauthAccountRequest, Empty>({
|
|
39
|
+
url: `${OAUTH_BINDING_URL}/${request.provider}`,
|
|
40
|
+
method: "delete",
|
|
41
|
+
params: request
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** defProfileOauthService 个人中心三方账号服务实例。 */
|
|
47
|
+
export const defProfileOauthService = new ProfileOauthServiceImpl();
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { EventStreamContentType, fetchEventSource, type EventSourceMessage } from "@microsoft/fetch-event-source";
|
|
2
|
+
import type { SubscribeSseRequest } from "@liujitcn/kratos-admin-system/rpc/base/v1/sse";
|
|
3
|
+
import { getRequestAccessToken, handleAuthExpired } from "@liujitcn/kratos-admin-core/request";
|
|
4
|
+
|
|
5
|
+
const SSE_URL = "/events";
|
|
6
|
+
|
|
7
|
+
/** SSE 取消订阅函数。 */
|
|
8
|
+
export type SseStop = () => void;
|
|
9
|
+
|
|
10
|
+
/** 同一条 SSE 流的共享连接记录。 */
|
|
11
|
+
interface SharedSseConnection {
|
|
12
|
+
/** 关闭当前 SSE 连接。 */
|
|
13
|
+
close: () => void;
|
|
14
|
+
/** 已注册的事件监听器。 */
|
|
15
|
+
listeners: Map<string, Set<(message: EventSourceMessage) => void>>;
|
|
16
|
+
/** 当前流上已绑定的事件监听器数量。 */
|
|
17
|
+
refCount: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** SSE 不可恢复异常。 */
|
|
21
|
+
class SseFatalError extends Error {}
|
|
22
|
+
|
|
23
|
+
/** SSE 可重试异常。 */
|
|
24
|
+
class SseRetriableError extends Error {}
|
|
25
|
+
|
|
26
|
+
/** Base SSE 服务。 */
|
|
27
|
+
export class SseServiceImpl {
|
|
28
|
+
private readonly sharedConnections = new Map<string, SharedSseConnection>();
|
|
29
|
+
|
|
30
|
+
/** 创建或复用 SSE 订阅连接。 */
|
|
31
|
+
SubscribeSse(request: SubscribeSseRequest): SharedSseConnection | null {
|
|
32
|
+
if (typeof window === "undefined" || typeof AbortController === "undefined") {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const url = this.buildSubscribeURL(request);
|
|
37
|
+
if (!url) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const connectionKey = this.buildConnectionKey(request);
|
|
42
|
+
const cachedConnection = this.sharedConnections.get(connectionKey);
|
|
43
|
+
if (cachedConnection) {
|
|
44
|
+
return cachedConnection;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const controller = new AbortController();
|
|
48
|
+
const listeners = new Map<string, Set<(message: EventSourceMessage) => void>>();
|
|
49
|
+
const connection: SharedSseConnection = {
|
|
50
|
+
close: () => controller.abort(),
|
|
51
|
+
listeners,
|
|
52
|
+
refCount: 0
|
|
53
|
+
};
|
|
54
|
+
this.sharedConnections.set(connectionKey, connection);
|
|
55
|
+
void this.openFetchEventSource(connectionKey, url, controller, connection);
|
|
56
|
+
return connection;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** 释放 SSE 共享连接。 */
|
|
60
|
+
ReleaseSse(request: SubscribeSseRequest) {
|
|
61
|
+
const connectionKey = this.buildConnectionKey(request);
|
|
62
|
+
const cachedConnection = this.sharedConnections.get(connectionKey);
|
|
63
|
+
if (!cachedConnection) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
cachedConnection.refCount -= 1;
|
|
67
|
+
if (cachedConnection.refCount > 0) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
cachedConnection.close();
|
|
71
|
+
this.sharedConnections.delete(connectionKey);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** 构建 SSE 订阅地址。 */
|
|
75
|
+
private buildSubscribeURL(request: SubscribeSseRequest) {
|
|
76
|
+
const url = new URL(`${SSE_URL}/${request.stream}`, window.location.origin);
|
|
77
|
+
if (request.channel_id) {
|
|
78
|
+
url.searchParams.set("channel_id", request.channel_id);
|
|
79
|
+
}
|
|
80
|
+
return url.toString();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** 构建 SSE 共享连接键。 */
|
|
84
|
+
private buildConnectionKey(request: SubscribeSseRequest) {
|
|
85
|
+
return `${request.stream}:${request.channel_id ?? ""}`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** 打开基于 fetch 的 SSE 长连接。 */
|
|
89
|
+
private async openFetchEventSource(
|
|
90
|
+
connectionKey: string,
|
|
91
|
+
url: string,
|
|
92
|
+
controller: AbortController,
|
|
93
|
+
connection: SharedSseConnection
|
|
94
|
+
) {
|
|
95
|
+
try {
|
|
96
|
+
const accessToken = await getRequestAccessToken();
|
|
97
|
+
if (!accessToken) {
|
|
98
|
+
this.sharedConnections.delete(connectionKey);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
await fetchEventSource(url, {
|
|
103
|
+
method: "GET",
|
|
104
|
+
signal: controller.signal,
|
|
105
|
+
openWhenHidden: true,
|
|
106
|
+
headers: {
|
|
107
|
+
Accept: EventStreamContentType,
|
|
108
|
+
Authorization: accessToken
|
|
109
|
+
},
|
|
110
|
+
async onopen(response) {
|
|
111
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
112
|
+
if (response.ok && contentType.startsWith(EventStreamContentType)) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (response.status === 401 || response.status === 403) {
|
|
116
|
+
throw new SseFatalError("SSE 认证已失效");
|
|
117
|
+
}
|
|
118
|
+
throw new SseRetriableError(`SSE 连接失败: ${response.status}`);
|
|
119
|
+
},
|
|
120
|
+
onmessage: message => {
|
|
121
|
+
const eventName = message.event || "";
|
|
122
|
+
if (!eventName) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const eventListeners = connection.listeners.get(eventName);
|
|
126
|
+
if (!eventListeners || eventListeners.size === 0) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
eventListeners.forEach(listener => listener(message));
|
|
130
|
+
},
|
|
131
|
+
onclose: () => {
|
|
132
|
+
throw new SseRetriableError("SSE 连接已关闭");
|
|
133
|
+
},
|
|
134
|
+
onerror: error => {
|
|
135
|
+
if (controller.signal.aborted) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (error instanceof SseFatalError) {
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
return 1000;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
} catch (error) {
|
|
145
|
+
if (controller.signal.aborted) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
// SSE 与常规请求复用同一套登录失效处理,避免页面静默断流后用户无感知。
|
|
149
|
+
if (error instanceof SseFatalError) {
|
|
150
|
+
handleAuthExpired();
|
|
151
|
+
}
|
|
152
|
+
this.sharedConnections.delete(connectionKey);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export const defSseService = new SseServiceImpl();
|
|
158
|
+
|
|
159
|
+
/** 订阅指定 SSE 事件。 */
|
|
160
|
+
export function subscribeSseEvent<T>(
|
|
161
|
+
request: SubscribeSseRequest,
|
|
162
|
+
event: string,
|
|
163
|
+
parser: (raw: string) => T | null,
|
|
164
|
+
handler: (payload: T) => void
|
|
165
|
+
): SseStop {
|
|
166
|
+
const connection = defSseService.SubscribeSse(request);
|
|
167
|
+
if (!connection) return () => undefined;
|
|
168
|
+
|
|
169
|
+
connection.refCount += 1;
|
|
170
|
+
const eventName = event;
|
|
171
|
+
let eventListeners = connection.listeners.get(eventName);
|
|
172
|
+
if (!eventListeners) {
|
|
173
|
+
eventListeners = new Set();
|
|
174
|
+
connection.listeners.set(eventName, eventListeners);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const listener = (message: EventSourceMessage) => {
|
|
178
|
+
const payload = parser(message.data);
|
|
179
|
+
if (!payload) return;
|
|
180
|
+
handler(payload);
|
|
181
|
+
};
|
|
182
|
+
eventListeners.add(listener);
|
|
183
|
+
|
|
184
|
+
return () => {
|
|
185
|
+
const currentListeners = connection.listeners.get(eventName);
|
|
186
|
+
currentListeners?.delete(listener);
|
|
187
|
+
if (currentListeners && currentListeners.size === 0) {
|
|
188
|
+
connection.listeners.delete(eventName);
|
|
189
|
+
}
|
|
190
|
+
defSseService.ReleaseSse(request);
|
|
191
|
+
};
|
|
192
|
+
}
|