@liujitcn/kratos-admin-system 0.0.28 → 0.0.31

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 (135) hide show
  1. package/README.md +19 -2
  2. package/dist/package/declarations/src/api/base/notification.d.ts +24 -0
  3. package/dist/package/declarations/src/api/system/base_audit_log.d.ts +55 -0
  4. package/dist/package/declarations/src/api/system/base_dashboard.d.ts +14 -0
  5. package/dist/package/declarations/src/api/system/base_file.d.ts +13 -0
  6. package/dist/package/declarations/src/api/system/base_i18n.d.ts +5 -5
  7. package/dist/package/declarations/src/api/system/base_login_policy.d.ts +10 -0
  8. package/dist/package/declarations/src/api/system/base_message.d.ts +24 -0
  9. package/dist/package/declarations/src/api/system/base_message_category.d.ts +21 -0
  10. package/dist/package/declarations/src/api/system/base_session.d.ts +11 -0
  11. package/dist/package/declarations/src/api/system/oauth_client.d.ts +24 -0
  12. package/dist/package/declarations/src/components/AuditLogTable.vue.d.ts +45 -0
  13. package/dist/package/declarations/src/components/DynamicI18nCell.vue.d.ts +16 -0
  14. package/dist/package/declarations/src/components/DynamicI18nEditor.vue.d.ts +20 -0
  15. package/dist/package/declarations/src/components/auditLog.d.ts +9 -0
  16. package/dist/package/declarations/src/components/dynamicI18n.d.ts +38 -0
  17. package/dist/package/declarations/src/locales/generated.d.ts +1364 -68
  18. package/dist/package/declarations/src/rpc/base/v1/login.d.ts +149 -0
  19. package/dist/package/declarations/src/rpc/base/v1/notification.d.ts +281 -0
  20. package/dist/package/declarations/src/rpc/base/v1/oauth.d.ts +25 -0
  21. package/dist/package/declarations/src/rpc/base/v1/oauth_client.d.ts +23 -0
  22. package/dist/package/declarations/src/rpc/system/admin/v1/base_audit_log.d.ts +640 -0
  23. package/dist/package/declarations/src/rpc/system/admin/v1/base_config.d.ts +3 -3
  24. package/dist/package/declarations/src/rpc/system/admin/v1/base_dashboard.d.ts +60 -0
  25. package/dist/package/declarations/src/rpc/system/admin/v1/base_dict.d.ts +4 -4
  26. package/dist/package/declarations/src/rpc/system/admin/v1/base_file.d.ts +73 -0
  27. package/dist/package/declarations/src/rpc/system/admin/v1/base_i18n.d.ts +27 -23
  28. package/dist/package/declarations/src/rpc/system/admin/v1/base_job.d.ts +5 -0
  29. package/dist/package/declarations/src/rpc/system/admin/v1/base_login_policy.d.ts +51 -0
  30. package/dist/package/declarations/src/rpc/system/admin/v1/base_menu.d.ts +2 -2
  31. package/dist/package/declarations/src/rpc/system/admin/v1/base_message.d.ts +193 -0
  32. package/dist/package/declarations/src/rpc/system/admin/v1/base_message_category.d.ts +125 -0
  33. package/dist/package/declarations/src/rpc/system/admin/v1/base_session.d.ts +33 -0
  34. package/dist/package/declarations/src/rpc/system/admin/v1/base_user.d.ts +3 -3
  35. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen.d.ts +1 -1
  36. package/dist/package/declarations/src/rpc/system/admin/v1/oauth_client.d.ts +145 -0
  37. package/dist/package/declarations/src/views/base/api-log/index.vue.d.ts +3 -0
  38. package/dist/package/declarations/src/views/base/dashboard/index.vue.d.ts +3 -0
  39. package/dist/package/declarations/src/views/base/data-access-log/index.vue.d.ts +3 -0
  40. package/dist/package/declarations/src/views/base/file/index.vue.d.ts +3 -0
  41. package/dist/package/declarations/src/views/base/login-log/index.vue.d.ts +3 -0
  42. package/dist/package/declarations/src/views/base/login-policy/index.vue.d.ts +3 -0
  43. package/dist/package/declarations/src/views/base/message/index.vue.d.ts +3 -0
  44. package/dist/package/declarations/src/views/base/message-category/index.vue.d.ts +3 -0
  45. package/dist/package/declarations/src/views/base/oauth-client/index.vue.d.ts +3 -0
  46. package/dist/package/declarations/src/views/base/operation-log/index.vue.d.ts +3 -0
  47. package/dist/package/declarations/src/views/base/permission-log/index.vue.d.ts +3 -0
  48. package/dist/package/declarations/src/views/base/policy-evaluation-log/index.vue.d.ts +3 -0
  49. package/dist/package/declarations/src/views/message/inbox/index.vue.d.ts +3 -0
  50. package/dist/package/declarations/src/views/profile/components/session.vue.d.ts +3 -0
  51. package/dist/package/src/api/base/notification.ts +69 -0
  52. package/dist/package/src/api/base/sse.ts +4 -4
  53. package/dist/package/src/api/system/auth.ts +1 -0
  54. package/dist/package/src/api/system/base_audit_log.ts +168 -0
  55. package/dist/package/src/api/system/base_dashboard.ts +55 -0
  56. package/dist/package/src/api/system/base_file.ts +43 -0
  57. package/dist/package/src/api/system/base_i18n.ts +12 -12
  58. package/dist/package/src/api/system/base_login_policy.ts +32 -0
  59. package/dist/package/src/api/system/base_message.ts +70 -0
  60. package/dist/package/src/api/system/base_message_category.ts +57 -0
  61. package/dist/package/src/api/system/base_session.ts +33 -0
  62. package/dist/package/src/api/system/oauth_client.ts +102 -0
  63. package/dist/package/src/components/AuditLogTable.vue +105 -0
  64. package/dist/package/src/components/{DynamicTranslationCell.vue → DynamicI18nCell.vue} +50 -50
  65. package/dist/package/src/components/{DynamicTranslationEditor.vue → DynamicI18nEditor.vue} +45 -45
  66. package/dist/package/src/components/Notification.vue +196 -0
  67. package/dist/package/src/components/auditLog.ts +46 -0
  68. package/dist/package/src/components/{dynamicTranslation.ts → dynamicI18n.ts} +15 -15
  69. package/dist/package/src/locales/README.md +5 -3
  70. package/dist/package/src/locales/en-US.json +345 -21
  71. package/dist/package/src/locales/ja-JP.json +347 -23
  72. package/dist/package/src/locales/zh-CN.json +343 -19
  73. package/dist/package/src/locales/zh-TW.json +346 -22
  74. package/dist/package/src/module.ts +5 -2
  75. package/dist/package/src/rpc/base/v1/login.ts +172 -0
  76. package/dist/package/src/rpc/base/v1/notification.ts +315 -0
  77. package/dist/package/src/rpc/base/v1/oauth.ts +25 -0
  78. package/dist/package/src/rpc/base/v1/oauth_client.ts +33 -0
  79. package/dist/package/src/rpc/system/admin/v1/base_audit_log.ts +737 -0
  80. package/dist/package/src/rpc/system/admin/v1/base_config.ts +3 -3
  81. package/dist/package/src/rpc/system/admin/v1/base_dashboard.ts +81 -0
  82. package/dist/package/src/rpc/system/admin/v1/base_dict.ts +4 -4
  83. package/dist/package/src/rpc/system/admin/v1/base_file.ts +88 -0
  84. package/dist/package/src/rpc/system/admin/v1/base_i18n.ts +27 -23
  85. package/dist/package/src/rpc/system/admin/v1/base_job.ts +5 -0
  86. package/dist/package/src/rpc/system/admin/v1/base_login_policy.ts +63 -0
  87. package/dist/package/src/rpc/system/admin/v1/base_menu.ts +2 -2
  88. package/dist/package/src/rpc/system/admin/v1/base_message.ts +236 -0
  89. package/dist/package/src/rpc/system/admin/v1/base_message_category.ts +149 -0
  90. package/dist/package/src/rpc/system/admin/v1/base_session.ts +44 -0
  91. package/dist/package/src/rpc/system/admin/v1/base_user.ts +3 -3
  92. package/dist/package/src/rpc/system/admin/v1/code_gen.ts +1 -1
  93. package/dist/package/src/rpc/system/admin/v1/oauth_client.ts +174 -0
  94. package/dist/package/src/views/ai/chat/components/ChatPanel.vue +2 -2
  95. package/dist/package/src/views/ai/chat/message.ts +7 -3
  96. package/dist/package/src/views/base/api-log/index.vue +83 -0
  97. package/dist/package/src/views/base/config/index.vue +41 -41
  98. package/dist/package/src/views/base/dashboard/index.vue +200 -0
  99. package/dist/package/src/views/base/data-access-log/index.vue +84 -0
  100. package/dist/package/src/views/base/dict/index.vue +23 -23
  101. package/dist/package/src/views/base/dict/item.vue +25 -25
  102. package/dist/package/src/views/base/file/index.vue +119 -0
  103. package/dist/package/src/views/base/job/index.vue +62 -7
  104. package/dist/package/src/views/base/language/index.vue +2 -1
  105. package/dist/package/src/views/base/login-log/index.vue +92 -0
  106. package/dist/package/src/views/base/login-policy/index.vue +219 -0
  107. package/dist/package/src/views/base/menu/index.vue +23 -23
  108. package/dist/package/src/views/base/message/index.vue +582 -0
  109. package/dist/package/src/views/base/message-category/index.vue +356 -0
  110. package/dist/package/src/views/base/oauth-client/index.vue +411 -0
  111. package/dist/package/src/views/base/operation-log/index.vue +82 -0
  112. package/dist/package/src/views/base/permission-log/index.vue +85 -0
  113. package/dist/package/src/views/base/policy-evaluation-log/index.vue +82 -0
  114. package/dist/package/src/views/message/inbox/index.vue +249 -0
  115. package/dist/package/src/views/profile/components/base.vue +6 -5
  116. package/dist/package/src/views/profile/components/password.vue +2 -2
  117. package/dist/package/src/views/profile/components/security.vue +475 -62
  118. package/dist/package/src/views/profile/components/session.vue +153 -0
  119. package/dist/package/src/views/profile/index.vue +35 -22
  120. package/dist/package/src/views/tool/code-gen/code-preview/index.vue +9 -9
  121. package/dist/package/src/views/tool/code-gen/columns/index.vue +1 -1
  122. package/dist/package/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue +8 -8
  123. package/dist/package/src/views/tool/code-gen/config.ts +1 -0
  124. package/dist/package/src/views/tool/code-gen/table/index.vue +7 -7
  125. package/dist/package/src/views/tool/ops-monitoring/index.vue +25 -21
  126. package/package.json +2 -2
  127. package/dist/package/declarations/src/api/system/base_log.d.ts +0 -9
  128. package/dist/package/declarations/src/components/DynamicTranslationCell.vue.d.ts +0 -16
  129. package/dist/package/declarations/src/components/DynamicTranslationEditor.vue.d.ts +0 -20
  130. package/dist/package/declarations/src/components/dynamicTranslation.d.ts +0 -38
  131. package/dist/package/declarations/src/rpc/system/admin/v1/base_log.d.ts +0 -87
  132. package/dist/package/src/api/system/base_log.ts +0 -32
  133. package/dist/package/src/rpc/system/admin/v1/base_log.ts +0 -101
  134. package/dist/package/src/views/base/log/index.vue +0 -339
  135. /package/dist/package/declarations/src/{views/base/log/index.vue.d.ts → components/Notification.vue.d.ts} +0 -0
