@liujitcn/kratos-admin-system 0.0.64 → 0.0.66
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 +5 -3
- package/dist/package/declarations/src/api/base/v1/ai_knowledge.d.ts +7 -0
- package/dist/package/declarations/src/api/system/admin/v1/ai_provider.d.ts +5 -1
- package/dist/package/declarations/src/api/system/admin/v1/ai_query.d.ts +10 -0
- package/dist/package/declarations/src/api/system/admin/v1/ai_session.d.ts +9 -0
- package/dist/package/declarations/src/locales/generated.d.ts +1405 -1089
- package/dist/package/declarations/src/rpc/base/v1/ai_knowledge.d.ts +22 -0
- package/dist/package/declarations/src/rpc/base/v1/ai_message.d.ts +2 -0
- package/dist/package/declarations/src/rpc/base/v1/ai_provider.d.ts +13 -6
- package/dist/package/declarations/src/rpc/system/admin/v1/ai_provider.d.ts +85 -4
- package/dist/package/declarations/src/rpc/system/admin/v1/ai_query.d.ts +73 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/ai_session.d.ts +114 -0
- package/dist/package/declarations/src/views/ai/chat/components/ChatPanel.vue.d.ts +9 -2
- package/dist/package/declarations/src/views/ai/chat/components/XSender.vue.d.ts +7 -0
- package/dist/package/declarations/src/views/ai/chat/modelDisplay.d.ts +5 -0
- package/dist/package/declarations/src/views/ai/chat/modelSelection.d.ts +9 -0
- package/dist/package/declarations/src/views/ai/query/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/ai/session/index.vue.d.ts +3 -0
- package/dist/package/src/api/base/v1/ai_knowledge.ts +22 -0
- package/dist/package/src/api/system/admin/v1/ai_provider.ts +14 -0
- package/dist/package/src/api/system/admin/v1/ai_query.ts +25 -0
- package/dist/package/src/api/system/admin/v1/ai_session.ts +25 -0
- package/dist/package/src/components/account/ChangePasswordForm.vue +1 -1
- package/dist/package/src/components/tenant-project/TenantProjectSelect.vue +21 -4
- package/dist/package/src/locales/en-US.json +351 -272
- package/dist/package/src/locales/ja-JP.json +351 -272
- package/dist/package/src/locales/zh-CN.json +361 -282
- package/dist/package/src/locales/zh-TW.json +351 -272
- package/dist/package/src/rpc/base/v1/ai_knowledge.ts +33 -0
- package/dist/package/src/rpc/base/v1/ai_message.ts +2 -0
- package/dist/package/src/rpc/base/v1/ai_provider.ts +14 -6
- package/dist/package/src/rpc/system/admin/v1/ai_provider.ts +93 -4
- package/dist/package/src/rpc/system/admin/v1/ai_query.ts +89 -0
- package/dist/package/src/rpc/system/admin/v1/ai_session.ts +131 -0
- package/dist/package/src/views/ai/chat/components/ChatPanel.vue +22 -1
- package/dist/package/src/views/ai/chat/components/XSender.vue +367 -71
- package/dist/package/src/views/ai/chat/index.vue +46 -8
- package/dist/package/src/views/ai/chat/modelDisplay.ts +67 -0
- package/dist/package/src/views/ai/chat/modelSelection.ts +31 -0
- package/dist/package/src/views/ai/query/index.vue +222 -0
- package/dist/package/src/views/ai/session/index.vue +422 -0
- package/dist/package/src/views/base/ai-provider/index.vue +301 -154
- package/dist/package/src/views/base/api-rate-limit-policy/index.vue +4 -3
- package/dist/package/src/views/base/message-provider/index.vue +9 -5
- package/dist/package/src/views/base/message-template/index.vue +2 -2
- package/dist/package/src/views/base/oauth-provider/index.vue +2 -2
- package/dist/package/src/views/base/rate-limit-rule/index.vue +8 -3
- package/dist/package/src/views/base/tenant-project-grant/index.vue +9 -4
- package/dist/package/src/views/tool/code-gen/config.ts +1 -0
- package/package.json +2 -2
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<el-icon class="parameter-help" tabindex="0"><QuestionFilled /></el-icon>
|
|
31
31
|
</el-tooltip>
|
|
32
32
|
</span>
|
|
33
|
-
<el-input-number v-model="form.params.tokens_per_second" :min="0" :max="1000000" :precision="3" :step="1" controls-position="right" />
|
|
33
|
+
<el-input-number v-model="form.params.tokens_per_second" :min="0.001" :max="1000000" :precision="3" :step="1" controls-position="right" />
|
|
34
34
|
</div>
|
|
35
35
|
<div class="parameter-item">
|
|
36
36
|
<span class="parameter-label">
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
<el-icon class="parameter-help" tabindex="0"><QuestionFilled /></el-icon>
|
|
40
40
|
</el-tooltip>
|
|
41
41
|
</span>
|
|
42
|
-
<el-input-number v-model="form.params.burst" :min="
|
|
42
|
+
<el-input-number v-model="form.params.burst" :min="1" :max="1000000" :precision="0" controls-position="right" />
|
|
43
43
|
</div>
|
|
44
44
|
</div>
|
|
45
45
|
<div v-else-if="windowedAlgorithms.includes(form.rule_type)" class="parameter-grid">
|
|
@@ -262,7 +262,8 @@ function resetForm() {
|
|
|
262
262
|
/** 根据所选模板加载默认参数。 */
|
|
263
263
|
function handleRuleChange(ruleId?: number) {
|
|
264
264
|
const selected = ruleCatalog.value.find(rule => rule.id === Number(ruleId));
|
|
265
|
-
|
|
265
|
+
// 模板缺失时保留当前算法类型,避免编辑态参数区空白导致无法保存。
|
|
266
|
+
if (selected) form.rule_type = selected.rule_type;
|
|
266
267
|
form.params = selected ? parseRateLimitParams(form.rule_type, selected.default_params) : defaultRateLimitParams(form.rule_type);
|
|
267
268
|
}
|
|
268
269
|
|
|
@@ -59,8 +59,8 @@ const statusOptions = computed<ProFormOption[]>(() => [
|
|
|
59
59
|
]);
|
|
60
60
|
|
|
61
61
|
const rules = computed(() => ({
|
|
62
|
-
provider: [{ required: true, message: t("system.base.message_provider.
|
|
63
|
-
name: [{ required: true, message: t("system.base.message_provider.
|
|
62
|
+
provider: [{ required: true, message: t("system.base.message_provider.validation.provider"), trigger: "blur" }],
|
|
63
|
+
name: [{ required: true, message: t("system.base.message_provider.validation.name"), trigger: "blur" }]
|
|
64
64
|
}));
|
|
65
65
|
|
|
66
66
|
const formFields = computed<ProFormField[]>(() => [
|
|
@@ -68,8 +68,8 @@ const formFields = computed<ProFormField[]>(() => [
|
|
|
68
68
|
{ prop: "name", label: t("system.base.message_provider.field.name"), component: "input", props: { maxlength: 50 } },
|
|
69
69
|
{ prop: "description", label: t("system.base.message_provider.field.description"), component: "input", colSpan: 24, props: { maxlength: 255 } },
|
|
70
70
|
{ prop: "icon", label: t("system.base.message_provider.field.icon"), component: "input", props: { maxlength: 100 } },
|
|
71
|
-
{ prop: "client_id", label: t("system.base.message_provider.field.client_id"), component: "input", props: { maxlength: 255 } },
|
|
72
|
-
{ prop: "client_secret", label: t("system.base.message_provider.field.client_secret"), component: "input", props: { type: "password", showPassword: true, maxlength: 1024, placeholder: dialog.editing ? t("system.base.message_provider.placeholder.keep_secret") : "" } },
|
|
71
|
+
{ prop: "client_id", label: t("system.base.message_provider.field.client_id"), component: "input", props: { maxlength: 255, autocomplete: "off" } },
|
|
72
|
+
{ prop: "client_secret", label: t("system.base.message_provider.field.client_secret"), component: "input", props: { type: "password", showPassword: true, maxlength: 1024, autocomplete: "new-password", placeholder: dialog.editing ? t("system.base.message_provider.placeholder.keep_secret") : "" } },
|
|
73
73
|
{ prop: "config_items", label: t("system.base.message_provider.field.config"), component: "kv-list", props: { keyInputProps: { maxlength: 128 } } },
|
|
74
74
|
{ prop: "sort", label: t("common.field.sort"), component: "input-number", props: { min: 0, precision: 0 } },
|
|
75
75
|
{ prop: "status", label: t("common.field.status"), component: "radio-group", options: statusOptions.value }
|
|
@@ -131,7 +131,11 @@ async function handleSubmit() {
|
|
|
131
131
|
async function handleDelete(value: BaseMessageProvider | number | number[]) {
|
|
132
132
|
const ids = (Array.isArray(value) ? value : typeof value === "object" ? [value.id] : normalizeSelectedIds(value)).join(",");
|
|
133
133
|
if (!ids) return;
|
|
134
|
-
|
|
134
|
+
try {
|
|
135
|
+
await ElMessageBox.confirm(t("common.confirm.delete"), t("common.title.warning"), { type: "warning" });
|
|
136
|
+
} catch {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
135
139
|
await defBaseMessageProviderService.DeleteBaseMessageProvider({ id: ids });
|
|
136
140
|
await proTable.value?.getTableList();
|
|
137
141
|
ElMessage.success(t("common.message.operation_success"));
|
|
@@ -60,7 +60,7 @@ const contentFormatOptions = computed<ProFormOption[]>(() => [
|
|
|
60
60
|
]);
|
|
61
61
|
const categoryOptions = computed<ProFormOption[]>(() => categories.value.map(item => ({ label: item.name, value: item.id })));
|
|
62
62
|
const providerOptions = computed<ProFormOption[]>(() => providers.value.map(item => ({ label: item.name, value: item.id, disabled: item.status !== 1 })));
|
|
63
|
-
const rules = computed(() => ({ category_id: [{ required: true, message: t("system.base.message_template.
|
|
63
|
+
const rules = computed(() => ({ category_id: [{ required: true, message: t("system.base.message_template.validation.category"), trigger: "change" }], provider_id: [{ required: true, message: t("system.base.message_template.validation.provider"), trigger: "change" }], title: [{ required: true, message: t("system.base.message_template.validation.title"), trigger: "blur" }] }));
|
|
64
64
|
const formFields = computed<ProFormField[]>(() => [
|
|
65
65
|
{ prop: "category_id", label: t("system.base.message_template.field.category"), component: "select", options: categoryOptions.value, props: { disabled: dialog.editing, filterable: true } },
|
|
66
66
|
{ prop: "provider_id", label: t("system.base.message_template.field.provider"), component: "select", options: providerOptions.value, props: { disabled: dialog.editing, filterable: true } },
|
|
@@ -97,7 +97,7 @@ async function loadOptions() {
|
|
|
97
97
|
async function requestTable(params: Record<string, unknown>) { const data = await defBaseMessageTemplateService.PageBaseMessageTemplate(buildPageRequest<PageBaseMessageTemplateRequest>(params as unknown as PageBaseMessageTemplateRequest)); return { data: { list: data.base_message_templates ?? [], total: data.total } }; }
|
|
98
98
|
async function openDialog(id?: number) { await loadOptions(); await formDialogRef.value?.open({ load: () => (id ? defBaseMessageTemplateService.GetBaseMessageTemplate({ id }) : undefined), commit: data => { Object.assign(formData, defaultForm(), data ?? {}); dialog.editing = Boolean(id); formData.config_items = configToItems(formData.config); } }); }
|
|
99
99
|
async function handleSubmit() { if (!(await formDialogRef.value?.validate())) return; const config = configItemsToMap(formData.config_items); if (!config) return; const payload = JSON.parse(JSON.stringify(formData)) as BaseMessageTemplateForm & { config_items?: ConfigItem[] }; delete payload.config_items; payload.config = config; if (payload.id) await defBaseMessageTemplateService.UpdateBaseMessageTemplate({ base_message_template: payload }); else await defBaseMessageTemplateService.CreateBaseMessageTemplate({ base_message_template: payload }); ElMessage.success(t("common.message.operation_success")); dialog.visible = false; await proTable.value?.getTableList(); }
|
|
100
|
-
async function handleDelete(value: BaseMessageTemplate | number | number[]) { const ids = (Array.isArray(value) ? value : typeof value === "object" ? [value.id] : normalizeSelectedIds(value)).join(","); if (!ids) return; await ElMessageBox.confirm(t("common.confirm.delete"), t("common.title.warning"), { type: "warning" }); await defBaseMessageTemplateService.DeleteBaseMessageTemplate({ id: ids }); await proTable.value?.getTableList(); ElMessage.success(t("common.message.operation_success")); }
|
|
100
|
+
async function handleDelete(value: BaseMessageTemplate | number | number[]) { const ids = (Array.isArray(value) ? value : typeof value === "object" ? [value.id] : normalizeSelectedIds(value)).join(","); if (!ids) return; try { await ElMessageBox.confirm(t("common.confirm.delete"), t("common.title.warning"), { type: "warning" }); } catch { return; } await defBaseMessageTemplateService.DeleteBaseMessageTemplate({ id: ids }); await proTable.value?.getTableList(); ElMessage.success(t("common.message.operation_success")); }
|
|
101
101
|
function handleClose() { Object.assign(formData, defaultForm()); formDialogRef.value?.resetFields(); }
|
|
102
102
|
function contentFormatLabel(value: MessageContentFormat) { return contentFormatOptions.value.find(item => item.value === value)?.label ?? ""; }
|
|
103
103
|
function configToItems(config: Record<string, any> | undefined): ConfigItem[] { return Object.entries(config ?? {}).map(([key, value]) => ({ key, value: typeof value === "string" ? value : JSON.stringify(value) })); }
|
|
@@ -102,8 +102,8 @@ const formFields = computed<ProFormField[]>(() => [
|
|
|
102
102
|
{ prop: "name", suffixSlotName: "nameI18ns", label: t("system.base.oauth_provider.field.name"), component: "input", colSpan: 12, props: { maxlength: 50, placeholder: t("system.base.oauth_provider.placeholder.name") } },
|
|
103
103
|
{ prop: "description", suffixSlotName: "descriptionI18ns", label: t("system.base.oauth_provider.field.description"), component: "input", colSpan: 24, props: { maxlength: 255, placeholder: t("system.base.oauth_provider.placeholder.description") } },
|
|
104
104
|
{ prop: "icon", label: t("system.base.oauth_provider.field.icon"), component: "input", colSpan: 12, props: { maxlength: 255, placeholder: t("system.base.oauth_provider.placeholder.icon") } },
|
|
105
|
-
{ prop: "client_id", label: t("system.base.oauth_provider.field.client_id"), component: "input", colSpan: 12, props: { maxlength: 255, placeholder: t("system.base.oauth_provider.placeholder.client_id") } },
|
|
106
|
-
{ prop: "client_secret", label: t("system.base.oauth_provider.field.client_secret"), component: "input", colSpan: 12, props: { type: "password", showPassword: true, maxlength: 512, placeholder: dialog.editing ? t("system.base.oauth_provider.placeholder.keep_secret") : t("system.base.oauth_provider.placeholder.client_secret") } },
|
|
105
|
+
{ prop: "client_id", label: t("system.base.oauth_provider.field.client_id"), component: "input", colSpan: 12, props: { maxlength: 255, autocomplete: "off", placeholder: t("system.base.oauth_provider.placeholder.client_id") } },
|
|
106
|
+
{ prop: "client_secret", label: t("system.base.oauth_provider.field.client_secret"), component: "input", colSpan: 12, props: { type: "password", showPassword: true, maxlength: 512, autocomplete: "new-password", placeholder: dialog.editing ? t("system.base.oauth_provider.placeholder.keep_secret") : t("system.base.oauth_provider.placeholder.client_secret") } },
|
|
107
107
|
{ prop: "redirect_uri", label: t("system.base.oauth_provider.field.redirect_uri"), component: "input", colSpan: 12, props: { maxlength: 512, placeholder: t("system.base.oauth_provider.placeholder.redirect_uri") } },
|
|
108
108
|
{ prop: "scopes", label: t("system.base.oauth_provider.field.scopes"), component: "dynamic-list", colSpan: 12, props: { inputProps: { maxlength: 128, placeholder: t("system.base.oauth_provider.placeholder.scopes") } } },
|
|
109
109
|
{ prop: "config_items", label: t("system.base.oauth_provider.field.config"), component: "kv-list", colSpan: 12, props: { keyInputProps: { maxlength: 128 } } },
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
<el-icon class="parameter-help" tabindex="0"><QuestionFilled /></el-icon>
|
|
22
22
|
</el-tooltip>
|
|
23
23
|
</span>
|
|
24
|
-
<el-input-number v-model="form.params.tokens_per_second" :min="0" :max="1000000" :precision="3" :step="1" controls-position="right" />
|
|
24
|
+
<el-input-number v-model="form.params.tokens_per_second" :min="0.001" :max="1000000" :precision="3" :step="1" controls-position="right" />
|
|
25
25
|
</div>
|
|
26
26
|
<div class="parameter-item">
|
|
27
27
|
<span class="parameter-label">
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<el-icon class="parameter-help" tabindex="0"><QuestionFilled /></el-icon>
|
|
31
31
|
</el-tooltip>
|
|
32
32
|
</span>
|
|
33
|
-
<el-input-number v-model="form.params.burst" :min="
|
|
33
|
+
<el-input-number v-model="form.params.burst" :min="1" :max="1000000" :precision="0" controls-position="right" />
|
|
34
34
|
</div>
|
|
35
35
|
</div>
|
|
36
36
|
<div v-else-if="windowedAlgorithms.includes(form.rule_type)" class="parameter-grid">
|
|
@@ -125,10 +125,15 @@ const statusOptions = computed<ProFormOption[]>(() => [
|
|
|
125
125
|
{ label: t("common.status.enabled"), value: Status.STATUS_ENABLE },
|
|
126
126
|
{ label: t("common.status.disabled"), value: Status.STATUS_DISABLE }
|
|
127
127
|
]);
|
|
128
|
+
/** 当前算法说明提示,未选择算法时为空避免渲染空 tooltip。 */
|
|
129
|
+
const ruleTypeTooltip = computed(() => {
|
|
130
|
+
const key = rateLimitAlgorithmTooltipKey(form.rule_type);
|
|
131
|
+
return key ? t(key) : undefined;
|
|
132
|
+
});
|
|
128
133
|
const fields = computed<ProFormField[]>(() => [
|
|
129
134
|
{ prop: "code", label: t("system.base.rate_limit_rule.field.code"), component: "input", props: { disabled: Boolean(form.id) } },
|
|
130
135
|
{ prop: "name", label: t("system.base.rate_limit_rule.field.name"), component: "input" },
|
|
131
|
-
{ prop: "rule_type", label: t("system.base.rate_limit_rule.field.rule_type"), labelTooltip:
|
|
136
|
+
{ prop: "rule_type", label: t("system.base.rate_limit_rule.field.rule_type"), labelTooltip: ruleTypeTooltip.value, component: "select", options: algorithmOptions.value, props: { disabled: Boolean(form.id), onChange: handleAlgorithmChange } },
|
|
132
137
|
{ prop: "parameters", label: t("system.base.rate_limit_rule.field.parameters"), labelTooltip: t("system.base.rate_limit_rule.tooltip.parameters"), component: "slot", slotName: "parameters", colSpan: 24 },
|
|
133
138
|
{ prop: "status", label: t("common.field.status"), component: "radio-group", options: statusOptions.value },
|
|
134
139
|
{ prop: "remark", label: t("common.field.remark"), component: "textarea" }
|
|
@@ -150,9 +150,12 @@ const columns = computed<ColumnProps[]>(() => [
|
|
|
150
150
|
showOverflowTooltip: true,
|
|
151
151
|
render: scope => {
|
|
152
152
|
const row = scope.row as BaseTenantProjectGrant;
|
|
153
|
-
|
|
153
|
+
// proto3 JSON 会省略空数组字段,project_id / project_names 可能为 undefined。
|
|
154
|
+
const projectIds = row.project_id ?? [];
|
|
155
|
+
const projectNames = row.project_names ?? [];
|
|
156
|
+
return projectIds.length === 1 && projectIds[0] === 0
|
|
154
157
|
? t("system.base.tenant_project_grant.all_projects")
|
|
155
|
-
:
|
|
158
|
+
: projectNames.join(", ") || projectIds.join(", ") || t("common.value.none");
|
|
156
159
|
}
|
|
157
160
|
},
|
|
158
161
|
{
|
|
@@ -213,12 +216,14 @@ async function handleOpenDialog(row?: BaseTenantProjectGrant) {
|
|
|
213
216
|
await formDialogRef.value?.open({
|
|
214
217
|
load: async () => {
|
|
215
218
|
await loadTenantOptions(true);
|
|
219
|
+
// proto3 JSON 会省略空数组字段,行数据里的 project_id 可能为 undefined。
|
|
220
|
+
const rowProjectIds = row?.project_id ?? [];
|
|
216
221
|
const nextForm = {
|
|
217
222
|
tenant_id: row?.tenant_id ?? (isDefaultTenant.value ? undefined : Number(tenantOptions.value[0]?.value) || undefined),
|
|
218
223
|
subject_type: row?.subject_type ?? DEFAULT_SUBJECT_TYPE,
|
|
219
224
|
subject_id: row?.subject_id,
|
|
220
|
-
project_id: row && !(
|
|
221
|
-
all: Boolean(row &&
|
|
225
|
+
project_id: row && !(rowProjectIds.length === 1 && rowProjectIds[0] === 0) ? [...rowProjectIds] : [],
|
|
226
|
+
all: Boolean(row && rowProjectIds.length === 1 && rowProjectIds[0] === 0)
|
|
222
227
|
} satisfies ProjectGrantFormState;
|
|
223
228
|
const [projects, subjects] = await Promise.all([
|
|
224
229
|
requestProjectOptions(nextForm.tenant_id),
|
|
@@ -74,6 +74,7 @@ const codeGenFormComponentLabelKeys: Record<ProFormComponentType, string> = {
|
|
|
74
74
|
input: "system.code.gen.component.input",
|
|
75
75
|
password: "system.code.gen.component.password",
|
|
76
76
|
textarea: "system.code.gen.component.textarea",
|
|
77
|
+
"yaml-editor": "system.code.gen.component.yaml_editor",
|
|
77
78
|
"input-number": "system.code.gen.component.input_number",
|
|
78
79
|
"color-picker": "system.code.gen.component.color_picker",
|
|
79
80
|
segmented: "system.code.gen.component.segmented",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liujitcn/kratos-admin-system",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.66",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "kratos-admin system management module",
|
|
7
7
|
"license": "MIT",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"sortablejs": "^1.15.2",
|
|
17
17
|
"swagger-ui-dist": "^5.32.15",
|
|
18
18
|
"vue-element-plus-x": "^2.0.3",
|
|
19
|
-
"@liujitcn/kratos-admin-core": "0.0.
|
|
19
|
+
"@liujitcn/kratos-admin-core": "0.0.66"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
22
|
"@element-plus/icons-vue": "^2.3.1",
|