@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.
- package/dist/package/declarations/src/api/base/v1/sse.d.ts +1 -1
- package/dist/package/declarations/src/locales/generated.d.ts +32 -0
- package/dist/package/declarations/src/rpc/base/v1/ai_search.d.ts +26 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_redact_output_policy.d.ts +0 -1
- package/dist/package/src/api/base/v1/sse.ts +19 -12
- package/dist/package/src/components/log/LogTable.vue +25 -18
- package/dist/package/src/components/notification/Notification.vue +14 -7
- package/dist/package/src/components/tenant-project/TenantProjectManager.vue +12 -6
- package/dist/package/src/components/tenant-project-grant/ProjectGrantDialog.vue +22 -7
- package/dist/package/src/locales/en-US.json +8 -0
- package/dist/package/src/locales/ja-JP.json +8 -0
- package/dist/package/src/locales/zh-CN.json +8 -0
- package/dist/package/src/locales/zh-TW.json +8 -0
- package/dist/package/src/rpc/base/v1/ai_search.ts +37 -0
- package/dist/package/src/rpc/system/admin/v1/base_redact_output_policy.ts +0 -1
- package/dist/package/src/views/ai/chat/index.vue +16 -7
- package/dist/package/src/views/base/api-log/index.vue +1 -1
- package/dist/package/src/views/base/area/index.vue +15 -9
- package/dist/package/src/views/base/backup-management/archive-config/index.vue +22 -10
- package/dist/package/src/views/base/backup-management/backup-config/index.vue +13 -6
- package/dist/package/src/views/base/config/index.vue +38 -14
- package/dist/package/src/views/base/dashboard/index.vue +201 -53
- package/dist/package/src/views/base/dept/index.vue +31 -25
- package/dist/package/src/views/base/dict/index.vue +12 -8
- package/dist/package/src/views/base/dict/item.vue +12 -8
- package/dist/package/src/views/base/i18n-custom/index.vue +13 -7
- package/dist/package/src/views/base/job/index.vue +12 -8
- package/dist/package/src/views/base/job/log.vue +14 -9
- package/dist/package/src/views/base/language/index.vue +7 -4
- package/dist/package/src/views/base/login-policy/index.vue +22 -11
- package/dist/package/src/views/base/menu/index.vue +23 -16
- package/dist/package/src/views/base/message/index.vue +65 -21
- package/dist/package/src/views/base/message-category/index.vue +10 -4
- package/dist/package/src/views/base/oauth-client/index.vue +15 -5
- package/dist/package/src/views/base/post/index.vue +10 -4
- package/dist/package/src/views/base/redact-output-policy/index.vue +12 -5
- package/dist/package/src/views/base/redact-rule/index.vue +8 -7
- package/dist/package/src/views/base/redact-storage-policy/index.vue +32 -8
- package/dist/package/src/views/base/role/index.vue +24 -17
- package/dist/package/src/views/base/tenant/index.vue +7 -6
- package/dist/package/src/views/base/tenant-project-grant/index.vue +44 -27
- package/dist/package/src/views/base/user/components/dept-tree.vue +4 -9
- package/dist/package/src/views/base/user/index.vue +39 -28
- package/dist/package/src/views/message/inbox/index.vue +8 -3
- package/dist/package/src/views/profile/components/base.vue +1 -1
- package/dist/package/src/views/profile/index.vue +1 -1
- package/dist/package/src/views/tool/cache/index.vue +1 -1
- package/dist/package/src/views/tool/code-gen/columns/index.vue +35 -16
- package/dist/package/src/views/tool/code-gen/table/index.vue +58 -31
- package/package.json +2 -2
|
@@ -301,16 +301,15 @@ function refreshTable() {
|
|
|
301
301
|
/**
|
|
302
302
|
* 加载部门下拉树数据,供弹窗选择上级部门。
|
|
303
303
|
*/
|
|
304
|
-
async function
|
|
304
|
+
async function requestDeptOptions(tenantId = formData.tenant_id) {
|
|
305
305
|
// 默认租户未选择目标租户时仅保留顶级部门,避免混入其他租户的部门树。
|
|
306
|
-
if (isDefaultTenant.value && !
|
|
307
|
-
|
|
308
|
-
return;
|
|
306
|
+
if (isDefaultTenant.value && !tenantId) {
|
|
307
|
+
return [{ value: 0, label: t("system.base.dept.value.root"), disabled: false, has_children: true, children: [] }];
|
|
309
308
|
}
|
|
310
309
|
const optionBaseDeptResponse = await defBaseDeptService.OptionBaseDept({
|
|
311
|
-
tenant_id: toRequestTenantId(
|
|
310
|
+
tenant_id: toRequestTenantId(tenantId)
|
|
312
311
|
});
|
|
313
|
-
|
|
312
|
+
return [
|
|
314
313
|
{
|
|
315
314
|
value: 0,
|
|
316
315
|
label: t("system.base.dept.value.root"),
|
|
@@ -321,6 +320,11 @@ async function loadDeptOptions() {
|
|
|
321
320
|
];
|
|
322
321
|
}
|
|
323
322
|
|
|
323
|
+
/** 加载部门下拉树数据并更新表单选项。 */
|
|
324
|
+
async function loadDeptOptions() {
|
|
325
|
+
deptOptions.value = await requestDeptOptions();
|
|
326
|
+
}
|
|
327
|
+
|
|
324
328
|
/**
|
|
325
329
|
* 切换表单租户时重新加载对应租户的上级部门树。
|
|
326
330
|
*/
|
|
@@ -333,31 +337,33 @@ async function handleFormTenantChange() {
|
|
|
333
337
|
* 打开部门弹窗。
|
|
334
338
|
*/
|
|
335
339
|
async function handleOpenDialog(parent_id?: number, deptId?: number, tenantId?: number) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
340
|
+
await formDialogRef.value?.open({
|
|
341
|
+
load: async () => {
|
|
342
|
+
await loadTenantOptions();
|
|
343
|
+
const data = deptId ? await defBaseDeptService.GetBaseDept({ id: deptId }) : undefined;
|
|
344
|
+
const options = await requestDeptOptions(data?.tenant_id ?? tenantId);
|
|
345
|
+
return { data, options };
|
|
346
|
+
},
|
|
347
|
+
commit: ({ data, options }) => {
|
|
348
|
+
resetForm();
|
|
349
|
+
deptOptions.value = options;
|
|
350
|
+
dialog.titleKey = deptId ? "common.action.edit_resource" : "common.action.create_resource";
|
|
351
|
+
if (data) {
|
|
352
|
+
Object.assign(formData, data);
|
|
353
|
+
} else {
|
|
354
|
+
// 从部门行新增子部门时,继承父部门租户并加载同租户上级部门树。
|
|
355
|
+
formData.tenant_id = tenantId;
|
|
356
|
+
formData.parent_id = parent_id ?? 0;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
});
|
|
354
360
|
}
|
|
355
361
|
|
|
356
362
|
/**
|
|
357
363
|
* 关闭部门弹窗。
|
|
358
364
|
*/
|
|
359
365
|
function handleCloseDialog() {
|
|
360
|
-
|
|
366
|
+
formDialogRef.value?.close();
|
|
361
367
|
resetForm();
|
|
362
368
|
}
|
|
363
369
|
|
|
@@ -247,22 +247,26 @@ function refreshTable() {
|
|
|
247
247
|
* 打开字典编辑弹窗。
|
|
248
248
|
*/
|
|
249
249
|
async function handleOpenDialog(dictId?: number) {
|
|
250
|
-
await loadEnabledBaseLanguages();
|
|
251
250
|
resetForm();
|
|
252
251
|
dialog.editing = Boolean(dictId);
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
252
|
+
await formDialogRef.value?.open({
|
|
253
|
+
load: async () => ({
|
|
254
|
+
data: dictId ? await defBaseDictService.GetBaseDict({ id: dictId }) : undefined,
|
|
255
|
+
languages: await loadEnabledBaseLanguages()
|
|
256
|
+
}),
|
|
257
|
+
commit: ({ data }) => {
|
|
258
|
+
if (!data) return;
|
|
259
|
+
Object.assign(formData, data);
|
|
260
|
+
i18nValues.value = normalizeDynamicI18ns(data.i18ns as DynamicI18nRecord[]);
|
|
261
|
+
}
|
|
262
|
+
});
|
|
259
263
|
}
|
|
260
264
|
|
|
261
265
|
/**
|
|
262
266
|
* 关闭字典弹窗并恢复表单初始值。
|
|
263
267
|
*/
|
|
264
268
|
function handleCloseDialog() {
|
|
265
|
-
|
|
269
|
+
formDialogRef.value?.close();
|
|
266
270
|
resetForm();
|
|
267
271
|
}
|
|
268
272
|
|
|
@@ -310,22 +310,26 @@ function refreshTable() {
|
|
|
310
310
|
* 打开字典项编辑弹窗。
|
|
311
311
|
*/
|
|
312
312
|
async function handleOpenDialog(dictItemId?: number) {
|
|
313
|
-
await loadEnabledBaseLanguages();
|
|
314
313
|
resetForm();
|
|
315
314
|
dialog.editing = Boolean(dictItemId);
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
315
|
+
await formDialogRef.value?.open({
|
|
316
|
+
load: async () => ({
|
|
317
|
+
data: dictItemId ? await defBaseDictItemService.GetBaseDictItem({ id: dictItemId }) : undefined,
|
|
318
|
+
languages: await loadEnabledBaseLanguages()
|
|
319
|
+
}),
|
|
320
|
+
commit: ({ data }) => {
|
|
321
|
+
if (!data) return;
|
|
322
|
+
Object.assign(formData, data);
|
|
323
|
+
i18nValues.value = normalizeDynamicI18ns(data.i18ns as DynamicI18nRecord[]);
|
|
324
|
+
}
|
|
325
|
+
});
|
|
322
326
|
}
|
|
323
327
|
|
|
324
328
|
/**
|
|
325
329
|
* 关闭字典项弹窗并恢复默认值。
|
|
326
330
|
*/
|
|
327
331
|
function handleCloseDialog() {
|
|
328
|
-
|
|
332
|
+
formDialogRef.value?.close();
|
|
329
333
|
resetForm();
|
|
330
334
|
}
|
|
331
335
|
|
|
@@ -213,14 +213,14 @@ const headerActions = computed<HeaderActionProps[]>(() => [
|
|
|
213
213
|
|
|
214
214
|
/** 请求国际化自定义翻译分页列表。 */
|
|
215
215
|
async function requestBaseI18nCustomTable(params: PageBaseI18nCustomRequest) {
|
|
216
|
-
await loadLanguages();
|
|
216
|
+
enabledLanguages.value = await loadLanguages();
|
|
217
217
|
const data = await defBaseI18nCustomService.PageBaseI18nCustom(buildPageRequest(params));
|
|
218
218
|
return { data: { list: data.items ?? [], total: data.total } };
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
/** 加载启用语言选项。 */
|
|
222
222
|
async function loadLanguages() {
|
|
223
|
-
|
|
223
|
+
return loadEnabledBaseLanguages();
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
/** 返回语言显示名称。 */
|
|
@@ -231,17 +231,23 @@ function getLanguageLabel(locale: string) {
|
|
|
231
231
|
|
|
232
232
|
/** 打开国际化自定义翻译编辑弹窗。 */
|
|
233
233
|
async function handleOpenDialog(id?: number) {
|
|
234
|
-
await loadLanguages();
|
|
235
234
|
resetForm();
|
|
236
235
|
dialog.editing = Boolean(id);
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
236
|
+
await formDialogRef.value?.open({
|
|
237
|
+
load: async () => ({
|
|
238
|
+
languages: await loadLanguages(),
|
|
239
|
+
data: id ? await defBaseI18nCustomService.GetBaseI18nCustom({ id }) : undefined
|
|
240
|
+
}),
|
|
241
|
+
commit: ({ languages, data }) => {
|
|
242
|
+
enabledLanguages.value = languages;
|
|
243
|
+
if (data) Object.assign(formData, data);
|
|
244
|
+
}
|
|
245
|
+
});
|
|
240
246
|
}
|
|
241
247
|
|
|
242
248
|
/** 关闭编辑弹窗并重置表单。 */
|
|
243
249
|
function handleCloseDialog() {
|
|
244
|
-
|
|
250
|
+
formDialogRef.value?.close();
|
|
245
251
|
resetForm();
|
|
246
252
|
}
|
|
247
253
|
|
|
@@ -368,22 +368,26 @@ function refreshTable() {
|
|
|
368
368
|
* 打开定时任务弹窗。
|
|
369
369
|
*/
|
|
370
370
|
async function handleOpenDialog(jobId?: number) {
|
|
371
|
-
await loadEnabledBaseLanguages();
|
|
372
371
|
resetForm();
|
|
373
372
|
dialog.editing = Boolean(jobId);
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
373
|
+
await formDialogRef.value?.open({
|
|
374
|
+
load: async () => ({
|
|
375
|
+
data: jobId ? await defBaseJobService.GetBaseJob({ id: jobId }) : undefined,
|
|
376
|
+
languages: await loadEnabledBaseLanguages()
|
|
377
|
+
}),
|
|
378
|
+
commit: ({ data }) => {
|
|
379
|
+
if (!data) return;
|
|
380
|
+
Object.assign(formData, data);
|
|
381
|
+
i18nValues.value = normalizeDynamicI18ns(data.i18ns as DynamicI18nRecord[]);
|
|
382
|
+
}
|
|
383
|
+
});
|
|
380
384
|
}
|
|
381
385
|
|
|
382
386
|
/**
|
|
383
387
|
* 关闭定时任务弹窗并恢复默认表单值。
|
|
384
388
|
*/
|
|
385
389
|
function handleCloseDialog() {
|
|
386
|
-
|
|
390
|
+
formDialogRef.value?.close();
|
|
387
391
|
resetForm();
|
|
388
392
|
}
|
|
389
393
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div class="table-box">
|
|
3
3
|
<ProTable ref="proTable" row-key="id" :columns="columns" :request-api="requestBaseJobLogTable" />
|
|
4
4
|
|
|
5
|
-
<ProDialog v-model="dialog.visible" :title="t('system.base.job.log.title.detail')" width="1200px" @close="handleCloseDialog">
|
|
5
|
+
<ProDialog ref="dialogRef" v-model="dialog.visible" :title="t('system.base.job.log.title.detail')" width="1200px" @close="handleCloseDialog">
|
|
6
6
|
<div class="detail-container">
|
|
7
7
|
<el-descriptions :title="t('system.base.job.log.section.basic')" border :column="2">
|
|
8
8
|
<el-descriptions-item :label="t('common.field.status')">
|
|
@@ -60,6 +60,7 @@ defineOptions({
|
|
|
60
60
|
|
|
61
61
|
const route = useRoute();
|
|
62
62
|
const proTable = ref<ProTableInstance>();
|
|
63
|
+
const dialogRef = ref<InstanceType<typeof ProDialog>>();
|
|
63
64
|
const initialJobID = Number(route.query.jobId ?? 0);
|
|
64
65
|
|
|
65
66
|
const dialog = reactive({
|
|
@@ -180,21 +181,25 @@ async function requestBaseJobLogTable(params: PageBaseJobLogRequest) {
|
|
|
180
181
|
/**
|
|
181
182
|
* 打开定时任务日志详情弹窗。
|
|
182
183
|
*/
|
|
183
|
-
function handleOpenDialog(logId?: number) {
|
|
184
|
+
async function handleOpenDialog(logId?: number) {
|
|
184
185
|
resetDetail();
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
186
|
+
try {
|
|
187
|
+
await dialogRef.value?.open({
|
|
188
|
+
load: () => (logId ? defBaseJobLogService.GetBaseJobLog({ id: logId }) : undefined),
|
|
189
|
+
commit: data => {
|
|
190
|
+
if (data) Object.assign(detail, data);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
} catch {
|
|
194
|
+
dialogRef.value?.close();
|
|
195
|
+
}
|
|
191
196
|
}
|
|
192
197
|
|
|
193
198
|
/**
|
|
194
199
|
* 关闭定时任务日志详情弹窗。
|
|
195
200
|
*/
|
|
196
201
|
function handleCloseDialog() {
|
|
197
|
-
|
|
202
|
+
dialogRef.value?.close();
|
|
198
203
|
resetDetail();
|
|
199
204
|
}
|
|
200
205
|
|
|
@@ -144,14 +144,17 @@ async function requestBaseLanguageTable(params: PageBaseLanguageRequest) {
|
|
|
144
144
|
async function handleOpenDialog(id?: number) {
|
|
145
145
|
resetForm();
|
|
146
146
|
dialog.editing = Boolean(id);
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
await formDialogRef.value?.open({
|
|
148
|
+
load: () => (id ? defBaseLanguageService.GetBaseLanguage({ id }) : undefined),
|
|
149
|
+
commit: data => {
|
|
150
|
+
if (data) Object.assign(formData, data);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
150
153
|
}
|
|
151
154
|
|
|
152
155
|
/** 关闭语言编辑弹窗。 */
|
|
153
156
|
function handleCloseDialog() {
|
|
154
|
-
|
|
157
|
+
formDialogRef.value?.close();
|
|
155
158
|
resetForm();
|
|
156
159
|
}
|
|
157
160
|
|
|
@@ -442,23 +442,34 @@ async function requestTable(params: Record<string, unknown>) {
|
|
|
442
442
|
|
|
443
443
|
/** 打开登录策略表单。 */
|
|
444
444
|
async function openDialog(id?: number) {
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
445
|
+
await formDialogRef.value?.open({
|
|
446
|
+
load: async () => {
|
|
447
|
+
await loadTenantOptions();
|
|
448
|
+
const detail = id ? await defBaseLoginPolicyService.GetBaseLoginPolicy({ id }) : undefined;
|
|
449
|
+
const loadedUserOptions =
|
|
450
|
+
detail?.scope_type === BaseLoginPolicyScopeType.BASE_LOGIN_POLICY_SCOPE_TYPE_USER && detail.tenant_id
|
|
451
|
+
? await requestUserOptions(detail.tenant_id)
|
|
452
|
+
: [];
|
|
453
|
+
return { detail, loadedUserOptions };
|
|
454
|
+
},
|
|
455
|
+
commit: ({ detail, loadedUserOptions }) => {
|
|
456
|
+
Object.assign(formData, defaultForm());
|
|
457
|
+
dialog.titleKey = id ? "common.action.edit" : "common.action.create";
|
|
458
|
+
if (detail) Object.assign(formData, detail, { initial_password: "", rules: detail.rules ?? [] });
|
|
459
|
+
userOptions.value = loadedUserOptions;
|
|
453
460
|
}
|
|
454
|
-
}
|
|
455
|
-
dialog.visible = true;
|
|
461
|
+
});
|
|
456
462
|
}
|
|
457
463
|
|
|
458
464
|
/** 加载指定租户的用户选项。 */
|
|
459
465
|
async function loadUserOptions(tenantId: number) {
|
|
466
|
+
userOptions.value = await requestUserOptions(tenantId);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/** 请求指定租户的用户选项。 */
|
|
470
|
+
async function requestUserOptions(tenantId: number) {
|
|
460
471
|
const response = await defBaseUserService.OptionBaseUser({ keyword: "", tenant_id: tenantId });
|
|
461
|
-
|
|
472
|
+
return response.list ?? [];
|
|
462
473
|
}
|
|
463
474
|
|
|
464
475
|
/** 提交登录策略表单。 */
|
|
@@ -1053,8 +1053,10 @@ function buildSubmitPayload(): BaseMenuForm {
|
|
|
1053
1053
|
/** 加载菜单树选项和 API 列表,确保弹窗打开时相关数据已可用。 */
|
|
1054
1054
|
async function loadDialogResources() {
|
|
1055
1055
|
const [menuData, apiData] = await Promise.all([defBaseMenuService.TreeBaseMenu({}), defBaseApiService.OptionBaseApi({})]);
|
|
1056
|
-
|
|
1057
|
-
|
|
1056
|
+
return {
|
|
1057
|
+
menuOptions: buildMenuOptions(menuData.base_menus ?? []),
|
|
1058
|
+
apiList: apiData.base_apis ?? []
|
|
1059
|
+
};
|
|
1058
1060
|
}
|
|
1059
1061
|
|
|
1060
1062
|
/** 根据关键字递归过滤菜单树,保留匹配节点及其父级。 */
|
|
@@ -1108,24 +1110,29 @@ function refreshTable() {
|
|
|
1108
1110
|
* parentMenu 为新增时的固定父节点,menuId 为编辑时的菜单 ID。
|
|
1109
1111
|
*/
|
|
1110
1112
|
async function handleOpenDialog(parentMenu?: BaseMenu, menuId?: number) {
|
|
1111
|
-
await
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1113
|
+
await formDialogRef.value?.open({
|
|
1114
|
+
load: async () => {
|
|
1115
|
+
await loadEnabledBaseLanguages();
|
|
1116
|
+
const [resources, data] = await Promise.all([
|
|
1117
|
+
loadDialogResources(),
|
|
1118
|
+
menuId ? defBaseMenuService.GetBaseMenu({ id: menuId }) : Promise.resolve(undefined)
|
|
1119
|
+
]);
|
|
1120
|
+
return { resources, data };
|
|
1121
|
+
},
|
|
1122
|
+
commit: ({ resources, data }) => {
|
|
1123
|
+
menuOptions.value = resources.menuOptions;
|
|
1124
|
+
apiList.value = resources.apiList;
|
|
1125
|
+
dialog.parentLocked = Boolean(parentMenu || menuId);
|
|
1126
|
+
dialog.editing = Boolean(menuId);
|
|
1127
|
+
dialog.parentType = parentMenu?.type ?? BaseMenuType.BASE_MENU_TYPE_UNSPECIFIED;
|
|
1128
|
+
resetForm(data ?? (menuId ? undefined : { parent_id: parentMenu?.id }));
|
|
1129
|
+
}
|
|
1130
|
+
});
|
|
1124
1131
|
}
|
|
1125
1132
|
|
|
1126
1133
|
/** 关闭菜单弹窗并显式重置表单与校验状态。 */
|
|
1127
1134
|
function handleCloseDialog() {
|
|
1128
|
-
|
|
1135
|
+
formDialogRef.value?.close();
|
|
1129
1136
|
dialog.parentType = BaseMenuType.BASE_MENU_TYPE_UNSPECIFIED;
|
|
1130
1137
|
dialog.parentLocked = true;
|
|
1131
1138
|
resetForm();
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
</template>
|
|
48
48
|
</FormDialog>
|
|
49
49
|
<ProDialog
|
|
50
|
+
ref="contentDialogRef"
|
|
50
51
|
v-model="content.visible"
|
|
51
52
|
:title="content.data?.base_message?.title || t('system.base.message.content.title')"
|
|
52
53
|
width="760px"
|
|
@@ -68,6 +69,7 @@
|
|
|
68
69
|
</template>
|
|
69
70
|
</ProDialog>
|
|
70
71
|
<ProDialog
|
|
72
|
+
ref="detailDialogRef"
|
|
71
73
|
v-model="detail.visible"
|
|
72
74
|
:title="t('system.base.message.send_detail.title')"
|
|
73
75
|
width="min(1200px, calc(100vw - 32px))"
|
|
@@ -112,7 +114,9 @@
|
|
|
112
114
|
<el-table-column prop="include_children" :label="t('system.base.message.field.include_children')" width="120">
|
|
113
115
|
<template #default="scope">{{ scope.row.include_children ? t("common.value.yes") : t("common.value.no") }}</template>
|
|
114
116
|
</el-table-column>
|
|
115
|
-
<el-table-column prop="status" :label="t('common.field.status')" width="120"
|
|
117
|
+
<el-table-column prop="status" :label="t('common.field.status')" width="120">
|
|
118
|
+
<template #default="scope">{{ optionLabel(dispatchStatusOptions, scope.row.status) }}</template>
|
|
119
|
+
</el-table-column>
|
|
116
120
|
<el-table-column prop="matched_total" :label="t('system.base.message.field.matched_total')" width="110" align="right" />
|
|
117
121
|
<el-table-column prop="inserted_total" :label="t('system.base.message.field.inserted_total')" width="110" align="right" />
|
|
118
122
|
<el-table-column prop="attempt_count" :label="t('system.base.message.field.attempt_count')" width="90" align="right" />
|
|
@@ -190,6 +194,8 @@ const { BUTTONS } = useAuthButtons();
|
|
|
190
194
|
const { isDefaultTenant, tenantColumns, tenantFormField, loadTenantOptions } = useTenantScope();
|
|
191
195
|
const proTable = ref<ProTableInstance>();
|
|
192
196
|
const formDialogRef = ref<InstanceType<typeof FormDialog>>();
|
|
197
|
+
const contentDialogRef = ref<InstanceType<typeof ProDialog>>();
|
|
198
|
+
const detailDialogRef = ref<InstanceType<typeof ProDialog>>();
|
|
193
199
|
const categoryOptions = ref<ProFormOption[]>([]);
|
|
194
200
|
const dialog = reactive({ visible: false, titleKey: "common.action.create" });
|
|
195
201
|
const content = reactive<{ visible: boolean; loading: boolean; data?: BaseMessageDetail }>({ visible: false, loading: false });
|
|
@@ -219,6 +225,13 @@ const statusOptions = computed<ProFormOption[]>(() => [
|
|
|
219
225
|
{ label: t("system.base.message.status.published"), value: MessageStatus.MESSAGE_STATUS_PUBLISHED },
|
|
220
226
|
{ label: t("system.base.message.status.revoked"), value: MessageStatus.MESSAGE_STATUS_REVOKED }
|
|
221
227
|
]);
|
|
228
|
+
const dispatchStatusOptions = computed<ProFormOption[]>(() => [
|
|
229
|
+
{ label: t("system.base.message.dispatch_status.pending"), value: MessageDispatchStatus.MESSAGE_DISPATCH_STATUS_PENDING },
|
|
230
|
+
{ label: t("system.base.message.dispatch_status.running"), value: MessageDispatchStatus.MESSAGE_DISPATCH_STATUS_RUNNING },
|
|
231
|
+
{ label: t("system.base.message.dispatch_status.succeeded"), value: MessageDispatchStatus.MESSAGE_DISPATCH_STATUS_SUCCEEDED },
|
|
232
|
+
{ label: t("system.base.message.dispatch_status.failed"), value: MessageDispatchStatus.MESSAGE_DISPATCH_STATUS_FAILED },
|
|
233
|
+
{ label: t("system.base.message.dispatch_status.cancelled"), value: MessageDispatchStatus.MESSAGE_DISPATCH_STATUS_CANCELLED }
|
|
234
|
+
]);
|
|
222
235
|
onMounted(() => {
|
|
223
236
|
void loadCategoryOptions();
|
|
224
237
|
void loadTenantOptions();
|
|
@@ -539,26 +552,42 @@ async function requestTable(params: Record<string, unknown>) {
|
|
|
539
552
|
|
|
540
553
|
/** 加载消息分类选项。 */
|
|
541
554
|
async function loadCategoryOptions() {
|
|
555
|
+
categoryOptions.value = await requestCategoryOptions();
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/** 请求消息分类选项。 */
|
|
559
|
+
async function requestCategoryOptions() {
|
|
542
560
|
const result = await defBaseMessageCategoryService.OptionBaseMessageCategory({});
|
|
543
|
-
|
|
561
|
+
return result.list.map(item => ({ label: item.label, value: item.value, disabled: item.disabled }));
|
|
544
562
|
}
|
|
545
563
|
|
|
546
564
|
/** 打开消息草稿表单。 */
|
|
547
565
|
async function openDialog(id?: number) {
|
|
548
|
-
await
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
566
|
+
await formDialogRef.value?.open({
|
|
567
|
+
load: async () => {
|
|
568
|
+
await loadTenantOptions();
|
|
569
|
+
const [detail, categories] = await Promise.all([
|
|
570
|
+
id ? defBaseMessageService.GetBaseMessage({ id }) : Promise.resolve(undefined),
|
|
571
|
+
requestCategoryOptions()
|
|
572
|
+
]);
|
|
573
|
+
return { detail, categories };
|
|
574
|
+
},
|
|
575
|
+
commit: ({ detail, categories }) => {
|
|
576
|
+
Object.assign(formState, defaultForm());
|
|
577
|
+
dialog.titleKey = id ? "common.action.edit" : "common.action.create";
|
|
578
|
+
categoryOptions.value = categories;
|
|
579
|
+
if (detail) {
|
|
580
|
+
Object.assign(formState, detail.form);
|
|
581
|
+
formState.audiences = detail.form?.audiences?.map(item => ({ ...item })) ?? [defaultAudience()];
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
});
|
|
558
585
|
}
|
|
559
586
|
|
|
560
587
|
/** 提交消息草稿。 */
|
|
561
588
|
async function handleSubmit() {
|
|
589
|
+
const valid = await formDialogRef.value?.validate();
|
|
590
|
+
if (!valid) return;
|
|
562
591
|
const audiences = formState.audiences.length > 0 ? formState.audiences.map(item => ({ ...item })) : [defaultAudience()];
|
|
563
592
|
const payload: BaseMessageForm = {
|
|
564
593
|
...formState,
|
|
@@ -576,21 +605,27 @@ async function handleSubmit() {
|
|
|
576
605
|
|
|
577
606
|
/** 打开发送详情并加载投递进度。 */
|
|
578
607
|
async function openDetail(id: number) {
|
|
579
|
-
|
|
580
|
-
|
|
608
|
+
await detailDialogRef.value?.open({
|
|
609
|
+
load: () => defBaseMessageService.GetBaseMessage({ id }),
|
|
610
|
+
commit: data => {
|
|
611
|
+
detail.data = data;
|
|
612
|
+
}
|
|
613
|
+
});
|
|
581
614
|
}
|
|
582
615
|
|
|
583
616
|
/** 打开消息正文并单独展示内容。 */
|
|
584
617
|
async function openContent(id: number) {
|
|
585
|
-
content.visible = true;
|
|
586
|
-
content.loading = true;
|
|
587
|
-
content.data = undefined;
|
|
588
618
|
try {
|
|
589
|
-
|
|
619
|
+
await contentDialogRef.value?.open({
|
|
620
|
+
load: () => defBaseMessageService.GetBaseMessage({ id }),
|
|
621
|
+
commit: data => {
|
|
622
|
+
content.data = data;
|
|
623
|
+
content.loading = false;
|
|
624
|
+
}
|
|
625
|
+
});
|
|
590
626
|
} catch {
|
|
591
|
-
content.visible = false;
|
|
592
|
-
} finally {
|
|
593
627
|
content.loading = false;
|
|
628
|
+
contentDialogRef.value?.close();
|
|
594
629
|
}
|
|
595
630
|
}
|
|
596
631
|
|
|
@@ -604,7 +639,16 @@ async function retryDispatch(id: number) {
|
|
|
604
639
|
|
|
605
640
|
/** 删除草稿消息。 */
|
|
606
641
|
async function handleDelete(value: BaseMessage | BaseMessage[] | number | number[]) {
|
|
607
|
-
const
|
|
642
|
+
const idList = Array.isArray(value)
|
|
643
|
+
? value.map(item => (typeof item === "object" ? item.id : item))
|
|
644
|
+
: typeof value === "object"
|
|
645
|
+
? [value.id]
|
|
646
|
+
: normalizeSelectedIds(value);
|
|
647
|
+
const ids = idList.filter(item => item !== undefined && item !== null && item !== "");
|
|
648
|
+
if (!ids.length) {
|
|
649
|
+
ElMessage.warning(t("common.message.select_delete_item"));
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
608
652
|
await ElMessageBox.confirm(t("common.confirm.delete"), t("common.title.warning"), { type: "warning" });
|
|
609
653
|
await defBaseMessageService.DeleteBaseMessage({ id: ids.join(",") });
|
|
610
654
|
ElMessage.success(t("common.message.operation_success"));
|
|
@@ -302,14 +302,20 @@ async function requestTable(params: Record<string, unknown>) {
|
|
|
302
302
|
|
|
303
303
|
/** 打开消息分类表单。 */
|
|
304
304
|
async function openDialog(id?: number) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
305
|
+
await formDialogRef.value?.open({
|
|
306
|
+
load: () => (id ? defBaseMessageCategoryService.GetBaseMessageCategory({ id }) : undefined),
|
|
307
|
+
commit: data => {
|
|
308
|
+
Object.assign(formData, defaultForm());
|
|
309
|
+
dialog.titleKey = id ? "common.action.edit" : "common.action.create";
|
|
310
|
+
if (data) Object.assign(formData, data);
|
|
311
|
+
}
|
|
312
|
+
});
|
|
309
313
|
}
|
|
310
314
|
|
|
311
315
|
/** 提交消息分类表单。 */
|
|
312
316
|
async function handleSubmit() {
|
|
317
|
+
const valid = await formDialogRef.value?.validate();
|
|
318
|
+
if (!valid) return;
|
|
313
319
|
const payload = formData as BaseMessageCategoryForm;
|
|
314
320
|
if (payload.id) await defBaseMessageCategoryService.UpdateBaseMessageCategory({ base_message_category: payload });
|
|
315
321
|
else await defBaseMessageCategoryService.CreateBaseMessageCategory({ base_message_category: payload });
|
|
@@ -266,12 +266,17 @@ async function loadApiOptions() {
|
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
async function handleOpenDialog(id?: number) {
|
|
269
|
-
await loadTenantOptions();
|
|
270
|
-
await loadApiOptions();
|
|
271
269
|
resetForm();
|
|
272
270
|
dialog.titleKey = id ? "common.action.edit" : "common.action.create";
|
|
273
|
-
|
|
274
|
-
|
|
271
|
+
await formDialogRef.value?.open({
|
|
272
|
+
load: async () => ({
|
|
273
|
+
data: id ? await defOauthClientService.GetOauthClient({ id }) : undefined,
|
|
274
|
+
resources: await Promise.all([loadTenantOptions(), loadApiOptions()])
|
|
275
|
+
}),
|
|
276
|
+
commit: ({ data }) => {
|
|
277
|
+
if (data) Object.assign(formData, data);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
275
280
|
}
|
|
276
281
|
|
|
277
282
|
function resetForm() {
|
|
@@ -289,7 +294,7 @@ function resetForm() {
|
|
|
289
294
|
}
|
|
290
295
|
|
|
291
296
|
function handleCloseDialog() {
|
|
292
|
-
|
|
297
|
+
formDialogRef.value?.close();
|
|
293
298
|
resetForm();
|
|
294
299
|
}
|
|
295
300
|
|
|
@@ -369,6 +374,11 @@ function handleDelete(selected?: number | string | Array<number | string> | Oaut
|
|
|
369
374
|
}
|
|
370
375
|
|
|
371
376
|
async function handleCopyCredentials(row: OauthClient) {
|
|
377
|
+
await ElMessageBox.confirm(
|
|
378
|
+
t("system.base.oauth_client.confirm.rotate_credentials"),
|
|
379
|
+
t("common.title.warning"),
|
|
380
|
+
{ type: "warning" }
|
|
381
|
+
);
|
|
372
382
|
const credentials = await defOauthClientService.RotateOauthClientCredentials({ id: row.id });
|
|
373
383
|
const content = [
|
|
374
384
|
`${t("system.base.oauth_client.field.client_id")}:${credentials.client_id}`,
|