@@ -0,0 +1,153 @@
1
+ <template>
2
+ <el-card class="session-card" shadow="never">
3
+ <template #header>
4
+ <div class="session-header">
5
+ <div>
6
+ <h3>{{ t("system.profile.session.title") }}</h3>
7
+ <p>{{ t("system.profile.session.description") }}</p>
8
+ </div>
9
+ <el-button :loading="loading" @click="loadSession">
10
+ <el-icon><Refresh /></el-icon>
11
+ {{ t("system.profile.session.action.refresh") }}
12
+ </el-button>
13
+ </div>
14
+ </template>
15
+
16
+ <el-skeleton v-if="loading && !session" :rows="5" animated />
17
+ <el-empty v-else-if="!session" :description="t('system.profile.session.empty')" />
18
+ <div v-else class="session-details">
19
+ <div class="session-status">
20
+ <el-tag type="success" effect="plain">{{ t("system.profile.session.status.active") }}</el-tag>
21
+ <span>{{ session.user_name }} · {{ session.tenant_code }}</span>
22
+ </div>
23
+ <dl class="session-grid">
24
+ <div>
25
+ <dt>{{ t("system.profile.session.field.client_ip") }}</dt>
26
+ <dd>{{ session.client_ip || "-" }}</dd>
27
+ </div>
28
+ <div>
29
+ <dt>{{ t("system.profile.session.field.device") }}</dt>
30
+ <dd>{{ session.device || "-" }}</dd>
31
+ </div>
32
+ <div>
33
+ <dt>{{ t("system.profile.session.field.issued_at") }}</dt>
34
+ <dd>{{ session.issued_at || "-" }}</dd>
35
+ </div>
36
+ <div>
37
+ <dt>{{ t("system.profile.session.field.expires_in") }}</dt>
38
+ <dd>{{ formatExpires(session.expires_in) }}</dd>
39
+ </div>
40
+ </dl>
41
+ <div class="session-actions">
42
+ <el-button type="danger" plain @click="revokeAll">
43
+ <el-icon><SwitchButton /></el-icon>
44
+ {{ t("system.profile.session.action.revoke_all") }}
45
+ </el-button>
46
+ </div>
47
+ </div>
48
+ </el-card>
49
+ </template>
50
+
51
+ <script setup lang="ts">
52
+ import { onMounted, ref } from "vue";
53
+ import { useRouter } from "vue-router";
54
+ import { t } from "@liujitcn/kratos-admin-core";
55
+ import { LOGIN_URL } from "@liujitcn/kratos-admin-core/config";
56
+ import { useUserStore } from "@liujitcn/kratos-admin-core/stores/runtime";
57
+ import { defBaseSessionService } from "@liujitcn/kratos-admin-system/api/system/base_session";
58
+ import type { BaseSession } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_session";
59
+
60
+ const loading = ref(false);
61
+ const session = ref<BaseSession>();
62
+ const router = useRouter();
63
+ const userStore = useUserStore();
64
+
65
+ /** 拉取当前会话信息。 */
66
+ async function loadSession() {
67
+ loading.value = true;
68
+ try {
69
+ session.value = await defBaseSessionService.GetCurrentBaseSession({});
70
+ } finally {
71
+ loading.value = false;
72
+ }
73
+ }
74
+
75
+ /** 撤销当前用户全部会话并返回登录页。 */
76
+ async function revokeAll() {
77
+ await ElMessageBox.confirm(t("system.profile.session.confirm.revoke_all"), t("system.profile.session.confirm.title"), {
78
+ type: "warning"
79
+ });
80
+ await defBaseSessionService.RevokeAllBaseSessions({});
81
+ userStore.clearAuthData();
82
+ ElMessage.success(t("system.profile.session.message.revoked"));
83
+ session.value = undefined;
84
+ await router.replace(LOGIN_URL);
85
+ }
86
+
87
+ /** 将秒数格式化为可读的剩余有效期。 */
88
+ function formatExpires(seconds: number) {
89
+ if (!seconds || seconds < 60) return t("system.profile.session.value.less_than_minute");
90
+ const hours = Math.floor(seconds / 3600);
91
+ const minutes = Math.floor((seconds % 3600) / 60);
92
+ if (hours > 0) return t("system.profile.session.value.hours_minutes", { hours, minutes });
93
+ return t("system.profile.session.value.minutes", { minutes });
94
+ }
95
+
96
+ onMounted(loadSession);
97
+ </script>
98
+
99
+ <style scoped lang="scss">
100
+ .session-card {
101
+ border: 1px solid var(--el-border-color-light);
102
+ }
103
+ .session-header,
104
+ .session-status,
105
+ .session-actions {
106
+ display: flex;
107
+ align-items: center;
108
+ justify-content: space-between;
109
+ gap: 12px;
110
+ }
111
+ .session-header h3 {
112
+ margin: 0;
113
+ color: var(--el-text-color-primary);
114
+ font-size: 18px;
115
+ }
116
+ .session-header p {
117
+ margin: 6px 0 0;
118
+ color: var(--el-text-color-secondary);
119
+ font-size: 13px;
120
+ }
121
+ .session-grid {
122
+ display: grid;
123
+ grid-template-columns: repeat(2, minmax(0, 1fr));
124
+ gap: 16px;
125
+ margin: 24px 0;
126
+ }
127
+ .session-grid div {
128
+ padding: 14px;
129
+ background: var(--el-fill-color-light);
130
+ border-radius: 6px;
131
+ }
132
+ .session-grid dt {
133
+ color: var(--el-text-color-secondary);
134
+ font-size: 12px;
135
+ }
136
+ .session-grid dd {
137
+ margin: 6px 0 0;
138
+ color: var(--el-text-color-primary);
139
+ overflow-wrap: anywhere;
140
+ }
141
+ .session-actions {
142
+ justify-content: flex-end;
143
+ }
144
+ @media screen and (width <= 640px) {
145
+ .session-header {
146
+ align-items: flex-start;
147
+ flex-direction: column;
148
+ }
149
+ .session-grid {
150
+ grid-template-columns: 1fr;
151
+ }
152
+ }
153
+ </style>
@@ -26,6 +26,7 @@
26
26
  @refreshed="loadUserProfile"
