fix: 修复管理端前端 lint 与构建问题
- 收敛 easyflow-ui-admin 的 lint、格式和类型问题 - 修正 demo 页面与管理端前端构建失败点 - 验证 pnpm lint 与 pnpm build 均已通过
This commit is contained in:
@@ -76,7 +76,9 @@ function clearSelectedFile() {
|
||||
async function downloadTemplate() {
|
||||
downloadLoading.value = true;
|
||||
try {
|
||||
const blob = await api.download('/api/v1/sysAccount/downloadImportTemplate');
|
||||
const blob = await api.download(
|
||||
'/api/v1/sysAccount/downloadImportTemplate',
|
||||
);
|
||||
downloadFileFromBlob({
|
||||
fileName: 'user_import_template.xlsx',
|
||||
source: blob,
|
||||
@@ -136,7 +138,9 @@ async function handleImport() {
|
||||
<ElIcon class="text-4xl text-[var(--el-text-color-secondary)]">
|
||||
<UploadFilled />
|
||||
</ElIcon>
|
||||
<div class="text-[15px] font-semibold text-[var(--el-text-color-primary)]">
|
||||
<div
|
||||
class="text-[15px] font-semibold text-[var(--el-text-color-primary)]"
|
||||
>
|
||||
{{ $t('sysAccount.importUploadTitle') }}
|
||||
</div>
|
||||
<div class="text-[13px] text-[var(--el-text-color-secondary)]">
|
||||
@@ -182,17 +186,23 @@ async function handleImport() {
|
||||
</div>
|
||||
<div class="result-stats">
|
||||
<div class="stat-item">
|
||||
<div class="stat-label">{{ $t('sysAccount.importTotalCount') }}</div>
|
||||
<div class="stat-label">
|
||||
{{ $t('sysAccount.importTotalCount') }}
|
||||
</div>
|
||||
<div class="stat-value">{{ importResult.totalCount || 0 }}</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-label">{{ $t('sysAccount.importSuccessCount') }}</div>
|
||||
<div class="stat-label">
|
||||
{{ $t('sysAccount.importSuccessCount') }}
|
||||
</div>
|
||||
<div class="stat-value success-text">
|
||||
{{ importResult.successCount || 0 }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-label">{{ $t('sysAccount.importErrorCount') }}</div>
|
||||
<div class="stat-label">
|
||||
{{ $t('sysAccount.importErrorCount') }}
|
||||
</div>
|
||||
<div class="stat-value" :class="hasErrors ? 'danger-text' : ''">
|
||||
{{ importResult.errorCount || 0 }}
|
||||
</div>
|
||||
@@ -267,25 +277,25 @@ async function handleImport() {
|
||||
}
|
||||
|
||||
.sys-account-upload-area :deep(.el-upload-dragger) {
|
||||
background: hsl(var(--surface) / 72%);
|
||||
border-color: hsl(var(--border) / 68%);
|
||||
border-radius: 18px;
|
||||
border-color: hsl(var(--border) / 0.68);
|
||||
background: hsl(var(--surface) / 0.72);
|
||||
}
|
||||
|
||||
.selected-file-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border: 1px solid hsl(var(--border) / 0.72);
|
||||
border-radius: 16px;
|
||||
padding: 12px 16px;
|
||||
background: hsl(var(--surface-subtle) / 0.95);
|
||||
background: hsl(var(--surface-subtle) / 95%);
|
||||
border: 1px solid hsl(var(--border) / 72%);
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.selected-file-main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
@@ -296,15 +306,15 @@ async function handleImport() {
|
||||
.selected-file-name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: var(--el-text-color-primary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.result-wrap {
|
||||
border: 1px solid hsl(var(--border) / 0.72);
|
||||
border-radius: 18px;
|
||||
padding: 18px;
|
||||
background: hsl(var(--surface-subtle) / 0.94);
|
||||
background: hsl(var(--surface-subtle) / 94%);
|
||||
border: 1px solid hsl(var(--border) / 72%);
|
||||
border-radius: 18px;
|
||||
}
|
||||
|
||||
.result-head {
|
||||
@@ -313,8 +323,8 @@ async function handleImport() {
|
||||
|
||||
.result-title-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
@@ -327,9 +337,9 @@ async function handleImport() {
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
border-radius: 14px;
|
||||
padding: 14px 16px;
|
||||
background: hsl(var(--surface) / 0.95);
|
||||
background: hsl(var(--surface) / 95%);
|
||||
border-radius: 14px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
@@ -354,9 +364,9 @@ async function handleImport() {
|
||||
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -270,7 +270,9 @@ function isAdmin(data: any) {
|
||||
<template #middle>
|
||||
<div v-if="selectedCount > 0" class="sys-account-batch-inline">
|
||||
<span class="sys-account-batch-inline__count">
|
||||
{{ $t('sysAccount.batchSelectedCount', { count: selectedCount }) }}
|
||||
{{
|
||||
$t('sysAccount.batchSelectedCount', { count: selectedCount })
|
||||
}}
|
||||
</span>
|
||||
<div class="sys-account-batch-inline__actions">
|
||||
<div v-access:code="'/api/v1/sysAccount/save'">
|
||||
@@ -427,9 +429,9 @@ function isAdmin(data: any) {
|
||||
<style scoped>
|
||||
.sys-account-batch-inline {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.sys-account-batch-inline__count {
|
||||
@@ -444,9 +446,9 @@ function isAdmin(data: any) {
|
||||
|
||||
.sys-account-batch-inline__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.sys-account-batch-inline__actions :deep(.el-button) {
|
||||
@@ -464,8 +466,8 @@ function isAdmin(data: any) {
|
||||
:deep(.sys-account-batch-inline__button:not(.is-disabled):hover),
|
||||
:deep(.sys-account-batch-inline__button:not(.is-disabled):focus-visible) {
|
||||
color: hsl(var(--primary));
|
||||
background: hsl(var(--primary) / 0.08);
|
||||
border-color: hsl(var(--primary) / 0.16);
|
||||
background: hsl(var(--primary) / 8%);
|
||||
border-color: hsl(var(--primary) / 16%);
|
||||
}
|
||||
|
||||
:deep(.sys-account-batch-inline__button.is-danger) {
|
||||
@@ -473,10 +475,12 @@ function isAdmin(data: any) {
|
||||
}
|
||||
|
||||
:deep(.sys-account-batch-inline__button.is-danger:not(.is-disabled):hover),
|
||||
:deep(.sys-account-batch-inline__button.is-danger:not(.is-disabled):focus-visible) {
|
||||
:deep(
|
||||
.sys-account-batch-inline__button.is-danger:not(.is-disabled):focus-visible
|
||||
) {
|
||||
color: hsl(var(--destructive));
|
||||
background: hsl(var(--destructive) / 0.08);
|
||||
border-color: hsl(var(--destructive) / 0.16);
|
||||
background: hsl(var(--destructive) / 8%);
|
||||
border-color: hsl(var(--destructive) / 16%);
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
|
||||
@@ -153,10 +153,7 @@ function closeDialog() {
|
||||
:label="$t('sysAccount.password')"
|
||||
>
|
||||
<div class="w-full">
|
||||
<EasyFlowInputPassword
|
||||
v-model="entity.password"
|
||||
password-strength
|
||||
/>
|
||||
<EasyFlowInputPassword v-model="entity.password" password-strength />
|
||||
<div class="mt-2 text-xs text-[var(--el-text-color-secondary)]">
|
||||
{{ $t('sysAccount.passwordStrongTip') }}
|
||||
</div>
|
||||
|
||||
@@ -190,7 +190,7 @@ function getTree() {
|
||||
|
||||
<style scoped>
|
||||
.search-input {
|
||||
border-radius: 4px;
|
||||
width: 300px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,12 +5,7 @@ import { computed, ref } from 'vue';
|
||||
|
||||
import { EasyFlowFormModal } from '@easyflow/common-ui';
|
||||
|
||||
import {
|
||||
ElForm,
|
||||
ElFormItem,
|
||||
ElInput,
|
||||
ElMessage,
|
||||
} from 'element-plus';
|
||||
import { ElForm, ElFormItem, ElInput, ElMessage } from 'element-plus';
|
||||
|
||||
import { api } from '#/api/request';
|
||||
import DictSelect from '#/components/dict/DictSelect.vue';
|
||||
@@ -41,14 +36,16 @@ interface CategoryPermissionTreeNode {
|
||||
label: string;
|
||||
}
|
||||
|
||||
const RESOURCE_SCOPE_GROUPS: Array<{ label: string; resourceType: ResourceType }> =
|
||||
[
|
||||
{ resourceType: 'BOT', label: $t('bot.chatAssistant') },
|
||||
{ resourceType: 'PLUGIN', label: $t('menus.ai.plugin') },
|
||||
{ resourceType: 'WORKFLOW', label: $t('menus.ai.workflow') },
|
||||
{ resourceType: 'KNOWLEDGE', label: $t('menus.ai.documentCollection') },
|
||||
{ resourceType: 'RESOURCE', label: $t('menus.ai.resources') },
|
||||
];
|
||||
const RESOURCE_SCOPE_GROUPS: Array<{
|
||||
label: string;
|
||||
resourceType: ResourceType;
|
||||
}> = [
|
||||
{ resourceType: 'BOT', label: $t('bot.chatAssistant') },
|
||||
{ resourceType: 'PLUGIN', label: $t('menus.ai.plugin') },
|
||||
{ resourceType: 'WORKFLOW', label: $t('menus.ai.workflow') },
|
||||
{ resourceType: 'KNOWLEDGE', label: $t('menus.ai.documentCollection') },
|
||||
{ resourceType: 'RESOURCE', label: $t('menus.ai.resources') },
|
||||
];
|
||||
|
||||
const saveForm = ref<FormInstance>();
|
||||
const dialogVisible = ref(false);
|
||||
@@ -270,29 +267,31 @@ function buildScopeItemsFromTree(): CategoryScopeItem[] {
|
||||
}
|
||||
|
||||
function getCategoryScopeDetail(roleId: number | string) {
|
||||
api.get('/api/v1/sysRoleCategoryScope/detail', {
|
||||
params: { roleId },
|
||||
}).then((res) => {
|
||||
if (res.errorCode !== 0) {
|
||||
categoryScopeEditable.value = false;
|
||||
api
|
||||
.get('/api/v1/sysRoleCategoryScope/detail', {
|
||||
params: { roleId },
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.errorCode !== 0) {
|
||||
categoryScopeEditable.value = false;
|
||||
categoryScopeDetail.value = {
|
||||
roleId,
|
||||
scopes: buildDefaultScopes(),
|
||||
};
|
||||
syncCategoryTreeCheckedKeys(categoryScopeDetail.value.scopes);
|
||||
return;
|
||||
}
|
||||
categoryScopeEditable.value = !!res.data?.editable;
|
||||
categoryScopeDetail.value = {
|
||||
roleId,
|
||||
scopes: buildDefaultScopes(),
|
||||
scopes: (res.data?.scopes || buildDefaultScopes()).map((item: any) => ({
|
||||
categoryIds: item.categoryIds || [],
|
||||
resourceType: item.resourceType,
|
||||
scopeMode: item.scopeMode || 'CUSTOM',
|
||||
})),
|
||||
};
|
||||
syncCategoryTreeCheckedKeys(categoryScopeDetail.value.scopes);
|
||||
return;
|
||||
}
|
||||
categoryScopeEditable.value = !!res.data?.editable;
|
||||
categoryScopeDetail.value = {
|
||||
roleId,
|
||||
scopes: (res.data?.scopes || buildDefaultScopes()).map((item: any) => ({
|
||||
categoryIds: item.categoryIds || [],
|
||||
resourceType: item.resourceType,
|
||||
scopeMode: item.scopeMode || 'CUSTOM',
|
||||
})),
|
||||
};
|
||||
syncCategoryTreeCheckedKeys(categoryScopeDetail.value.scopes);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function saveCategoryScope(roleId: number | string) {
|
||||
@@ -375,9 +374,9 @@ async function saveCategoryScope(roleId: number | string) {
|
||||
<style scoped>
|
||||
.role-category-scope-panel {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.role-category-scope-group {
|
||||
@@ -385,16 +384,16 @@ async function saveCategoryScope(roleId: number | string) {
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding: 12px;
|
||||
background: var(--el-fill-color-extra-light);
|
||||
border: 1px solid var(--el-border-color-lighter);
|
||||
border-radius: 10px;
|
||||
background: var(--el-fill-color-extra-light);
|
||||
}
|
||||
|
||||
.role-category-scope-head {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.role-category-scope-title {
|
||||
|
||||
Reference in New Issue
Block a user