@liujitcn/kratos-admin-system 0.0.52 → 0.0.54

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.
Files changed (50) hide show
  1. package/dist/package/declarations/src/api/base/v1/sse.d.ts +1 -1
  2. package/dist/package/declarations/src/locales/generated.d.ts +32 -0
  3. package/dist/package/declarations/src/rpc/base/v1/ai_search.d.ts +26 -0
  4. package/dist/package/declarations/src/rpc/system/admin/v1/base_redact_output_policy.d.ts +0 -1
  5. package/dist/package/src/api/base/v1/sse.ts +19 -12
  6. package/dist/package/src/components/log/LogTable.vue +25 -18
  7. package/dist/package/src/components/notification/Notification.vue +14 -7
  8. package/dist/package/src/components/tenant-project/TenantProjectManager.vue +12 -6
  9. package/dist/package/src/components/tenant-project-grant/ProjectGrantDialog.vue +22 -7
  10. package/dist/package/src/locales/en-US.json +8 -0
  11. package/dist/package/src/locales/ja-JP.json +8 -0
  12. package/dist/package/src/locales/zh-CN.json +8 -0
  13. package/dist/package/src/locales/zh-TW.json +8 -0
  14. package/dist/package/src/rpc/base/v1/ai_search.ts +37 -0
  15. package/dist/package/src/rpc/system/admin/v1/base_redact_output_policy.ts +0 -1
  16. package/dist/package/src/views/ai/chat/index.vue +16 -7
  17. package/dist/package/src/views/base/api-log/index.vue +1 -1
  18. package/dist/package/src/views/base/area/index.vue +15 -9
  19. package/dist/package/src/views/base/backup-management/archive-config/index.vue +22 -10
  20. package/dist/package/src/views/base/backup-management/backup-config/index.vue +13 -6
  21. package/dist/package/src/views/base/config/index.vue +38 -14
  22. package/dist/package/src/views/base/dashboard/index.vue +201 -53
  23. package/dist/package/src/views/base/dept/index.vue +31 -25
  24. package/dist/package/src/views/base/dict/index.vue +12 -8
  25. package/dist/package/src/views/base/dict/item.vue +12 -8
  26. package/dist/package/src/views/base/i18n-custom/index.vue +13 -7
  27. package/dist/package/src/views/base/job/index.vue +12 -8
  28. package/dist/package/src/views/base/job/log.vue +14 -9
  29. package/dist/package/src/views/base/language/index.vue +7 -4
  30. package/dist/package/src/views/base/login-policy/index.vue +22 -11
  31. package/dist/package/src/views/base/menu/index.vue +23 -16
  32. package/dist/package/src/views/base/message/index.vue +65 -21
  33. package/dist/package/src/views/base/message-category/index.vue +10 -4
  34. package/dist/package/src/views/base/oauth-client/index.vue +15 -5
  35. package/dist/package/src/views/base/post/index.vue +10 -4
  36. package/dist/package/src/views/base/redact-output-policy/index.vue +12 -5
  37. package/dist/package/src/views/base/redact-rule/index.vue +8 -7
  38. package/dist/package/src/views/base/redact-storage-policy/index.vue +32 -8
  39. package/dist/package/src/views/base/role/index.vue +24 -17
  40. package/dist/package/src/views/base/tenant/index.vue +7 -6
  41. package/dist/package/src/views/base/tenant-project-grant/index.vue +44 -27
  42. package/dist/package/src/views/base/user/components/dept-tree.vue +4 -9
  43. package/dist/package/src/views/base/user/index.vue +39 -28
  44. package/dist/package/src/views/message/inbox/index.vue +8 -3
  45. package/dist/package/src/views/profile/components/base.vue +1 -1
  46. package/dist/package/src/views/profile/index.vue +1 -1
  47. package/dist/package/src/views/tool/cache/index.vue +1 -1
  48. package/dist/package/src/views/tool/code-gen/columns/index.vue +35 -16
  49. package/dist/package/src/views/tool/code-gen/table/index.vue +58 -31
  50. package/package.json +2 -2
