@liujitcn/kratos-admin-system 0.0.38 → 0.0.39

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 (119) hide show
  1. package/dist/package/declarations/src/api/system/admin/v1/base_login_log.d.ts +3 -1
  2. package/dist/package/declarations/src/api/system/admin/v1/base_session.d.ts +7 -1
  3. package/dist/package/declarations/src/locales/generated.d.ts +100 -0
  4. package/dist/package/declarations/src/rpc/base/v1/login.d.ts +2 -0
  5. package/dist/package/declarations/src/rpc/base/v1/notification.d.ts +1 -1
  6. package/dist/package/declarations/src/rpc/base/v1/oauth.d.ts +4 -0
  7. package/dist/package/declarations/src/rpc/base/v1/oauth_client.d.ts +1 -1
  8. package/dist/package/declarations/src/rpc/system/admin/v1/base_api_log.d.ts +1 -1
  9. package/dist/package/declarations/src/rpc/system/admin/v1/base_data_access_log.d.ts +1 -1
  10. package/dist/package/declarations/src/rpc/system/admin/v1/base_i18n.d.ts +1 -1
  11. package/dist/package/declarations/src/rpc/system/admin/v1/base_log.d.ts +1 -1
  12. package/dist/package/declarations/src/rpc/system/admin/v1/base_login_log.d.ts +10 -1
  13. package/dist/package/declarations/src/rpc/system/admin/v1/base_login_policy.d.ts +8 -0
  14. package/dist/package/declarations/src/rpc/system/admin/v1/base_message.d.ts +1 -1
  15. package/dist/package/declarations/src/rpc/system/admin/v1/base_message_category.d.ts +1 -1
  16. package/dist/package/declarations/src/rpc/system/admin/v1/base_migration.d.ts +1 -1
  17. package/dist/package/declarations/src/rpc/system/admin/v1/base_operation_log.d.ts +1 -1
  18. package/dist/package/declarations/src/rpc/system/admin/v1/base_permission_log.d.ts +1 -1
  19. package/dist/package/declarations/src/rpc/system/admin/v1/base_policy_evaluation_log.d.ts +1 -1
  20. package/dist/package/declarations/src/rpc/system/admin/v1/base_redact_output_policy.d.ts +1 -1
  21. package/dist/package/declarations/src/rpc/system/admin/v1/base_redact_storage_policy.d.ts +1 -1
  22. package/dist/package/declarations/src/rpc/system/admin/v1/base_session.d.ts +41 -0
  23. package/dist/package/declarations/src/rpc/system/admin/v1/base_table_archive.d.ts +1 -1
  24. package/dist/package/declarations/src/rpc/system/admin/v1/base_table_archive_record.d.ts +1 -1
  25. package/dist/package/declarations/src/rpc/system/admin/v1/base_table_archive_restore.d.ts +1 -1
  26. package/dist/package/declarations/src/rpc/system/admin/v1/base_table_backup.d.ts +1 -1
  27. package/dist/package/declarations/src/rpc/system/admin/v1/base_table_backup_record.d.ts +1 -1
  28. package/dist/package/declarations/src/rpc/system/admin/v1/base_table_backup_restore.d.ts +1 -1
  29. package/dist/package/declarations/src/rpc/system/admin/v1/base_table_source.d.ts +1 -1
  30. package/dist/package/declarations/src/rpc/system/admin/v1/cache.d.ts +1 -1
  31. package/dist/package/declarations/src/rpc/system/admin/v1/oauth_client.d.ts +1 -1
  32. package/dist/package/declarations/src/rpc/system/admin/v1/ops_monitoring.d.ts +1 -1
  33. package/dist/package/declarations/src/views/base/online-session/index.vue.d.ts +3 -0
  34. package/dist/package/declarations/src/views/profile/components/login-log.vue.d.ts +3 -0
  35. package/dist/package/src/api/base/v1/sse.ts +11 -2
  36. package/dist/package/src/api/system/admin/v1/base_login_log.ts +10 -0
  37. package/dist/package/src/api/system/admin/v1/base_session.ts +32 -1
  38. package/dist/package/src/locales/en-US.json +33 -20
  39. package/dist/package/src/locales/ja-JP.json +35 -22
  40. package/dist/package/src/locales/zh-CN.json +34 -21
  41. package/dist/package/src/locales/zh-TW.json +33 -20
  42. package/dist/package/src/module.ts +1 -0
  43. package/dist/package/src/rpc/base/v1/ai_message.ts +1 -1
  44. package/dist/package/src/rpc/base/v1/ai_session.ts +1 -1
  45. package/dist/package/src/rpc/base/v1/ai_tool.ts +1 -1
  46. package/dist/package/src/rpc/base/v1/config.ts +1 -1
  47. package/dist/package/src/rpc/base/v1/login.ts +3 -1
  48. package/dist/package/src/rpc/base/v1/notification.ts +2 -2
  49. package/dist/package/src/rpc/base/v1/oauth.ts +5 -1
  50. package/dist/package/src/rpc/base/v1/oauth_client.ts +2 -2
  51. package/dist/package/src/rpc/base/v1/sse.ts +1 -1
  52. package/dist/package/src/rpc/common/v1/analytics.ts +1 -1
  53. package/dist/package/src/rpc/common/v1/common.ts +1 -1
  54. package/dist/package/src/rpc/common/v1/enum.ts +1 -1
  55. package/dist/package/src/rpc/common/v1/types.ts +1 -1
  56. package/dist/package/src/rpc/google/protobuf/empty.ts +1 -1
  57. package/dist/package/src/rpc/google/protobuf/timestamp.ts +1 -1
  58. package/dist/package/src/rpc/system/admin/v1/auth.ts +1 -1
  59. package/dist/package/src/rpc/system/admin/v1/base_api.ts +1 -1
  60. package/dist/package/src/rpc/system/admin/v1/base_api_log.ts +2 -2
  61. package/dist/package/src/rpc/system/admin/v1/base_area.ts +1 -1
  62. package/dist/package/src/rpc/system/admin/v1/base_config.ts +1 -1
  63. package/dist/package/src/rpc/system/admin/v1/base_dashboard.ts +1 -1
  64. package/dist/package/src/rpc/system/admin/v1/base_data_access_log.ts +2 -2
  65. package/dist/package/src/rpc/system/admin/v1/base_dept.ts +1 -1
  66. package/dist/package/src/rpc/system/admin/v1/base_dict.ts +1 -1
  67. package/dist/package/src/rpc/system/admin/v1/base_dict_item.ts +1 -1
  68. package/dist/package/src/rpc/system/admin/v1/base_file.ts +1 -1
  69. package/dist/package/src/rpc/system/admin/v1/base_i18n.ts +2 -2
  70. package/dist/package/src/rpc/system/admin/v1/base_job.ts +1 -1
  71. package/dist/package/src/rpc/system/admin/v1/base_job_log.ts +1 -1
  72. package/dist/package/src/rpc/system/admin/v1/base_language.ts +1 -1
  73. package/dist/package/src/rpc/system/admin/v1/base_log.ts +2 -2
  74. package/dist/package/src/rpc/system/admin/v1/base_login_log.ts +12 -2
  75. package/dist/package/src/rpc/system/admin/v1/base_login_policy.ts +11 -1
  76. package/dist/package/src/rpc/system/admin/v1/base_menu.ts +1 -1
  77. package/dist/package/src/rpc/system/admin/v1/base_message.ts +2 -2
  78. package/dist/package/src/rpc/system/admin/v1/base_message_category.ts +2 -2
  79. package/dist/package/src/rpc/system/admin/v1/base_migration.ts +2 -2
  80. package/dist/package/src/rpc/system/admin/v1/base_operation_log.ts +2 -2
  81. package/dist/package/src/rpc/system/admin/v1/base_permission_log.ts +2 -2
  82. package/dist/package/src/rpc/system/admin/v1/base_policy_evaluation_log.ts +2 -2
  83. package/dist/package/src/rpc/system/admin/v1/base_post.ts +1 -1
  84. package/dist/package/src/rpc/system/admin/v1/base_redact_common.ts +1 -1
  85. package/dist/package/src/rpc/system/admin/v1/base_redact_output_policy.ts +2 -2
  86. package/dist/package/src/rpc/system/admin/v1/base_redact_rule.ts +1 -1
  87. package/dist/package/src/rpc/system/admin/v1/base_redact_storage_policy.ts +2 -2
  88. package/dist/package/src/rpc/system/admin/v1/base_role.ts +1 -1
  89. package/dist/package/src/rpc/system/admin/v1/base_session.ts +47 -1
  90. package/dist/package/src/rpc/system/admin/v1/base_table_archive.ts +2 -2
  91. package/dist/package/src/rpc/system/admin/v1/base_table_archive_record.ts +2 -2
  92. package/dist/package/src/rpc/system/admin/v1/base_table_archive_restore.ts +2 -2
  93. package/dist/package/src/rpc/system/admin/v1/base_table_backup.ts +2 -2
  94. package/dist/package/src/rpc/system/admin/v1/base_table_backup_record.ts +2 -2
  95. package/dist/package/src/rpc/system/admin/v1/base_table_backup_restore.ts +2 -2
  96. package/dist/package/src/rpc/system/admin/v1/base_table_source.ts +2 -2
  97. package/dist/package/src/rpc/system/admin/v1/base_tenant.ts +1 -1
  98. package/dist/package/src/rpc/system/admin/v1/base_third_account.ts +1 -1
  99. package/dist/package/src/rpc/system/admin/v1/base_user.ts +1 -1
  100. package/dist/package/src/rpc/system/admin/v1/cache.ts +2 -2
  101. package/dist/package/src/rpc/system/admin/v1/code_gen.ts +1 -1
  102. package/dist/package/src/rpc/system/admin/v1/code_gen_column.ts +1 -1
  103. package/dist/package/src/rpc/system/admin/v1/code_gen_proto.ts +1 -1
  104. package/dist/package/src/rpc/system/admin/v1/code_gen_table.ts +1 -1
  105. package/dist/package/src/rpc/system/admin/v1/common.ts +1 -1
  106. package/dist/package/src/rpc/system/admin/v1/oauth_client.ts +2 -2
  107. package/dist/package/src/rpc/system/admin/v1/ops_monitoring.ts +2 -2
  108. package/dist/package/src/rpc/system/admin/v1/runtime_log.ts +1 -1
  109. package/dist/package/src/rpc/system/common/v1/common.ts +1 -1
  110. package/dist/package/src/rpc/system/config/v1/system_config.ts +1 -1
  111. package/dist/package/src/views/base/login-policy/index.vue +28 -0
  112. package/dist/package/src/views/base/online-session/index.vue +116 -0
  113. package/dist/package/src/views/base/user/index.vue +20 -8
  114. package/dist/package/src/views/profile/components/login-log.vue +123 -0
  115. package/dist/package/src/views/profile/components/session.vue +46 -61
  116. package/dist/package/src/views/profile/index.vue +13 -9
  117. package/dist/package/src/views/tool/code-gen/code-preview/index.vue +5 -15
  118. package/dist/package/src/views/tool/code-gen/table/index.vue +50 -24
  119. package/package.json +2 -2
