feat: style

This commit is contained in:
wangdan-fit2cloud 2025-07-09 16:12:02 +08:00
parent 14eea7df42
commit 078bb41fc5
41 changed files with 626 additions and 566 deletions

View File

@ -54,7 +54,7 @@ const putTool: (tool_id: string, data: toolData, loading?: Ref<boolean>) => Prom
* *
* @param tool_id id * @param tool_id id
* @param loading * @param loading
* @returns * @returns
*/ */
const getToolById: (tool_id: string, loading?: Ref<boolean>) => Promise<Result<any>> = ( const getToolById: (tool_id: string, loading?: Ref<boolean>) => Promise<Result<any>> = (
tool_id, tool_id,

View File

@ -62,7 +62,7 @@ const putTool: (tool_id: string, data: toolData, loading?: Ref<boolean>) => Prom
* *
* @param tool_id id * @param tool_id id
* @param loading * @param loading
* @returns * @returns
*/ */
const getToolById: (tool_id: string, loading?: Ref<boolean>) => Promise<Result<any>> = ( const getToolById: (tool_id: string, loading?: Ref<boolean>) => Promise<Result<any>> = (
tool_id, tool_id,

View File

@ -405,7 +405,7 @@
</div> </div>
</template> </template>
<!-- 函数--> <!-- 工具-->
<template <template
v-if=" v-if="
item.type === WorkflowType.ToolLib || item.type === WorkflowType.ToolLibCustom item.type === WorkflowType.ToolLib || item.type === WorkflowType.ToolLibCustom

View File

@ -7,16 +7,20 @@
clearable clearable
class="p-8" class="p-8"
/> />
<div <div class="tree-height" :style="treeStyle">
@click="handleSharedNodeClick" <div
v-if="showShared && hasPermission(EditionConst.IS_EE, 'OR')" @click="handleSharedNodeClick"
class="shared-button flex cursor" v-if="showShared && hasPermission(EditionConst.IS_EE, 'OR')"
:class="currentNodeKey === 'share' && 'active'" class="shared-button flex cursor border-b"
> :class="currentNodeKey === 'share' && 'active'"
<AppIcon iconName="app-shared-active" style="font-size: 18px" class="color-primary"></AppIcon> >
<span class="ml-8 lighter">{{ shareTitle }}</span> <AppIcon
</div> iconName="app-shared-active"
<div class="tree-height border-t" :style="treeStyle"> style="font-size: 18px"
class="color-primary"
></AppIcon>
<span class="ml-8 lighter">{{ shareTitle }}</span>
</div>
<el-scrollbar> <el-scrollbar>
<el-tree <el-tree
ref="treeRef" ref="treeRef"
@ -62,7 +66,8 @@
<AppIcon iconName="app-add-folder"></AppIcon> <AppIcon iconName="app-add-folder"></AppIcon>
{{ $t('components.folder.addChildFolder') }} {{ $t('components.folder.addChildFolder') }}
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item @click.stop="openEditFolder(data)" <el-dropdown-item
@click.stop="openEditFolder(data)"
v-if="permissionPrecise.folderEdit()" v-if="permissionPrecise.folderEdit()"
> >
<el-icon><EditPen /></el-icon> <el-icon><EditPen /></el-icon>
@ -270,7 +275,7 @@ function refreshFolder() {
} }
.tree-height { .tree-height {
padding-top: 4px; padding-top: 4px;
height: calc(100vh - 175px); height: calc(100vh - 210px);
} }
} }
:deep(.overflow-inherit_node__children) { :deep(.overflow-inherit_node__children) {

View File

@ -5,7 +5,6 @@ import tool from './tool'
import document from './document' import document from './document'
import system from './system' import system from './system'
import userManage from './user-manage' import userManage from './user-manage'
import resourceAuthorization from './resource-authorization'
import role from './role' import role from './role'
import workspace from './workspace' import workspace from './workspace'
import application from './application' import application from './application'
@ -25,7 +24,6 @@ export default {
document, document,
system, system,
userManage, userManage,
resourceAuthorization,
role, role,
workspace, workspace,
application, application,

View File

@ -1,26 +0,0 @@
export default {
title: 'Resource Authorization',
member: 'Member',
manage: 'Owner',
permissionSetting: 'Permission Setting',
addMember: 'Add Member',
addSubTitle: 'After members log in,they can access the data you have authorized.',
searchBar: {
placeholder: 'Please enter the username to search',
},
delete: {
button: 'Remove',
confirmTitle: 'Whether to remove the member:',
confirmMessage:
"After removal, the member's knowledge base and application permissions will be revoked. ",
},
setting: {
management: ' management',
check: 'check',
authorization: 'authorization',
},
priority: {
label: 'Resource permission priority',
role: 'Role',
},
}

View File

@ -5,4 +5,10 @@ export default {
shared_model: 'Shared Model', shared_model: 'Shared Model',
shared_knowledge: 'Shared Knowledge', shared_knowledge: 'Shared Knowledge',
authorized_workspace: 'Authorize Workspace', authorized_workspace: 'Authorize Workspace',
authorized_tip: ' ',
select_workspace: 'Select Workspace',
allCheck: 'Select All',
BLACK_LIST: 'Black List',
WHITE_LIST: 'White List',
type: 'Type',
} }

View File

@ -109,6 +109,20 @@ export default {
enableSSL: 'Enable SSL (if the SMTP port is 465, you usually need to enable SSL)', enableSSL: 'Enable SSL (if the SMTP port is 465, you usually need to enable SSL)',
enableTLS: 'Enable TLS (if the SMTP port is 587, you usually need to enable TLS)', enableTLS: 'Enable TLS (if the SMTP port is 587, you usually need to enable TLS)',
}, },
resourceAuthorization: {
title: 'Resource Authorization',
member: 'Member',
permissionSetting: 'Permission Setting',
setting: {
management: ' management',
check: 'check',
authorization: 'authorization',
},
priority: {
label: 'Resource permission priority',
role: 'Role',
},
},
resource_management: { resource_management: {
label: 'Resource Management', label: 'Resource Management',
type: 'Type', type: 'Type',

View File

@ -30,7 +30,7 @@ export default {
notRecyclable: '不可循环连线', notRecyclable: '不可循环连线',
onlyLeft: '只允许连接左边的锚点', onlyLeft: '只允许连接左边的锚点',
applicationNodeError: '该应用不可用', applicationNodeError: '该应用不可用',
toolNodeError: '该函数不可用', toolNodeError: '该工具不可用',
repeatedNodeError: '节点名称已存在!', repeatedNodeError: '节点名称已存在!',
cannotCopy: '不能被复制', cannotCopy: '不能被复制',
copyError: '已复制节点', copyError: '已复制节点',
@ -278,7 +278,7 @@ export default {
}, },
}, },
toolNode: { toolNode: {
label: '自定义函数', label: '自定义工具',
text: '通过执行自定义脚本,实现数据处理', text: '通过执行自定义脚本,实现数据处理',
}, },
applicationNode: { applicationNode: {

View File

@ -5,7 +5,6 @@ import tool from './tool'
import document from './document' import document from './document'
import system from './system' import system from './system'
import userManage from './user-manage' import userManage from './user-manage'
import resourceAuthorization from './resource-authorization'
import role from './role' import role from './role'
import workspace from './workspace' import workspace from './workspace'
import application from './application' import application from './application'
@ -25,7 +24,6 @@ export default {
document, document,
system, system,
userManage, userManage,
resourceAuthorization,
role, role,
workspace, workspace,
application, application,

View File

@ -1,25 +0,0 @@
export default {
title: '资源授权',
member: '成员',
manage: '所有者',
permissionSetting: '资源权限配置',
addMember: '添加成员',
addSubTitle: '成员登录后可以访问到您授权的数据。',
searchBar: {
placeholder: '请输入用户名搜索',
},
delete: {
button: '移除',
confirmTitle: '是否移除成员:',
confirmMessage: '移除后将会取消成员拥有的知识库和应用权限。',
},
setting: {
management: '管理',
check: '查看',
authorization: '授权',
},
priority: {
label: '资源权限优先级',
role: '按角色',
},
}

View File

@ -5,4 +5,10 @@ export default {
shared_model: '共享模型', shared_model: '共享模型',
shared_knowledge: '共享知识库', shared_knowledge: '共享知识库',
authorized_workspace: '授权工作空间', authorized_workspace: '授权工作空间',
authorized_tip: '被授权的工作空间,可使用当前资源',
select_workspace: '选择工作空间',
allCheck: '全选',
BLACK_LIST: '黑名单',
WHITE_LIST: '白名单',
type: '类型',
} }

View File

@ -109,8 +109,22 @@ export default {
enableSSL: '启用 SSL如果 SMTP 端口是 465通常需要启用 SSL', enableSSL: '启用 SSL如果 SMTP 端口是 465通常需要启用 SSL',
enableTLS: '启用 TLS如果 SMTP 端口是 587通常需要启用 TLS', enableTLS: '启用 TLS如果 SMTP 端口是 587通常需要启用 TLS',
}, },
resourceAuthorization: {
title: '资源授权',
member: '成员',
permissionSetting: '资源权限配置',
setting: {
management: '管理',
check: '查看',
authorization: '授权',
},
priority: {
label: '资源权限优先级',
role: '按角色',
},
},
resource_management: { resource_management: {
label: '资源管理', label: '资源管理',
type: '类型', type: '类型',
} },
} }

View File

@ -2,8 +2,8 @@ export default {
title: '工具', title: '工具',
createTool: '创建工具', createTool: '创建工具',
editTool: '编辑工具', editTool: '编辑工具',
copyTool: '复制函数', copyTool: '复制工具',
importTool: '导入函数', importTool: '导入工具',
toolStore: { toolStore: {
title: '工具商店', title: '工具商店',
createFromToolStore: '从工具商店创建', createFromToolStore: '从工具商店创建',

View File

@ -262,7 +262,7 @@ export default {
} }
}, },
toolNode: { toolNode: {
label: '自定義函數', label: '自定義工具',
text: '通過執行自定義腳本,實現數據處理' text: '通過執行自定義腳本,實現數據處理'
}, },
applicationNode: { applicationNode: {

View File

@ -6,7 +6,6 @@ import knowledge from './knowledge'
import system from './system' import system from './system'
import tool from './tool' import tool from './tool'
import userManage from './user-manage' import userManage from './user-manage'
import resourceAuthorization from './resource-authorization'
import model from './model' import model from './model'
import document from './document' import document from './document'
import paragraph from './paragraph' import paragraph from './paragraph'
@ -23,7 +22,6 @@ export default {
system, system,
tool, tool,
userManage, userManage,
resourceAuthorization,
model, model,
knowledge, knowledge,
applicationWorkflow, applicationWorkflow,

View File

@ -1,21 +0,0 @@
export default {
title: '资源授权',
member: '成员',
manage: '所有者',
permissionSetting: '资源权限配置',
addMember: '添加成员',
addSubTitle: '成员登录后可以访问到您授权的数据。',
searchBar: {
placeholder: '请输入用户名搜索',
},
delete: {
button: '移除',
confirmTitle: '是否移除成员:',
confirmMessage: '移除后将会取消成员拥有知识库和应用权限。',
},
setting: {
management: '管理',
check: '查看',
authorization: '授权',
},
}

View File

@ -5,4 +5,10 @@ export default {
shared_model: '共享模型', shared_model: '共享模型',
shared_knowledge: '共享知识库', shared_knowledge: '共享知识库',
authorized_workspace: '授权工作区', authorized_workspace: '授权工作区',
authorized_tip: '被授权的工作空间,可使用当前资源',
select_workspace: '选择工作空间',
allCheck: '全选',
BLACK_LIST: '黑名单',
WHITE_LIST: '白名单',
type: '类型',
} }

View File

@ -94,7 +94,6 @@ export default {
access: '接入', access: '接入',
}, },
}, },
email: { email: {
title: '郵箱設置', title: '郵箱設置',
smtpHost: 'SMTP Host', smtpHost: 'SMTP Host',
@ -110,7 +109,20 @@ export default {
enableSSL: '啟用 SSL如果 SMTP 端口是 465通常需要啟用 SSL', enableSSL: '啟用 SSL如果 SMTP 端口是 465通常需要啟用 SSL',
enableTLS: '啟用 TLS如果 SMTP 端口是 587通常需要啟用 TLS', enableTLS: '啟用 TLS如果 SMTP 端口是 587通常需要啟用 TLS',
}, },
resourceAuthorization: {
title: '资源授权',
member: '成员',
permissionSetting: '资源权限配置',
setting: {
management: '管理',
check: '查看',
authorization: '授权',
},
priority: {
label: '资源权限优先级',
role: '按角色',
},
},
resource_management: { resource_management: {
label: '资源管理', label: '资源管理',
type: '类型', type: '类型',

View File

@ -24,7 +24,7 @@ export default {
}, },
delete: { delete: {
confirmTitle: '是否刪除工具', confirmTitle: '是否刪除工具',
confirmMessage: '刪除後,引用該函數的應用在查詢時會報錯,請謹慎操作。', confirmMessage: '刪除後,引用該工具的應用在查詢時會報錯,請謹慎操作。',
}, },
disabled: { disabled: {
confirmTitle: '是否停用工具:', confirmTitle: '是否停用工具:',

View File

@ -192,7 +192,7 @@ const systemRouter = {
meta: { meta: {
icon: 'app-resource-authorization', icon: 'app-resource-authorization',
iconActive: 'app-resource-authorization-active', iconActive: 'app-resource-authorization-active',
title: 'views.resourceAuthorization.title', title: 'views.system.resourceAuthorization.title',
activeMenu: '/system', activeMenu: '/system',
parentPath: '/system', parentPath: '/system',
parentName: 'system', parentName: 'system',

View File

@ -52,7 +52,7 @@
<div class="layout-bg" style="height: calc(100vh - 160px)"> <div class="layout-bg" style="height: calc(100vh - 160px)">
<el-scrollbar> <el-scrollbar>
<div class="p-16-24"> <div class="p-16-24">
<el-row :gutter="12" v-loading="loading"> <el-row :gutter="12" v-loading="loading" v-if="filterData.length">
<el-col <el-col
:span="12" :span="12"
v-for="(item, index) in filterData.filter((v: any) => v.resource_type !== 'folder')" v-for="(item, index) in filterData.filter((v: any) => v.resource_type !== 'folder')"
@ -69,6 +69,7 @@
</CardCheckbox> </CardCheckbox>
</el-col> </el-col>
</el-row> </el-row>
<el-empty :description="$t('common.noData')" v-else />
</div> </div>
</el-scrollbar> </el-scrollbar>
</div> </div>

View File

@ -12,29 +12,32 @@
</div> </div>
<el-card style="--el-card-padding: 0"> <el-card style="--el-card-padding: 0">
<div class="flex"> <div class="flex">
<div class="user-left border-r p-16"> <div class="user-left border-r">
<div class="p-8 pb-0 mb-12"> <div class="p-24 pb-0">
<h4 class="medium">{{ $t('views.chatUser.group.title') }}</h4> <h4 class="medium mb-12">{{ $t('views.chatUser.group.title') }}</h4>
<el-input
v-model="filterText"
:placeholder="$t('common.search')"
prefix-icon="Search"
clearable
/>
</div> </div>
<el-input
v-model="filterText"
:placeholder="$t('common.search')"
prefix-icon="Search"
clearable
class="mb-8"
/>
<div class="list-height-left"> <div class="list-height-left">
<el-scrollbar v-loading="loading"> <el-scrollbar v-loading="loading">
<common-list :data="filterList" @click="clickUserGroup" :default-active="current?.id"> <div class="p-16">
<template #default="{ row }"> <common-list
<span>{{ row.name }}</span> :data="filterList"
</template> @click="clickUserGroup"
<template #empty> :default-active="current?.id"
<span></span> >
</template> <template #default="{ row }">
</common-list> <span class="ellipsis-1" :title="row.name">{{ row.name }}</span>
</template>
<template #empty>
<span></span>
</template>
</common-list>
</div>
</el-scrollbar> </el-scrollbar>
</div> </div>
</div> </div>
@ -43,7 +46,7 @@
<div class="user-right" v-loading="rightLoading"> <div class="user-right" v-loading="rightLoading">
<div class="flex-between"> <div class="flex-between">
<div class="flex align-center"> <div class="flex align-center">
<h4 class="medium">{{ current?.name }}</h4> <h4 class="medium ellipsis" :title="current?.name">{{ current?.name || '-' }}</h4>
<el-divider direction="vertical" class="mr-8 ml-8" /> <el-divider direction="vertical" class="mr-8 ml-8" />
<el-icon class="color-input-placeholder"><UserFilled /></el-icon> <el-icon class="color-input-placeholder"><UserFilled /></el-icon>
@ -56,15 +59,16 @@
:disabled="current?.is_auth" :disabled="current?.is_auth"
@click="handleSave" @click="handleSave"
v-if=" v-if="
route.path.includes('share/') ? false route.path.includes('share/')
: hasPermission( ? false
permissionObj[ : hasPermission(
route.path.includes('shared') permissionObj[
? 'SHAREDKNOWLEDGE' route.path.includes('shared')
: (route.meta?.resourceType as string) ? 'SHAREDKNOWLEDGE'
], : (route.meta?.resourceType as string)
'OR', ],
) 'OR',
)
" "
> >
{{ t('common.save') }} {{ t('common.save') }}
@ -88,15 +92,16 @@
<div <div
class="flex align-center" class="flex align-center"
v-if=" v-if="
route.path.includes('share/') ? false route.path.includes('share/')
: hasPermission( ? false
permissionObj[ : hasPermission(
route.path.includes('shared') permissionObj[
? 'SHAREDKNOWLEDGE' route.path.includes('shared')
: (route.meta?.resourceType as string) ? 'SHAREDKNOWLEDGE'
], : (route.meta?.resourceType as string)
'OR', ],
) 'OR',
)
" "
> >
<div class="color-secondary mr-8">{{ $t('views.chatUser.autoAuthorization') }}</div> <div class="color-secondary mr-8">{{ $t('views.chatUser.autoAuthorization') }}</div>
@ -114,10 +119,12 @@
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
@sizeChange="handleSizeChange" @sizeChange="handleSizeChange"
@changePage="getList" @changePage="getList"
:maxTableHeight="350"
> >
<el-table-column <el-table-column
prop="nick_name" prop="nick_name"
:label="$t('views.userManage.userForm.nick_name.label')" :label="$t('views.userManage.userForm.nick_name.label')"
show-overflow-tooltip
/> />
<el-table-column prop="username" :label="$t('views.login.loginForm.username.label')" /> <el-table-column prop="username" :label="$t('views.login.loginForm.username.label')" />
<el-table-column prop="source" :label="$t('views.userManage.source.label')"> <el-table-column prop="source" :label="$t('views.userManage.source.label')">
@ -370,7 +377,7 @@ async function handleSave() {
min-width: var(--setting-left-width); min-width: var(--setting-left-width);
.list-height-left { .list-height-left {
height: calc(100vh - 271px); height: calc(100vh - 251px);
} }
} }

View File

@ -135,7 +135,7 @@
<div <div
v-loading.fullscreen.lock="paginationConfig.current_page === 1 && loading" v-loading.fullscreen.lock="paginationConfig.current_page === 1 && loading"
style="max-height: calc(100vh - 140px)" style="max-height: calc(100vh - 120px)"
> >
<InfiniteScroll <InfiniteScroll
:size="knowledge.knowledgeList.length" :size="knowledge.knowledgeList.length"

View File

@ -6,7 +6,7 @@
<h5 class="ml-4 color-text-primary">{{ t('views.chatUser.title') }}</h5> <h5 class="ml-4 color-text-primary">{{ t('views.chatUser.title') }}</h5>
</el-breadcrumb-item> </el-breadcrumb-item>
</el-breadcrumb> </el-breadcrumb>
<el-card> <el-card style="height: calc(var(--app-main-height) + 10px)">
<div class="flex-between mb-16"> <div class="flex-between mb-16">
<div> <div>
<el-button <el-button
@ -16,16 +16,18 @@
new ComplexPermission( new ComplexPermission(
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE], [RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
[PermissionConst.CHAT_USER_CREATE, PermissionConst.WORKSPACE_CHAT_USER_CREATE], [PermissionConst.CHAT_USER_CREATE, PermissionConst.WORKSPACE_CHAT_USER_CREATE],
[],'OR',)" [],
'OR',
)
"
> >
{{ t('views.userManage.createUser') }} {{ t('views.userManage.createUser') }}
</el-button> </el-button>
<el-button @click="syncUsers" <el-button
v-hasPermission=" @click="syncUsers"
new ComplexPermission( v-hasPermission="
[RoleConst.ADMIN], new ComplexPermission([RoleConst.ADMIN], [PermissionConst.CHAT_USER_SYNC], [], 'OR')
[PermissionConst.CHAT_USER_SYNC], "
[],'OR',)"
> >
{{ $t('views.chatUser.syncUsers') }} {{ $t('views.chatUser.syncUsers') }}
</el-button> </el-button>
@ -34,9 +36,12 @@
@click="setUserGroups" @click="setUserGroups"
v-hasPermission=" v-hasPermission="
new ComplexPermission( new ComplexPermission(
[RoleConst.ADMIN,RoleConst.WORKSPACE_MANAGE], [RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
[PermissionConst.CHAT_USER_GROUP, PermissionConst.WORKSPACE_CHAT_USER_GROUP], [PermissionConst.CHAT_USER_GROUP, PermissionConst.WORKSPACE_CHAT_USER_GROUP],
[],'OR',)" [],
'OR',
)
"
> >
{{ $t('views.chatUser.setUserGroups') }} {{ $t('views.chatUser.setUserGroups') }}
</el-button> </el-button>
@ -47,7 +52,10 @@
new ComplexPermission( new ComplexPermission(
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE], [RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
[PermissionConst.WORKSPACE_CHAT_USER_DELETE, PermissionConst.CHAT_USER_DELETE], [PermissionConst.WORKSPACE_CHAT_USER_DELETE, PermissionConst.CHAT_USER_DELETE],
[],'OR',)" [],
'OR',
)
"
> >
{{ $t('common.delete') }} {{ $t('common.delete') }}
</el-button> </el-button>
@ -59,8 +67,8 @@
style="width: 120px" style="width: 120px"
@change="search_type_change" @change="search_type_change"
> >
<el-option :label="$t('views.login.loginForm.username.label')" value="username"/> <el-option :label="$t('views.login.loginForm.username.label')" value="username" />
<el-option :label="$t('views.userManage.userForm.nick_name.label')" value="nick_name"/> <el-option :label="$t('views.userManage.userForm.nick_name.label')" value="nick_name" />
</el-select> </el-select>
<el-input <el-input
v-if="search_type === 'username'" v-if="search_type === 'username'"
@ -87,18 +95,20 @@
v-loading="loading" v-loading="loading"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
@sort-change="handleSortChange" @sort-change="handleSortChange"
:maxTableHeight="270"
> >
<el-table-column type="selection" width="55"/> <el-table-column type="selection" width="55" />
<el-table-column <el-table-column
prop="nick_name" prop="nick_name"
:label="$t('views.userManage.userForm.nick_name.label')" :label="$t('views.userManage.userForm.nick_name.label')"
show-overflow-tooltip
/> />
<el-table-column prop="username" :label="$t('common.username')"/> <el-table-column prop="username" :label="$t('common.username')" show-overflow-tooltip />
<el-table-column prop="is_active" :label="$t('common.status.label')" width="100"> <el-table-column prop="is_active" :label="$t('common.status.label')" width="100">
<template #default="{ row }"> <template #default="{ row }">
<div v-if="row.is_active" class="flex align-center"> <div v-if="row.is_active" class="flex align-center">
<el-icon class="color-success mr-8" style="font-size: 16px"> <el-icon class="color-success mr-8" style="font-size: 16px">
<SuccessFilled/> <SuccessFilled />
</el-icon> </el-icon>
<span class="color-secondary"> <span class="color-secondary">
{{ $t('common.status.enabled') }} {{ $t('common.status.enabled') }}
@ -134,10 +144,10 @@
<el-table-column <el-table-column
prop="user_group_names" prop="user_group_names"
:label="$t('views.chatUser.group.title')" :label="$t('views.chatUser.group.title')"
min-width="110" min-width="120"
> >
<template #default="{ row }"> <template #default="{ row }">
<TagGroup :tags="row.user_group_names"/> <TagGroup :tags="row.user_group_names" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="source" :label="$t('views.userManage.source.label')"> <el-table-column prop="source" :label="$t('views.userManage.source.label')">
@ -171,26 +181,40 @@
size="small" size="small"
v-model="row.is_active" v-model="row.is_active"
:before-change="() => changeState(row)" :before-change="() => changeState(row)"
v-if="hasPermission(new ComplexPermission( v-if="
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE], hasPermission(
[PermissionConst.CHAT_USER_EDIT, PermissionConst.WORKSPACE_CHAT_USER_EDIT], new ComplexPermission(
[],'OR'),'OR')" [RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
[PermissionConst.CHAT_USER_EDIT, PermissionConst.WORKSPACE_CHAT_USER_EDIT],
[],
'OR',
),
'OR',
)
"
/> />
</span> </span>
<el-divider direction="vertical"/> <el-divider direction="vertical" />
<span class="mr-8"> <span class="mr-8">
<el-button <el-button
type="primary" type="primary"
text text
@click.stop="editUser(row)" @click.stop="editUser(row)"
:title="$t('common.edit')" :title="$t('common.edit')"
v-if="hasPermission(new ComplexPermission( v-if="
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE], hasPermission(
[PermissionConst.CHAT_USER_EDIT, PermissionConst.WORKSPACE_CHAT_USER_EDIT], new ComplexPermission(
[],'OR'),'OR')" [RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
[PermissionConst.CHAT_USER_EDIT, PermissionConst.WORKSPACE_CHAT_USER_EDIT],
[],
'OR',
),
'OR',
)
"
> >
<el-icon> <el-icon>
<EditPen/> <EditPen />
</el-icon> </el-icon>
</el-button> </el-button>
</span> </span>
@ -201,13 +225,20 @@
text text
@click.stop="editPwdUser(row)" @click.stop="editPwdUser(row)"
:title="$t('views.userManage.setting.updatePwd')" :title="$t('views.userManage.setting.updatePwd')"
v-if="hasPermission(new ComplexPermission( v-if="
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE], hasPermission(
[PermissionConst.CHAT_USER_EDIT, PermissionConst.WORKSPACE_CHAT_USER_EDIT], new ComplexPermission(
[],'OR'),'OR')" [RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
[PermissionConst.CHAT_USER_EDIT, PermissionConst.WORKSPACE_CHAT_USER_EDIT],
[],
'OR',
),
'OR',
)
"
> >
<el-icon> <el-icon>
<Lock/> <Lock />
</el-icon> </el-icon>
</el-button> </el-button>
</span> </span>
@ -218,13 +249,23 @@
text text
@click.stop="deleteUserManage(row)" @click.stop="deleteUserManage(row)"
:title="$t('common.delete')" :title="$t('common.delete')"
v-if="hasPermission(new ComplexPermission( v-if="
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE], hasPermission(
[PermissionConst.CHAT_USER_DELETE, PermissionConst.WORKSPACE_CHAT_USER_DELETE], new ComplexPermission(
[],'OR'),'OR')" [RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
[
PermissionConst.CHAT_USER_DELETE,
PermissionConst.WORKSPACE_CHAT_USER_DELETE,
],
[],
'OR',
),
'OR',
)
"
> >
<el-icon> <el-icon>
<Delete/> <Delete />
</el-icon> </el-icon>
</el-button> </el-button>
</span> </span>
@ -240,34 +281,34 @@
ref="UserDrawerRef" ref="UserDrawerRef"
@refresh="refresh" @refresh="refresh"
/> />
<UserPwdDialog ref="UserPwdDialogRef" @refresh="refresh"/> <UserPwdDialog ref="UserPwdDialogRef" @refresh="refresh" />
<SetUserGroupsDialog <SetUserGroupsDialog
:optionLoading="optionLoading" :optionLoading="optionLoading"
:chatGroupList="chatGroupList" :chatGroupList="chatGroupList"
ref="setUserGroupsRef" ref="setUserGroupsRef"
@refresh="refresh" @refresh="refresh"
/> />
<SyncUsersDialog ref="syncUsersDialogRef" @refresh="refresh"/> <SyncUsersDialog ref="syncUsersDialogRef" @refresh="refresh" />
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import {onMounted, ref, reactive} from 'vue' import { onMounted, ref, reactive } from 'vue'
import UserDrawer from './component/UserDrawer.vue' import UserDrawer from './component/UserDrawer.vue'
import UserPwdDialog from './component/UserPwdDialog.vue' import UserPwdDialog from './component/UserPwdDialog.vue'
import SetUserGroupsDialog from './component/SetUserGroupsDialog.vue' import SetUserGroupsDialog from './component/SetUserGroupsDialog.vue'
import SyncUsersDialog from './component/SyncUsersDialog.vue' import SyncUsersDialog from './component/SyncUsersDialog.vue'
import userManageApi from '@/api/system/chat-user' import userManageApi from '@/api/system/chat-user'
import {datetimeFormat} from '@/utils/time' import { datetimeFormat } from '@/utils/time'
import {MsgSuccess, MsgConfirm} from '@/utils/message' import { MsgSuccess, MsgConfirm } from '@/utils/message'
import {t} from '@/locales' import { t } from '@/locales'
import type {ChatUserItem} from '@/api/type/systemChatUser' import type { ChatUserItem } from '@/api/type/systemChatUser'
import SystemGroupApi from '@/api/system/user-group' import SystemGroupApi from '@/api/system/user-group'
import type {ListItem} from '@/api/type/common' import type { ListItem } from '@/api/type/common'
import {PermissionConst, RoleConst} from '@/utils/permission/data' import { PermissionConst, RoleConst } from '@/utils/permission/data'
import {ComplexPermission} from '@/utils/permission/type' import { ComplexPermission } from '@/utils/permission/type'
import {hasPermission} from '@/utils/permission' import { hasPermission } from '@/utils/permission'
import {loadPermissionApi} from "@/utils/dynamics-api/permission-api.ts"; import { loadPermissionApi } from '@/utils/dynamics-api/permission-api.ts'
const search_type = ref('username') const search_type = ref('username')
const search_form = ref<{ const search_form = ref<{
@ -278,7 +319,7 @@ const search_form = ref<{
nick_name: '', nick_name: '',
}) })
const search_type_change = () => { const search_type_change = () => {
search_form.value = {username: '', nick_name: ''} search_form.value = { username: '', nick_name: '' }
} }
const loading = ref(false) const loading = ref(false)
@ -300,17 +341,20 @@ const userTableData = ref<ChatUserItem[]>([])
function getList() { function getList() {
const params: any = {} const params: any = {}
if (search_form.value[search_type.value as keyof typeof search_form.value]) { if (search_form.value[search_type.value as keyof typeof search_form.value]) {
params[search_type.value] = search_form.value[search_type.value as keyof typeof search_form.value] params[search_type.value] =
search_form.value[search_type.value as keyof typeof search_form.value]
} }
return loadPermissionApi('chatUser').getUserManage(paginationConfig, params, loading).then((res: any) => { return loadPermissionApi('chatUser')
userTableData.value = res.data.records .getUserManage(paginationConfig, params, loading)
paginationConfig.total = res.data.total .then((res: any) => {
}) userTableData.value = res.data.records
paginationConfig.total = res.data.total
})
} }
const orderBy = ref<string>('') const orderBy = ref<string>('')
function handleSortChange({prop, order}: { prop: string; order: string }) { function handleSortChange({ prop, order }: { prop: string; order: string }) {
orderBy.value = order === 'ascending' ? prop : `-${prop}` orderBy.value = order === 'ascending' ? prop : `-${prop}`
getList() getList()
} }
@ -358,13 +402,14 @@ function deleteUserManage(row: ChatUserItem) {
}) })
.then(() => { .then(() => {
loading.value = true loading.value = true
loadPermissionApi('chatUser').delUserManage(row.id, loading).then(() => { loadPermissionApi('chatUser')
MsgSuccess(t('common.deleteSuccess')) .delUserManage(row.id, loading)
getList() .then(() => {
}) MsgSuccess(t('common.deleteSuccess'))
}) getList()
.catch(() => { })
}) })
.catch(() => {})
} }
const UserPwdDialogRef = ref() const UserPwdDialogRef = ref()
@ -395,7 +440,7 @@ async function getChatGroupList() {
} }
function handleBatchDelete() { function handleBatchDelete() {
MsgConfirm(t('views.chatUser.batchDeleteUser', {count: multipleSelection.value.length}), '', { MsgConfirm(t('views.chatUser.batchDeleteUser', { count: multipleSelection.value.length }), '', {
confirmButtonText: t('common.confirm'), confirmButtonText: t('common.confirm'),
confirmButtonClass: 'danger', confirmButtonClass: 'danger',
}) })
@ -410,8 +455,7 @@ function handleBatchDelete() {
await getList() await getList()
}) })
}) })
.catch(() => { .catch(() => {})
})
} }
const setUserGroupsRef = ref<InstanceType<typeof SetUserGroupsDialog>>() const setUserGroupsRef = ref<InstanceType<typeof SetUserGroupsDialog>>()