@@ -17,7 +17,7 @@ export declare class SseServiceImpl {
17
17
  /** 创建或复用 SSE 订阅连接。 */
18
18
  SubscribeSse(request: SubscribeSseRequest): SharedSseConnection | null;
19
19
  /** 释放 SSE 共享连接。 */
20
- ReleaseSse(request: SubscribeSseRequest): void;
20
+ ReleaseSse(request: SubscribeSseRequest, connection?: SharedSseConnection): void;
21
21
  /** 构建 SSE 订阅地址。 */
22
22
  private buildSubscribeURL;
23
23
  /** 构建 SSE 共享连接键。 */
@@ -399,6 +399,8 @@ export declare const LOCALE_MESSAGES: {
399
399
  "system.base.log.field.os": string;
400
400
  "system.base.log.field.path": string;
401
401
  "system.base.log.field.project": string;
402
+ "system.base.log.field.role_code": string;
403
+ "system.base.log.field.role_id": string;
402
404
  "system.base.log.field.reason": string;
403
405
  "system.base.log.field.reason_code": string;
404
406
  "system.base.log.field.referer": string;
@@ -649,6 +651,11 @@ export declare const LOCALE_MESSAGES: {
649
651
  "system.base.message.content_format.plain": string;
650
652
  "system.base.message.detail.action": string;
651
653
  "system.base.message.detail.title": string;
654
+ "system.base.message.dispatch_status.pending": string;
655
+ "system.base.message.dispatch_status.running": string;
656
+ "system.base.message.dispatch_status.succeeded": string;
657
+ "system.base.message.dispatch_status.failed": string;
658
+ "system.base.message.dispatch_status.cancelled": string;
652
659
  "system.base.message.field.action_target": string;
653
660
  "system.base.message.field.action_type": string;
654
661
  "system.base.message.field.attempt_count": string;
@@ -761,6 +768,7 @@ export declare const LOCALE_MESSAGES: {
761
768
  "system.base.migration.title.list": string;
762
769
  "system.base.migration.value.default_module": string;
763
770
  "system.base.oauth_client.action.copy_credentials": string;
771
+ "system.base.oauth_client.confirm.rotate_credentials": string;
764
772
  "system.base.oauth_client.field.api": string;
765
773
  "system.base.oauth_client.field.client_id": string;
766
774
  "system.base.oauth_client.field.client_name": string;
@@ -1971,6 +1979,8 @@ export declare const LOCALE_MESSAGES: {
1971
1979
  "system.base.log.field.os": string;
1972
1980
  "system.base.log.field.path": string;
1973
1981
  "system.base.log.field.project": string;
1982
+ "system.base.log.field.role_code": string;
1983
+ "system.base.log.field.role_id": string;
1974
1984
  "system.base.log.field.reason": string;
1975
1985
  "system.base.log.field.reason_code": string;
1976
1986
  "system.base.log.field.referer": string;
@@ -2221,6 +2231,11 @@ export declare const LOCALE_MESSAGES: {
2221
2231
  "system.base.message.content_format.plain": string;
2222
2232
  "system.base.message.detail.action": string;
2223
2233
  "system.base.message.detail.title": string;
2234
+ "system.base.message.dispatch_status.pending": string;
2235
+ "system.base.message.dispatch_status.running": string;
2236
+ "system.base.message.dispatch_status.succeeded": string;
2237
+ "system.base.message.dispatch_status.failed": string;
2238
+ "system.base.message.dispatch_status.cancelled": string;
2224
2239
  "system.base.message.field.action_target": string;
2225
2240
  "system.base.message.field.action_type": string;
2226
2241
  "system.base.message.field.attempt_count": string;
@@ -2333,6 +2348,7 @@ export declare const LOCALE_MESSAGES: {
2333
2348
  "system.base.migration.title.list": string;
2334
2349
  "system.base.migration.value.default_module": string;
2335
2350
  "system.base.oauth_client.action.copy_credentials": string;
2351
+ "system.base.oauth_client.confirm.rotate_credentials": string;
2336
2352
  "system.base.oauth_client.field.api": string;
2337
2353
  "system.base.oauth_client.field.client_id": string;
2338
2354
  "system.base.oauth_client.field.client_name": string;
@@ -3543,6 +3559,8 @@ export declare const LOCALE_MESSAGES: {
3543
3559
  "system.base.log.field.os": string;
3544
3560
  "system.base.log.field.path": string;
3545
3561
  "system.base.log.field.project": string;
3562
+ "system.base.log.field.role_code": string;
3563
+ "system.base.log.field.role_id": string;
3546
3564
  "system.base.log.field.reason": string;
3547
3565
  "system.base.log.field.reason_code": string;
3548
3566
  "system.base.log.field.referer": string;
@@ -3793,6 +3811,11 @@ export declare const LOCALE_MESSAGES: {
3793
3811
  "system.base.message.content_format.plain": string;
3794
3812
  "system.base.message.detail.action": string;
3795
3813
  "system.base.message.detail.title": string;
3814
+ "system.base.message.dispatch_status.pending": string;
3815
+ "system.base.message.dispatch_status.running": string;
3816
+ "system.base.message.dispatch_status.succeeded": string;
3817
+ "system.base.message.dispatch_status.failed": string;
3818
+ "system.base.message.dispatch_status.cancelled": string;
3796
3819
  "system.base.message.field.action_target": string;
3797
3820
  "system.base.message.field.action_type": string;
3798
3821
  "system.base.message.field.attempt_count": string;
@@ -3905,6 +3928,7 @@ export declare const LOCALE_MESSAGES: {
3905
3928
  "system.base.migration.title.list": string;
3906
3929
  "system.base.migration.value.default_module": string;
3907
3930
  "system.base.oauth_client.action.copy_credentials": string;
3931
+ "system.base.oauth_client.confirm.rotate_credentials": string;
3908
3932
  "system.base.oauth_client.field.api": string;
3909
3933
  "system.base.oauth_client.field.client_id": string;
3910
3934
  "system.base.oauth_client.field.client_name": string;
@@ -5115,6 +5139,8 @@ export declare const LOCALE_MESSAGES: {
5115
5139
  "system.base.log.field.os": string;
5116
5140
  "system.base.log.field.path": string;
5117
5141
  "system.base.log.field.project": string;
5142
+ "system.base.log.field.role_code": string;
5143
+ "system.base.log.field.role_id": string;
5118
5144
  "system.base.log.field.reason": string;
5119
5145
  "system.base.log.field.reason_code": string;
5120
5146
  "system.base.log.field.referer": string;
@@ -5365,6 +5391,11 @@ export declare const LOCALE_MESSAGES: {
5365
5391
  "system.base.message.content_format.plain": string;
5366
5392
  "system.base.message.detail.action": string;
5367
5393
  "system.base.message.detail.title": string;
5394
+ "system.base.message.dispatch_status.pending": string;
5395
+ "system.base.message.dispatch_status.running": string;
5396
+ "system.base.message.dispatch_status.succeeded": string;
5397
+ "system.base.message.dispatch_status.failed": string;
5398
+ "system.base.message.dispatch_status.cancelled": string;
5368
5399
  "system.base.message.field.action_target": string;
5369
5400
  "system.base.message.field.action_type": string;
5370
5401
  "system.base.message.field.attempt_count": string;
@@ -5477,6 +5508,7 @@ export declare const LOCALE_MESSAGES: {
5477
5508
  "system.base.migration.title.list": string;
5478
5509
  "system.base.migration.value.default_module": string;
5479
5510
  "system.base.oauth_client.action.copy_credentials": string;
5511
+ "system.base.oauth_client.confirm.rotate_credentials": string;
5480
5512
  "system.base.oauth_client.field.api": string;
5481
5513
  "system.base.oauth_client.field.client_id": string;
5482
5514
  "system.base.oauth_client.field.client_name": string;
@@ -0,0 +1,26 @@
1
+ /** AI 助手联网搜索请求 */
2
+ export interface SearchAiWebRequest {
3
+ /** 搜索关键词 */
4
+ query: string;
5
+ /** 返回结果数量:0 表示默认5条,最大10条 */
6
+ limit: number;
7
+ }
8
+ /** AI 助手联网搜索响应 */
9
+ export interface SearchAiWebResponse {
10
+ /** 搜索结果列表 */
11
+ items: SearchAiWebItem[];
12
+ }
13
+ /** AI 助手联网搜索结果 */
14
+ export interface SearchAiWebItem {
15
+ /** 结果标题 */
16
+ title: string;
17
+ /** 结果链接 */
18
+ url: string;
19
+ /** 结果摘要 */
20
+ snippet: string;
21
+ }
22
+ /** Base AI 助手联网搜索服务 */
23
+ export interface AiSearchService {
24
+ /** 联网搜索公开信息并返回结果摘要 */
25
+ SearchAiWeb(request: SearchAiWebRequest): Promise<SearchAiWebResponse>;
26
+ }
@@ -121,7 +121,6 @@ export interface BaseRedactOutputPolicy {
121
121
  }
122
122
  /** 查询可出库脱敏字段请求。 */
123
123
  export interface GetBaseRedactOutputFieldDocRequest {
124
- /** 接口ID */
125
124
  api_id: number;
126
125
  }
127
126
  /** Admin出库脱敏策略服务。 */
@@ -61,10 +61,10 @@ export class SseServiceImpl {
61
61
  }
62
62
 
63
63
  /** 释放 SSE 共享连接。 */
64
- ReleaseSse(request: SubscribeSseRequest) {
64
+ ReleaseSse(request: SubscribeSseRequest, connection?: SharedSseConnection) {
65
65
  const connectionKey = this.buildConnectionKey(request);
66
66
  const cachedConnection = this.sharedConnections.get(connectionKey);
67
- if (!cachedConnection) {
67
+ if (!cachedConnection || (connection && cachedConnection !== connection)) {
68
68
  return;
69
69
  }
70
70
  cachedConnection.refCount -= 1;
@@ -77,10 +77,9 @@ export class SseServiceImpl {
77
77
 
78
78
  /** 构建 SSE 订阅地址。 */
79
79
  private buildSubscribeURL(request: SubscribeSseRequest) {
80
- const url = new URL(SSE_URL, window.location.origin);
81
- url.searchParams.set("stream", request.stream);
80
+ const url = new URL(`${SSE_URL}/${encodeURIComponent(request.stream)}`, window.location.origin);
82
81
  if (request.channel_id) {
83
- url.searchParams.set("channel", request.channel_id);
82
+ url.searchParams.set("channel_id", request.channel_id);
84
83
  }
85
84
  return url.toString();
86
85
  }
@@ -100,19 +99,27 @@ export class SseServiceImpl {
100
99
  try {
101
100
  const accessToken = await getRequestAccessToken();
102
101
  if (!accessToken) {
103
- this.sharedConnections.delete(connectionKey);
102
+ if (this.sharedConnections.get(connectionKey) === connection) this.sharedConnections.delete(connectionKey);
104
103
  return;
105
104
  }
106
105
 
106
+ const headers: Record<string, string> = {
107
+ Accept: EventStreamContentType,
108
+ Authorization: accessToken,
109
+ ...getLocaleRequestHeaders()
110
+ };
107
111
  await fetchEventSource(url, {
108
112
  method: "GET",
109
113
  signal: controller.signal,
110
114
  openWhenHidden: true,
111
- headers: {
112
- Accept: EventStreamContentType,
113
- Authorization: accessToken,
114
- ...getLocaleRequestHeaders()
115
+ fetch: async (input, init) => {
116
+ const token = await getRequestAccessToken();
117
+ if (!token) return new Response(null, { status: 401 });
118
+ const requestHeaders = new Headers(init?.headers);
119
+ requestHeaders.set("Authorization", token);
120
+ return window.fetch(input, { ...init, headers: requestHeaders });
115
121
  },
122
+ headers,
116
123
  async onopen(response) {
117
124
  const contentType = response.headers.get("content-type") ?? "";
118
125
  if (response.ok && contentType.startsWith(EventStreamContentType)) {
@@ -161,7 +168,7 @@ export class SseServiceImpl {
161
168
  } else if (error instanceof SsePermissionError) {
162
169
  ElMessage.error(error.message);
163
170
  }
164
- this.sharedConnections.delete(connectionKey);
171
+ if (this.sharedConnections.get(connectionKey) === connection) this.sharedConnections.delete(connectionKey);
165
172
  }
166
173
  }
167
174
  }
@@ -199,6 +206,6 @@ export function subscribeSseEvent<T>(
199
206
  if (currentListeners && currentListeners.size === 0) {
200
207
  connection.listeners.delete(eventName);
201
208
  }
202
- defSseService.ReleaseSse(request);
209
+ defSseService.ReleaseSse(request, connection);
203
210
  };
204
211
  }
@@ -2,7 +2,7 @@
2
2
  <div class="table-box">
3
3
  <ProTable ref="proTable" row-key="id" :columns="resolvedColumns" :request-api="requestTable" />
4
4
 
5
- <ProDialog v-model="dialog.visible" :title="config.detailTitle" width="1280px" @close="handleCloseDialog">
5
+ <ProDialog ref="dialogRef" v-model="dialog.visible" :title="config.detailTitle" width="1280px" @close="handleCloseDialog">
6
6
  <el-descriptions border :column="2" class="detail-container">
7
7
  <el-descriptions-item
8
8
  v-for="field in config.detailFields"
@@ -93,6 +93,7 @@ export interface LogTableConfig {
93
93
 
94
94
  const props = defineProps<{ config: LogTableConfig }>();
95
95
  const proTable = ref<ProTableInstance>();
96
+ const dialogRef = ref<InstanceType<typeof ProDialog>>();
96
97
  const detail = reactive<Record<string, unknown>>({});
97
98
  const dialog = reactive({ visible: false });
98
99
  const traceItems = ref<BaseLogTraceItem[]>([]);
@@ -107,27 +108,33 @@ async function requestTable(params: Record<string, unknown>) {
107
108
 
108
109
  /** 打开审计详情弹窗。 */
109
110
  async function handleOpenDialog(id: string) {
110
- const value = await props.config.get(id);
111
- Object.keys(detail).forEach(key => delete detail[key]);
112
- Object.assign(detail, value);
113
- dialog.visible = true;
114
- traceItems.value = [];
115
- const requestID = String(detail.request_id ?? "");
116
- const traceID = String(detail.trace_id ?? "");
117
- if (!props.config.trace || (!requestID && !traceID)) return;
118
- traceLoading.value = true;
119
- try {
120
- traceItems.value = await props.config.trace(requestID, traceID);
121
- } catch {
122
- traceItems.value = [];
123
- } finally {
124
- traceLoading.value = false;
125
- }
111
+ await dialogRef.value?.open({
112
+ load: async () => {
113
+ const value = await props.config.get(id);
114
+ const requestID = String(value.request_id ?? "");
115
+ const traceID = String(value.trace_id ?? "");
116
+ let traces: BaseLogTraceItem[] = [];
117
+ if (props.config.trace && (requestID || traceID)) {
118
+ try {
119
+ traces = await props.config.trace(requestID, traceID);
120
+ } catch {
121
+ traces = [];
122
+ }
123
+ }
124
+ return { value, traces };
125
+ },
126
+ commit: ({ value, traces }) => {
127
+ Object.keys(detail).forEach(key => delete detail[key]);
128
+ Object.assign(detail, value);
129
+ traceItems.value = traces;
130
+ traceLoading.value = false;
131
+ }
132
+ });
126
133
  }
127
134
 
128
135
  /** 关闭并清理审计详情弹窗。 */
129
136
  function handleCloseDialog() {
130
- dialog.visible = false;
137
+ dialogRef.value?.close();
131
138
  Object.keys(detail).forEach(key => delete detail[key]);
132
139
  traceItems.value = [];
133
140
  traceLoading.value = false;
@@ -38,7 +38,7 @@
38
38
  <el-button class="notification-more" text @click="openInbox">{{ t("system.notification.action.view_all") }}</el-button>
39
39
  </div>
40
40
  </el-popover>
41
- <ProDialog v-model="detailVisible" :title="detail?.title" width="720px" destroy-on-close :show-footer="false">
41
+ <ProDialog ref="detailDialogRef" v-model="detailVisible" :title="detail?.title" width="720px" destroy-on-close :show-footer="false">
42
42
  <div v-if="detail" class="notification-detail">
43
43
  <div class="notification-detail-meta">
44
44
  <span class="notification-detail-category" :style="{ color: detail.category_color || undefined }">
@@ -82,6 +82,7 @@ import {
82
82
 
83
83
  const router = useRouter();
84
84
  const popoverVisible = ref(false);
85
+ const detailDialogRef = ref<InstanceType<typeof ProDialog>>();
85
86
  const unreadTotal = ref(0);
86
87
  const latestDeliveryID = ref(0);
87
88
  const notifications = ref<Notification[]>([]);
@@ -154,12 +155,18 @@ async function markAllRead() {
154
155
  async function openNotification(row: Notification) {
155
156
  popoverVisible.value = false;
156
157
  const wasUnread = !row.read_at;
157
- const [notification] = await Promise.all([
158
- defNotificationService.GetNotification({ id: row.id }),
159
- wasUnread ? defNotificationService.MarkNotificationRead({ ids: [row.id] }) : Promise.resolve()
160
- ]);
161
- detail.value = notification;
162
- detailVisible.value = true;
158
+ await detailDialogRef.value?.open({
159
+ load: async () => {
160
+ const [notification] = await Promise.all([
161
+ defNotificationService.GetNotification({ id: row.id }),
162
+ wasUnread ? defNotificationService.MarkNotificationRead({ ids: [row.id] }) : Promise.resolve()
163
+ ]);
164
+ return notification;
165
+ },
166
+ commit: notification => {
167
+ detail.value = notification;
168
+ }
169
+ });
163
170
  notifications.value = notifications.value.filter(item => item.id !== row.id);
164
171
  if (wasUnread) unreadTotal.value = Math.max(0, unreadTotal.value - 1);
165
172
  }
@@ -349,16 +349,22 @@ function resolveTenantProjectSlotContext(scope: Record<string, any>) {
349
349
 
350
350
  /** 打开项目编辑弹窗。 */
351
351
  async function handleOpenDialog(id?: number) {
352
- resetForm();
353
- await loadTenantOptions();
354
- dialog.titleKey = id ? "common.action.edit_resource" : "common.action.create_resource";
355
- dialog.visible = true;
356
- if (id) Object.assign(formData, await defBaseTenantProjectService.GetBaseTenantProject({ id }));
352
+ await formDialogRef.value?.open({
353
+ load: async () => {
354
+ await loadTenantOptions();
355
+ return id ? defBaseTenantProjectService.GetBaseTenantProject({ id }) : undefined;
356
+ },
357
+ commit: data => {
358
+ resetForm();
359
+ dialog.titleKey = id ? "common.action.edit_resource" : "common.action.create_resource";
360
+ if (data) Object.assign(formData, data);
361
+ }
362
+ });
357
363
  }
358
364
 
359
365
  /** 关闭项目弹窗并清理表单。 */
360
366
  function handleCloseDialog() {
361
- dialog.visible = false;
367
+ formDialogRef.value?.close();
362
368
  resetForm();
363
369
  }
364
370
 
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <FormDialog
3
+ ref="formDialogRef"
3
4
  v-model="visible"
4
5
  :title="t('system.base.tenant_project.grant')"
5
6
  :model="form"
@@ -26,6 +27,7 @@ import type {
26
27
  import type { SelectOptionResponse_Option } from "@liujitcn/kratos-admin-system/rpc/common/v1/common";
27
28
 
28
29
  const visible = ref(false);
30
+ const formDialogRef = ref<InstanceType<typeof FormDialog>>();
29
31
  const loading = ref(false);
30
32
  const projectOptions = ref<SelectOptionResponse_Option[]>([]);
31
33
  const form = reactive({ tenant_id: 0, all: false, project_id: [] as number[] });
@@ -42,13 +44,26 @@ const fields = computed<ProFormField[]>(() => [
42
44
 
43
45
  /** 打开指定主体的授权表单,目标租户切换后重新加载直接授权。 */
44
46
  async function open(type: BaseTenantProjectGrantSubjectType, id: number, tenantId: number) {
45
- reset();
46
- subjectType = type;
47
- subjectId = id;
48
- await loadTenantOptions(true);
49
- form.tenant_id = tenantId;
50
- visible.value = true;
51
- await load();
47
+ await formDialogRef.value?.open({
48
+ load: async () => {
49
+ await loadTenantOptions(true);
50
+ const request = { tenant_id: tenantId, subject_type: type, subject_id: id };
51
+ const [options, grant] = await Promise.all([
52
+ defBaseTenantProjectService.OptionBaseTenantProject({ tenant_id: request.tenant_id }),
53
+ defBaseTenantProjectGrantService.GetBaseTenantProjectGrant(request)
54
+ ]);
55
+ return { request, projects: options.list ?? [], grant };
56
+ },
57
+ commit: ({ request, projects, grant }) => {
58
+ reset();
59
+ subjectType = request.subject_type;
60
+ subjectId = request.subject_id;
61
+ form.tenant_id = request.tenant_id;
62
+ projectOptions.value = projects;
63
+ form.all = grant.project_id.length === 1 && grant.project_id[0] === 0;
64
+ form.project_id = form.all ? [] : grant.project_id;
65
+ }
66
+ });
52
67
  }
53
68
 
54
69
  /** 加载目标租户项目和当前主体的直接授权,避免快速切换时旧响应覆盖新结果。 */
@@ -398,6 +398,8 @@
398
398
  "system.base.log.field.os": "Operating system",
399
399
  "system.base.log.field.path": "Path",
400
400
  "system.base.log.field.project": "Project",
401
+ "system.base.log.field.role_code": "Role code",
402
+ "system.base.log.field.role_id": "Role ID",
401
403
  "system.base.log.field.reason": "Reason",
402
404
  "system.base.log.field.reason_code": "Reason code",
403
405
  "system.base.log.field.referer": "Referrer",
@@ -648,6 +650,11 @@
648
650
  "system.base.message.content_format.plain": "Plain text",
649
651
  "system.base.message.detail.action": "Details",
650
652
  "system.base.message.detail.title": "Message details",
653
+ "system.base.message.dispatch_status.pending": "Pending",
654
+ "system.base.message.dispatch_status.running": "Delivering",
655
+ "system.base.message.dispatch_status.succeeded": "Completed",
656
+ "system.base.message.dispatch_status.failed": "Failed",
657
+ "system.base.message.dispatch_status.cancelled": "Cancelled",
651
658
  "system.base.message.field.action_target": "Action view key",
652
659
  "system.base.message.field.action_type": "Click action",
653
660
  "system.base.message.field.attempt_count": "Attempts",
@@ -760,6 +767,7 @@
760
767
  "system.base.migration.title.list": "Migration records",
761
768
  "system.base.migration.value.default_module": "Database migration",
762
769
  "system.base.oauth_client.action.copy_credentials": "Copy credentials",
770
+ "system.base.oauth_client.confirm.rotate_credentials": "Rotating the client credentials immediately invalidates the old secret. Continue?",
763
771
  "system.base.oauth_client.field.api": "Authorized APIs",
764
772
  "system.base.oauth_client.field.client_id": "Client ID",
765
773
  "system.base.oauth_client.field.client_name": "Client name",
@@ -398,6 +398,8 @@
398
398
  "system.base.log.field.os": "オペレーティング システム",
399
399
  "system.base.log.field.path": "パス",
400
400
  "system.base.log.field.project": "プロジェクト",
401
+ "system.base.log.field.role_code": "ロールコード",
402
+ "system.base.log.field.role_id": "ロール ID",
401
403
  "system.base.log.field.reason": "理由",
402
404
  "system.base.log.field.reason_code": "理由コード",
403
405
  "system.base.log.field.referer": "ソース ページ",
@@ -648,6 +650,11 @@
648
650
  "system.base.message.content_format.plain": "プレーンテキスト",
649
651
  "system.base.message.detail.action": "詳細",
650
652
  "system.base.message.detail.title": "メッセージ詳細",
653
+ "system.base.message.dispatch_status.pending": "配信待ち",
654
+ "system.base.message.dispatch_status.running": "配信中",
655
+ "system.base.message.dispatch_status.succeeded": "完了",
656
+ "system.base.message.dispatch_status.failed": "失敗",
657
+ "system.base.message.dispatch_status.cancelled": "キャンセル済み",
651
658
  "system.base.message.field.action_target": "遷移先ビューキー",
652
659
  "system.base.message.field.action_type": "クリック操作",
653
660
  "system.base.message.field.attempt_count": "試行回数",
@@ -760,6 +767,7 @@
760
767
  "system.base.migration.title.list": "マイグレーション履歴一覧",
761
768
  "system.base.migration.value.default_module": "データベースの移行",
762
769
  "system.base.oauth_client.action.copy_credentials": "資格情報をコピー",
770
+ "system.base.oauth_client.confirm.rotate_credentials": "クライアント資格情報をローテーションすると旧シークレットは直ちに無効になります。続行しますか?",
763
771
  "system.base.oauth_client.field.api": "許可された API",
764
772
  "system.base.oauth_client.field.client_id": "クライアント ID",
765
773
  "system.base.oauth_client.field.client_name": "クライアント名",
@@ -398,6 +398,8 @@
398
398
  "system.base.log.field.os": "操作系统",
399
399
  "system.base.log.field.path": "请求路径",
400
400
  "system.base.log.field.project": "项目范围",
401
+ "system.base.log.field.role_code": "角色编码",
402
+ "system.base.log.field.role_id": "角色 ID",
401
403
  "system.base.log.field.reason": "原因说明",
402
404
  "system.base.log.field.reason_code": "原因编码",
403
405
  "system.base.log.field.referer": "来源页",
@@ -648,6 +650,11 @@
648
650
  "system.base.message.content_format.plain": "纯文本",
649
651
  "system.base.message.detail.action": "详情",
650
652
  "system.base.message.detail.title": "消息详情",
653
+ "system.base.message.dispatch_status.pending": "待投递",
654
+ "system.base.message.dispatch_status.running": "投递中",
655
+ "system.base.message.dispatch_status.succeeded": "已完成",
656
+ "system.base.message.dispatch_status.failed": "失败",
657
+ "system.base.message.dispatch_status.cancelled": "已取消",
651
658
  "system.base.message.field.action_target": "动作视图键",
652
659
  "system.base.message.field.action_type": "点击动作",
653
660
  "system.base.message.field.attempt_count": "尝试次数",
@@ -760,6 +767,7 @@
760
767
  "system.base.migration.title.list": "迁移记录列表",
761
768
  "system.base.migration.value.default_module": "数据库迁移",
762
769
  "system.base.oauth_client.action.copy_credentials": "复制客户端凭据",
770
+ "system.base.oauth_client.confirm.rotate_credentials": "轮换客户端凭据会立即使旧密钥失效,确认继续吗?",
763
771
  "system.base.oauth_client.field.api": "授权接口",
764
772
  "system.base.oauth_client.field.client_id": "客户端标识",
765
773
  "system.base.oauth_client.field.client_name": "客户端名称",
@@ -398,6 +398,8 @@
398
398
  "system.base.log.field.os": "作業系統",
399
399
  "system.base.log.field.path": "請求路徑",
400
400
  "system.base.log.field.project": "專案範圍",
401
+ "system.base.log.field.role_code": "角色編碼",
402
+ "system.base.log.field.role_id": "角色 ID",
401
403
  "system.base.log.field.reason": "原因說明",
402
404
  "system.base.log.field.reason_code": "原因編碼",
403
405
  "system.base.log.field.referer": "來源頁",
@@ -648,6 +650,11 @@
648
650
  "system.base.message.content_format.plain": "純文字",
649
651
  "system.base.message.detail.action": "詳情",
650
652
  "system.base.message.detail.title": "訊息詳情",
653
+ "system.base.message.dispatch_status.pending": "待投遞",
654
+ "system.base.message.dispatch_status.running": "投遞中",
655
+ "system.base.message.dispatch_status.succeeded": "已完成",
656
+ "system.base.message.dispatch_status.failed": "失敗",
657
+ "system.base.message.dispatch_status.cancelled": "已取消",
651
658
  "system.base.message.field.action_target": "動作視圖鍵",
652
659
  "system.base.message.field.action_type": "點擊動作",
653
660
  "system.base.message.field.attempt_count": "嘗試次數",
@@ -760,6 +767,7 @@
760
767
  "system.base.migration.title.list": "遷移記錄列表",
761
768
  "system.base.migration.value.default_module": "資料庫遷移",
762
769
  "system.base.oauth_client.action.copy_credentials": "複製客戶端憑據",
770
+ "system.base.oauth_client.confirm.rotate_credentials": "輪換客戶端憑據會立即使舊密鑰失效,確定要繼續嗎?",
763
771
  "system.base.oauth_client.field.api": "授權介面",
764
772
  "system.base.oauth_client.field.client_id": "客戶端識別碼",
765
773
  "system.base.oauth_client.field.client_name": "客戶端名稱",
@@ -0,0 +1,37 @@
1
+ // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2
+ // versions:
3
+ // protoc-gen-ts_proto v2.11.8
4
+ // protoc unknown
5
+ // source: base/v1/ai_search.proto
6
+
7
+ /* eslint-disable */
8
+
9
+ /** AI 助手联网搜索请求 */
10
+ export interface SearchAiWebRequest {
11
+ /** 搜索关键词 */
12
+ query: string;
13
+ /** 返回结果数量:0 表示默认5条,最大10条 */
14
+ limit: number;
15
+ }
16
+
17
+ /** AI 助手联网搜索响应 */
18
+ export interface SearchAiWebResponse {
19
+ /** 搜索结果列表 */
20
+ items: SearchAiWebItem[];
21
+ }
22
+
23
+ /** AI 助手联网搜索结果 */
24
+ export interface SearchAiWebItem {
25
+ /** 结果标题 */
26
+ title: string;
27
+ /** 结果链接 */
28
+ url: string;
29
+ /** 结果摘要 */
30
+ snippet: string;
31
+ }
32
+
33
+ /** Base AI 助手联网搜索服务 */
34
+ export interface AiSearchService {
35
+ /** 联网搜索公开信息并返回结果摘要 */
36
+ SearchAiWeb(request: SearchAiWebRequest): Promise<SearchAiWebResponse>;
37
+ }
@@ -143,7 +143,6 @@ export interface BaseRedactOutputPolicy {
143
143
 
144
144
  /** 查询可出库脱敏字段请求。 */
145
145
  export interface GetBaseRedactOutputFieldDocRequest {
146
- /** 接口ID */
147
146
  api_id: number;
148
147
  }
149
148
 
@@ -107,6 +107,7 @@ const pendingDeltaMap = new Map<string, AiStreamPayload>();
107
107
  const runningStreamTaskMap = new Map<string, AiStreamTask>();
108
108
  let pendingDeltaFrame = 0;
109
109
  let speakingMessageID = "";
110
+ let createSessionPromise: Promise<string | undefined> | undefined;
110
111
 
111
112
  /** 当前会话的流式任务状态。 */
112
113
  type AiStreamTask = {
@@ -728,13 +729,21 @@ async function ensureActiveSession() {
728
729
 
729
730
  /** 创建新的助手会话,并同步到本地列表。 */
730
731
  async function createSession(options?: { title?: string }) {
731
- const response = await defAiSessionService.CreateAiSession({
732
- title: options?.title || t("system.ai.chat.value.new_conversation"),
733
- terminal: Terminal.TERMINAL_ADMIN
734
- });
735
- const normalizedSession = normalizeSession(response.session);
736
- upsertSession(normalizedSession);
737
- return normalizedSession.id;
732
+ if (createSessionPromise) return createSessionPromise;
733
+ createSessionPromise = (async () => {
734
+ const response = await defAiSessionService.CreateAiSession({
735
+ title: options?.title || t("system.ai.chat.value.new_conversation"),
736
+ terminal: Terminal.TERMINAL_ADMIN
737
+ });
738
+ const normalizedSession = normalizeSession(response.session);
739
+ upsertSession(normalizedSession);
740
+ return normalizedSession.id;
741
+ })();
742
+ try {
743
+ return await createSessionPromise;
744
+ } finally {
745
+ createSessionPromise = undefined;
746
+ }
738
747
  }
739
748
 
740
749
  /** 使用当前消息内容生成一个易识别的分支会话标题。 */
@@ -35,7 +35,7 @@ const resultOptions = computed(() =>
35
35
  ])
36
36
  );
37
37
  const columns = computed<ColumnProps[]>(() => [
38
- { prop: "operation", label: t("system.base.log.field.operation"), minWidth: 320, search: { el: "input" } },
38
+ { prop: "operation", label: t("system.base.log.field.operation"), minWidth: 320, search: { el: "input", key: "keyword" } },
39
39
  { prop: "method", label: t("system.base.log.field.method"), minWidth: 90 },
40
40
  { prop: "status_code", label: t("system.base.log.field.status_code"), minWidth: 100, align: "right" },
41
41
  {