27
27
  @switch-tab="handleTabChange"
28
28
  />
29
+ <ProfileSession v-else-if="activeTab === 'session'" />
29
30
  <ProfilePassword v-else />
30
31
  </main>
31
32
  </section>
@@ -47,10 +48,10 @@ import { useUserStore } from "@liujitcn/kratos-admin-core/stores/runtime";
47
48
  import ProfileBase from "./components/base.vue";
48
49
  import ProfileSecurity from "./components/security.vue";
49
50
  import ProfilePassword from "./components/password.vue";
50
- import { ArrowRight } from "@element-plus/icons-vue";
51
+ import ProfileSession from "./components/session.vue";
51
52
 
52
53
  /** 个人中心标签页。 */
53
- type ProfileTab = "account" | "security" | "password";
54
+ type ProfileTab = "account" | "security" | "password" | "session";
54
55
 
55
56
  /** 左侧导航项结构。 */
56
57
  interface ProfileTabOption {
@@ -65,23 +66,33 @@ interface ProfileTabOption {
65
66
  const userStore = useUserStore();
66
67
  const route = useRoute();
67
68
  const activeTab = ref<ProfileTab>("account");
68
- const profileTabs = computed<ProfileTabOption[]>(() => [
69
- {
70
- value: "account",
71
- label: t("system.profile.account.title"),
72
- description: t("system.profile.account.nav_description")
73
- },
74
- {
75
- value: "security",
76
- label: t("system.profile.security.title"),
77
- description: t("system.profile.security.nav_description")
78
- },
79
- {
80
- value: "password",
81
- label: t("system.profile.password.title"),
82
- description: t("system.profile.password.nav_description")
69
+ const profileTabs = computed<ProfileTabOption[]>(() => {
70
+ const tabs: ProfileTabOption[] = [
71
+ {
72
+ value: "account",
73
+ label: t("system.profile.account.title"),
74
+ description: t("system.profile.account.nav_description")
75
+ },
76
+ {
77
+ value: "security",
78
+ label: t("system.profile.security.title"),
79
+ description: t("system.profile.security.nav_description")
80
+ },
81
+ {
82
+ value: "password",
83
+ label: t("system.profile.password.title"),
84
+ description: t("system.profile.password.nav_description")
85
+ }
86
+ ];
87
+ if (userStore.userInfo.role_code === "super") {
88
+ tabs.push({
89
+ value: "session",
90
+ label: t("system.profile.session.title"),
91
+ description: t("system.profile.session.nav_description")
92
+ });
83
93
  }
84
- ]);
94
+ return tabs;
95
+ });
85
96
  const userProfileForm = reactive<UserProfileForm>({
86
97
  user_name: "",
87
98
  nick_name: "",
@@ -115,8 +126,10 @@ async function loadUserProfile() {
115
126
  }
116
127
 
117
128
  onMounted(async () => {
118
- // OAuth 绑定回跳时优先打开安全设置,让子组件消费绑定结果并刷新状态。
119
- if (route.query.oauth_bind_success || route.query.oauth_bind_error) {
129
+ if (route.query.tab === "password") {
130
+ activeTab.value = "password";
131
+ } else if (route.query.oauth_bind_success || route.query.oauth_bind_error) {
132
+ // OAuth 绑定回跳时优先打开安全设置,让子组件消费绑定结果并刷新状态。
120
133
  activeTab.value = "security";
121
134
  }
122
135
  await loadUserProfile();
@@ -139,7 +152,7 @@ onMounted(async () => {
139
152
  padding: 16px;
140
153
  background: #ffffff;
141
154
  border: 1px solid #ebeef5;
142
- border-radius: 12px;
155
+ border-radius: var(--admin-page-radius);
143
156
  box-shadow: 0 2px 12px rgb(0 0 0 / 4%);
144
157
  }
145
158
  .nav-item {
@@ -153,7 +166,7 @@ onMounted(async () => {
153
166
  cursor: pointer;
154
167
  background: #ffffff;
155
168
  border: 1px solid transparent;
156
- border-radius: 10px;
169
+ border-radius: var(--admin-page-radius);
157
170
  transition: all 0.2s ease;
158
171
  }
159
172
  .nav-item + .nav-item {
@@ -60,7 +60,7 @@ const table = ref<CodeGenTableForm>();
60
60
  const files = ref<CodeGenPreviewFile[]>([]);
61
61
  const loading = ref(false);
62
62
  const previewError = ref("");
63
- const missingTranslations = ref<string[]>([]);
63
+ const missingI18ns = ref<string[]>([]);
64
64
  const progressTaskId = ref(typeof window === "undefined" ? "" : (window.sessionStorage.getItem(codeGenTaskStorageKey) ?? ""));
65
65
  const progressDialogVisible = ref(
66
66
  !!progressTaskId.value &&
@@ -94,7 +94,7 @@ async function loadCodePreview() {
94
94
  table.value = undefined;
95
95
  files.value = [];
96
96
  previewError.value = "";
97
- missingTranslations.value = [];
97
+ missingI18ns.value = [];
98
98
  if (!tableId.value) return;
99
99
  loading.value = true;
100
100
  try {
@@ -103,10 +103,10 @@ async function loadCodePreview() {
103
103
  try {
104
104
  const preview = await defCodeGenService.PreviewCodeGen({ table_id: tableId.value, output_paths: undefined });
105
105
  files.value = preview.files ?? [];
106
- missingTranslations.value = preview.missing_translations ?? [];
107
- if (missingTranslations.value.length) {
108
- previewError.value = t("system.code.gen.preview.message.missing_translations", {
109
- items: missingTranslations.value.join(t("system.code.gen.preview.value.list_separator"))
106
+ missingI18ns.value = preview.missing_i18ns ?? [];
107
+ if (missingI18ns.value.length) {
108
+ previewError.value = t("system.code.gen.preview.message.missing_i18ns", {
109
+ items: missingI18ns.value.join(t("system.code.gen.preview.value.list_separator"))
110
110
  });
111
111
  }
112
112
  if (!files.value.length && !previewError.value) previewError.value = t("system.code.gen.preview.message.no_preview_files");
@@ -134,11 +134,11 @@ async function handleGenerate() {
134
134
  ElMessage.warning(t("system.code.gen.table.message.disabled", { name: table.value.name }));
135
135
  return;
136
136
  }
137
- if (missingTranslations.value.length) {
137
+ if (missingI18ns.value.length) {
138
138
  try {
139
139
  await ElMessageBox.alert(
140
- t("system.code.gen.preview.message.missing_translations", {
141
- items: missingTranslations.value.join(t("system.code.gen.preview.value.list_separator"))
140
+ t("system.code.gen.preview.message.missing_i18ns", {
141
+ items: missingI18ns.value.join(t("system.code.gen.preview.value.list_separator"))
142
142
  }),
143
143
  t("common.title.warning"),
144
144
  {
@@ -557,7 +557,7 @@ import type {
557
557
  } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/code_gen_column";
558
558
  import type { CodeGenDatabaseTable, CodeGenTableForm } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/code_gen_table";
559
559
  import CodeGenLocaleEditor from "../components/CodeGenLocaleEditor.vue";
560
- import { getEditableLanguageOptions } from "@liujitcn/kratos-admin-system/components/dynamicTranslation";
560
+ import { getEditableLanguageOptions } from "@liujitcn/kratos-admin-system/components/dynamicI18n";
561
561
  import {
562
562
  copyCodeGenOptionToEmptyMatches,
563
563
  copyFirstMatchingCodeGenOption,
@@ -35,7 +35,7 @@
35
35
  :disabled="!canTranslate(locale.value, 'comment', sourceComment)"
36
36
  @click="handleTranslate(locale.value, 'comment', sourceComment, locale.label)"
37
37
  >
38
- {{ t("system.base.translation.action.translate") }}
38
+ {{ t("system.base.i18n.action.translate") }}
39
39
  </el-button>
40
40
  </div>
41
41
  <div v-if="showLeftTreeComment" class="code-gen-locale-editor__control">
@@ -56,7 +56,7 @@
56
56
  :disabled="!canTranslate(locale.value, 'left_tree_comment', sourceLeftTreeComment)"
57
57
  @click="handleTranslate(locale.value, 'left_tree_comment', sourceLeftTreeComment, locale.label)"
58
58
  >
59
- {{ t("system.base.translation.action.translate") }}
59
+ {{ t("system.base.i18n.action.translate") }}
60
60
  </el-button>
61
61
  </div>
62
62
  </div>
@@ -140,13 +140,13 @@ async function handleTranslate(locale: string, field: keyof CodeGenLocaleConfig,
140
140
  if (!canTranslate(locale, field, source)) return;
141
141
  translatingField.value = `${locale}:${field}`;
142
142
  try {
143
- const response = await defBaseI18nService.DraftBaseTranslation({ source, locale });
144
- const translation = response.translations.find(item => item.locale === locale)?.translation;
145
- if (!translation) throw new Error("translation not found");
146
- updateLocale(locale, field, translation);
147
- ElMessage.success(t("system.base.translation.message.translate_success", { language }));
143
+ const response = await defBaseI18nService.DraftBaseI18n({ source, locale });
144
+ const i18n = response.i18ns.find(item => item.locale === locale)?.i18n;
145
+ if (!i18n) throw new Error("i18n not found");
146
+ updateLocale(locale, field, i18n);
147
+ ElMessage.success(t("system.base.i18n.message.translate_success", { language }));
148
148
  } catch {
149
- ElMessage.error(t("system.base.translation.message.translate_failed", { language }));
149
+ ElMessage.error(t("system.base.i18n.message.translate_failed", { language }));
150
150
  } finally {
151
151
  translatingField.value = "";
152
152
  }
@@ -73,6 +73,7 @@ const codeGenFormComponentLabelKeys: Record<ProFormComponentType, string> = {
73
73
  password: "system.code.gen.component.password",
74
74
  textarea: "system.code.gen.component.textarea",
75
75
  "input-number": "system.code.gen.component.input_number",
76
+ "color-picker": "system.code.gen.component.color_picker",
76
77
  segmented: "system.code.gen.component.segmented",
77
78
  switch: "system.code.gen.component.switch",
78
79
  checkbox: "system.code.gen.component.checkbox",
@@ -212,7 +212,7 @@ const formFields = computed<ProFormField[]>(() => [
212
212
  },
213
213
  {
214
214
  prop: "i18n_config",
215
- label: t("system.code.gen.i18n.field.translations"),
215
+ label: t("system.code.gen.i18n.field.i18ns"),
216
216
  component: "slot",
217
217
  slotName: "tableI18nConfig",
218
218
  colSpan: 24,
@@ -589,7 +589,7 @@ async function handleGenerate(selected: CodeGenGenerateTarget) {
589
589
  return;
590
590
  }
591
591
  generating.value = true;
592
- let missingTranslations: string[] = [];
592
+ let missingI18ns: string[] = [];
593
593
  try {
594
594
  const previewEntries = await Promise.all(
595
595
  tables.map(async table => ({
@@ -597,17 +597,17 @@ async function handleGenerate(selected: CodeGenGenerateTarget) {
597
597
  preview: await defCodeGenService.PreviewCodeGen({ table_id: table.id, output_paths: undefined })
598
598
  }))
599
599
  );
600
- missingTranslations = previewEntries.flatMap(({ table, preview }) =>
601
- (preview.missing_translations ?? []).map(item => (tables.length === 1 ? item : `${table.name}: ${item}`))
600
+ missingI18ns = previewEntries.flatMap(({ table, preview }) =>
601
+ (preview.missing_i18ns ?? []).map(item => (tables.length === 1 ? item : `${table.name}: ${item}`))
602
602
  );
603
603
  } finally {
604
604
  generating.value = false;
605
605
  }
606
- if (missingTranslations.length) {
606
+ if (missingI18ns.length) {
607
607
  try {
608
608
  await ElMessageBox.alert(
609
- t("system.code.gen.preview.message.missing_translations", {
610
- items: missingTranslations.join(t("system.code.gen.preview.value.list_separator"))
609
+ t("system.code.gen.preview.message.missing_i18ns", {
610
+ items: missingI18ns.join(t("system.code.gen.preview.value.list_separator"))
611
611
  }),
612
612
  t("common.title.warning"),
613
613
  {
@@ -128,7 +128,7 @@
128
128
  <code>{{ item.address }}</code>
129
129
  </div>
130
130
  </div>
131
- <el-tag :type="item.status === '正常' ? 'success' : 'warning'" size="small" effect="plain">{{
131
+ <el-tag :type="isNormalStatus(item.status) ? 'success' : 'warning'" size="small" effect="plain">{{
132
132
  item.statusLabel
133
133
  }}</el-tag>
134
134
  </div>
@@ -199,12 +199,7 @@
199
199
  <strong>{{ metric.percentageLabel }}</strong>
200
200
  </span>
201
201
  </div>
202
- <el-progress
203
- :percentage="metric.percentage"
204
- :show-text="false"
205
- :stroke-width="10"
206
- :color="metric.color"
207
- />
202
+ <el-progress :percentage="metric.percentage" :show-text="false" :stroke-width="10" :color="metric.color" />
208
203
  </div>
209
204
  </div>
210
205
  </div>
@@ -362,11 +357,17 @@ const alerts = ref<OpsAlertsResponse>();
362
357
  const windowMinutes = ref(15);
363
358
  const lastCollectedAt = ref("");
364
359
  const trendGridLines = [16, 62, 108, 154, 198];
365
- const nodeMetricLabelKeys: Record<string, string> = {
366
- 堆内存: "system.ops_monitoring.node_metric.heap_memory",
367
- 内存: "system.ops_monitoring.node_metric.memory",
368
- 硬盘: "system.ops_monitoring.node_metric.disk"
369
- };
360
+ const monitoringStatusKeys = [
361
+ "system.ops_monitoring.status.normal",
362
+ "system.ops_monitoring.status.unconfigured",
363
+ "system.ops_monitoring.status.error",
364
+ "system.ops_monitoring.status.attention"
365
+ ] as const;
366
+ const nodeMetricLabelKeys = [
367
+ "system.ops_monitoring.node_metric.heap_memory",
368
+ "system.ops_monitoring.node_metric.memory",
369
+ "system.ops_monitoring.node_metric.disk"
370
+ ] as const;
370
371
  const byteUnits = ["B", "KB", "MB", "GB", "TB", "PB"];
371
372
  const trafficSummary = computed(() => traffic.value?.traffic);
372
373
 
@@ -454,7 +455,7 @@ const availabilityItems = computed<AvailabilityItem[]>(() =>
454
455
  (services.value?.services ?? []).map(service => ({
455
456
  label: service.name,
456
457
  value: translateStatus(service.status),
457
- tone: service.status === "正常" ? "ok" : "warn"
458
+ tone: isNormalStatus(service.status) ? "ok" : "warn"
458
459
  }))
459
460
  );
460
461
 
@@ -580,17 +581,20 @@ function formatRelativeTime(value?: string) {
580
581
  }
581
582
 
582
583
  function translateStatus(status?: string) {
583
- if (status === "正常") return t("system.ops_monitoring.status.normal");
584
- if (status === "未配置") return t("system.ops_monitoring.status.unconfigured");
585
- if (status === "异常") return t("system.ops_monitoring.status.error");
586
- if (status === "关注") return t("system.ops_monitoring.status.attention");
584
+ const localeKey = monitoringStatusKeys.find(key => t(key) === status);
585
+ if (localeKey) return t(localeKey);
587
586
  return status || t("system.ops_monitoring.unknown");
588
587
  }
589
588
 
589
+ /** 判断监控状态是否为当前语言下的正常状态。 */
590
+ function isNormalStatus(status?: string) {
591
+ return status === t("system.ops_monitoring.status.normal");
592
+ }
593
+
590
594
  function mapStorage(item: OpsStorage) {
591
595
  return {
592
596
  ...item,
593
- color: item.status === "正常" ? "var(--el-color-success)" : "var(--el-color-warning)",
597
+ color: isNormalStatus(item.status) ? "var(--el-color-success)" : "var(--el-color-warning)",
594
598
  statusLabel: translateStatus(item.status),
595
599
  shortName: item.short_name || item.name,
596
600
  capacityLabel: item.capacity_label || t("system.ops_monitoring.capacity"),
@@ -606,7 +610,7 @@ function mapEndpoint(endpoint: OpsEndpoint): EndpointItem {
606
610
  latency: `${formatNumber(endpoint.p95_latency_ms)} ms`,
607
611
  errorRate: `${formatNumber(endpoint.error_rate)}%`,
608
612
  status: translateStatus(endpoint.status),
609
- healthy: endpoint.status === "正常"
613
+ healthy: isNormalStatus(endpoint.status)
610
614
  };
611
615
  }
612
616
 
@@ -649,7 +653,7 @@ function formatFixedNumber(value: number) {
649
653
 
650
654
  /** 翻译实例资源指标名称,未知指标保留后端原值。 */
651
655
  function translateNodeMetricLabel(label: string) {
652
- const localeKey = nodeMetricLabelKeys[label];
656
+ const localeKey = nodeMetricLabelKeys.find(key => t(key) === label);
653
657
  return localeKey ? t(localeKey) : label;
654
658
  }
655
659
 
@@ -658,7 +662,7 @@ function mapAlert(alert: OpsAlert) {
658
662
  title: alert.title,
659
663
  detail: alert.detail,
660
664
  at: alert.at,
661
- tone: alert.status === "正常" ? "ok" : "warn"
665
+ tone: isNormalStatus(alert.status) ? "ok" : "warn"
662
666
  };
663
667
  }
664
668
 
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.28",
4
+ "version": "0.0.31",
5
5
  "type": "module",
6
6
  "description": "kratos-admin system management module",
7
7
  "license": "MIT",
@@ -15,7 +15,7 @@
15
15
  "sortablejs": "^1.15.2",
16
16
  "swagger-ui-dist": "^5.32.9",
17
17
  "vue-element-plus-x": "^2.0.3",
18
- "@liujitcn/kratos-admin-core": "0.0.28"
18
+ "@liujitcn/kratos-admin-core": "0.0.31"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "@element-plus/icons-vue": "^2.3.1",
@@ -1,9 +0,0 @@
1
- import { type BaseLog, type BaseLogService, type GetBaseLogRequest, type PageBaseLogRequest, type PageBaseLogResponse } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_log";
2
- /** Admin系统日志服务 */
3
- export declare class BaseLogServiceImpl implements BaseLogService {
4
- /** 查询系统日志分页列表 */
5
- PageBaseLog(request: PageBaseLogRequest): Promise<PageBaseLogResponse>;
6
- /** 查询系统日志 */
7
- GetBaseLog(request: GetBaseLogRequest): Promise<BaseLog>;
8
- }
9
- export declare const defBaseLogService: BaseLogServiceImpl;
@@ -1,16 +0,0 @@
1
- import type { BaseI18n } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_i18n";
2
- import { TranslationTargetType } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_i18n";
3
- /** DynamicTranslationCellProps 动态翻译列表单元格属性。 */
4
- interface DynamicTranslationCellProps {
5
- /** 资源源文。 */
6
- source: string;
7
- /** 统一翻译表目标类型。 */
8
- targetType?: TranslationTargetType;
9
- /** 目标资源编号。 */
10
- targetId?: number;
11
- /** 资源列表返回的非主语言翻译。 */
12
- translations?: BaseI18n[];
13
- }
14
- declare const __VLS_export: import("vue").DefineComponent<DynamicTranslationCellProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<DynamicTranslationCellProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
- declare const _default: typeof __VLS_export;
16
- export default _default;
@@ -1,20 +0,0 @@
1
- import { type DynamicTranslationValue } from "./dynamicTranslation";
2
- /** DynamicTranslationEditorProps 动态翻译编辑器属性。 */
3
- interface DynamicTranslationEditorProps {
4
- modelValue: DynamicTranslationValue[];
5
- /** 当前语言源文本。 */
6
- source?: string;
7
- maxlength?: number;
8
- multiline?: boolean;
9
- }
10
- declare const __VLS_export: import("vue").DefineComponent<DynamicTranslationEditorProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
- "update:modelValue": (value: DynamicTranslationValue[]) => any;
12
- }, string, import("vue").PublicProps, Readonly<DynamicTranslationEditorProps> & Readonly<{
13
- "onUpdate:modelValue"?: ((value: DynamicTranslationValue[]) => any) | undefined;
14
- }>, {
15
- source: string;
16
- maxlength: number;
17
- multiline: boolean;
18
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
19
- declare const _default: typeof __VLS_export;
20
- export default _default;
@@ -1,38 +0,0 @@
1
- import type { TranslationTargetType } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_i18n";
2
- /** DynamicTranslationValue 动态资源单语言翻译编辑状态。 */
3
- export interface DynamicTranslationValue {
4
- /** 语言代码。 */
5
- locale: string;
6
- text: string;
7
- id: number;
8
- }
9
- /** DynamicTranslationRecord 描述三类动态资源翻译共有字段。 */
10
- export interface DynamicTranslationRecord extends Omit<DynamicTranslationValue, "text"> {
11
- target_type?: TranslationTargetType;
12
- target_id?: number;
13
- name?: string;
14
- /** 兼容旧接口缓存中的字段名。 */
15
- title?: string;
16
- label?: string;
17
- }
18
- /** DynamicLanguageOption 动态翻译编辑器显示的语言选项。 */
19
- export interface DynamicLanguageOption {
20
- /** 语言代码。 */
21
- value: string;
22
- /** 语言显示名称。 */
23
- label: string;
24
- }
25
- /** 返回语言管理中启用且非主语言的翻译语言选项。 */
26
- export declare function getEditableLanguageOptions(): DynamicLanguageOption[];
27
- /** 返回语言管理中的语言显示名称。 */
28
- export declare function getLanguageLabel(locale: string): string;
29
- /** normalizeDynamicTranslations 将后端翻译记录补齐为全部非主语言编辑状态。 */
30
- export declare function normalizeDynamicTranslations(records: DynamicTranslationRecord[] | undefined, _textField: "title" | "name" | "label", locales?: string[]): DynamicTranslationValue[];
31
- /** serializeDynamicTranslations 将编辑状态转换回后端资源翻译结构。 */
32
- export declare function serializeDynamicTranslations(values: DynamicTranslationValue[], targetType: TranslationTargetType, targetId: number): Array<{
33
- id: number;
34
- target_type: TranslationTargetType;
35
- target_id: number;
36
- locale: string;
37
- name: string;
38
- }>;