View File

@ -61,7 +61,7 @@
> >
<template #default="{ row }"> <template #default="{ row }">
<div class="flex-between"> <div class="flex-between">
<span class="ellipsis">{{ row.name }}</span> <span class="ellipsis" :title="row.name">{{ row.name }}</span>
<div @click.stop v-show="mouseId === row.id"> <div @click.stop v-show="mouseId === row.id">
<el-dropdown :teleported="false" trigger="click"> <el-dropdown :teleported="false" trigger="click">
<el-button text> <el-button text>
@ -135,7 +135,7 @@
<!-- 右边 --> <!-- 右边 -->
<div class="user-right" v-loading="rightLoading"> <div class="user-right" v-loading="rightLoading">
<div class="flex align-center"> <div class="flex align-center">
<h4 class="medium">{{ current?.name }}</h4> <h4 class="medium ellipsis" :title="current?.name">{{ current?.name }}</h4>
<el-divider direction="vertical" class="mr-8 ml-8" /> <el-divider direction="vertical" class="mr-8 ml-8" />
<AppIcon <AppIcon
iconName="app-workspace" iconName="app-workspace"
@ -217,11 +217,13 @@
@sizeChange="handleSizeChange" @sizeChange="handleSizeChange"
@changePage="getList" @changePage="getList"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
:maxTableHeight="330"
> >
<el-table-column type="selection" width="55" /> <el-table-column type="selection" width="55" />
<el-table-column <el-table-column
prop="nick_name" prop="nick_name"
:label="$t('views.userManage.userForm.nick_name.label')" :label="$t('views.userManage.userForm.nick_name.label')"
show-overflow-tooltip
/> />
<el-table-column prop="username" :label="$t('views.login.loginForm.username.label')" /> <el-table-column prop="username" :label="$t('views.login.loginForm.username.label')" />
<el-table-column prop="source" :label="$t('views.userManage.source.label')"> <el-table-column prop="source" :label="$t('views.userManage.source.label')">
@ -466,7 +468,7 @@ function mouseenter(row: any) {
min-width: var(--setting-left-width); min-width: var(--setting-left-width);
.list-height-left { .list-height-left {
height: calc(100vh - 271px); height: calc(100vh - 231px);
} }
} }