@@ -0,0 +1,123 @@
1
+ <template>
2
+ <el-card class="login-log-card" shadow="never">
3
+ <template #header>
4
+ <div class="login-log-header">
5
+ <div>
6
+ <h3>{{ t("system.profile.login_log.title") }}</h3>
7
+ <p>{{ t("system.profile.login_log.description") }}</p>
8
+ </div>
9
+ <el-button :loading="loading" @click="refresh">
10
+ <el-icon><Refresh /></el-icon>
11
+ {{ t("system.profile.login_log.action.refresh") }}
12
+ </el-button>
13
+ </div>
14
+ </template>
15
+ <ProTable ref="proTable" row-key="id" :columns="columns" :request-api="requestTable" />
16
+ </el-card>
17
+ </template>
18
+
19
+ <script setup lang="ts">
20
+ import { computed, ref } from "vue";
21
+ import ProTable from "@liujitcn/kratos-admin-core/components/ProTable";
22
+ import type { ColumnProps, ProTableInstance } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
23
+ import { buildPageRequest } from "@liujitcn/kratos-admin-core/table";
24
+ import { t } from "@liujitcn/kratos-admin-core";
25
+ import { defBaseLoginLogService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_login_log";
26
+ import { BaseLogResult } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_log";
27
+ import { BaseLoginLogType } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_login_log";
28
+ import type { BaseLoginLog } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_login_log";
29
+
30
+ defineOptions({ name: "ProfileLoginLog", inheritAttrs: false });
31
+
32
+ const proTable = ref<ProTableInstance>();
33
+ const loading = ref(false);
34
+ const loginTypeOptions = computed<Array<[number, string]>>(() => [
35
+ [BaseLoginLogType.BASE_LOGIN_LOG_TYPE_PASSWORD, t("system.base.log.login_type.password")],
36
+ [BaseLoginLogType.BASE_LOGIN_LOG_TYPE_OAUTH, t("system.base.log.login_type.oauth")],
37
+ [BaseLoginLogType.BASE_LOGIN_LOG_TYPE_MFA, t("system.base.log.login_type.mfa")],
38
+ [BaseLoginLogType.BASE_LOGIN_LOG_TYPE_TOKEN_REFRESH, t("system.base.log.login_type.token_refresh")],
39
+ [BaseLoginLogType.BASE_LOGIN_LOG_TYPE_LOGOUT, t("system.base.log.login_type.logout")]
40
+ ]);
41
+ const resultOptions = computed<Array<[number, string]>>(() => [
42
+ [BaseLogResult.BASE_LOG_RESULT_SUCCESS, t("system.base.log.result.success")],
43
+ [BaseLogResult.BASE_LOG_RESULT_FAILURE, t("system.base.log.result.failure")],
44
+ [BaseLogResult.BASE_LOG_RESULT_ERROR, t("system.base.log.result.error")]
45
+ ]);
46
+ const columns = computed<ColumnProps[]>(() => [
47
+ { prop: "occurred_at", label: t("system.profile.login_log.field.occurred_at"), minWidth: 180 },
48
+ {
49
+ prop: "login_type",
50
+ label: t("system.profile.login_log.field.login_type"),
51
+ minWidth: 130,
52
+ render: scope => enumLabel(loginTypeOptions.value, (scope.row as BaseLoginLog).login_type)
53
+ },
54
+ {
55
+ prop: "result",
56
+ label: t("system.profile.login_log.field.result"),
57
+ minWidth: 100,
58
+ render: scope => enumLabel(resultOptions.value, (scope.row as BaseLoginLog).result)
59
+ },
60
+ { prop: "client_ip", label: t("system.profile.login_log.field.client_ip"), minWidth: 140 },
61
+ { prop: "device_id", label: t("system.profile.login_log.field.device_id"), minWidth: 160 },
62
+ { prop: "reason", label: t("system.profile.login_log.field.reason"), minWidth: 180 }
63
+ ]);
64
+
65
+ /** 查询当前用户的登录记录。 */
66
+ async function requestTable(params: Record<string, unknown>) {
67
+ const response = await defBaseLoginLogService.PageCurrentUserLoginLog(
68
+ buildPageRequest({ page_num: Number(params.page_num ?? 1), page_size: Number(params.page_size ?? 10) })
69
+ );
70
+ return { data: { list: response.base_login_logs ?? [], total: response.total } };
71
+ }
72
+
73
+ /** 刷新当前用户的登录记录。 */
74
+ async function refresh() {
75
+ loading.value = true;
76
+ try {
77
+ await proTable.value?.getTableList();
78
+ } finally {
79
+ loading.value = false;
80
+ }
81
+ }
82
+
83
+ /** 输出枚举显示文本。 */
84
+ function enumLabel(options: Array<[number, string]>, value: number) {
85
+ return options.find(option => option[0] === value)?.[1] ?? String(value);
86
+ }
87
+ </script>
88
+
89
+ <style scoped lang="scss">
90
+ .login-log-card {
91
+ border: 1px solid var(--el-border-color-light);
92
+ border-radius: var(--admin-page-radius);
93
+ }
94
+ :deep(.login-log-card .el-card__header) {
95
+ padding: 18px 20px;
96
+ border-bottom: 1px solid var(--el-border-color-light);
97
+ }
98
+ :deep(.login-log-card .el-card__body) {
99
+ padding: 20px;
100
+ }
101
+ .login-log-header {
102
+ display: flex;
103
+ align-items: center;
104
+ justify-content: space-between;
105
+ gap: 12px;
106
+ }
107
+ .login-log-header h3 {
108
+ margin: 0;
109
+ color: var(--el-text-color-primary);
110
+ font-size: 18px;
111
+ }
112
+ .login-log-header p {
113
+ margin: 6px 0 0;
114
+ color: var(--el-text-color-secondary);
115
+ font-size: 13px;
116
+ }
117
+ @media screen and (width <= 640px) {
118
+ .login-log-header {
119
+ align-items: flex-start;
120
+ flex-direction: column;
121
+ }
122
+ }
123
+ </style>
@@ -13,43 +13,20 @@
13
13
  </div>
14
14
  </template>
15
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>
16
+ <ProTable ref="proTable" row-key="session_id" :columns="columns" :request-api="requestSessionTable" :pagination="false" />
17
+ <div class="session-actions">
18
+ <el-button type="danger" plain :disabled="!hasSessions" @click="revokeAll">
19
+ <el-icon><SwitchButton /></el-icon>
20
+ {{ t("system.profile.session.action.revoke_all") }}
21
+ </el-button>
47
22
  </div>
48
23
  </el-card>
49
24
  </template>
50
25
 
51
26
  <script setup lang="ts">
52
- import { onMounted, ref } from "vue";
27
+ import { computed, ref } from "vue";
28
+ import ProTable from "@liujitcn/kratos-admin-core/components/ProTable";
29
+ import type { ColumnProps, ProTableInstance } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
53
30
  import { useRouter } from "vue-router";
54
31
  import { t } from "@liujitcn/kratos-admin-core";
55
32
  import { LOGIN_URL } from "@liujitcn/kratos-admin-core/config";
@@ -58,15 +35,47 @@ import { defBaseSessionService } from "@liujitcn/kratos-admin-system/api/system/
58
35
  import type { BaseSession } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_session";
59
36
 
60
37
  const loading = ref(false);
61
- const session = ref<BaseSession>();
38
+ const proTable = ref<ProTableInstance>();
39
+ const hasSessions = ref(false);
40
+ const columns = computed<ColumnProps[]>(() => [
41
+ {
42
+ prop: "current",
43
+ label: t("system.profile.session.field.current"),
44
+ cellType: "status",
45
+ minWidth: 130,
46
+ statusProps: {
47
+ activeValue: true,
48
+ inactiveValue: false,
49
+ activeText: t("system.profile.session.status.current"),
50
+ inactiveText: t("system.profile.session.status.other")
51
+ }
52
+ },
53
+ { prop: "client_ip", label: t("system.profile.session.field.client_ip"), minWidth: 140 },
54
+ { prop: "device", label: t("system.profile.session.field.device"), minWidth: 200 },
55
+ { prop: "issued_at", label: t("system.profile.session.field.issued_at"), minWidth: 180 },
56
+ {
57
+ prop: "expires_in",
58
+ label: t("system.profile.session.field.expires_in"),
59
+ minWidth: 140,
60
+ render: scope => formatExpires((scope.row as BaseSession).expires_in)
61
+ }
62
+ ]);
63
+
64
+ /** 查询本人全部有效会话。 */
65
+ async function requestSessionTable() {
66
+ const response = await defBaseSessionService.ListCurrentBaseSessions({});
67
+ const sessions = response.sessions ?? [];
68
+ hasSessions.value = sessions.length > 0;
69
+ return { data: sessions };
70
+ }
62
71
  const router = useRouter();
63
72
  const userStore = useUserStore();
64
73
 
65
- /** 拉取当前会话信息。 */
74
+ /** 刷新本人会话列表。 */
66
75
  async function loadSession() {
67
76
  loading.value = true;
68
77
  try {
69
- session.value = await defBaseSessionService.GetCurrentBaseSession({});
78
+ await proTable.value?.getTableList();
70
79
  } finally {
71
80
  loading.value = false;
72
81
  }
@@ -80,7 +89,7 @@ async function revokeAll() {
80
89
  await defBaseSessionService.RevokeAllBaseSessions({});
81
90
  userStore.clearAuthData();
82
91
  ElMessage.success(t("system.profile.session.message.revoked"));
83
- session.value = undefined;
92
+ hasSessions.value = false;
84
93
  await router.replace(LOGIN_URL);
85
94
  }
86
95
 
@@ -92,8 +101,6 @@ function formatExpires(seconds: number) {
92
101
  if (hours > 0) return t("system.profile.session.value.hours_minutes", { hours, minutes });
93
102
  return t("system.profile.session.value.minutes", { minutes });
94
103
  }
95
-
96
- onMounted(loadSession);
97
104
  </script>
98
105
 
99
106
  <style scoped lang="scss">
@@ -126,36 +133,14 @@ onMounted(loadSession);
126
133
  color: var(--el-text-color-secondary);
127
134
  font-size: 13px;
128
135
  }
129
- .session-grid {
130
- display: grid;
131
- grid-template-columns: repeat(2, minmax(0, 1fr));
132
- gap: 16px;
133
- margin: 24px 0;
134
- }
135
- .session-grid div {
136
- padding: 14px;
137
- background: var(--el-fill-color-light);
138
- border-radius: var(--admin-page-radius);
139
- }
140
- .session-grid dt {
141
- color: var(--el-text-color-secondary);
142
- font-size: 12px;
143
- }
144
- .session-grid dd {
145
- margin: 6px 0 0;
146
- color: var(--el-text-color-primary);
147
- overflow-wrap: anywhere;
148
- }
149
136
  .session-actions {
150
137
  justify-content: flex-end;
138
+ margin-top: 20px;
151
139
  }
152
140
  @media screen and (width <= 640px) {
153
141
  .session-header {
154
142
  align-items: flex-start;
155
143
  flex-direction: column;
156
144
  }
157
- .session-grid {
158
- grid-template-columns: 1fr;
159
- }
160
145
  }
161
146
  </style>
@@ -27,6 +27,7 @@
27
27
  @switch-tab="handleTabChange"
28
28
  />
29
29
  <ProfileSession v-else-if="activeTab === 'session'" />
30
+ <ProfileLoginLog v-else-if="activeTab === 'login-log'" />
30
31
  <ProfilePassword v-else />
31
32
  </main>
32
33
  </section>
@@ -49,9 +50,10 @@ import ProfileBase from "./components/base.vue";
49
50
  import ProfileSecurity from "./components/security.vue";
50
51
  import ProfilePassword from "./components/password.vue";
51
52
  import ProfileSession from "./components/session.vue";
53
+ import ProfileLoginLog from "./components/login-log.vue";
52
54
 
53
55
  /** 个人中心标签页。 */
54
- type ProfileTab = "account" | "security" | "password" | "session";
56
+ type ProfileTab = "account" | "security" | "password" | "session" | "login-log";
55
57
 
56
58
  /** 左侧导航项结构。 */
57
59
  interface ProfileTabOption {
@@ -84,13 +86,16 @@ const profileTabs = computed<ProfileTabOption[]>(() => {
84
86
  description: t("system.profile.password.nav_description")
85
87
  }
86
88
  ];
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
- });
93
- }
89
+ tabs.push({
90
+ value: "session",
91
+ label: t("system.profile.session.title"),
92
+ description: t("system.profile.session.nav_description")
93
+ });
94
+ tabs.push({
95
+ value: "login-log",
96
+ label: t("system.profile.login_log.title"),
97
+ description: t("system.profile.login_log.nav_description")
98
+ });
94
99
  return tabs;