View File

@ -6,7 +6,7 @@
<h5 class="ml-4 color-text-primary">{{ t('views.application.title') }}</h5> <h5 class="ml-4 color-text-primary">{{ t('views.application.title') }}</h5>
</el-breadcrumb-item> </el-breadcrumb-item>
</el-breadcrumb> </el-breadcrumb>
<el-card class="mt-16"> <el-card class="mt-16" style="height: calc(var(--app-main-height) + 20px)">
<div class="flex-between mb-16"> <div class="flex-between mb-16">
<div class="complex-search"> <div class="complex-search">
<el-select <el-select
@ -45,9 +45,10 @@
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
@sizeChange="getList" @sizeChange="getList"
@changePage="getList" @changePage="getList"
:maxTableHeight="260"
> >
<!-- <el-table-column type="selection" width="55" /> --> <!-- <el-table-column type="selection" width="55" /> -->
<el-table-column width="220" :label="$t('common.name')"> <el-table-column width="220" :label="$t('common.name')" show-overflow-tooltip>
<template #default="scope"> <template #default="scope">
<div class="table-name flex align-center"> <div class="table-name flex align-center">
<el-icon size="24" class="mr-8"> <el-icon size="24" class="mr-8">
@ -207,11 +208,7 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column prop="nick_name" :label="$t('common.creator')" show-overflow-tooltip />
prop="nick_name"
:label="$t('common.creator')"
show-overflow-tooltip
/>
<el-table-column :label="$t('views.application.publishTime')" width="180"> <el-table-column :label="$t('views.application.publishTime')" width="180">
<template #default="{ row }"> <template #default="{ row }">
{{ datetimeFormat(row.update_time) }} {{ datetimeFormat(row.update_time) }}

View File

@ -6,7 +6,7 @@
<h5 class="ml-4 color-text-primary">{{ t('views.knowledge.title') }}</h5> <h5 class="ml-4 color-text-primary">{{ t('views.knowledge.title') }}</h5>
</el-breadcrumb-item> </el-breadcrumb-item>
</el-breadcrumb> </el-breadcrumb>
<el-card class="mt-16"> <el-card class="mt-16" style="height: calc(var(--app-main-height) + 20px)">
<div class="flex-between mb-16"> <div class="flex-between mb-16">
<div class="complex-search"> <div class="complex-search">
<el-select <el-select
@ -45,9 +45,10 @@
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
@sizeChange="getList" @sizeChange="getList"
@changePage="getList" @changePage="getList"
:maxTableHeight="260"
> >
<!-- <el-table-column type="selection" width="55" /> --> <!-- <el-table-column type="selection" width="55" /> -->
<el-table-column width="220" :label="$t('common.name')"> <el-table-column width="220" :label="$t('common.name')" show-overflow-tooltip>
<template #default="{ row }"> <template #default="{ row }">
<div class="flex align-center"> <div class="flex align-center">
<KnowledgeIcon :type="row.type" /> <KnowledgeIcon :type="row.type" />
@ -149,7 +150,7 @@ import KnowledgeResourceApi from '@/api/system-resource-management/knowledge'
import { t } from '@/locales' import { t } from '@/locales'
import useStore from '@/stores' import useStore from '@/stores'
import { datetimeFormat } from '@/utils/time' import { datetimeFormat } from '@/utils/time'
import {loadPermissionApi} from "@/utils/dynamics-api/permission-api.ts"; import { loadPermissionApi } from '@/utils/dynamics-api/permission-api.ts'
import UserApi from '@/api/user/user' import UserApi from '@/api/user/user'
const { user } = useStore() const { user } = useStore()

View File