95
100
  });
96
101
  const userProfileForm = reactive<UserProfileForm>({
@@ -210,5 +215,4 @@ onMounted(async () => {
210
215
  position: static;
211
216
  }
212
217
  }
213
-
214
218
  </style>
@@ -135,21 +135,11 @@ async function handleGenerate() {
135
135
  return;
136
136
  }
137
137
  if (missingI18ns.value.length) {
138
- try {
139
- await ElMessageBox.alert(
140
- t("system.code.gen.preview.message.missing_i18ns", {
141
- items: missingI18ns.value.join(t("system.code.gen.preview.value.list_separator"))
142
- }),
143
- t("common.title.warning"),
144
- {
145
- confirmButtonText: t("common.action.close"),
146
- type: "warning"
147
- }
148
- );
149
- } catch {
150
- // 关闭提示框与点击关闭按钮语义一致。
151
- }
152
- return;
138
+ ElMessage.warning(
139
+ t("system.code.gen.preview.message.missing_i18ns", {
140
+ items: missingI18ns.value.join(t("system.code.gen.preview.value.list_separator"))
141
+ })
142
+ );
153
143
  }
154
144
  try {
155
145
  await ElMessageBox.confirm(
@@ -15,8 +15,8 @@
15
15
  v-model="dialog.visible"
16
16
  ref="formDialogRef"
17
17
  :title="dialogTitle"
18
- width="920px"
19
- label-width="240px"
18
+ width="min(1440px, calc(100vw - 32px))"
19
+ label-width="180px"
20
20
  top="4vh"
21
21
  :model="formData"
22
22
  :fields="formFields"
@@ -24,11 +24,13 @@
24
24
  :confirm-loading="saving"
25
25
  :gutter="16"
26
26
  :col-span="12"
27
+ :form-props="{ class: 'code-gen-table-form' }"
27
28
  @confirm="handleSubmit"
28
29
  @close="handleCloseDialog"
29
30
  >
30
31
  <template #tableI18nConfig>
31
32
  <CodeGenLocaleEditor
33
+ class="code-gen-table-locales"
32
34
  :model-value="formData.i18n_config"
33
35
  :source-comment="formData.comment"
34
36
  :show-left-tree-comment="formData.page_type === 'left_tree'"
@@ -263,6 +265,7 @@ const formFields = computed<ProFormField[]>(() => [
263
265
  prop: "page_type",
264
266
  label: t("system.code.gen.table.field.page_type"),
265
267
  component: "segmented",
268
+ colSpan: 16,
266
269
  options: pageTypeOptions.value,
267
270
  labelTooltip: t("system.code.gen.table.tooltip.page_type"),
268
271
  props: { onChange: handlePageTypeChange }
@@ -387,9 +390,9 @@ const formFields = computed<ProFormField[]>(() => [
387
390
  label: t("system.code.gen.table.field.gen_backend"),
388
391
  component: "switch",
389
392
  labelTooltip: t("system.code.gen.table.tooltip.gen_backend"),
390
- // 三个生成开关始终从新行开始并排展示。
393
+ // 生成开关按两列排列,减少表单横向空置并保持开关内容紧凑。
391
394
  rowBreakBefore: true,
392
- colSpan: 8,
395
+ colSpan: 12,
393
396
  props: { activeText: t("system.code.gen.value.generate"), inactiveText: t("system.code.gen.value.skip") }
394
397
  },
395
398
  {
@@ -397,14 +400,15 @@ const formFields = computed<ProFormField[]>(() => [
397
400
  label: t("system.code.gen.table.field.gen_frontend"),
398
401
  component: "switch",
399
402
  labelTooltip: t("system.code.gen.table.tooltip.gen_frontend"),
400
- colSpan: 8,
403
+ colSpan: 12,
401
404
  props: { activeText: t("system.code.gen.value.generate"), inactiveText: t("system.code.gen.value.skip") }
402
405
  },
403
406
  {
404
407
  prop: "gen_sql",
405
408
  label: t("system.code.gen.table.field.gen_sql"),
406
409
  component: "switch",
407
- colSpan: 8,
410
+ colSpan: 12,
411
+ rowBreakBefore: false,
408
412
  labelTooltip: t("system.code.gen.table.tooltip.gen_sql"),
409
413
  props: { activeText: t("system.code.gen.value.generate"), inactiveText: t("system.code.gen.value.skip") }
410
414
  },
@@ -412,7 +416,7 @@ const formFields = computed<ProFormField[]>(() => [
412
416
  prop: "status",
413
417
  label: t("system.code.gen.table.field.status"),
414
418
  component: "dict",
415
- colSpan: 24,
419
+ colSpan: 12,
416
420
  props: { code: "code_gen_table_status", codeType: "number", type: "radio" },
417
421
  labelTooltip: t("system.code.gen.table.tooltip.status")
418
422
  },
@@ -623,21 +627,11 @@ async function handleGenerate(selected: CodeGenGenerateTarget) {
623
627
  generating.value = false;
624
628
  }
625
629
  if (missingI18ns.length) {
626
- try {
627
- await ElMessageBox.alert(
628
- t("system.code.gen.preview.message.missing_i18ns", {
629
- items: missingI18ns.join(t("system.code.gen.preview.value.list_separator"))
630
- }),
631
- t("common.title.warning"),
632
- {
633
- confirmButtonText: t("common.action.close"),
634
- type: "warning"
635
- }
636
- );
637
- } catch {
638
- // 关闭提示框与点击关闭按钮语义一致。
639
- }
640
- return;
630
+ ElMessage.warning(
631
+ t("system.code.gen.preview.message.missing_i18ns", {
632
+ items: missingI18ns.join(t("system.code.gen.preview.value.list_separator"))
633
+ })
634
+ );
641
635
  }
642
636
  const message =
643
637
  tables.length === 1
@@ -970,14 +964,14 @@ function resolveDefaultColumn(columns: CodeGenDatabaseColumn[], columnName: stri
970
964
  return columns.some(item => item.name === columnName) ? columnName : "";
971
965
  }
972
966
 
973
- /** 转换菜单树为 ProForm 树形选择项。 */
967
+ /** 转换菜单树为 ProForm 树形选择项,仅允许八位编号的一至三级目录承载生成页面。 */
974
968
  function convertMenuOptions(options: BaseMenu[]): ProFormOption[] {
975
969
  return options
976
970
  .filter(item => item.type === BaseMenuType.BASE_MENU_TYPE_FOLDER)
977
971
  .map(item => ({
978
972
  label: item.meta?.title || item.name || item.path,
979
973
  value: item.id,
980
- disabled: item.id < 100 || item.id > 99999,
974
+ disabled: item.id < 10000000 || item.id > 99999999 || item.id % 100 !== 0,
981
975
  children: convertMenuOptions(item.children ?? [])
982
976
  }));
983
977
  }
@@ -1022,6 +1016,38 @@ function ensureLeftTreeConfig() {
1022
1016
  </script>
1023
1017
 
1024
1018
  <style scoped lang="scss">
1019
+ .code-gen-table-locales {
1020
+ display: grid;
1021
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
1022
+ width: 100%;
1023
+ min-width: 0;
1024
+ :deep(.el-alert) {
1025
+ grid-column: 1 / -1;
1026
+ }
1027
+ }
1028
+
1029
+ @media (max-width: 767px) {
1030
+ .code-gen-table-locales {
1031
+ grid-template-columns: 1fr;
1032
+ }
1033
+ :deep(.code-gen-table-form) {
1034
+ .el-col {
1035
+ flex: 0 0 100%;
1036
+ max-width: 100%;
1037
+ }
1038
+ .el-form-item {
1039
+ flex-direction: column;
1040
+ }
1041
+ .el-form-item__label {
1042
+ justify-content: flex-start;
1043
+ width: auto !important;
1044
+ }
1045
+ .el-form-item__content {
1046
+ margin-left: 0 !important;
1047
+ }
1048
+ }
1049
+ }
1050
+
1025
1051
  /* 固定操作列表头与普通表头使用同一主题背景,并保持行内操作单行展示。 */
1026
1052
  :deep(.code-gen-table) {
1027
1053
  --el-table-header-bg-color: var(--el-fill-color-light);
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.38",
4
+ "version": "0.0.39",
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.38"
18
+ "@liujitcn/kratos-admin-core": "0.0.39"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "@element-plus/icons-vue": "^2.3.1",