@ -6,7 +6,7 @@
<h5 class="ml-4 color-text-primary">{{ t('views.model.title') }}</h5> <h5 class="ml-4 color-text-primary">{{ t('views.model.title') }}</h5>
</el-breadcrumb-item> </el-breadcrumb-item>
</el-breadcrumb> </el-breadcrumb>
<el-card class="mt-16"> <el-card class="mt-16" style="height: calc(var(--app-main-height) + 20px)">
<div class="flex-between mb-16"> <div class="flex-between mb-16">
<div class="complex-search"> <div class="complex-search">
<el-select <el-select
@ -15,9 +15,9 @@
style="width: 120px" style="width: 120px"
@change="search_type_change" @change="search_type_change"
> >
<el-option :label="$t('common.creator')" value="create_user"/> <el-option :label="$t('common.creator')" value="create_user" />
<el-option :label="$t('views.model.modelForm.model_type.label')" value="model_type"/> <el-option :label="$t('views.model.modelForm.model_type.label')" value="model_type" />
<el-option :label="$t('views.model.modelForm.modeName.label')" value="name"/> <el-option :label="$t('views.model.modelForm.modeName.label')" value="name" />
</el-select> </el-select>
<el-input <el-input
v-if="search_type === 'name'" v-if="search_type === 'name'"
@ -35,7 +35,7 @@
clearable clearable
style="width: 220px" style="width: 220px"
> >
<el-option v-for="u in user_options" :key="u.id" :value="u.id" :label="u.nick_name"/> <el-option v-for="u in user_options" :key="u.id" :value="u.id" :label="u.nick_name" />
</el-select> </el-select>
<el-select <el-select
v-else-if="search_type === 'model_type'" v-else-if="search_type === 'model_type'"
@ -45,7 +45,7 @@
style="width: 220px" style="width: 220px"
> >
<template v-for="item in modelTypeList" :key="item.value"> <template v-for="item in modelTypeList" :key="item.value">
<el-option :label="item.text" :value="item.value"/> <el-option :label="item.text" :value="item.value" />
</template> </template>
</el-select> </el-select>
</div> </div>
@ -56,9 +56,10 @@
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
@sizeChange="getList" @sizeChange="getList"
@changePage="getList" @changePage="getList"
:maxTableHeight="260"
> >
<!-- <el-table-column type="selection" width="55" /> --> <!-- <el-table-column type="selection" width="55" /> -->
<el-table-column width="220" :label="$t('common.name')"> <el-table-column width="220" :label="$t('common.name')" show-overflow-tooltip>
<template #default="{ row }"> <template #default="{ row }">
{{ row.name }} {{ row.name }}
</template> </template>
@ -114,7 +115,7 @@
@click="workspaceVisible = !workspaceVisible" @click="workspaceVisible = !workspaceVisible"
> >
<el-icon> <el-icon>
<Filter/> <Filter />
</el-icon> </el-icon>
</el-button> </el-button>
</template> </template>
@ -139,17 +140,17 @@
</div> </div>
<div class="text-right"> <div class="text-right">
<el-button size="small" @click="filterWorkspaceChange('clear')" <el-button size="small" @click="filterWorkspaceChange('clear')"
>{{ $t('common.clear') }} >{{ $t('common.clear') }}
</el-button> </el-button>
<el-button type="primary" @click="filterWorkspaceChange" size="small" <el-button type="primary" @click="filterWorkspaceChange" size="small"
>{{ $t('common.confirm') }} >{{ $t('common.confirm') }}
</el-button> </el-button>
</div> </div>
</el-popover> </el-popover>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="nick_name" :label="$t('common.creator')" show-overflow-tooltip/> <el-table-column prop="nick_name" :label="$t('common.creator')" show-overflow-tooltip />
<el-table-column :label="$t('views.document.table.updateTime')" width="180"> <el-table-column :label="$t('views.document.table.updateTime')" width="180">
<template #default="{ row }"> <template #default="{ row }">
{{ datetimeFormat(row.update_time) }} {{ datetimeFormat(row.update_time) }}
@ -166,18 +167,18 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import {onBeforeMount, onMounted, ref, reactive, nextTick, computed} from 'vue' import { onBeforeMount, onMounted, ref, reactive, nextTick, computed } from 'vue'
import type {Provider, Model} from '@/api/type/model' import type { Provider, Model } from '@/api/type/model'
import ModelResourceApi from '@/api/system-resource-management/model' import ModelResourceApi from '@/api/system-resource-management/model'
import {modelTypeList} from '@/views/model/component/data' import { modelTypeList } from '@/views/model/component/data'
import {modelType} from '@/enums/model' import { modelType } from '@/enums/model'
import {t} from '@/locales' import { t } from '@/locales'
import useStore from '@/stores' import useStore from '@/stores'
import {datetimeFormat} from '@/utils/time' import { datetimeFormat } from '@/utils/time'
import {loadPermissionApi} from "@/utils/dynamics-api/permission-api.ts"; import { loadPermissionApi } from '@/utils/dynamics-api/permission-api.ts'
import UserApi from '@/api/user/user.ts' import UserApi from '@/api/user/user.ts'
const {user, model} = useStore() const { user, model } = useStore()
const search_type = ref('name') const search_type = ref('name')
const model_search_form = ref<{ const model_search_form = ref<{
@ -231,7 +232,7 @@ async function getWorkspaceList() {
} }
const search_type_change = () => { const search_type_change = () => {
model_search_form.value = {name: '', create_user: '', model_type: ''} model_search_form.value = { name: '', create_user: '', model_type: '' }
} }
function getRequestParams() { function getRequestParams() {

View File

@ -6,7 +6,7 @@
<h5 class="ml-4 color-text-primary">{{ t('views.tool.title') }}</h5> <h5 class="ml-4 color-text-primary">{{ t('views.tool.title') }}</h5>
</el-breadcrumb-item> </el-breadcrumb-item>
</el-breadcrumb> </el-breadcrumb>
<el-card class="mt-16"> <el-card class="mt-16" style="height: calc(var(--app-main-height) + 20px)">
<div class="flex-between mb-16"> <div class="flex-between mb-16">
<div class="complex-search"> <div class="complex-search">
<el-select <el-select
@ -45,9 +45,10 @@
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
@sizeChange="getList" @sizeChange="getList"
@changePage="getList" @changePage="getList"
:maxTableHeight="260"
> >
<!-- <el-table-column type="selection" width="55" /> --> <!-- <el-table-column type="selection" width="55" /> -->
<el-table-column width="220" :label="$t('common.name')"> <el-table-column width="220" :label="$t('common.name')" show-overflow-tooltip>
<template #default="scope"> <template #default="scope">
<div class="table-name flex align-center"> <div class="table-name flex align-center">
<el-icon size="24" class="mr-8"> <el-icon size="24" class="mr-8">
@ -166,12 +167,12 @@
import { onMounted, ref, reactive, computed } from 'vue' import { onMounted, ref, reactive, computed } from 'vue'
import ToolResourceApi from '@/api/system-resource-management/tool' import ToolResourceApi from '@/api/system-resource-management/tool'
import { t } from '@/locales' import { t } from '@/locales'
import {isAppIcon, resetUrl} from '@/utils/common' import { isAppIcon, resetUrl } from '@/utils/common'
import { ToolType } from '@/enums/tool' import { ToolType } from '@/enums/tool'
import useStore from '@/stores' import useStore from '@/stores'
import { datetimeFormat } from '@/utils/time' import { datetimeFormat } from '@/utils/time'
import {loadPermissionApi} from "@/utils/dynamics-api/permission-api.ts"; import { loadPermissionApi } from '@/utils/dynamics-api/permission-api.ts'
import UserApi from "@/api/user/user.ts"; import UserApi from '@/api/user/user.ts'
const { user } = useStore() const { user } = useStore()

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="email-setting p-16-24"> <div class="email-setting p-16-24">
<h4 class="mb-16">{{ $t('views.system.email.title') }}</h4> <h4 class="mb-16">{{ $t('views.system.email.title') }}</h4>
<el-card style="--el-card-padding: 16px" v-loading="loading"> <el-card style="--el-card-padding: 16px" v-loading="loading" class="main-calc-height">
<el-scrollbar> <el-scrollbar>
<div class="email-setting__main p-16"> <div class="email-setting__main p-16">
<el-form <el-form
@ -52,12 +52,18 @@
>{{ $t('views.system.email.enableTLS') }} >{{ $t('views.system.email.enableTLS') }}
</el-checkbox> </el-checkbox>
</el-form-item> </el-form-item>
<el-button @click="submit(emailFormRef)" type="primary" :disabled="loading" <el-button
@click="submit(emailFormRef)"
type="primary"
:disabled="loading"
v-hasPermission=" v-hasPermission="
new ComplexPermission( new ComplexPermission(
[RoleConst.ADMIN], [RoleConst.ADMIN],
[PermissionConst.EMAIL_SETTING_EDIT], [PermissionConst.EMAIL_SETTING_EDIT],
[],'OR',)" [],
'OR',
)
"
> >
{{ $t('common.save') }} {{ $t('common.save') }}
</el-button> </el-button>

View File

@ -2,15 +2,15 @@
<el-dialog modal-class="authorized-workspace" v-model="centerDialogVisible" width="840"> <el-dialog modal-class="authorized-workspace" v-model="centerDialogVisible" width="840">
<template #header="{ titleId, titleClass }"> <template #header="{ titleId, titleClass }">
<h4 class="mb-8">{{ $t('views.shared.authorized_workspace') }}</h4> <h4 class="mb-8">{{ $t('views.shared.authorized_workspace') }}</h4>
<el-text class="color-secondary lighter">被授权的工作空间可使用当前资源</el-text> <el-text class="color-secondary lighter">{{ $t('views.shared.authorized_tip') }}</el-text>
</template> </template>
<p class="mb-8 lighter">类型</p> <p class="mb-8 lighter">{{ $t('views.shared.type') }}</p>
<el-radio-group v-model="listType"> <el-radio-group v-model="listType">
<el-radio value="WHITE_LIST">白名单</el-radio> <el-radio value="WHITE_LIST">{{ $t('views.shared.WHITE_LIST') }}</el-radio>
<el-radio value="BLACK_LIST">黑名单</el-radio> <el-radio value="BLACK_LIST">{{ $t('views.shared.BLACK_LIST') }}</el-radio>
</el-radio-group> </el-radio-group>
<p class="mb-8 lighter mt-16">选择工作空间</p> <p class="mb-8 lighter mt-16">{{ $t('views.shared.select_workspace') }}</p>
<div class="flex border" v-loading="loading"> <div class="flex border" v-loading="loading">
<div class="p-16 border-r"> <div class="p-16 border-r">
<el-input <el-input
@ -34,7 +34,7 @@
@change="handleCheckAllChange" @change="handleCheckAllChange"
v-if="!search" v-if="!search"
> >
全选 {{ $t('views.shared.allCheck') }}<
</el-checkbox> </el-checkbox>
<el-checkbox-group <el-checkbox-group
class="checkbox-group-block" class="checkbox-group-block"

View File

@ -1,261 +1,260 @@
<template> <template>
<div class="operate-log p-16-24"> <div class="operate-log p-16-24">
<h2 class="mb-16">{{ $t('views.operateLog.title') }}</h2> <h2 class="mb-16">{{ $t('views.operateLog.title') }}</h2>
<el-card style="--el-card-padding: 0"> <el-card style="--el-card-padding: 0" class="main-calc-height">
<div class="p-24">
<div class="p-24"> <div class="flex-between">
<div class="flex-between">
<div>
<el-select
v-model="history_day"
class="mr-12"
@change="changeDayHandle"
style="width: 180px"
>
<el-option
v-for="item in dayOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-date-picker
v-if="history_day === 'other'"
v-model="daterangeValue"
type="daterange"
:start-placeholder="$t('views.applicationOverview.monitor.startDatePlaceholder')"
:end-placeholder="$t('views.applicationOverview.monitor.endDatePlaceholder')"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
@change="changeDayRangeHandle"
/>
</div>
<div style="display: flex">
<div class="flex-between complex-search">
<el-select
v-model="filter_type"
class="complex-search__left"
@change="changeFilterHandle"
style="width: 120px"
>
<el-option
v-for="item in filterOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-select
v-if="filter_type === 'status'"
v-model="filter_status"
@change="changeStatusHandle"
style="width: 220px"
clearable
>
<el-option
v-for="item in statusOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-input
v-else
v-model="searchValue"
@change="getList"
:placeholder="$t('common.search')"
prefix-icon="Search"
style="width: 220px"
clearable
/>
</div>
<el-button @click="exportLog" style="margin-left: 10px">{{
$t('common.export')
}}
</el-button>
</div>
</div>
<app-table
class="mt-16"
:data="tableData"
:pagination-config="paginationConfig"
@sizeChange="handleSizeChange"
@changePage="getList"
v-loading="loading"
>
<el-table-column prop="menu" :label="$t('views.operateLog.table.menu.label')" width="160">
<template #header>
<div> <div>
<span>{{ $t('views.operateLog.table.menu.label') }}</span> <el-select
<el-popover :width="200" trigger="click" :visible="popoverVisible"> v-model="history_day"
<template #reference> class="mr-12"
<el-button @change="changeDayHandle"
style="margin-top: -2px" style="width: 180px"
:type="operateTypeArr && operateTypeArr.length > 0 ? 'primary' : ''" >
link <el-option
@click="popoverVisible = !popoverVisible" v-for="item in dayOptions"
> :key="item.value"
<el-icon> :label="item.label"
<Filter/> :value="item.value"
</el-icon> />
</el-button> </el-select>
</template> <el-date-picker
<div class="filter"> v-if="history_day === 'other'"
<div class="form-item mb-16"> v-model="daterangeValue"
<div @click.stop> type="daterange"
<el-scrollbar height="300" style="margin: 0 0 0 10px"> :start-placeholder="$t('views.applicationOverview.monitor.startDatePlaceholder')"
<el-checkbox-group :end-placeholder="$t('views.applicationOverview.monitor.endDatePlaceholder')"
v-model="operateTypeArr" format="YYYY-MM-DD"
style="display: flex; flex-direction: column" value-format="YYYY-MM-DD"
> @change="changeDayRangeHandle"
<el-checkbox />
v-for="item in operateOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-checkbox-group>
</el-scrollbar>
</div>
</div>
</div>
<div class="text-right">
<el-button size="small" @click="filterChange('clear')">{{
$t('common.clear')
}}
</el-button>
<el-button type="primary" @click="filterChange" size="small">{{
$t('common.confirm')
}}
</el-button>
</div>
</el-popover>
</div> </div>
</template>
</el-table-column> <div style="display: flex">
<el-table-column prop="operate" :label="$t('views.operateLog.table.operate.detail')"> <div class="flex-between complex-search">
<template #default="{ row }"> <el-select
<el-tooltip v-model="filter_type"
:content=" class="complex-search__left"
row.operate + (row.operation_object?.name ? `${row.operation_object.name}` : '') @change="changeFilterHandle"
" style="width: 120px"
effect="dark" >
placement="top" <el-option
> v-for="item in filterOptions"
<span class="text-ellipsis"> :key="item.value"
{{ :label="item.label"
:value="item.value"
/>
</el-select>
<el-select
v-if="filter_type === 'status'"
v-model="filter_status"
@change="changeStatusHandle"
style="width: 220px"
clearable
>
<el-option
v-for="item in statusOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-input
v-else
v-model="searchValue"
@change="getList"
:placeholder="$t('common.search')"
prefix-icon="Search"
style="width: 220px"
clearable
/>
</div>
<el-button @click="exportLog" style="margin-left: 10px"
>{{ $t('common.export') }}
</el-button>
</div>
</div>
<app-table
class="mt-16"
:data="tableData"
:pagination-config="paginationConfig"
@sizeChange="handleSizeChange"
@changePage="getList"
v-loading="loading"
>
<el-table-column prop="menu" :label="$t('views.operateLog.table.menu.label')" width="160">
<template #header>
<div>
<span>{{ $t('views.operateLog.table.menu.label') }}</span>
<el-popover :width="200" trigger="click" :visible="popoverVisible">
<template #reference>
<el-button
style="margin-top: -2px"
:type="operateTypeArr && operateTypeArr.length > 0 ? 'primary' : ''"
link
@click="popoverVisible = !popoverVisible"
>
<el-icon>
<Filter />
</el-icon>
</el-button>
</template>
<div class="filter">
<div class="form-item mb-16">
<div @click.stop>
<el-scrollbar height="300" style="margin: 0 0 0 10px">
<el-checkbox-group
v-model="operateTypeArr"
style="display: flex; flex-direction: column"
>
<el-checkbox
v-for="item in operateOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-checkbox-group>
</el-scrollbar>
</div>
</div>
</div>
<div class="text-right">
<el-button size="small" @click="filterChange('clear')"
>{{ $t('common.clear') }}
</el-button>
<el-button type="primary" @click="filterChange" size="small"
>{{ $t('common.confirm') }}
</el-button>
</div>
</el-popover>
</div>
</template>
</el-table-column>
<el-table-column prop="operate" :label="$t('views.operateLog.table.operate.detail')">
<template #default="{ row }">
<el-tooltip
:content="
row.operate + row.operate +
(row.operation_object?.name ? `${row.operation_object.name}` : '') (row.operation_object?.name ? `${row.operation_object.name}` : '')
}} "
</span> effect="dark"
</el-tooltip> placement="top"
</template> >
</el-table-column> <span class="text-ellipsis">
<el-table-column {{
width="120" row.operate +
prop="user.username" (row.operation_object?.name ? `${row.operation_object.name}` : '')
:label="$t('views.operateLog.table.user.label')" }}
/> </span>
<el-table-column v-if="user.isEE()" </el-tooltip>
width="200" </template>
prop="workspace_name" </el-table-column>
:label="$t('views.workspace.title') "> <el-table-column
<template #header> width="120"
<div> prop="user.username"
<span>{{ $t('views.workspace.title') }}</span> :label="$t('views.operateLog.table.user.label')"
<el-popover :width="200" trigger="click" :visible="workspaceVisible"> />
<template #reference> <el-table-column
<el-button v-if="user.isEE()"
style="margin-top: -2px" width="200"
:type="workspaceArr && workspaceArr.length > 0 ? 'primary' : ''" prop="workspace_name"
link :label="$t('views.workspace.title')"
@click="workspaceVisible = !workspaceVisible" >
> <template #header>
<el-icon> <div>
<Filter/> <span>{{ $t('views.workspace.title') }}</span>
</el-icon> <el-popover :width="200" trigger="click" :visible="workspaceVisible">
</el-button> <template #reference>
</template> <el-button
<div class="filter"> style="margin-top: -2px"
<div class="form-item mb-16"> :type="workspaceArr && workspaceArr.length > 0 ? 'primary' : ''"
<div @click.stop> link
<el-scrollbar height="300" style="margin: 0 0 0 10px"> @click="workspaceVisible = !workspaceVisible"
<el-checkbox-group >
v-model="workspaceArr" <el-icon>
style="display: flex; flex-direction: column" <Filter />
> </el-icon>
<el-checkbox </el-button>
v-for="item in workspaceOptions" </template>
:key="item.value" <div class="filter">
:label="item.label" <div class="form-item mb-16">
:value="item.value" <div @click.stop>
/> <el-scrollbar height="300" style="margin: 0 0 0 10px">
</el-checkbox-group> <el-checkbox-group
</el-scrollbar> v-model="workspaceArr"
style="display: flex; flex-direction: column"
>
<el-checkbox
v-for="item in workspaceOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-checkbox-group>
</el-scrollbar>
</div>
</div>
</div> </div>
</div> <div class="text-right">
<el-button size="small" @click="filterWorkspaceChange('clear')"
>{{ $t('common.clear') }}
</el-button>
<el-button type="primary" @click="filterWorkspaceChange" size="small"
>{{ $t('common.confirm') }}
</el-button>
</div>
</el-popover>
</div> </div>
<div class="text-right"> </template>
<el-button size="small" @click="filterWorkspaceChange('clear')">{{ </el-table-column>
$t('common.clear') <el-table-column
}} prop="status"
:label="$t('views.operateLog.table.status.label')"
width="100"
>
<template #default="{ row }">
<span v-if="row.status === 200">{{
$t('views.operateLog.table.status.success')
}}</span>
<span v-else style="color: red">{{ $t('views.operateLog.table.status.fail') }}</span>
</template>
</el-table-column>
<el-table-column
prop="ip_address"
:label="$t('views.operateLog.table.ip_address.label')"
width="160"
></el-table-column>
<el-table-column :label="$t('views.operateLog.table.operateTime.label')" width="180">
<template #default="{ row }">
{{ datetimeFormat(row.create_time) }}
</template>
</el-table-column>
<el-table-column :label="$t('common.operation')" width="110" align="left" fixed="right">
<template #default="{ row }">
<span class="mr-4">
<el-button type="primary" text @click.stop="showDetails(row)" class="text-button">
{{ $t('views.operateLog.table.opt.label') }}
</el-button> </el-button>
<el-button type="primary" @click="filterWorkspaceChange" size="small">{{ </span>
$t('common.confirm') </template>
}} </el-table-column>
</el-button> </app-table>
</div> </div>
</el-popover> <DetailDialog ref="DetailDialogRef" />
</div>
</template>
</el-table-column>
<el-table-column
prop="status"
:label="$t('views.operateLog.table.status.label')"
width="100"
>
<template #default="{ row }">
<span v-if="row.status === 200">{{ $t('views.operateLog.table.status.success') }}</span>
<span v-else style="color: red">{{ $t('views.operateLog.table.status.fail') }}</span>
</template>
</el-table-column>
<el-table-column
prop="ip_address"
:label="$t('views.operateLog.table.ip_address.label')"
width="160"
></el-table-column>
<el-table-column :label="$t('views.operateLog.table.operateTime.label')" width="180">
<template #default="{ row }">
{{ datetimeFormat(row.create_time) }}
</template>
</el-table-column>
<el-table-column :label="$t('common.operation')" width="110" align="left" fixed="right">
<template #default="{ row }">
<span class="mr-4">
<el-button type="primary" text @click.stop="showDetails(row)" class="text-button">
{{ $t('views.operateLog.table.opt.label') }}
</el-button>
</span>
</template>
</el-table-column>
</app-table>
</div>
<DetailDialog ref="DetailDialogRef"/>
</el-card> </el-card>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import {ref, onMounted, reactive} from 'vue' import { ref, onMounted, reactive } from 'vue'
import operateLog from '@/api/system/operate-log' import operateLog from '@/api/system/operate-log'
import DetailDialog from './component/DetailDialog.vue' import DetailDialog from './component/DetailDialog.vue'
import {t} from '@/locales' import { t } from '@/locales'
import {beforeDay, datetimeFormat, nowDate} from '@/utils/time' import { beforeDay, datetimeFormat, nowDate } from '@/utils/time'
import useStore from "@/stores"; import useStore from '@/stores'
import WorkspaceApi from "@/api/system/workspace.ts"; import WorkspaceApi from '@/api/system/workspace.ts'
const {user} = useStore() const { user } = useStore()
const popoverVisible = ref(false) const popoverVisible = ref(false)
const operateTypeArr = ref<any[]>([]) const operateTypeArr = ref<any[]>([])
const workspaceVisible = ref(false) const workspaceVisible = ref(false)
@ -265,7 +264,7 @@ const loading = ref(false)
const paginationConfig = reactive({ const paginationConfig = reactive({
current_page: 1, current_page: 1,
page_size: 20, page_size: 20,
total: 0 total: 0,
}) })
const searchValue = ref('') const searchValue = ref('')
const tableData = ref<any[]>([]) const tableData = ref<any[]>([])
@ -274,55 +273,55 @@ const filter_type = ref<string>('user')
const filter_status = ref<string>('') const filter_status = ref<string>('')
const daterange = ref({ const daterange = ref({
start_time: '', start_time: '',
end_time: '' end_time: '',
}) })
const daterangeValue = ref('') const daterangeValue = ref('')
const dayOptions = [ const dayOptions = [
{ {
value: 7, value: 7,
// @ts-ignore // @ts-ignore
label: t('views.applicationOverview.monitor.pastDayOptions.past7Days') // 使 t label: t('views.applicationOverview.monitor.pastDayOptions.past7Days'), // 使 t
}, },
{ {
value: 30, value: 30,
label: t('views.applicationOverview.monitor.pastDayOptions.past30Days') label: t('views.applicationOverview.monitor.pastDayOptions.past30Days'),
}, },
{ {
value: 90, value: 90,
label: t('views.applicationOverview.monitor.pastDayOptions.past90Days') label: t('views.applicationOverview.monitor.pastDayOptions.past90Days'),
}, },
{ {
value: 183, value: 183,
label: t('views.applicationOverview.monitor.pastDayOptions.past183Days') label: t('views.applicationOverview.monitor.pastDayOptions.past183Days'),
}, },
{ {
value: 'other', value: 'other',
label: t('common.custom') label: t('common.custom'),
} },
] ]
const filterOptions = [ const filterOptions = [
{ {
value: 'user', value: 'user',
label: t('views.operateLog.table.user.label') label: t('views.operateLog.table.user.label'),
}, },
{ {
value: 'status', value: 'status',
label: t('views.operateLog.table.status.label') label: t('views.operateLog.table.status.label'),
}, },
{ {
value: 'ip_address', value: 'ip_address',
label: t('views.operateLog.table.ip_address.label') label: t('views.operateLog.table.ip_address.label'),
} },
] ]
const statusOptions = [ const statusOptions = [
{ {
value: '200', value: '200',
label: t('views.operateLog.table.status.success') label: t('views.operateLog.table.status.success'),
}, },
{ {
value: '500', value: '500',
label: t('views.operateLog.table.status.fail') label: t('views.operateLog.table.status.fail'),
} },
] ]
const operateOptions = ref<any[]>([]) const operateOptions = ref<any[]>([])
@ -381,7 +380,7 @@ function handleSizeChange() {
function getRequestParams() { function getRequestParams() {
let obj: any = { let obj: any = {
start_time: daterange.value.start_time, start_time: daterange.value.start_time,
end_time: daterange.value.end_time end_time: daterange.value.end_time,
} }
if (searchValue.value && filter_type.value !== 'status') { if (searchValue.value && filter_type.value !== 'status') {
obj[filter_type.value] = searchValue.value obj[filter_type.value] = searchValue.value
@ -411,7 +410,7 @@ function getMenuList() {
arr arr
.filter((item, index, self) => index === self.findIndex((i) => i['menu'] === item['menu'])) .filter((item, index, self) => index === self.findIndex((i) => i['menu'] === item['menu']))
.forEach((ele) => { .forEach((ele) => {
operateOptions.value.push({label: ele.menu_label, value: ele.menu}) operateOptions.value.push({ label: ele.menu_label, value: ele.menu })
}) })
}) })
} }
@ -425,7 +424,7 @@ async function getWorkspaceList() {
const res = await WorkspaceApi.getSystemWorkspaceList(loading) const res = await WorkspaceApi.getSystemWorkspaceList(loading)
workspaceOptions.value = res.data.map((item: any) => ({ workspaceOptions.value = res.data.map((item: any) => ({
label: item.name, label: item.name,
value: item.id value: item.id,
})) }))
} }
} }

View File

@ -4,10 +4,10 @@
<div class="flex align-center" <div class="flex align-center"
v-if="hasPermission([EditionConst.IS_EE,EditionConst.IS_PE], 'OR')"> v-if="hasPermission([EditionConst.IS_EE,EditionConst.IS_PE], 'OR')">
<!-- 企业版: 选优先级--> <!-- 企业版: 选优先级-->
<span class="lighter mr-16">{{ $t('views.resourceAuthorization.priority.label') }}</span> <span class="lighter mr-16">{{ $t('views.system.resourceAuthorization.priority.label') }}</span>
<el-radio-group v-model="radioRole"> <el-radio-group v-model="radioRole">
<el-radio :value="true" size="large">{{ <el-radio :value="true" size="large">{{
$t('views.resourceAuthorization.priority.role') $t('views.system.resourceAuthorization.priority.role')
}} }}
</el-radio> </el-radio>
<el-radio :value="false" size="large">{{ $t('common.custom') }}</el-radio> <el-radio :value="false" size="large">{{ $t('common.custom') }}</el-radio>
@ -80,7 +80,7 @@
</el-table-column> </el-table-column>
<el-table-column <el-table-column
v-if="isRole" v-if="isRole"
:label="$t('views.resourceAuthorization.setting.authorization')" :label="$t('views.system.resourceAuthorization.setting.authorization')"
align="center" align="center"
width="100" width="100"
> >
@ -89,7 +89,7 @@
:disabled="props.manage" :disabled="props.manage"
v-model="allChecked[AuthorizationEnum.MANAGE]" v-model="allChecked[AuthorizationEnum.MANAGE]"
:indeterminate="allIndeterminate[AuthorizationEnum.MANAGE]" :indeterminate="allIndeterminate[AuthorizationEnum.MANAGE]"
:label="$t('views.resourceAuthorization.setting.management')" :label="$t('views.system.resourceAuthorization.setting.management')"
/> />
</template> --> </template> -->
<template #default="{ row }"> <template #default="{ row }">
@ -110,7 +110,7 @@
</el-table-column> </el-table-column>
<el-table-column <el-table-column
v-if="!isRole" v-if="!isRole"
:label="$t('views.resourceAuthorization.setting.management')" :label="$t('views.system.resourceAuthorization.setting.management')"
align="center" align="center"
width="100" width="100"
> >
@ -119,7 +119,7 @@
:disabled="props.manage" :disabled="props.manage"
v-model="allChecked[AuthorizationEnum.MANAGE]" v-model="allChecked[AuthorizationEnum.MANAGE]"
:indeterminate="allIndeterminate[AuthorizationEnum.MANAGE]" :indeterminate="allIndeterminate[AuthorizationEnum.MANAGE]"
:label="$t('views.resourceAuthorization.setting.management')" :label="$t('views.system.resourceAuthorization.setting.management')"
/> />
</template> --> </template> -->
<template #default="{ row }"> <template #default="{ row }">
@ -140,7 +140,7 @@
</el-table-column> </el-table-column>
<el-table-column <el-table-column
v-if="!isRole" v-if="!isRole"
:label="$t('views.resourceAuthorization.setting.check')" :label="$t('views.system.resourceAuthorization.setting.check')"
align="center" align="center"
width="100" width="100"
> >
@ -149,7 +149,7 @@
:disabled="props.manage" :disabled="props.manage"
v-model="allChecked[AuthorizationEnum.VIEW]" v-model="allChecked[AuthorizationEnum.VIEW]"
:indeterminate="allIndeterminate[AuthorizationEnum.VIEW]" :indeterminate="allIndeterminate[AuthorizationEnum.VIEW]"
:label="$t('views.resourceAuthorization.setting.check')" :label="$t('views.system.resourceAuthorization.setting.check')"
/> />
</template> --> </template> -->
<template #default="{ row }"> <template #default="{ row }">

View File

@ -2,7 +2,7 @@
<div class="resource-authorization p-16-24"> <div class="resource-authorization p-16-24">
<div class="flex align-center mb-16"> <div class="flex align-center mb-16">
<el-breadcrumb separator-icon="ArrowRight"> <el-breadcrumb separator-icon="ArrowRight">
<el-breadcrumb-item>{{ t('views.resourceAuthorization.title') }}</el-breadcrumb-item> <el-breadcrumb-item>{{ t('views.system.resourceAuthorization.title') }}</el-breadcrumb-item>
<el-breadcrumb-item> <el-breadcrumb-item>
<h5 class="ml-4 color-text-primary">{{ activeData.label }}</h5> <h5 class="ml-4 color-text-primary">{{ activeData.label }}</h5>
</el-breadcrumb-item> </el-breadcrumb-item>
@ -25,7 +25,7 @@
<div class="flex main-calc-height"> <div class="flex main-calc-height">
<div class="resource-authorization__left border-r"> <div class="resource-authorization__left border-r">
<div class="p-24 pb-0"> <div class="p-24 pb-0">
<h4 class="mb-12">{{ $t('views.resourceAuthorization.member') }}</h4> <h4 class="mb-12">{{ $t('views.system.resourceAuthorization.member') }}</h4>
<el-input <el-input
v-model="filterText" v-model="filterText"
:placeholder="$t('common.search')" :placeholder="$t('common.search')"
@ -57,7 +57,7 @@
</div> </div>
<div class="permission-setting p-24 flex" v-loading="rLoading"> <div class="permission-setting p-24 flex" v-loading="rLoading">
<div class="resource-authorization__table"> <div class="resource-authorization__table">
<h4 class="mb-16">{{ $t('views.resourceAuthorization.permissionSetting') }}</h4> <h4 class="mb-16">{{ $t('views.system.resourceAuthorization.permissionSetting') }}</h4>
<!-- <el-tabs <!-- <el-tabs
v-model="activeName" v-model="activeName"
@tab-change="handleTabChange" @tab-change="handleTabChange"
@ -447,10 +447,10 @@ function changeWorkspace(item: WorkspaceItem) {
} }
onMounted(() => { onMounted(() => {
tableHeight.value = window.innerHeight - 330 tableHeight.value = window.innerHeight - 300
window.onresize = () => { window.onresize = () => {
return (() => { return (() => {
tableHeight.value = window.innerHeight - 330 tableHeight.value = window.innerHeight - 300
})() })()
} }
if (user.isEE()) { if (user.isEE()) {

View File

@ -6,11 +6,12 @@
@click="handleAdd" @click="handleAdd"
v-hasPermission=" v-hasPermission="
new ComplexPermission( new ComplexPermission(
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE], [RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
[PermissionConst.WORKSPACE_ROLE_ADD_MEMBER, PermissionConst.ROLE_ADD_MEMBER], [PermissionConst.WORKSPACE_ROLE_ADD_MEMBER, PermissionConst.ROLE_ADD_MEMBER],
[], [],
'OR', 'OR',
)" )
"
> >
{{ $t('views.role.member.add') }} {{ $t('views.role.member.add') }}
</el-button> </el-button>
@ -36,6 +37,7 @@
@changePage="getList" @changePage="getList"
v-loading="loading" v-loading="loading"
:span-method="objectSpanMethod" :span-method="objectSpanMethod"
:maxTableHeight="330"
> >
<el-table-column prop="nick_name" :label="$t('views.userManage.userForm.nick_name.label')" /> <el-table-column prop="nick_name" :label="$t('views.userManage.userForm.nick_name.label')" />
<el-table-column prop="username" :label="$t('views.login.loginForm.username.label')" /> <el-table-column prop="username" :label="$t('views.login.loginForm.username.label')" />
@ -57,11 +59,14 @@
@click.stop="handleDelete(row)" @click.stop="handleDelete(row)"
v-hasPermission=" v-hasPermission="
new ComplexPermission( new ComplexPermission(
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE], [RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
[PermissionConst.ROLE_REMOVE_MEMBER, PermissionConst.WORKSPACE_ROLE_REMOVE_MEMBER], [
[], PermissionConst.ROLE_REMOVE_MEMBER,
'OR', PermissionConst.WORKSPACE_ROLE_REMOVE_MEMBER,
) ],
[],
'OR',
)
" "
> >
<AppIcon iconName="app-delete-users"></AppIcon> <AppIcon iconName="app-delete-users"></AppIcon>
@ -138,20 +143,20 @@ watch(
const objectSpanMethod = ({ row, column, rowIndex, columnIndex }: any) => { const objectSpanMethod = ({ row, column, rowIndex, columnIndex }: any) => {
if (column.property === 'nick_name' || column.property === 'username') { if (column.property === 'nick_name' || column.property === 'username') {
const sameUserRows = tableData.value.filter(item => item.user_id === row.user_id); const sameUserRows = tableData.value.filter((item) => item.user_id === row.user_id)
if (rowIndex === tableData.value.findIndex(item => item.user_id === row.user_id)) { if (rowIndex === tableData.value.findIndex((item) => item.user_id === row.user_id)) {
return { return {
rowspan: sameUserRows.length, rowspan: sameUserRows.length,
colspan: 1 colspan: 1,
}; }
} else { } else {
return { return {
rowspan: 0, rowspan: 0,
colspan: 0 colspan: 0,
}; }
} }
} }
}; }
const addMemberDrawerRef = ref<InstanceType<typeof AddMemberDrawer>>() const addMemberDrawerRef = ref<InstanceType<typeof AddMemberDrawer>>()

View File

@ -1,6 +1,6 @@
<template> <template>
<el-scrollbar v-loading="loading"> <el-scrollbar v-loading="loading">
<app-table :data="tableData" border :span-method="objectSpanMethod"> <app-table :data="tableData" border :span-method="objectSpanMethod" :maxTableHeight="280">
<el-table-column prop="module" :width="130" :label="$t('views.role.permission.moduleName')"/> <el-table-column prop="module" :width="130" :label="$t('views.role.permission.moduleName')"/>
<el-table-column <el-table-column
prop="name" prop="name"
@ -40,8 +40,8 @@
</el-table-column> </el-table-column>
</app-table> </app-table>
</el-scrollbar> </el-scrollbar>
<div v-if="!disabled" class="footer border-t"> <div class="footer border-t">
<el-button type="primary" style="width: 80px" :loading="loading" @click="handleSave"> <el-button type="primary" :disabled="disabled" :loading="loading" @click="handleSave">
{{ $t('common.save') }} {{ $t('common.save') }}
</el-button> </el-button>
</div> </div>
@ -61,6 +61,7 @@ import {MsgSuccess} from '@/utils/message'
import {t} from '@/locales' import {t} from '@/locales'
import {hasPermission} from "@/utils/permission"; import {hasPermission} from "@/utils/permission";
import {EditionConst, RoleConst} from "@/utils/permission/data.ts"; import {EditionConst, RoleConst} from "@/utils/permission/data.ts";
import { max } from 'moment'
const props = defineProps<{ const props = defineProps<{
currentRole?: RoleItem currentRole?: RoleItem

View File

@ -1,8 +1,8 @@
<template> <template>
<div class="role-manage p-16-24"> <div class="role-manage p-16-24">
<h2 class="mb-16">{{ $t('views.role.title') }}</h2> <h2 class="mb-16">{{ $t('views.role.title') }}</h2>
<el-card style="--el-card-padding: 0"> <el-card style="--el-card-padding: 0" class="main-calc-height">
<div class="flex h-full"> <div class="flex">
<div class="role-left border-r"> <div class="role-left border-r">
<div class="p-24 pb-0"> <div class="p-24 pb-0">
<el-input <el-input
@ -26,7 +26,7 @@
@mouseleave="mouseId = ''" @mouseleave="mouseId = ''"
> >
<template #default="{ row }"> <template #default="{ row }">
<span>{{ row.role_name }}</span> <span class="ellipsis-1" :title="row.role_name">{{ row.role_name }}</span>
</template> </template>
<template #empty> <template #empty>
<span></span> <span></span>
@ -290,7 +290,7 @@ function mouseenter(row: any) {
min-width: var(--setting-left-width); min-width: var(--setting-left-width);
.list-height-left { .list-height-left {
height: calc(100vh - 213px); height: calc(100vh - 200px);
} }
} }
.role-right { .role-right {

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="p-16-24"> <div class="p-16-24">
<h2 class="mb-16">{{ $t('views.userManage.title') }}</h2> <h2 class="mb-16">{{ $t('views.userManage.title') }}</h2>
<el-card> <el-card class="main-calc-height">
<div class="flex-between mb-16"> <div class="flex-between mb-16">
<el-button <el-button
type="primary" type="primary"
@ -53,14 +53,20 @@
@sizeChange="handleSizeChange" @sizeChange="handleSizeChange"
@changePage="getList" @changePage="getList"
v-loading="loading" v-loading="loading"
:maxTableHeight="280"
> >
<el-table-column <el-table-column
prop="nick_name" prop="nick_name"
:label="$t('views.userManage.userForm.nick_name.label')" :label="$t('views.userManage.userForm.nick_name.label')"
min-width="180" min-width="180"
show-overflow-tooltip show-overflow-tooltip
/> />
<el-table-column prop="username" min-width="180" show-overflow-tooltip :label="$t('views.login.loginForm.username.label')" /> <el-table-column
prop="username"
min-width="180"
show-overflow-tooltip
:label="$t('views.login.loginForm.username.label')"
/>
<el-table-column width="100" prop="is_active" :label="$t('common.status.label')"> <el-table-column width="100" prop="is_active" :label="$t('common.status.label')">
<template #default="{ row }"> <template #default="{ row }">
<div v-if="row.is_active" class="flex align-center"> <div v-if="row.is_active" class="flex align-center">
@ -90,7 +96,11 @@
{{ row.email || '-' }} {{ row.email || '-' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="phone" width="120" :label="$t('views.userManage.userForm.phone.label')"> <el-table-column
prop="phone"
width="120"
:label="$t('views.userManage.userForm.phone.label')"
>
<template #default="{ row }"> <template #default="{ row }">
{{ row.phone || '-' }} {{ row.phone || '-' }}
</template> </template>

View File

@ -41,7 +41,7 @@
> >
<template #default="{ row }"> <template #default="{ row }">
<div class="flex-between"> <div class="flex-between">
<span class="ellipsis">{{ row.name }}</span> <span class="ellipsis" :title="row.name">{{ row.name }}</span>
<div @click.stop v-show="mouseId === row.id"> <div @click.stop v-show="mouseId === row.id">
<el-dropdown :teleported="false" trigger="click"> <el-dropdown :teleported="false" trigger="click">
<el-button text> <el-button text>

View File

@ -106,7 +106,7 @@
<div <div
v-loading.fullscreen.lock="paginationConfig.current_page === 1 && loading" v-loading.fullscreen.lock="paginationConfig.current_page === 1 && loading"
style="max-height: calc(100vh - 140px)" style="max-height: calc(100vh - 120px)"
> >
<InfiniteScroll <InfiniteScroll
:size="tool.toolList.length" :size="tool.toolList.length"