feat(acl-ui):i18n

This commit is contained in:
wang-liang0615 2023-12-29 18:03:29 +08:00
parent ace160ae19
commit 70d674ac4f
40 changed files with 1350 additions and 1403 deletions

View File

@ -0,0 +1,125 @@
const acl_en = {
date: 'Date',
operator: 'Operator',
resource: 'Resource',
resourceType: 'Resource Type',
addResourceType: 'Add Resource Type',
app: 'App',
operateTime: 'Operate Time',
permission: 'Permission',
permission_placeholder: 'please select permission',
permissionList: 'Permission List',
summaryPermissions: 'Summary of permissions',
source: 'Source',
username: 'Username',
username_placeholder: 'please input username',
userList: 'User List',
groupUser: 'Group User',
addUser: 'Add User',
subordinateUsers: 'Subordinate Users',
nickname: 'Nickname',
nickname_placeholder: 'please input nickname',
password: 'Password',
password_placeholder: 'please input password',
department: 'Department',
group: 'Group',
email: 'Email',
email_placeholder: 'please input email',
mobile: 'Mobile',
isBlock: 'Is Block',
block: 'Block',
joined_at: 'Joined At',
role: 'Role',
role_placeholder1: 'please input role',
role_placeholder2: 'please select role',
role_placeholder3: 'please select a role name, multiple choices are allowed',
allRole: 'All Roles',
visualRole: 'Virtual Role',
addVisualRole: 'Add Virtual Role',
inheritedFrom: 'Inherited from',
heir: 'Inherit Roles',
permissionChange: 'Permissions',
roleChange: 'Roles',
resourceChange: 'Resources',
resourceTypeChange: 'Resource Type',
trigger: 'Triggers',
triggerNameInput: 'Please enter trigger name',
triggerChange: 'Triggers',
roleManage: 'Roles',
userManage: 'Users',
appManage: 'Applications',
resourceManage: 'Resources',
history: 'Audits',
userSecret: 'Secrets',
none: 'none',
danger: 'Dangerous',
confirmDeleteApp: 'Are you sure you want to delete this app?',
revoke: 'Revoke',
convenient: 'Quick Grant',
group2: 'Group',
groupName: 'Group Name',
resourceName: 'Resource Name',
creator: 'Creator',
member: 'Members',
viewAuth: 'view Auth',
addTypeTips: 'There is no type information yet, please add the resource type first!',
addResource: 'Add Resource',
resourceList: 'Resource List',
confirmResetSecret: 'Are you sure you want to reset the user secrets?',
addTrigger: 'Add Trigger',
deleteTrigger: 'Delete Trigger',
applyTrigger: 'Apply Trigger',
cancelTrigger: 'Cancel Trigger',
enable: 'Enable',
disable: 'Disable',
viewMatchResult: 'View regular matching results',
confirmDeleteTrigger: 'Are you sure you want to delete this trigger?',
ruleApply: 'Apply',
triggerTip1: 'Are you sure you want to apply this trigger?',
triggerTip2: 'Cancel applying this trigger?',
appNameInput: 'Please enter an application name',
descInput: 'Please enter a description',
addApp: 'Add',
updateApp: 'Update',
cancel: 'Cancel',
typeName: 'Name',
typeNameInput: 'Please enter a type name',
resourceNameInput: 'Please enter resource name',
pressEnter: 'Press Enter to confirm filtering',
groupMember: 'Group Members:',
isGroup: 'Group?',
errorTips: 'Error message',
roleList: 'Role List',
virtual: 'Virtual',
resourceBatchTips: 'Please enter the resource name, separated by newlines',
memberManage: 'Members: ',
newResource: 'New Resource: ',
deleteResource: 'Delete Resource: ',
deleteResourceType: 'Delete Resource Type: ',
noChange: 'No change',
batchOperate: 'Batch Operations',
batchGrant: 'Batch Grant',
batchRevoke: 'Batch Revoke',
editPerm: 'Add authorization: ',
permInput: 'Please enter permission name',
resourceTypeName: 'Resource Type Name',
selectedParents: 'Optionally inherit roles',
isAppAdmin: 'is app admin',
addRole: 'Add Role',
roleRelation: 'Role Relation',
roleRelationAdd: 'Add Role Relation',
roleRelationDelete: 'Delete Role Relation',
role2: 'Role',
admin: 'Admin',
involvingRP: 'Involving resources and permissions',
startAt: 'Start Time',
endAt: 'End Time',
triggerTips1: 'Priority regular pattern (secondary wildcard)',
pleaseSelectType: 'Please select resource type',
apply: 'Apply',
mobileTips: 'Please enter the correct phone number',
remove: 'Remove',
deleteUserConfirm: 'Are you sure you want to remove this user?',
copyResource: 'Copy resource name'
}
export default acl_en

View File

@ -0,0 +1,125 @@
const acl_zh = {
date: '日期',
operator: '操作员',
resource: '资源',
resourceType: '资源类型',
addResourceType: '新增资源类型',
app: '应用',
operateTime: '操作时间',
permission: '权限',
permission_placeholder: '请选择权限',
permissionList: '权限列表',
summaryPermissions: '权限汇总',
source: '来源',
username: '用户名',
username_placeholder: '请输入用户名',
userList: '用户列表',
groupUser: '组用户',
addUser: '新增用户',
subordinateUsers: '下属用户',
nickname: '中文名',
nickname_placeholder: '请输入中文名',
password: '密码',
password_placeholder: '请输入密码',
department: '部门',
group: '小组',
email: '邮箱',
email_placeholder: '请输入邮箱',
mobile: '手机号',
isBlock: '是否锁定',
block: '锁定',
joined_at: '加入时间',
role: '角色名',
role_placeholder1: '请输入角色名',
role_placeholder2: '请选择角色名称',
role_placeholder3: '请选择角色名称,可多选',
allRole: '所有角色',
visualRole: '虚拟角色',
addVisualRole: '新增虚拟角色',
inheritedFrom: '继承自',
heir: '继承者',
permissionChange: '权限变更',
roleChange: '角色变更',
resourceChange: '资源变更',
resourceTypeChange: '资源类型变更',
trigger: '触发器',
triggerNameInput: '请输入触发器名',
triggerChange: '触发器变更',
roleManage: '角色管理',
userManage: '用户管理',
appManage: '应用管理',
resourceManage: '资源管理',
history: '操作审计',
userSecret: '用户密钥',
none: '无',
danger: '危险操作',
confirmDeleteApp: '确定要删除该App吗',
revoke: '权限回收',
convenient: '便捷授权',
group2: '组',
groupName: '资源组名',
resourceName: '资源名',
creator: '创建者',
member: '成员',
viewAuth: '查看授权',
addTypeTips: '暂无类型信息,请先添加资源类型!',
addResource: '新增资源',
resourceList: '资源列表',
confirmResetSecret: '确定重置用户密钥?',
addTrigger: '新增触发器',
deleteTrigger: '删除触发器',
applyTrigger: '应用触发器',
cancelTrigger: '取消触发器',
enable: '启用',
disable: '禁用',
viewMatchResult: '查看正则匹配结果',
confirmDeleteTrigger: '确认删除该触发器吗?',
ruleApply: '规则应用',
triggerTip1: '是否确定应用该触发器?',
triggerTip2: '是否取消应用该触发器?',
appNameInput: '请输入应用名称',
descInput: '请输入描述',
addApp: '创建应用',
updateApp: '更新应用',
cancel: '撤销',
typeName: '类型名',
typeNameInput: '请输入类型名',
resourceNameInput: '请输入资源名',
pressEnter: '按回车确认筛选',
groupMember: '组成员:',
isGroup: '是否组',
errorTips: '错误提示',
roleList: '角色列表',
virtual: '虚拟',
resourceBatchTips: '请输入资源名,换行分隔',
memberManage: '成员管理:',
newResource: '新建资源:',
deleteResource: '删除资源:',
deleteResourceType: '删除资源类型:',
noChange: '没有修改',
batchOperate: '批量操作',
batchGrant: '批量授权',
batchRevoke: '批量权限回收',
editPerm: '添加授权:',
permInput: '请输入权限名',
resourceTypeName: '资源类型名',
selectedParents: '可选择继承角色',
isAppAdmin: '是否应用管理员',
addRole: '新增角色',
roleRelation: '角色关系',
roleRelationAdd: '添加角色关系',
roleRelationDelete: '删除角色关系',
role2: '角色',
admin: '管理员',
involvingRP: '涉及资源及权限',
startAt: '开始时间',
endAt: '结束时间',
triggerTips1: '优先正则模式(次通配符)',
pleaseSelectType: '请选择资源类型',
apply: '应用',
mobileTips: '请输入正确的手机号码',
remove: '移除',
deleteUserConfirm: '是否确定要移除该用户',
copyResource: '复制资源名'
}
export default acl_zh

View File

@ -12,35 +12,35 @@ const genAppRoute = ({ name }) => {
name: `${name}_roles_acl`, name: `${name}_roles_acl`,
hideChildrenInMenu: true, hideChildrenInMenu: true,
component: () => import('../views/roles'), component: () => import('../views/roles'),
meta: { title: '角色管理', icon: 'team', keepAlive: true } meta: { title: 'acl.roleManage', icon: 'team', keepAlive: true }
}, },
{ {
path: `/acl/${name}/resources`, path: `/acl/${name}/resources`,
name: `${name}_resources_acl`, name: `${name}_resources_acl`,
hideChildrenInMenu: true, hideChildrenInMenu: true,
component: () => import('../views/resources'), component: () => import('../views/resources'),
meta: { title: '资源管理', icon: 'credit-card', keepAlive: false } meta: { title: 'acl.resourceManage', icon: 'credit-card', keepAlive: false }
}, },
{ {
path: `/acl/${name}/resource_types`, path: `/acl/${name}/resource_types`,
name: `${name}_resource_types_acl`, name: `${name}_resource_types_acl`,
hideChildrenInMenu: true, hideChildrenInMenu: true,
component: () => import('../views/resource_types'), component: () => import('../views/resource_types'),
meta: { title: '资源类型', icon: 'file-text', keepAlive: true } meta: { title: 'acl.resourceType', icon: 'file-text', keepAlive: true }
}, },
{ {
path: `/acl/${name}/trigger`, path: `/acl/${name}/trigger`,
name: `${name}_trigger_acl`, name: `${name}_trigger_acl`,
hideChildrenInMenu: true, hideChildrenInMenu: true,
component: () => import('../views/trigger'), component: () => import('../views/trigger'),
meta: { title: '触发器', icon: 'clock-circle', keepAlive: true } meta: { title: 'acl.trigger', icon: 'clock-circle', keepAlive: true }
}, },
{ {
path: `/acl/${name}/history`, path: `/acl/${name}/history`,
name: `${name}_history_acl`, name: `${name}_history_acl`,
hideChildrenInMenu: true, hideChildrenInMenu: true,
component: () => import('../views/history'), component: () => import('../views/history'),
meta: { title: '操作审计', icon: 'search', keepAlive: false } meta: { title: 'acl.history', icon: 'search', keepAlive: false }
} }
] ]
} }
@ -59,31 +59,31 @@ const genAclRoutes = async () => {
path: `/acl/secret_key`, path: `/acl/secret_key`,
name: 'acl_secret_key', name: 'acl_secret_key',
component: () => import('../views/secretKey'), component: () => import('../views/secretKey'),
meta: { title: '用户密钥', icon: 'key' } meta: { title: 'acl.userSecret', icon: 'key' }
}, },
{ {
path: `/acl/operate_history`, path: `/acl/operate_history`,
name: 'acl_operate_history', name: 'acl_operate_history',
component: () => import('../views/operation_history/index.vue'), component: () => import('../views/operation_history/index.vue'),
meta: { title: '操作审计', icon: 'search', permission: ['acl_admin'] }, meta: { title: 'acl.history', icon: 'search', permission: ['acl_admin'] }
}, },
{ {
path: `/acl/user`, path: `/acl/user`,
name: 'acl_user', name: 'acl_user',
component: () => import('../views/users'), component: () => import('../views/users'),
meta: { title: '用户管理', icon: 'user', permission: ['acl_admin'] } meta: { title: 'acl.userManage', icon: 'user', permission: ['acl_admin'] }
}, },
{ {
path: `/acl/roles`, path: `/acl/roles`,
name: `acl_roles`, name: `acl_roles`,
component: () => import('../views/roles'), component: () => import('../views/roles'),
meta: { title: '角色管理', icon: 'team', keepAlive: true, permission: ['acl_admin'] } meta: { title: 'acl.roleManage', icon: 'team', keepAlive: true, permission: ['acl_admin'] }
}, },
{ {
path: `/acl/apps`, path: `/acl/apps`,
name: 'acl_apps', name: 'acl_apps',
component: () => import('../views/apps'), component: () => import('../views/apps'),
meta: { title: '应用管理', icon: 'appstore', permission: ['acl_admin'] } meta: { title: 'acl.appManage', icon: 'appstore', permission: ['acl_admin'] }
} }
] ]
} }

View File

@ -11,7 +11,7 @@
:xs="24"> :xs="24">
<a-card> <a-card>
<a-card-meta :title="app.name"> <a-card-meta :title="app.name">
<div slot="description" :title="app.description || ''">{{ app.description || '' }}</div> <div slot="description" :title="app.description || ''">{{ app.description || $t('none') }}</div>
<a-avatar style="background-color: #5dc2f1" slot="avatar">{{ app.name[0].toUpperCase() }}</a-avatar> <a-avatar style="background-color: #5dc2f1" slot="avatar">{{ app.name[0].toUpperCase() }}</a-avatar>
</a-card-meta> </a-card-meta>
<template slot="actions"> <template slot="actions">
@ -65,11 +65,11 @@ export default {
handleDeleteApp(app) { handleDeleteApp(app) {
const that = this const that = this
this.$confirm({ this.$confirm({
title: '危险操作', title: that.$t('danger'),
content: '确定要删除该App吗', content: that.$t('confirmDeleteApp'),
onOk() { onOk() {
deleteApp(app.id).then((res) => { deleteApp(app.id).then((res) => {
that.$message.success(`删除成功${app.name}`) that.$message.success(that.$t('deleteSuccess'))
that.loadApps() that.loadApps()
}) })
}, },

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="acl-history"> <div class="acl-history">
<a-tabs default-active-key="1"> <a-tabs default-active-key="1">
<a-tab-pane key="1" tab="权限变更"> <a-tab-pane key="1" :tab="$t('acl.permissionChange')">
<permisson-history-table <permisson-history-table
v-if="isloaded" v-if="isloaded"
:allResourceTypes="allResourceTypes" :allResourceTypes="allResourceTypes"
@ -17,7 +17,7 @@
@resourceClear="resourceClear" @resourceClear="resourceClear"
></permisson-history-table> ></permisson-history-table>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="2" tab="角色变更"> <a-tab-pane key="2" :tab="$t('acl.roleChange')">
<role-history-table <role-history-table
v-if="isloaded" v-if="isloaded"
:allUsers="allUsers" :allUsers="allUsers"
@ -26,7 +26,7 @@
:allUsersMap="allUsersMap" :allUsersMap="allUsersMap"
></role-history-table> ></role-history-table>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="3" tab="资源变更"> <a-tab-pane key="3" :tab="$t('acl.resourceChange')">
<resource-history-table <resource-history-table
v-if="isloaded" v-if="isloaded"
:allResources="allResources" :allResources="allResources"
@ -41,7 +41,7 @@
@resourceClear="resourceClear" @resourceClear="resourceClear"
></resource-history-table> ></resource-history-table>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="4" tab="资源类型变更"> <a-tab-pane key="4" :tab="$t('acl.resourceTypeChange')">
<resource-type-history-table <resource-type-history-table
v-if="isloaded" v-if="isloaded"
:allResourceTypes="allResourceTypes" :allResourceTypes="allResourceTypes"
@ -52,7 +52,7 @@
:allResourceTypesMap="allResourceTypesMap" :allResourceTypesMap="allResourceTypesMap"
></resource-type-history-table> ></resource-type-history-table>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="5" tab="触发器变更"> <a-tab-pane key="5" :tab="$t('acl.triggerChange')">
<trigger-history-table <trigger-history-table
v-if="isloaded" v-if="isloaded"
:allTriggers="allTriggers" :allTriggers="allTriggers"

View File

@ -1,11 +1,12 @@
<template> <template>
<CustomDrawer @close="handleClose" width="500" :title="title" :visible="visible" :closable="false"> <CustomDrawer @close="handleClose" width="500" :title="title" :visible="visible" :closable="false">
<a-form :form="form" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }"> <a-form :form="form" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
<a-form-item label="应用名称"> <a-form-item :label="$t('acl.app')">
<a-input v-decorator="['name', { rules: [{ required: true, message: '请输入应用名称' }] }]"> </a-input> <a-input v-decorator="['name', { rules: [{ required: true, message: $t('acl.appNameInput') }] }]"> </a-input>
</a-form-item> </a-form-item>
<a-form-item label="描述"> <a-form-item :label="$t('desc')">
<a-input v-decorator="['description', { rules: [{ required: true, message: '请输入描述' }] }]"> </a-input> <a-input v-decorator="['description', { rules: [{ required: true, message: $t('acl.descInput') }] }]">
</a-input>
</a-form-item> </a-form-item>
<a-form-item label="AppId"> <a-form-item label="AppId">
<a-input v-decorator="['app_id', { rules: [{ required: false }] }]" :disabled="mode === 'update'"> </a-input> <a-input v-decorator="['app_id', { rules: [{ required: false }] }]" :disabled="mode === 'update'"> </a-input>
@ -19,8 +20,8 @@
</a-form-item> </a-form-item>
</a-form> </a-form>
<div class="custom-drawer-bottom-action"> <div class="custom-drawer-bottom-action">
<a-button @click="handleClose">取消</a-button> <a-button @click="handleClose">{{ $t('cancel') }}</a-button>
<a-button @click="handleSubmit" type="primary">提交</a-button> <a-button @click="handleSubmit" type="primary">{{ $t('submit') }}</a-button>
</div> </div>
</CustomDrawer> </CustomDrawer>
</template> </template>
@ -32,10 +33,14 @@ export default {
data() { data() {
return { return {
visible: false, visible: false,
title: '创建应用',
mode: 'create', mode: 'create',
} }
}, },
computed: {
title() {
return this.$t('acl.addApp')
},
},
beforeCreate() { beforeCreate() {
this.form = this.$form.createForm(this) this.form = this.$form.createForm(this)
}, },
@ -43,7 +48,7 @@ export default {
handleEdit(ele) { handleEdit(ele) {
this.visible = true this.visible = true
if (ele) { if (ele) {
this.title = '修改应用' this.title = this.$t('updateApp')
this.mode = 'update' this.mode = 'update'
console.log(ele) console.log(ele)
const { name, description } = ele const { name, description } = ele
@ -55,7 +60,7 @@ export default {
}) })
} else { } else {
this.mode = 'create' this.mode = 'create'
this.title = '创建应用' this.title = this.$t('acl.addApp')
} }
}, },
handleClose() { handleClose() {
@ -69,11 +74,11 @@ export default {
} }
if (values.id) { if (values.id) {
await updateApp(values.id, values).then((res) => { await updateApp(values.id, values).then((res) => {
this.$message.success('修改成功!') this.$message.success(this.$t('updateSuccess'))
}) })
} else { } else {
await addApp(values).then((res) => { await addApp(values).then((res) => {
this.$message.success('创建成功!') this.$message.success(this.$t('addSuccess'))
}) })
} }
this.handleClose() this.handleClose()

View File

@ -9,10 +9,10 @@
<a-dropdown class="dropdown" size="small" placement="topCenter" :trigger="['click']" :disabled="dropdownIsDisabled"> <a-dropdown class="dropdown" size="small" placement="topCenter" :trigger="['click']" :disabled="dropdownIsDisabled">
<a-menu slot="overlay"> <a-menu slot="overlay">
<a-menu-item v-for="(size,index) in pageSizes" :key="index" @click="handleItemClick(size)"> <a-menu-item v-for="(size,index) in pageSizes" :key="index" @click="handleItemClick(size)">
{{ size }}/ {{ size }}{{ $t('itemsPerPage') }}
</a-menu-item> </a-menu-item>
</a-menu> </a-menu>
<a-button size="small"> {{ pageSize }}/ <a-icon type="down" /> </a-button> <a-button size="small"> {{ pageSize }}{{ $t('itemsPerPage') }}<a-icon type="down" /> </a-button>
</a-dropdown> </a-dropdown>
</a-space> </a-space>
</a-col> </a-col>

View File

@ -1,6 +1,6 @@
<template> <template>
<CustomDrawer <CustomDrawer
:title="`权限汇总: ${user.nickname}`" :title="`${$t('acl.summaryPermissions')}: ${user.nickname}`"
:visible="visible" :visible="visible"
placement="left" placement="left"
width="100%" width="100%"
@ -24,7 +24,7 @@
<vxe-table :max-height="`${windowHeight - 230}px`" :data="resources" ref="rTable"> <vxe-table :max-height="`${windowHeight - 230}px`" :data="resources" ref="rTable">
<vxe-column <vxe-column
field="name" field="name"
title="资源名" :title="$t('acl.resourceName')"
width="30%" width="30%"
:filters="[{ data: '' }]" :filters="[{ data: '' }]"
:filter-method="filterNameMethod" :filter-method="filterNameMethod"
@ -39,62 +39,17 @@
v-model="option.data" v-model="option.data"
@input="$panel.changeOption($event, !!option.data, option)" @input="$panel.changeOption($event, !!option.data, option)"
@keyup.enter="$panel.confirmFilter()" @keyup.enter="$panel.confirmFilter()"
placeholder="按回车确认筛选" :placeholder="$t('acl.pressEnter')"
/> />
</template> </template>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="permissions" title="权限列表" width="70%"> <vxe-column field="permissions" :title="$t('acl.permissionList')" width="70%">
<template #default="{row}"> <template #default="{row}">
<a-tag color="cyan" v-for="(r, index) in row.permissions" :key="index">{{ r }}</a-tag> <a-tag color="cyan" v-for="(r, index) in row.permissions" :key="index">{{ r }}</a-tag>
</template> </template>
</vxe-column> </vxe-column>
</vxe-table> </vxe-table>
<!-- <a-table
:columns="tableColumns"
:dataSource="resources"
:rowKey="record=>record.id"
:pagination="{ showTotal: (total, range) => `${range[0]}-${range[1]} 共 ${total} 条记录` }"
showPagination="auto"
ref="rTable"
size="middle">
<div slot="filterDropdown" slot-scope="{ setSelectedKeys, selectedKeys, confirm, clearFilters, column }" class="custom-filter-dropdown">
<a-input
v-ant-ref="c => searchInput = c"
:placeholder="` ${column.title}`"
:value="selectedKeys[0]"
@change="e => setSelectedKeys(e.target.value ? [e.target.value] : [])"
@pressEnter="() => handleSearch(selectedKeys, confirm, column)"
style="width: 188px; margin-bottom: 8px; display: block;"
/>
<a-button
type="primary"
@click="() => handleSearch(selectedKeys, confirm, column)"
icon="search"
size="small"
style="width: 90px; margin-right: 8px"
>搜索</a-button>
<a-button
@click="() => handleReset(clearFilters, column)"
size="small"
style="width: 90px"
>重置</a-button>
</div>
<a-icon slot="filterIcon" slot-scope="filtered" type="search" :style="{ color: filtered ? '#108ee9' : undefined }" />
<template slot="nameSearchRender" slot-scope="text">
<span v-if="columnSearchText.name">
<template v-for="(fragment, i) in text.toString().split(new RegExp(`(?<=${columnSearchText.name})|(?=${columnSearchText.name})`, 'i'))">
<mark v-if="fragment.toLowerCase() === columnSearchText.name.toLowerCase()" :key="i" class="highlight">{{ fragment }}</mark>
<template v-else>{{ fragment }}</template>
</template>
</span>
<template v-else>{{ text }}</template>
</template>
<template slot="permissions" slot-scope="record">
<a-tag color="cyan" v-for="(r, index) in record" :key="index">{{ r }}</a-tag>
</template>
</a-table> -->
</a-spin> </a-spin>
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
@ -122,33 +77,6 @@ export default {
resourceTypes: [], resourceTypes: [],
resourceTypePerms: [], resourceTypePerms: [],
resources: [], resources: [],
// tableColumns: [
// {
// title: '资源名',
// dataIndex: 'name',
// sorter: false,
// width: 150,
// // scopedSlots: {
// // customRender: 'nameSearchRender',
// // filterDropdown: 'filterDropdown',
// // filterIcon: 'filterIcon'
// // },
// // onFilter: (value, record) => record.name && record.name.toLowerCase().includes(value.toLowerCase()),
// // onFilterDropdownVisibleChange: (visible) => {
// // if (visible) {
// // setTimeout(() => {
// // this.searchInput.focus()
// // }, 0)
// // }
// // }
// },
// {
// title: '权限列表',
// dataIndex: 'permissions',
// width: 300,
// scopedSlots: { customRender: 'permissions' },
// },
// ],
columnSearchText: { columnSearchText: {
name: '', name: '',
}, },
@ -156,14 +84,14 @@ export default {
}, },
computed: { computed: {
...mapState({ ...mapState({
windowHeight: state => state.windowHeight, windowHeight: (state) => state.windowHeight,
}), }),
displayApps() { displayApps() {
const roles = this.$store.state.user.roles.permissions const roles = this.$store.state.user.roles.permissions
if (roles.includes('acl_admin')) { if (roles.includes('acl_admin')) {
return this.apps return this.apps
} }
return this.apps.filter(item => { return this.apps.filter((item) => {
if (roles.includes(`${item.name}_admin`)) { if (roles.includes(`${item.name}_admin`)) {
return true return true
} }
@ -192,7 +120,7 @@ export default {
}, },
async loadRoles(_appId) { async loadRoles(_appId) {
const res = await searchRole({ app_id: _appId, page_size: 9999, is_all: true }) const res = await searchRole({ app_id: _appId, page_size: 9999, is_all: true })
this.roles = res.roles.filter(item => item.uid) this.roles = res.roles.filter((item) => item.uid)
}, },
async handleSwitchApp(appId) { async handleSwitchApp(appId) {
this.currentAppId = appId this.currentAppId = appId
@ -218,7 +146,7 @@ export default {
}, },
async loadResource() { async loadResource() {
this.spinning = true this.spinning = true
const fil = this.roles.filter(role => role.uid === this.user.uid) const fil = this.roles.filter((role) => role.uid === this.user.uid)
if (!fil[0]) { if (!fil[0]) {
return return
} }

View File

@ -1,29 +1,33 @@
<template> <template>
<CustomDrawer <CustomDrawer
:closable="false" :closable="false"
:title="drawerTitle" :title="$t('acl.addReourceType')"
:visible="drawerVisible" :visible="drawerVisible"
@close="onClose" @close="onClose"
placement="right" placement="right"
width="30%" width="30%"
> >
<a-form :form="form" :layout="formLayout" @submit="handleSubmit"> <a-form :form="form" :layout="formLayout" @submit="handleSubmit">
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="类型名"> <a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" :label="$t('acl.typeName')">
<a-input <a-input
name="name" name="name"
placeholder="" placeholder=""
v-decorator="['name', { rules: [{ required: true, message: '请输入资源名' }] }]" v-decorator="['name', { rules: [{ required: true, message: $t('acl.resourceNameInput') }] }]"
/> />
</a-form-item> </a-form-item>
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="描述"> <a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" :label="$t('desc')">
<a-textarea placeholder="请输入描述信息..." name="description" :rows="4" /> <a-textarea :placeholder="$t('acl.descInput')" name="description" :rows="4" />
</a-form-item> </a-form-item>
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="权限"> <a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
:label="$t('acl.permission')"
>
<div :style="{ borderBottom: '1px solid #E9E9E9' }"> <div :style="{ borderBottom: '1px solid #E9E9E9' }">
<a-checkbox :indeterminate="indeterminate" @change="onCheckAllChange" :checked="checkAll"> <a-checkbox :indeterminate="indeterminate" @change="onCheckAllChange" :checked="checkAll">
全选 {{ $t('checkAll') }}
</a-checkbox> </a-checkbox>
</div> </div>
<br /> <br />
@ -35,8 +39,8 @@
</a-form-item> </a-form-item>
<div class="custom-drawer-bottom-action"> <div class="custom-drawer-bottom-action">
<a-button @click="onClose">取消</a-button> <a-button @click="onClose">{{ $t('cancel') }}</a-button>
<a-button @click="handleSubmit" type="primary">确定</a-button> <a-button @click="handleSubmit" type="primary">{{ $t('confirm') }}</a-button>
</div> </div>
</a-form> </a-form>
</CustomDrawer> </CustomDrawer>
@ -49,7 +53,6 @@ export default {
name: 'ResourceForm', name: 'ResourceForm',
data() { data() {
return { return {
drawerTitle: '新增资源类型',
drawerVisible: false, drawerVisible: false,
formLayout: 'vertical', formLayout: 'vertical',
perms: ['1'], perms: ['1'],
@ -142,8 +145,8 @@ export default {
}) })
}, },
updateResourceType(id, data) { updateResourceType(id, data) {
updateResourceTypeById(id, data).then(res => { updateResourceTypeById(id, data).then((res) => {
this.$message.success(`更新成功`) this.$message.success(this.$t('updateSuccess'))
this.handleOk() this.handleOk()
this.onClose() this.onClose()
}) })
@ -151,18 +154,12 @@ export default {
}, },
createResourceType(data) { createResourceType(data) {
addResourceType(data).then(res => { addResourceType(data).then((res) => {
this.$message.success(`添加成功`) this.$message.success(this.$t('addSuccess'))
this.handleOk() this.handleOk()
this.onClose() this.onClose()
}) })
// .catch(err => this.requestFailed(err))
}, },
// requestFailed (err) {
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
// this.$message.error(`${msg}`)
// }
}, },
watch: {}, watch: {},
props: { props: {

View File

@ -21,22 +21,22 @@
:height="`${windowHeight - windowHeightMinus}px`" :height="`${windowHeight - windowHeightMinus}px`"
:scroll-y="{ enabled: false }" :scroll-y="{ enabled: false }"
> >
<vxe-column field="created_at" width="144px" title="操作时间"> <vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')">
<template #default="{ row }"> <template #default="{ row }">
<span>{{ row.deleted_at || row.updated_at || row.created_at }}</span> <span>{{ row.deleted_at || row.updated_at || row.created_at }}</span>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column> <vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
<vxe-column field="operate_type" width="80px" title="操作"> <vxe-column field="operate_type" width="100px" :title="$t('operation')">
<template #default="{ row }"> <template #default="{ row }">
<a-tag :color="row.operate_type === 'grant' ? 'green' : 'red'">{{ <a-tag :color="row.operate_type === 'grant' ? 'green' : 'red'">{{
operateTypeMap.get(row.operate_type) operateTypeMap.get(row.operate_type)
}}</a-tag> }}</a-tag>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="rid" title="用户"></vxe-column> <vxe-column field="rid" :title="$t('user')"></vxe-column>
<vxe-column field="resource_type_id" title="资源类型"></vxe-column> <vxe-column field="resource_type_id" :title="$t('acl.resourceType')"></vxe-column>
<vxe-column field="resources" title="资源"> <vxe-column field="resources" :title="$t('acl.resource')">
<template #default="{ row }"> <template #default="{ row }">
<template v-if="row.resource_ids.length > 0"> <template v-if="row.resource_ids.length > 0">
<a-tooltip placement="top"> <a-tooltip placement="top">
@ -55,14 +55,14 @@
</template> </template>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column title="权限"> <vxe-column :title="$t('acl.permission')">
<template #default="{ row }"> <template #default="{ row }">
<a-tag v-for="(perm, index) in row.permission_ids" :key="'perms_' + perm + index"> <a-tag v-for="(perm, index) in row.permission_ids" :key="'perms_' + perm + index">
{{ perm }} {{ perm }}
</a-tag> </a-tag>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="source" width="100px" title="来源"></vxe-column> <vxe-column field="source" width="100px" :title="$t('acl.source')"></vxe-column>
</vxe-table> </vxe-table>
<pager <pager
:current-page.sync="queryParams.page" :current-page.sync="queryParams.page"
@ -122,10 +122,6 @@ export default {
loading: true, loading: true,
app_id: this.$route.name.split('_')[0], app_id: this.$route.name.split('_')[0],
tableData: [], tableData: [],
operateTypeMap: new Map([
['grant', '授权'],
['revoke', '撤销'],
]),
queryParams: { queryParams: {
page: 1, page: 1,
page_size: 50, page_size: 50,
@ -133,49 +129,6 @@ export default {
start: '', start: '',
end: '', end: '',
}, },
permissionTableAttrList: [
{
alias: '日期',
is_choice: false,
name: 'datetime',
value_type: '3',
},
{
alias: '操作员',
is_choice: true,
name: 'operate_uid',
value_type: '2',
choice_value: this.allUsers,
},
{
alias: '用户',
is_choice: true,
name: 'rid',
value_type: '2',
choice_value: this.allRoles,
},
{
alias: '资源类型',
is_choice: true,
name: 'resource_type_id',
value_type: '2',
choice_value: this.allResourceTypes,
},
{
alias: '资源',
is_choice: true,
name: 'resource_id',
value_type: '2',
choice_value: this.allResources,
},
{
alias: '操作',
is_choice: true,
name: 'operate_type',
value_type: '2',
choice_value: [{ 授权: 'grant' }, { 撤销: 'revoke' }],
},
],
} }
}, },
async created() { async created() {
@ -198,6 +151,12 @@ export default {
}, },
}, },
computed: { computed: {
operateTypeMap() {
return new Map([
['grant', this.$t('grant')],
['revoke', this.$t('acl.cancel')],
])
},
windowHeight() { windowHeight() {
return this.$store.state.windowHeight return this.$store.state.windowHeight
}, },
@ -207,6 +166,51 @@ export default {
tableDataLength() { tableDataLength() {
return this.tableData.length return this.tableData.length
}, },
permissionTableAttrList() {
return [
{
alias: this.$t('acl.date'),
is_choice: false,
name: 'datetime',
value_type: '3',
},
{
alias: this.$t('acl.operator'),
is_choice: true,
name: 'operate_uid',
value_type: '2',
choice_value: this.allUsers,
},
{
alias: this.$t('user'),
is_choice: true,
name: 'rid',
value_type: '2',
choice_value: this.allRoles,
},
{
alias: this.$t('acl.resourceType'),
is_choice: true,
name: 'resource_type_id',
value_type: '2',
choice_value: this.allResourceTypes,
},
{
alias: this.$t('acl.resource'),
is_choice: true,
name: 'resource_id',
value_type: '2',
choice_value: this.allResources,
},
{
alias: this.$t('operation'),
is_choice: true,
name: 'operate_type',
value_type: '2',
choice_value: [{ [this.$t('grant')]: 'grant' }, { [this.$t('acl.cancel')]: 'revoke' }],
},
]
},
}, },
methods: { methods: {
// 获取数据 // 获取数据

View File

@ -1,6 +1,6 @@
<template> <template>
<CustomDrawer <CustomDrawer
title="便捷授权" :title="$t('acl.convenient')"
width="500px" width="500px"
:maskClosable="false" :maskClosable="false"
:closable="true" :closable="true"
@ -10,12 +10,12 @@
<a-form :form="form"> <a-form :form="form">
<a-form-item> <a-form-item>
<div slot="label" style="display: inline-block"> <div slot="label" style="display: inline-block">
<span>角色列表</span> <span>{{ $t('acl.roleList') }}</span>
<a-divider type="vertical" /> <a-divider type="vertical" />
<a-switch <a-switch
style="display: inline-block" style="display: inline-block"
checked-children="用户" :checked-children="$t('user')"
un-checked-children="虚拟" :un-checked-children="$t('acl.virtual')"
@change="handleRoleTypeChange" @change="handleRoleTypeChange"
v-model="roleType" v-model="roleType"
/> />
@ -23,37 +23,37 @@
<el-select <el-select
:style="{ width: '100%' }" :style="{ width: '100%' }"
size="small" size="small"
v-decorator="['roleIdList', { rules: [{ required: true, message: '请选择角色名称' }] }]" v-decorator="['roleIdList', { rules: [{ required: true, message: $t('acl.role_placeholder2') }] }]"
multiple multiple
filterable filterable
placeholder="请选择角色名称,可多选!" :placeholder="$t('acl.role_placeholder3')"
> >
<el-option v-for="role in allRoles" :key="role.id" :value="role.id" :label="role.name"></el-option> <el-option v-for="role in allRoles" :key="role.id" :value="role.id" :label="role.name"></el-option>
</el-select> </el-select>
</a-form-item> </a-form-item>
<a-form-item label="权限列表"> <a-form-item :label="$t('acl.permissionList')">
<el-select <el-select
:style="{ width: '100%' }" :style="{ width: '100%' }"
size="small" size="small"
name="permName" name="permName"
v-decorator="['permName', { rules: [{ required: true, message: '请选择权限' }] }]" v-decorator="['permName', { rules: [{ required: true, message: this.$t('acl.permission_placeholder') }] }]"
multiple multiple
placeholder="请选择权限,可多选!" :placeholder="this.$t('acl.permission_placeholder')"
> >
<el-option v-for="perm in allPerms" :key="perm.name" :value="perm.name" :label="perm.name"></el-option> <el-option v-for="perm in allPerms" :key="perm.name" :value="perm.name" :label="perm.name"></el-option>
</el-select> </el-select>
</a-form-item> </a-form-item>
<a-form-item label="资源名"> <a-form-item :label="$t('acl.resourceName')">
<a-textarea <a-textarea
v-decorator="['resource_names', { rules: [{ required: true, message: '请输入资源名,换行分隔' }] }]" v-decorator="['resource_names', { rules: [{ required: true, message: $t('acl.resourceBatchTips') }] }]"
:autoSize="{ minRows: 4 }" :autoSize="{ minRows: 4 }"
placeholder="请输入资源名,换行分隔" :placeholder="$t('acl.resourceBatchTips')"
/> />
</a-form-item> </a-form-item>
<div class="custom-drawer-bottom-action"> <div class="custom-drawer-bottom-action">
<a-button @click="handleRevoke" type="danger" ghost>权限回收</a-button> <a-button @click="handleRevoke" type="danger" ghost>{{ $t('acl.revoke') }}</a-button>
<a-button @click="handleSubmit" type="primary">授权</a-button> <a-button @click="handleSubmit" type="primary">{{ $t('grant') }}</a-button>
</div> </div>
</a-form> </a-form>
</CustomDrawer> </CustomDrawer>
@ -98,12 +98,12 @@ export default {
this.loadRoles(Number(target)) this.loadRoles(Number(target))
}, },
loadRoles(isUserRole) { loadRoles(isUserRole) {
searchRole({ page_size: 9999, app_id: this.$route.name.split('_')[0], user_role: isUserRole }).then(res => { searchRole({ page_size: 9999, app_id: this.$route.name.split('_')[0], user_role: isUserRole }).then((res) => {
this.allRoles = res.roles this.allRoles = res.roles
}) })
}, },
loadPerm(resourceTypeId) { loadPerm(resourceTypeId) {
getResourceTypePerms(resourceTypeId).then(res => { getResourceTypePerms(resourceTypeId).then((res) => {
this.allPerms = res this.allPerms = res
}) })
}, },
@ -111,13 +111,13 @@ export default {
this.form.validateFields((err, values) => { this.form.validateFields((err, values) => {
if (!err) { if (!err) {
console.log(values) console.log(values)
values.roleIdList.forEach(roleId => { values.roleIdList.forEach((roleId) => {
setBatchRoleResourceByResourceName(roleId, { setBatchRoleResourceByResourceName(roleId, {
resource_names: values.resource_names.split('\n'), resource_names: values.resource_names.split('\n'),
perms: values.permName, perms: values.permName,
resource_type_id: this.resource_type_id, resource_type_id: this.resource_type_id,
}).then(res => { }).then((res) => {
this.$message.success('授权成功') this.$message.success(this.$t('operateSuccess'))
this.form.resetFields() this.form.resetFields()
}) })
}) })
@ -128,13 +128,13 @@ export default {
this.form.validateFields((err, values) => { this.form.validateFields((err, values) => {
if (!err) { if (!err) {
console.log(values) console.log(values)
values.roleIdList.forEach(roleId => { values.roleIdList.forEach((roleId) => {
setBatchRoleResourceRevokeByResourceName(roleId, { setBatchRoleResourceRevokeByResourceName(roleId, {
resource_names: values.resource_names.split('\n'), resource_names: values.resource_names.split('\n'),
perms: values.permName, perms: values.permName,
resource_type_id: this.resource_type_id, resource_type_id: this.resource_type_id,
}).then(res => { }).then((res) => {
this.$message.success('权限回收成功') this.$message.success(this.$t('operateSuccess'))
this.form.resetFields() this.form.resetFields()
}) })
}) })

View File

@ -8,27 +8,27 @@
width="30%" width="30%"
> >
<a-form :form="form" @submit="handleSubmit" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }"> <a-form :form="form" @submit="handleSubmit" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
<a-form-item label="资源名"> <a-form-item :label="$t('acl.resourceName')">
<a-input <a-input
name="name" name="name"
placeholder="" placeholder=""
v-decorator="['name', { rules: [{ required: true, message: '请输入资源名' }] }]" v-decorator="['name', { rules: [{ required: true, message: $t('acl.resourceNameInput') }] }]"
/> />
</a-form-item> </a-form-item>
<a-form-item label="资源类型"> <a-form-item :label="$t('acl.resourceType')">
<a-select v-model="selectedTypeId"> <a-select v-model="selectedTypeId">
<a-select-option v-for="type in allTypes" :key="type.id">{{ type.name }}</a-select-option> <a-select-option v-for="type in allTypes" :key="type.id">{{ type.name }}</a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-item>
<a-form-item label="是否组"> <a-form-item :label="$t('acl.isGroup')">
<a-radio-group v-model="isGroup"> <a-radio-group v-model="isGroup">
<a-radio :value="true"> <a-radio :value="true">
{{ $t('yes') }}
</a-radio> </a-radio>
<a-radio :value="false"> <a-radio :value="false">
{{ $t('no') }}
</a-radio> </a-radio>
</a-radio-group> </a-radio-group>
</a-form-item> </a-form-item>
@ -36,8 +36,8 @@
<a-input name="id" type="hidden" v-decorator="['id', { rules: [] }]" /> <a-input name="id" type="hidden" v-decorator="['id', { rules: [] }]" />
</a-form-item> </a-form-item>
<div class="custom-drawer-bottom-action"> <div class="custom-drawer-bottom-action">
<a-button @click="onClose">取消</a-button> <a-button @click="onClose">{{ $t('cancel') }}</a-button>
<a-button @click="handleSubmit" type="primary">确定</a-button> <a-button @click="handleSubmit" type="primary">{{ $t('confirm') }}</a-button>
</div> </div>
</a-form> </a-form>
</CustomDrawer> </CustomDrawer>
@ -52,7 +52,6 @@ export default {
name: 'ResourceForm', name: 'ResourceForm',
data() { data() {
return { return {
drawerTitle: '新增资源',
drawerVisible: false, drawerVisible: false,
allTypes: [], allTypes: [],
isGroup: false, isGroup: false,
@ -68,7 +67,11 @@ export default {
this.getAllResourceTypes() this.getAllResourceTypes()
}, },
computed: {}, computed: {
drawerTitle() {
return this.$t('acl.addResource')
},
},
mounted() {}, mounted() {},
methods: { methods: {
getAllResourceTypes() { getAllResourceTypes() {
@ -95,7 +98,7 @@ export default {
values.type_id = this.selectedTypeId values.type_id = this.selectedTypeId
values.app_id = this.$route.name.split('_')[0] values.app_id = this.$route.name.split('_')[0]
if (values.id) { if (values.id) {
this.$message.error('错误提示') this.$message.error(this.$t('acl.errorTips'))
} else { } else {
this.createResource(values) this.createResource(values)
} }
@ -105,23 +108,17 @@ export default {
createResource(data) { createResource(data) {
if (!this.isGroup) { if (!this.isGroup) {
addResource(data).then((res) => { addResource(data).then((res) => {
this.$message.success(`添加成功`) this.$message.success(this.$t('addSuccess'))
this.onClose() this.onClose()
}) })
// .catch(err => this.requestFailed(err)) // .catch(err => this.requestFailed(err))
} else { } else {
addResourceGroup(data).then((res) => { addResourceGroup(data).then((res) => {
this.$message.success(`添加成功`) this.$message.success(this.$t('addSuccess'))
this.onClose() this.onClose()
}) })
// .catch(err => this.requestFailed(err))
} }
}, },
// requestFailed(err) {
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
// this.$message.error(`${msg}`)
// },
}, },
watch: { watch: {
'$route.name': function(newValue, oldValue) { '$route.name': function(newValue, oldValue) {

View File

@ -1,5 +1,5 @@
<template> <template>
<a-modal v-model="visible" :title="`组成员:${editRecord.name}`" :width="800" :footer="null"> <a-modal v-model="visible" :title="`${$t('acl.groupMember')}${editRecord.name}`" :width="800" :footer="null">
<div :style="{ maxHeight: '500px', overflow: 'auto' }"> <div :style="{ maxHeight: '500px', overflow: 'auto' }">
<a-tag :style="{ marginBottom: '5px' }" v-for="mem in members" :key="mem.name"> <a-tag :style="{ marginBottom: '5px' }" v-for="mem in members" :key="mem.name">
{{ mem.name }} {{ mem.name }}

View File

@ -1,5 +1,5 @@
<template> <template>
<a-modal v-model="visible" :title="`成员管理:${editRecord.name}`" @ok="handleSubmit" :width="690"> <a-modal v-model="visible" :title="`${$t('acl.memberManage')}${editRecord.name}`" @ok="handleSubmit" :width="690">
<!-- <CustomTransfer <!-- <CustomTransfer
ref="customTransfer" ref="customTransfer"
:show-search="true" :show-search="true"
@ -26,7 +26,7 @@
@selectChange="selectChange" @selectChange="selectChange"
:selectedKeys="selectedKeys" :selectedKeys="selectedKeys"
> >
<span slot="notFoundContent">暂无数据</span> <span slot="notFoundContent">{{ $t('noData') }}</span>
<template slot="children" slot-scope="{ props: { direction, filteredItems } }"> <template slot="children" slot-scope="{ props: { direction, filteredItems } }">
<div class="ant-transfer-list-content" v-if="direction === 'right'"> <div class="ant-transfer-list-content" v-if="direction === 'right'">
<div <div
@ -104,7 +104,7 @@ export default {
}) })
updateResourceGroup(this.editRecord['id'], { items: items.join(',') }).then(() => { updateResourceGroup(this.editRecord['id'], { items: items.join(',') }).then(() => {
this.visible = false this.visible = false
this.$message.success('更新成功!') this.$message.success(this.$t('updateSuccess'))
}) })
// .catch(err => this.$httpError(err)) // .catch(err => this.$httpError(err))
}, },

View File

@ -4,7 +4,7 @@
ref="child" ref="child"
:attrList="resourceTableAttrList" :attrList="resourceTableAttrList"
:hasSwitch="true" :hasSwitch="true"
switchValue="" :switchValue="$t('acl.group2')"
@onSwitchChange="onSwitchChange" @onSwitchChange="onSwitchChange"
@search="handleSearch" @search="handleSearch"
@searchFormReset="searchFormReset" @searchFormReset="searchFormReset"
@ -22,30 +22,30 @@
resizable resizable
:height="`${windowHeight - 310}px`" :height="`${windowHeight - 310}px`"
> >
<vxe-column field="created_at" width="144px" title="操作时间"></vxe-column> <vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')"></vxe-column>
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column> <vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
<vxe-column field="operate_type" width="80px" title="操作"> <vxe-column field="operate_type" width="100px" :title="$t('operation')">
<template #default="{ row }"> <template #default="{ row }">
<a-tag :color="handleTagColor(row.operate_type)"> <a-tag :color="handleTagColor(row.operate_type)">
{{ operateTypeMap.get(row.operate_type) }} {{ operateTypeMap.get(row.operate_type) }}
</a-tag> </a-tag>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="link_id" title="资源名"> <vxe-column field="link_id" :title="$t('acl.resourceName')">
<template #default="{ row }"> <template #default="{ row }">
<span> <span>
{{ row.current.name || row.origin.name }} {{ row.current.name || row.origin.name }}
</span> </span>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column title="描述"> <vxe-column :title="$t('desc')">
<template #default="{ row }"> <template #default="{ row }">
<p> <p>
{{ row.description }} {{ row.description }}
</p> </p>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="source" width="100px" title="来源"></vxe-column> <vxe-column field="source" width="100px" :title="$t('acl.source')"></vxe-column>
</vxe-table> </vxe-table>
<pager <pager
:current-page.sync="queryParams.page" :current-page.sync="queryParams.page"
@ -99,40 +99,6 @@ export default {
checked: false, checked: false,
tableData: [], tableData: [],
app_id: this.$route.name.split('_')[0], app_id: this.$route.name.split('_')[0],
resourceTableAttrList: [
{
alias: '日期',
is_choice: false,
name: 'datetime',
value_type: '3',
},
{
alias: '操作员',
is_choice: true,
name: 'operate_uid',
value_type: '2',
choice_value: this.allUsers,
},
{
alias: '操作',
is_choice: true,
name: 'operate_type',
value_type: '2',
choice_value: [{ 新建: 'create' }, { 修改: 'update' }, { 删除: 'delete' }],
},
{
alias: '资源名',
is_choice: true,
name: 'link_id',
value_type: '2',
choice_value: this.allResources,
},
],
operateTypeMap: new Map([
['create', '新建'],
['update', '修改'],
['delete', '删除'],
]),
colorMap: new Map([ colorMap: new Map([
['create', 'green'], ['create', 'green'],
['update', 'orange'], ['update', 'orange'],
@ -170,9 +136,47 @@ export default {
windowHeight() { windowHeight() {
return this.$store.state.windowHeight return this.$store.state.windowHeight
}, },
operateTypeMap() {
return new Map([
['create', this.$t('create')],
['update', this.$t('update')],
['delete', this.$t('delete')],
])
},
tableDataLength() { tableDataLength() {
return this.tableData.length return this.tableData.length
}, },
resourceTableAttrList() {
return [
{
alias: this.$t('acl.date'),
is_choice: false,
name: 'datetime',
value_type: '3',
},
{
alias: this.$t('acl.operator'),
is_choice: true,
name: 'operate_uid',
value_type: '2',
choice_value: this.allUsers,
},
{
alias: this.$t('operation'),
is_choice: true,
name: 'operate_type',
value_type: '2',
choice_value: [{ [this.$t('create')]: 'create' }, { [this.$t('update')]: 'update' }, { [this.$t('delete')]: 'delete' }],
},
{
alias: this.$t('acl.resourceName'),
is_choice: true,
name: 'link_id',
value_type: '2',
choice_value: this.allResources,
},
]
},
}, },
methods: { methods: {
async getTable(queryParams) { async getTable(queryParams) {
@ -280,7 +284,7 @@ export default {
switch (operate_type) { switch (operate_type) {
// create // create
case 'create': { case 'create': {
item.description = `新建资源${item.current.name}` item.description = `${this.$t('acl.newResource')}${item.current.name}`
break break
} }
case 'update': { case 'update': {
@ -290,9 +294,9 @@ export default {
const oldVal = item.origin[key] const oldVal = item.origin[key]
if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') { if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') {
if (oldVal === null) { if (oldVal === null) {
item.description += ` ${key} : 改为 ${newVal} ` item.description += ` ${key} : -> ${newVal} `
} else { } else {
item.description += ` ${key} : ${oldVal} 改为 ${newVal} ` item.description += ` ${key} : ${oldVal} -> ${newVal} `
} }
} }
} }
@ -300,18 +304,18 @@ export default {
const currentResource_ids = item.currentResource_ids const currentResource_ids = item.currentResource_ids
if (!_.isEqual(originResource_ids, currentResource_ids)) { if (!_.isEqual(originResource_ids, currentResource_ids)) {
if (originResource_ids.length === 0) { if (originResource_ids.length === 0) {
const str = ` resource_ids : 新增 ${currentResource_ids} ` const str = ` resource_ids : ${this.$t('new')} ${currentResource_ids} `
item.description += str item.description += str
} else { } else {
const str = ` resource_ids : ${originResource_ids} 改为 ${currentResource_ids} ` const str = ` resource_ids : ${originResource_ids} -> ${currentResource_ids} `
item.description += str item.description += str
} }
} }
if (!item.description) item.description = '没有修改' if (!item.description) item.description = this.$t('acl.noChange')
break break
} }
case 'delete': { case 'delete': {
item.description = `删除资源${item.origin.name}` item.description = `${this.$t('acl.deleteResource')}${item.origin.name}`
break break
} }
} }

View File

@ -17,7 +17,7 @@
> >
<vxe-column <vxe-column
field="name" field="name"
title="角色名" :title="$t('acl.role')"
width="20%" width="20%"
:filters="[{ data: '' }]" :filters="[{ data: '' }]"
:filter-method="filterNameMethod" :filter-method="filterNameMethod"
@ -32,19 +32,19 @@
v-model="option.data" v-model="option.data"
@input="$panel.changeOption($event, !!option.data, option)" @input="$panel.changeOption($event, !!option.data, option)"
@keyup.enter="$panel.confirmFilter()" @keyup.enter="$panel.confirmFilter()"
placeholder="按回车确认筛选" :placeholder="$t('acl.pressEnter')"
/> />
</template> </template>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="users" title="下属用户" width="35%"> <vxe-column field="users" :title="$t('acl.subordinateUsers')" width="35%">
<template #default="{row}"> <template #default="{row}">
<a-tag color="green" v-for="user in row.users" :key="user.nickname"> <a-tag color="green" v-for="user in row.users" :key="user.nickname">
{{ user.nickname }} {{ user.nickname }}
</a-tag> </a-tag>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="perms" title="权限列表" width="35%"> <vxe-column field="perms" :title="$t('acl.permissionList')" width="35%">
<template #default="{row}"> <template #default="{row}">
<a-tag <a-tag
closable closable
@ -57,43 +57,18 @@
</a-tag> </a-tag>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="operate" title="批量操作"> <vxe-column field="operate" :title="$t('batchOperate')">
<template #default="{row}"> <template #default="{row}">
<a-button size="small" type="danger" @click="handleClearAll(row)"> <a-button size="small" type="danger" @click="handleClearAll(row)">
清空 {{ $t('clear') }}
</a-button> </a-button>
</template> </template>
</vxe-column> </vxe-column>
<template slot="empty"> <template slot="empty">
<img :src="require(`@/assets/data_empty.png`)" /> <img :src="require(`@/assets/data_empty.png`)" />
<p style="font-size: 14px; line-height: 17px; color: rgba(0, 0, 0, 0.6)">暂无数据</p> <p style="font-size: 14px; line-height: 17px; color: rgba(0, 0, 0, 0.6)">{{ $t('noData') }}</p>
</template> </template>
</vxe-table> </vxe-table>
<!-- <a-table
:columns="columns"
:dataSource="resPerms"
:rowKey="record => record.name"
:pagination="{ showTotal: (total, range) => `${range[0]}-${range[1]} 共 ${total} 条记录` }"
showPagination="auto"
ref="rTable"
size="middle"
>
<div slot="perms" slot-scope="text">
<a-tag closable color="cyan" v-for="perm in text" :key="perm.name" @close="deletePerm(perm.rid, perm.name)">
{{ perm.name }}
</a-tag>
</div>
<div slot="users" slot-scope="text">
<a-tag color="green" v-for="user in text" :key="user.nickname">
{{ user.nickname }}
</a-tag>
</div>
<div slot="operate" slot-scope="text">
<a-button size="small" type="danger" @click="handleClearAll(text)">
清空
</a-button>
</div>
</a-table> -->
</CustomDrawer> </CustomDrawer>
</template> </template>
<script> <script>
@ -112,40 +87,11 @@ export default {
data() { data() {
return { return {
isGroup: false, isGroup: false,
drawerTitle: '权限列表',
drawerVisible: false, drawerVisible: false,
record: null, record: null,
allPerms: [], allPerms: [],
resPerms: [], resPerms: [],
roleID: null, roleID: null,
// columns: [
// {
// title: '角色名',
// dataIndex: 'name',
// sorter: false,
// width: 50,
// },
// {
// title: '下属用户',
// dataIndex: 'users',
// sorter: false,
// width: 150,
// scopedSlots: { customRender: 'users' },
// },
// {
// title: '权限列表',
// dataIndex: 'perms',
// sorter: false,
// width: 150,
// scopedSlots: { customRender: 'perms' },
// },
// {
// title: '批量操作',
// sorter: false,
// width: 50,
// scopedSlots: { customRender: 'operate' },
// },
// ],
childrenDrawer: false, childrenDrawer: false,
allRoles: [], allRoles: [],
} }
@ -154,6 +100,9 @@ export default {
...mapState({ ...mapState({
windowHeight: (state) => state.windowHeight, windowHeight: (state) => state.windowHeight,
}), }),
drawerTitle() {
return this.$t('acl.permissionList')
}
}, },
beforeCreate() { beforeCreate() {
this.form = this.$form.createForm(this) this.form = this.$form.createForm(this)
@ -175,7 +124,7 @@ export default {
perms: [], perms: [],
app_id: this.$route.name.split('_')[0], app_id: this.$route.name.split('_')[0],
}).then((res) => { }).then((res) => {
this.$message.success('删除成功') this.$message.success(this.$t('deleteSuccess'))
this.$nextTick(() => { this.$nextTick(() => {
this.getResPerms(this.record.id) this.getResPerms(this.record.id)
}) })
@ -185,7 +134,7 @@ export default {
perms: [], perms: [],
app_id: this.$route.name.split('_')[0], app_id: this.$route.name.split('_')[0],
}).then((res) => { }).then((res) => {
this.$message.success('删除成功') this.$message.success(this.$t('deleteSuccess'))
// for (let i = 0; i < this.resPerms.length; i++) { // for (let i = 0; i < this.resPerms.length; i++) {
// if (this.resPerms[i].name === text.name) { // if (this.resPerms[i].name === text.name) {
// this.resPerms[i].perms = [] // this.resPerms[i].perms = []
@ -227,7 +176,7 @@ export default {
perms: [permName], perms: [permName],
app_id: this.$route.name.split('_')[0], app_id: this.$route.name.split('_')[0],
}).then((res) => { }).then((res) => {
this.$message.success(`删除成功`) this.$message.success(this.$t('deleteSuccess'))
}) })
// .catch(err => this.requestFailed(err)) // .catch(err => this.requestFailed(err))
} else { } else {
@ -235,18 +184,13 @@ export default {
perms: [permName], perms: [permName],
app_id: this.$route.name.split('_')[0], app_id: this.$route.name.split('_')[0],
}).then((res) => { }).then((res) => {
this.$message.success(`删除成功`) this.$message.success(this.$t('deleteSuccess'))
}) })
// .catch(err => this.requestFailed(err))
} }
}, },
handleCancel(e) { handleCancel(e) {
this.drawerVisible = false this.drawerVisible = false
}, },
// requestFailed(err) {
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
// this.$message.error(`${msg}`)
// },
filterNameMethod({ option, row }) { filterNameMethod({ option, row }) {
return row.name.toLowerCase().includes(option.data.toLowerCase()) return row.name.toLowerCase().includes(option.data.toLowerCase())
}, },

View File

@ -3,42 +3,42 @@
<a-form :form="form"> <a-form :form="form">
<a-form-item> <a-form-item>
<div slot="label" style="display: inline-block"> <div slot="label" style="display: inline-block">
<span>角色列表</span> <span>{{ $t('acl.roleList') }}</span>
<a-divider type="vertical" /> <a-divider type="vertical" />
<a-switch <a-switch
style="display: inline-block" style="display: inline-block"
checked-children="用户" :checked-children="$t('user')"
un-checked-children="虚拟" :un-checked-children="$t('acl.virtual')"
@change="handleRoleTypeChange" @change="handleRoleTypeChange"
/> />
</div> </div>
<el-select <el-select
:style="{ width: '100%' }" :style="{ width: '100%' }"
size="small" size="small"
v-decorator="['roleIdList', { rules: [{ required: true, message: '请选择角色名称' }] }]" v-decorator="['roleIdList', { rules: [{ required: true, message: $t('acl.role_placeholder2') }] }]"
multiple multiple
filterable filterable
placeholder="请选择角色名称,可多选!" :placeholder="$t('acl.role_placeholder3')"
> >
<el-option v-for="role in allRoles" :key="role.id" :value="role.id" :label="role.name"></el-option> <el-option v-for="role in allRoles" :key="role.id" :value="role.id" :label="role.name"></el-option>
</el-select> </el-select>
</a-form-item> </a-form-item>
<a-form-item label="权限列表"> <a-form-item :label="$t('acl.permissionList')">
<el-select <el-select
:style="{ width: '100%' }" :style="{ width: '100%' }"
size="small" size="small"
name="permName" name="permName"
v-decorator="['permName', { rules: [{ required: true, message: '请选择权限' }] }]" v-decorator="['permName', { rules: [{ required: true, message: $t('acl.permission_placeholder') }] }]"
multiple multiple
placeholder="请选择权限,可多选!" :placeholder="$t('acl.permission_placeholder') "
> >
<el-option v-for="perm in allPerms" :key="perm.name" :value="perm.name" :label="perm.name"></el-option> <el-option v-for="perm in allPerms" :key="perm.name" :value="perm.name" :label="perm.name"></el-option>
</el-select> </el-select>
</a-form-item> </a-form-item>
<div class="custom-drawer-bottom-action"> <div class="custom-drawer-bottom-action">
<a-button @click="closeForm">取消</a-button> <a-button @click="closeForm">{{ $t('cancel') }}</a-button>
<a-button @click="handleSubmit" type="primary" :loading="loading">确定</a-button> <a-button @click="handleSubmit" type="primary" :loading="loading">{{ $t('confirm') }}</a-button>
</div> </div>
</a-form> </a-form>
</CustomDrawer> </CustomDrawer>
@ -117,16 +117,12 @@ export default {
this.type = type this.type = type
if (Array.isArray(record)) { if (Array.isArray(record)) {
this.loadPerm(record[0]['resource_type_id']) this.loadPerm(record[0]['resource_type_id'])
this.title = `${type === 'grant' ? '批量授权' : '批量权限回收'}` this.title = `${type === 'grant' ? this.$t('acl.batchGrant') : this.$t('acl.batchRevoke')}`
} else { } else {
this.title = `添加授权${record.name}` this.title = `${this.$t('acl.editPerm')}${record.name}`
this.loadPerm(record['resource_type_id']) this.loadPerm(record['resource_type_id'])
} }
}, },
// requestFailed(err) {
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
// this.$message.error(`${msg}`)
// },
handleSubmit(e) { handleSubmit(e) {
e.preventDefault() e.preventDefault()
this.form.validateFields((err, values) => { this.form.validateFields((err, values) => {
@ -136,16 +132,10 @@ export default {
this.loading = true this.loading = true
if (!this.isGroup) { if (!this.isGroup) {
if (Array.isArray(this.instance)) { if (Array.isArray(this.instance)) {
// const promises = this.instance.map(item => {
// return setRoleResourcePerm(roleId, item.id, params)
// })
// Promise.all(promises).then(() => {
// this.$message.success('添加授权成功')
// })
if (this.type === 'grant') { if (this.type === 'grant') {
setBatchRoleResourcePerm(roleId, { ...params, resource_ids: this.instance.map((a) => a.id) }) setBatchRoleResourcePerm(roleId, { ...params, resource_ids: this.instance.map((a) => a.id) })
.then((res) => { .then((res) => {
this.$message.success('添加授权成功') this.$message.success(this.$t('operateSuccess'))
}) })
.finally(() => { .finally(() => {
this.loading = false this.loading = false
@ -153,7 +143,7 @@ export default {
} else { } else {
setBatchRoleResourceRevoke(roleId, { ...params, resource_ids: this.instance.map((a) => a.id) }) setBatchRoleResourceRevoke(roleId, { ...params, resource_ids: this.instance.map((a) => a.id) })
.then((res) => { .then((res) => {
this.$message.success('批量权限回收成功') this.$message.success(this.$t('operateSuccess'))
}) })
.finally(() => { .finally(() => {
this.loading = false this.loading = false
@ -162,7 +152,7 @@ export default {
} else { } else {
setRoleResourcePerm(roleId, this.instance.id, params) setRoleResourcePerm(roleId, this.instance.id, params)
.then((res) => { .then((res) => {
this.$message.success('添加授权成功') this.$message.success(this.$t('operateSuccess'))
}) })
.finally(() => { .finally(() => {
this.loading = false this.loading = false
@ -170,16 +160,10 @@ export default {
} }
} else { } else {
if (Array.isArray(this.instance)) { if (Array.isArray(this.instance)) {
// const promises = this.instance.map(item => {
// return setRoleResourceGroupPerm(roleId, item.id, params)
// })
// Promise.all(promises).then(() => {
// this.$message.success('添加授权成功')
// })
if (this.type === 'grant') { if (this.type === 'grant') {
setBatchRoleResourceGroupPerm(roleId, { ...params, group_ids: this.instance.map((a) => a.id) }) setBatchRoleResourceGroupPerm(roleId, { ...params, group_ids: this.instance.map((a) => a.id) })
.then((res) => { .then((res) => {
this.$message.success('添加授权成功') this.$message.success(this.$t('operateSuccess'))
}) })
.finally(() => { .finally(() => {
this.loading = false this.loading = false
@ -190,7 +174,7 @@ export default {
group_ids: this.instance.map((a) => a.id), group_ids: this.instance.map((a) => a.id),
}) })
.then((res) => { .then((res) => {
this.$message.success('批量权限回收成功') this.$message.success(this.$t('operateSuccess'))
}) })
.finally(() => { .finally(() => {
this.loading = false this.loading = false
@ -199,7 +183,7 @@ export default {
} else { } else {
setRoleResourceGroupPerm(roleId, this.instance.id, params) setRoleResourceGroupPerm(roleId, this.instance.id, params)
.then((res) => { .then((res) => {
this.$message.success('添加授权成功') this.$message.success(this.$t('operateSuccess'))
}) })
.finally(() => { .finally(() => {
this.loading = false this.loading = false

View File

@ -1,32 +1,32 @@
<template> <template>
<CustomDrawer <CustomDrawer
:closable="false" :closable="false"
:title="drawerTitle" :title="$t('acl.addReourceType')"
:visible="drawerVisible" :visible="drawerVisible"
@close="onClose" @close="onClose"
placement="right" placement="right"
width="500px" width="500px"
> >
<a-form :form="form" @submit="handleSubmit" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }"> <a-form :form="form" @submit="handleSubmit" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
<a-form-item label="类型名"> <a-form-item :label="$t('acl.typeName')">
<a-input <a-input
name="name" name="name"
placeholder="类型名称" :placeholder="$t('acl.typeName')"
v-decorator="['name', { rules: [{ required: true, message: '请输入类型名' }] }]" v-decorator="['name', { rules: [{ required: true, message: $t('acl.typeNameInput') }] }]"
/> />
</a-form-item> </a-form-item>
<a-form-item label="描述"> <a-form-item :label="$t('desc')">
<a-textarea <a-textarea
placeholder="请输入描述信息..." :placeholder="$t('acl.descInput')"
name="description" name="description"
:rows="4" :rows="4"
v-decorator="['description', { rules: [] }]" v-decorator="['description', { rules: [] }]"
/> />
</a-form-item> </a-form-item>
<a-form-item label="权限"> <a-form-item :label="$t('acl.permission')">
<a-select mode="tags" v-model="perms" style="width: 100%" placeholder="请输入权限名..."> </a-select> <a-select mode="tags" v-model="perms" style="width: 100%" :placeholder="$t('acl.permInput')"> </a-select>
</a-form-item> </a-form-item>
<a-form-item> <a-form-item>
@ -34,8 +34,8 @@
</a-form-item> </a-form-item>
<div class="custom-drawer-bottom-action"> <div class="custom-drawer-bottom-action">
<a-button @click="onClose">取消</a-button> <a-button @click="onClose">{{ $t('cancel') }}</a-button>
<a-button @click="handleSubmit" type="primary">确定</a-button> <a-button @click="handleSubmit" type="primary">{{ $t('confirm') }}</a-button>
</div> </div>
</a-form> </a-form>
</CustomDrawer> </CustomDrawer>
@ -48,7 +48,6 @@ export default {
name: 'ResourceForm', name: 'ResourceForm',
data() { data() {
return { return {
drawerTitle: '新增资源类型',
drawerVisible: false, drawerVisible: false,
perms: [], perms: [],
} }
@ -104,7 +103,7 @@ export default {
}, },
updateResourceType(id, data) { updateResourceType(id, data) {
updateResourceTypeById(id, data).then((res) => { updateResourceTypeById(id, data).then((res) => {
this.$message.success(`更新成功`) this.$message.success(this.$t('updateSuccess'))
this.handleOk() this.handleOk()
this.onClose() this.onClose()
}) })
@ -113,17 +112,11 @@ export default {
createResourceType(data) { createResourceType(data) {
addResourceType(data).then((res) => { addResourceType(data).then((res) => {
this.$message.success(`添加成功`) this.$message.success(this.$t('addSuccess'))
this.handleOk() this.handleOk()
this.onClose() this.onClose()
}) })
// .catch(err => this.requestFailed(err))
}, },
// requestFailed (err) {
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
// this.$message.error(`${msg}`)
// }
}, },
watch: {}, watch: {},
props: { props: {

View File

@ -16,30 +16,30 @@
:loading="loading" :loading="loading"
:height="`${windowHeight - 310}px`" :height="`${windowHeight - 310}px`"
> >
<vxe-column field="created_at" width="144px" title="操作时间"></vxe-column> <vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')"></vxe-column>
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column> <vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
<vxe-column field="operate_type" width="80px" title="操作"> <vxe-column field="operate_type" width="100px" :title="$t('operation')">
<template #default="{ row }"> <template #default="{ row }">
<a-tag :color="handleTagColor(row.operate_type)"> <a-tag :color="handleTagColor(row.operate_type)">
{{ operateTypeMap.get(row.operate_type) }} {{ operateTypeMap.get(row.operate_type) }}
</a-tag> </a-tag>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="link_id" title="资源类型名"> <vxe-column field="link_id" :title="$t('acl.resourceTypeName')">
<template #default="{ row }"> <template #default="{ row }">
<span> <span>
{{ row.current.name || row.origin.name }} {{ row.current.name || row.origin.name }}
</span> </span>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column title="描述"> <vxe-column :title="$t('desc')">
<template #default="{ row }"> <template #default="{ row }">
<p> <p>
{{ row.changeDescription }} {{ row.changeDescription }}
</p> </p>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="source" width="100px" title="来源"></vxe-column> <vxe-column field="source" width="100px" :title="$t('acl.source')"></vxe-column>
</vxe-table> </vxe-table>
<pager <pager
:current-page.sync="queryParams.page" :current-page.sync="queryParams.page"
@ -93,40 +93,6 @@ export default {
checked: false, checked: false,
tableData: [], tableData: [],
app_id: this.$route.name.split('_')[0], app_id: this.$route.name.split('_')[0],
resourceTableAttrList: [
{
alias: '日期',
is_choice: false,
name: 'datetime',
value_type: '3',
},
{
alias: '操作员',
is_choice: true,
name: 'operate_uid',
value_type: '2',
choice_value: this.allUsers,
},
{
alias: '操作',
is_choice: true,
name: 'operate_type',
value_type: '2',
choice_value: [{ 新建: 'create' }, { 修改: 'update' }, { 删除: 'delete' }],
},
{
alias: '资源类型',
is_choice: true,
name: 'link_id',
value_type: '2',
choice_value: this.allResourceTypes,
},
],
operateTypeMap: new Map([
['create', '新建'],
['update', '修改'],
['delete', '删除'],
]),
colorMap: new Map([ colorMap: new Map([
['create', 'green'], ['create', 'green'],
['update', 'orange'], ['update', 'orange'],
@ -155,12 +121,50 @@ export default {
}, },
}, },
computed: { computed: {
operateTypeMap() {
return new Map([
['create', this.$t('create')],
['update', this.$t('update')],
['delete', this.$t('delete')],
])
},
windowHeight() { windowHeight() {
return this.$store.state.windowHeight return this.$store.state.windowHeight
}, },
tableDataLength() { tableDataLength() {
return this.tableData.length return this.tableData.length
}, },
resourceTableAttrList() {
return [
{
alias: this.$t('acl.date'),
is_choice: false,
name: 'datetime',
value_type: '3',
},
{
alias: this.$t('acl.operator'),
is_choice: true,
name: 'operate_uid',
value_type: '2',
choice_value: this.allUsers,
},
{
alias: this.$t('operation'),
is_choice: true,
name: 'operate_type',
value_type: '2',
choice_value: [{ [this.$t('create')]: 'create' }, { [this.$t('update')]: 'update' }, { [this.$t('delete')]: 'delete' }],
},
{
alias: this.$t('acl.resourceType'),
is_choice: true,
name: 'link_id',
value_type: '2',
choice_value: this.allResourceTypes,
},
]
},
}, },
methods: { methods: {
async getTable(queryParams) { async getTable(queryParams) {
@ -236,7 +240,9 @@ export default {
switch (operate_type) { switch (operate_type) {
// create // create
case 'create': { case 'create': {
item.changeDescription = `新增资源类型${item.current.name}\n描述${item.current.description}\n权限${item.extra.permission_ids.current}` item.changeDescription = `${this.$t('acl.addReourceType')}${item.current.name}\n${this.$t('desc')}${
item.current.description
}\n${this.$t('acl.permission')}: ${item.extra.permission_ids.current}`
break break
} }
case 'update': { case 'update': {
@ -246,10 +252,10 @@ export default {
const oldVal = item.origin[key] const oldVal = item.origin[key]
if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') { if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') {
if (oldVal === null || oldVal === '') { if (oldVal === null || oldVal === '') {
const str = ` ${key} : 改为 ${newVal} \n` const str = ` ${key} : -> ${newVal} \n`
item.changeDescription += str item.changeDescription += str
} else { } else {
const str = ` ${key} : ${oldVal} 改为 ${newVal} \n` const str = ` ${key} : ${oldVal} -> ${newVal} \n`
item.changeDescription += str item.changeDescription += str
} }
} }
@ -257,13 +263,13 @@ export default {
const currentPerms = item.extra.permission_ids.current const currentPerms = item.extra.permission_ids.current
const originPerms = item.extra.permission_ids.origin const originPerms = item.extra.permission_ids.origin
if (!_.isEqual(currentPerms, originPerms)) { if (!_.isEqual(currentPerms, originPerms)) {
item.changeDescription += ` permission_ids : ${originPerms} 改为 ${currentPerms} ` item.changeDescription += ` permission_ids : ${originPerms} -> ${currentPerms} `
} }
if (!item.changeDescription) item.changeDescription = '没有修改' if (!item.changeDescription) item.changeDescription = this.$t('acl.noChange')
break break
} }
case 'delete': { case 'delete': {
item.changeDescription = `删除资源类型${item.origin.name}\n描述${item.origin.description}\n权限${item.extra.permission_ids.origin}` item.changeDescription = `${this.$t('acl.deleteResourceType')}${item.origin.name}\n${this.$t('desc')}: ${item.origin.description}\n${this.$t('acl.permission')}: ${item.extra.permission_ids.origin}`
break break
} }
} }

View File

@ -2,12 +2,12 @@
<CustomDrawer <CustomDrawer
width="800px" width="800px"
placement="left" placement="left"
title="资源列表" :title="$t('acl.resourceList')"
@close="handleCancel" @close="handleCancel"
:visible="visible" :visible="visible"
:hasFooter="false" :hasFooter="false"
> >
<a-form-item label="资源类型" :label-col="{ span: 2 }" :wrapper-col="{ span: 14 }"> <a-form-item :label="$t('acl.resourceType')" :label-col="{ span: 4 }" :wrapper-col="{ span: 14 }">
<a-select v-model="typeSelected" style="width:100%" @change="refresh"> <a-select v-model="typeSelected" style="width:100%" @change="refresh">
<a-select-option v-for="type in resourceTypes" :value="type.id" :key="type.id">{{ type.name }}</a-select-option> <a-select-option v-for="type in resourceTypes" :value="type.id" :key="type.id">{{ type.name }}</a-select-option>
</a-select> </a-select>
@ -22,7 +22,7 @@
> >
<vxe-column <vxe-column
field="name" field="name"
title="资源名" :title="$t('acl.resourceName')"
width="30%" width="30%"
:filters="[{ data: '' }]" :filters="[{ data: '' }]"
:filter-method="filterNameMethod" :filter-method="filterNameMethod"
@ -30,7 +30,7 @@
> >
<template #header="{ column }"> <template #header="{ column }">
<span>{{ column.title }}</span> <span>{{ column.title }}</span>
<a-tooltip title="复制资源名"> <a-tooltip :title="$t('acl.copyResource')">
<a-icon @click="copyResourceName" class="resource-user-form-copy" theme="filled" type="copy" /> <a-icon @click="copyResourceName" class="resource-user-form-copy" theme="filled" type="copy" />
</a-tooltip> </a-tooltip>
</template> </template>
@ -48,7 +48,7 @@
</template> </template>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="permissions" title="权限列表" width="70%"> <vxe-column field="permissions" :title="$t('acl.permissionList')" width="70%">
<template #default="{row}"> <template #default="{row}">
<a-tag color="cyan" v-for="(r, index) in row.permissions" :key="index">{{ r }}</a-tag> <a-tag color="cyan" v-for="(r, index) in row.permissions" :key="index">{{ r }}</a-tag>
</template> </template>
@ -58,69 +58,6 @@
<p style="font-size: 14px; line-height: 17px; color: rgba(0, 0, 0, 0.6)">暂无数据</p> <p style="font-size: 14px; line-height: 17px; color: rgba(0, 0, 0, 0.6)">暂无数据</p>
</template> </template>
</vxe-table> </vxe-table>
<!-- <a-table
:columns="columns"
:dataSource="records"
:rowKey="record => record.id"
:pagination="false"
ref="rTable"
size="middle"
:scroll="{ y: 300 }"
> -->
<!-- <div slot="filterDropdown" slot-scope="{ setSelectedKeys, selectedKeys, confirm, clearFilters, column }" class="custom-filter-dropdown">
<a-input
v-ant-ref="c => searchInput = c"
:placeholder="` ${column.title}`"
:value="selectedKeys[0]"
@change="e => setSelectedKeys(e.target.value ? [e.target.value] : [])"
@pressEnter="() => handleSearch(selectedKeys, confirm, column)"
style="width: 188px; margin-bottom: 8px; display: block;"
/>
<a-button
type="primary"
@click="() => handleSearch(selectedKeys, confirm, column)"
icon="search"
size="small"
style="width: 90px; margin-right: 8px"
>搜索</a-button>
<a-button
@click="() => handleReset(clearFilters, column)"
size="small"
style="width: 90px"
>重置</a-button>
</div>
<a-icon slot="filterIcon" slot-scope="filtered" type="search" :style="{ color: filtered ? '#108ee9' : undefined }" />
<template slot="nameSearchRender" slot-scope="text">
<span v-if="columnSearchText.name">
<template v-for="(fragment, i) in text.toString().split(new RegExp(`(?<=${columnSearchText.name})|(?=${columnSearchText.name})`, 'i'))">
<mark v-if="fragment.toLowerCase() === columnSearchText.name.toLowerCase()" :key="i" class="highlight">{{ fragment }}</mark>
<template v-else>{{ fragment }}</template>
</template>
</span>
<template v-else>{{ text }}</template>
</template> -->
<!-- <template slot="permissions" slot-scope="record">
<a-tag color="cyan" v-for="(r, index) in record" :key="index">{{ r }}</a-tag>
</template>
</a-table> -->
<!-- <div
:style="{
position: 'absolute',
left: 0,
bottom: 0,
width: '100%',
borderTop: '1px solid #e9e9e9',
padding: '10px 16px',
background: '#fff',
textAlign: 'right',
}"
>
<a-button :style="{marginRight: '8px'}" @click="handleCancel">
取消
</a-button>
<a-button @click="handleOk" type="primary">确定</a-button>
</div> -->
</CustomDrawer> </CustomDrawer>
</template> </template>
<script> <script>
@ -141,33 +78,6 @@ export default {
name: '', name: '',
}, },
filterName: '', filterName: '',
// columns: [
// {
// title: '资源名',
// field: 'name',
// sorter: false,
// width: '30%',
// // scopedSlots: {
// // customRender: 'nameSearchRender',
// // filterDropdown: 'filterDropdown',
// // filterIcon: 'filterIcon'
// // },
// // onFilter: (value, record) => record.name && record.name.toLowerCase().includes(value.toLowerCase()),
// // onFilterDropdownVisibleChange: (visible) => {
// // if (visible) {
// // setTimeout(() => {
// // this.searchInput.focus()
// // }, 0)
// // }
// // }
// },
// {
// title: '权限列表',
// field: 'permissions',
// width: '70%',
// slots: { default: 'permissions_default' },
// },
// ],
} }
}, },
computed: { computed: {
@ -184,14 +94,6 @@ export default {
this.rid = record.id this.rid = record.id
this.refresh() this.refresh()
}, },
// handleSearch(selectedKeys, confirm, column) {
// confirm()
// this.columnSearchText[column.dataIndex] = selectedKeys[0]
// },
// handleReset(clearFilters, column) {
// clearFilters()
// this.columnSearchText[column.dataIndex] = ''
// },
loadResourceTypes() { loadResourceTypes() {
this.resourceTypes = [] this.resourceTypes = []
const appId = this.$route.name.split('_')[0] const appId = this.$route.name.split('_')[0]
@ -204,7 +106,6 @@ export default {
this.typeSelected = null this.typeSelected = null
} }
}) })
// .catch(err => this.$httpError(err))
}, },
handleOk() { handleOk() {
this.visible = false this.visible = false
@ -217,7 +118,6 @@ export default {
}).then(res => { }).then(res => {
this.records = res.resources this.records = res.resources
}) })
// .catch(err=>this.$httpError(err))
} }
}, },
handleCancel() { handleCancel() {
@ -238,7 +138,7 @@ export default {
.join('\n') .join('\n')
this.copy(val, () => { this.copy(val, () => {
this.$message.success('复制成功') this.$message.success(this.$t('copySuccess'))
}) })
}, },
copy(value, cb) { copy(value, cb) {

View File

@ -8,40 +8,29 @@
width="500px" width="500px"
> >
<a-form :form="form" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }" @submit="handleSubmit"> <a-form :form="form" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }" @submit="handleSubmit">
<a-form-item label="角色名"> <a-form-item :label="$t('acl.role')">
<a-input <a-input
name="name" name="name"
placeholder="角色名" :placeholder="$t('acl.role_placeholder1')"
v-decorator="['name', { rules: [{ required: true, message: '请输入角色名' }] }]" v-decorator="['name', { rules: [{ required: true, message: $t('acl.role_placeholder1') }] }]"
/> />
</a-form-item> </a-form-item>
<a-form-item v-if="$route.name.split('_')[0] !== 'acl'" label="密码"> <a-form-item v-if="$route.name.split('_')[0] !== 'acl'" :label="$t('acl.password')">
<a-input name="password" placeholder="密码" v-decorator="['password', { rules: [{ required: false }] }]" /> <a-input name="password" :placeholder="$t('acl.password')" v-decorator="['password', { rules: [{ required: false }] }]" />
</a-form-item> </a-form-item>
<!-- <a-form-item label="继承自"> <a-form-item :label="$t('acl.inheritedFrom')">
<a-select
showSearch
v-model="selectedParents"
:filterOption="false"
placeholder="可选择继承角色"
mode="multiple"
>
<a-select-option v-for="role in scrollData" :key="role.id">{{ role.name }}</a-select-option>
</a-select>
</a-form-item> -->
<a-form-item label="继承自">
<el-select <el-select
:style="{ width: '100%' }" :style="{ width: '100%' }"
size="small" size="small"
v-model="selectedParents" v-model="selectedParents"
multiple multiple
filterable filterable
placeholder="可选择继承角色" :placeholder="$t('acl.selectedParents')"
> >
<el-option v-for="role in allRoles" :key="role.id" :value="role.id" :label="role.name"></el-option> <el-option v-for="role in allRoles" :key="role.id" :value="role.id" :label="role.name"></el-option>
</el-select> </el-select>
</a-form-item> </a-form-item>
<a-form-item label="是否应用管理员"> <a-form-item :label="$t('acl.isAppAdmin')">
<a-switch <a-switch
@change="onChange" @change="onChange"
name="is_app_admin" name="is_app_admin"
@ -53,8 +42,8 @@
</a-form-item> </a-form-item>
<div class="custom-drawer-bottom-action"> <div class="custom-drawer-bottom-action">
<a-button @click="onClose">取消</a-button> <a-button @click="onClose">{{ $t('cancel') }}</a-button>
<a-button @click="handleSubmit" type="primary">确定</a-button> <a-button @click="handleSubmit" type="primary">{{ $t('confirm') }}</a-button>
</div> </div>
</a-form> </a-form>
</CustomDrawer> </CustomDrawer>
@ -93,7 +82,7 @@ export default {
// return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0 // return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
// }, // },
handleCreate() { handleCreate() {
this.drawerTitle = '新增角色' this.drawerTitle = this.$t('acl.addRole')
this.drawerVisible = true this.drawerVisible = true
}, },
onClose() { onClose() {
@ -107,7 +96,7 @@ export default {
}, },
handleEdit(record) { handleEdit(record) {
this.drawerTitle = `编辑${record.name}` this.drawerTitle = `${this.$t('edit')}: ${record.name}`
this.drawerVisible = true this.drawerVisible = true
this.current_id = record.id this.current_id = record.id
const _parents = this.id2parents[record.id] const _parents = this.id2parents[record.id]
@ -142,7 +131,7 @@ export default {
updateRole(id, data) { updateRole(id, data) {
this.updateParents(id) this.updateParents(id)
updateRoleById(id, { ...data, app_id: this.$route.name.split('_')[0] }).then((res) => { updateRoleById(id, { ...data, app_id: this.$route.name.split('_')[0] }).then((res) => {
this.$message.success(`更新成功`) this.$message.success(this.$t('updateSuccess'))
this.handleOk() this.handleOk()
this.onClose() this.onClose()
}) })
@ -151,7 +140,7 @@ export default {
createRole(data) { createRole(data) {
addRole({ ...data, app_id: this.$route.name.split('_')[0] }).then((res) => { addRole({ ...data, app_id: this.$route.name.split('_')[0] }).then((res) => {
this.$message.success(`添加成功`) this.$message.success(this.$t('addSuccess'))
this.updateParents(res.id) this.updateParents(res.id)
this.handleOk() this.handleOk()
this.onClose() this.onClose()
@ -171,16 +160,9 @@ export default {
child_ids: [id], child_ids: [id],
app_id: this.$route.name.split('_')[0], app_id: this.$route.name.split('_')[0],
}) })
// addParentRole(id, item, { app_id: this.$route.name.split('_')[0] })
// .catch(err => this.requestFailed(err))
} }
}) })
}, },
// requestFailed(err) {
// console.log(err)
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
// this.$message.error(`${msg}`)
// },
}, },
watch: {}, watch: {},
props: { props: {

View File

@ -4,7 +4,7 @@
ref="child" ref="child"
:attrList="roleTableAttrList" :attrList="roleTableAttrList"
:hasSwitch="true" :hasSwitch="true"
switchValue="角色关系" :switchValue="$t('acl.roleRelation')"
@onSwitchChange="onSwitchChange" @onSwitchChange="onSwitchChange"
@search="handleSearch" @search="handleSearch"
@searchFormReset="searchFormReset" @searchFormReset="searchFormReset"
@ -19,16 +19,16 @@
resizable resizable
:height="`${windowHeight - 310}px`" :height="`${windowHeight - 310}px`"
> >
<vxe-column field="created_at" width="144px" title="操作时间"></vxe-column> <vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')"></vxe-column>
<vxe-column field="operate_uid" title="操作员" width="130px"></vxe-column> <vxe-column field="operate_uid" :title="$t('acl.operator')" width="130px"></vxe-column>
<vxe-column field="operate_type" title="操作" width="112px"> <vxe-column field="operate_type" :title="$t('operation')" width="112px">
<template #default="{ row }"> <template #default="{ row }">
<template> <template>
<a-tag :color="handleTagColor(row.operate_type)">{{ operateTypeMap.get(row.operate_type) }}</a-tag> <a-tag :color="handleTagColor(row.operate_type)">{{ operateTypeMap.get(row.operate_type) }}</a-tag>
</template> </template>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column :title="checked ? '角色' : '角色'"> <vxe-column :title="checked ? $t('acl.role2') : $t('acl.role2')">
<template #default="{ row }"> <template #default="{ row }">
<template v-if="!checked"> <template v-if="!checked">
<a-tag color="blue">{{ row.current.name || row.origin.name }}</a-tag> <a-tag color="blue">{{ row.current.name || row.origin.name }}</a-tag>
@ -40,7 +40,7 @@
</template> </template>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column :title="checked ? '继承自' : '管理员'" :width="checked ? '350px' : '80px'"> <vxe-column :title="checked ? $t('acl.inheritedFrom') : $t('acl.admin')" :width="checked ? '350px' : '80px'">
<template #default="{ row }"> <template #default="{ row }">
<template v-if="!checked"> <template v-if="!checked">
<a-icon type="check" v-if="row.current.is_app_admin" /> <a-icon type="check" v-if="row.current.is_app_admin" />
@ -52,14 +52,14 @@
</template> </template>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column title="描述" v-if="!checked"> <vxe-column :title="$t('desc')" v-if="!checked">
<template #default="{ row }"> <template #default="{ row }">
<p> <p>
{{ row.description }} {{ row.description }}
</p> </p>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="source" title="来源" width="100px"></vxe-column> <vxe-column field="source" :title="$t('acl.source')" width="100px"></vxe-column>
</vxe-table> </vxe-table>
<pager <pager
:current-page.sync="queryParams.page" :current-page.sync="queryParams.page"
@ -105,13 +105,6 @@ export default {
checked: false, checked: false,
tableData: [], tableData: [],
app_id: this.$route.name.split('_')[0], app_id: this.$route.name.split('_')[0],
operateTypeMap: new Map([
['create', '新建'],
['delete', '删除'],
['update', '修改'],
['role_relation_add', '添加角色关系'],
['role_relation_delete', '删除角色关系'],
]),
colorMap: new Map([ colorMap: new Map([
['create', 'green'], ['create', 'green'],
['delete', 'red'], ['delete', 'red'],
@ -127,42 +120,53 @@ export default {
start: '', start: '',
end: '', end: '',
}, },
roleTableAttrList: [ }
},
computed: {
operateTypeMap() {
return new Map([
['create', this.$t('create')],
['update', this.$t('update')],
['delete', this.$t('delete')],
['role_relation_add', this.$t('acl.roleRelationAdd')],
['role_relation_delete', this.$t('acl.roleRelationDelete')],
])
},
windowHeight() {
return this.$store.state.windowHeight
},
tableDataLength() {
return this.tableData.length
},
roleTableAttrList() {
return [
{ {
alias: '日期', alias: this.$t('acl.date'),
is_choice: false, is_choice: false,
name: 'datetime', name: 'datetime',
value_type: '3', value_type: '3',
}, },
{ {
alias: '操作员', alias: this.$t('acl.operator'),
is_choice: true, is_choice: true,
name: 'operate_uid', name: 'operate_uid',
value_type: '2', value_type: '2',
choice_value: this.allUsers, choice_value: this.allUsers,
}, },
{ {
alias: '操作', alias: this.$t('operation'),
is_choice: true, is_choice: true,
name: 'operate_type', name: 'operate_type',
value_type: '2', value_type: '2',
choice_value: [ choice_value: [
{ 新建: 'create' }, { [this.$t('create')]: 'create' },
{ 修改: 'update' }, { [this.$t('update')]: 'update' },
{ 删除: 'delete' }, { [this.$t('delete')]: 'delete' },
{ 添加角色关系: 'role_relation_add' }, { [this.$t('acl.roleRelationAdd')]: 'role_relation_add' },
{ 删除角色关系: 'role_relation_delete' }, { [this.$t('acl.roleRelationDelete')]: 'role_relation_delete' },
], ],
}, },
], ]
}
},
computed: {
windowHeight() {
return this.$store.state.windowHeight
},
tableDataLength() {
return this.tableData.length
}, },
}, },
async created() { async created() {
@ -273,7 +277,7 @@ export default {
switch (operate_type) { switch (operate_type) {
// create // create
case 'create': { case 'create': {
item.description = `新建角色${item.current.name}` item.description = `${this.$t('acl.addRole')}${item.current.name}`
break break
} }
case 'update': { case 'update': {
@ -283,15 +287,15 @@ export default {
const oldVal = item.origin[key] const oldVal = item.origin[key]
if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') { if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') {
if (oldVal === null) { if (oldVal === null) {
const str = ` ${key} : 改为 ${newVal} ` const str = ` ${key} : -> ${newVal} `
item.description += str item.description += str
} else { } else {
const str = ` ${key} : ${oldVal} 改为 ${newVal} ` const str = ` ${key} : ${oldVal} -> ${newVal} `
item.description += str item.description += ` ${key} : ${oldVal} -> ${newVal} `
} }
} }
} }
if (!item.description) item.description = '没有修改' if (!item.description) item.description = this.$t('acl.noChange')
break break
} }
case 'delete': { case 'delete': {
@ -321,7 +325,7 @@ export default {
resourceMap.forEach((value, key) => { resourceMap.forEach((value, key) => {
permsArr.push(`${id2resources[key].name}${value}`) permsArr.push(`${id2resources[key].name}${value}`)
}) })
item.description = `继承者${child_ids}\n继承自${parent_ids}\n涉及资源及权限\n${permsArr.join(`\n`)}` item.description = `${this.$t('acl.heir')}${child_ids}\n${this.$t('acl.inheritedFrom')}${parent_ids}\n${this.$t('acl.involvingRP')}\n${permsArr.join(`\n`)}`
break break
} }
} }

View File

@ -19,7 +19,7 @@
@popupScroll="loadMoreData(attr.name, $event)" @popupScroll="loadMoreData(attr.name, $event)"
@search="(value) => fetchData(value, attr.name)" @search="(value) => fetchData(value, attr.name)"
v-model="queryParams[attr.name]" v-model="queryParams[attr.name]"
placeholder="请选择" :placeholder="$t('placeholder2')"
v-if="attr.is_choice" v-if="attr.is_choice"
show-search show-search
:filter-option="filterOption" :filter-option="filterOption"
@ -38,7 +38,6 @@
@change="onChange" @change="onChange"
:style="{ width: '100%' }" :style="{ width: '100%' }"
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
:placeholder="['开始时间', '结束时间']"
:show-time="{ :show-time="{
hideDisabledOptions: true, hideDisabledOptions: true,
defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')], defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
@ -67,7 +66,7 @@
@popupScroll="loadMoreData(item.name, $event)" @popupScroll="loadMoreData(item.name, $event)"
@search="(value) => fetchData(value, item.name)" @search="(value) => fetchData(value, item.name)"
v-model="queryParams[item.name]" v-model="queryParams[item.name]"
placeholder="请选择" :placeholder="$t('placeholder2')"
v-if="item.is_choice" v-if="item.is_choice"
show-search show-search
:filter-option="filterOption" :filter-option="filterOption"
@ -85,7 +84,7 @@
:style="{ width: '100%' }" :style="{ width: '100%' }"
@change="onChange" @change="onChange"
format="YYYY-MM-DD HH:mm" format="YYYY-MM-DD HH:mm"
:placeholder="['开始时间', '结束时间']" :placeholder="[$t('acl.startAt'), $t('acl.endAt')]"
v-else-if="valueTypeMap[item.value_type] == 'date' || valueTypeMap[item.value_type] == 'datetime'" v-else-if="valueTypeMap[item.value_type] == 'date' || valueTypeMap[item.value_type] == 'datetime'"
:show-time="{ :show-time="{
hideDisabledOptions: true, hideDisabledOptions: true,
@ -107,13 +106,13 @@
v-model="checked" v-model="checked"
/> />
<a-button :style="{ marginLeft: '8px' }" type="primary" html-type="submit" @click="handleSearch"> <a-button :style="{ marginLeft: '8px' }" type="primary" html-type="submit" @click="handleSearch">
查询 {{ $t('query') }}
</a-button> </a-button>
<a-button :style="{ marginLeft: '8px' }" @click="handleReset"> <a-button :style="{ marginLeft: '8px' }" @click="handleReset">
重置 {{ $t('reset') }}
</a-button> </a-button>
<a :style="{ marginLeft: '8px', fontSize: '12px' }" @click="toggle" v-if="attrList.length >= 5"> <a :style="{ marginLeft: '8px', fontSize: '12px' }" @click="toggle" v-if="attrList.length >= 5">
{{ expand ? '隐藏' : '展开' }} <a-icon :type="expand ? 'up' : 'down'" /> {{ expand ? $t('expand') : $t('expand') }} <a-icon :type="expand ? 'up' : 'down'" />
</a> </a>
</a-col> </a-col>
</a-row> </a-row>

View File

@ -2,30 +2,30 @@
<CustomDrawer <CustomDrawer
@close="handleClose" @close="handleClose"
width="500" width="500"
:title="`${triggerId ? '修改' : '新建'}触发器`" :title="`${triggerId ? $t('update') : $t('create')}${$t('acl.trigger')}`"
:visible="visible" :visible="visible"
:maskClosable="false" :maskClosable="false"
> >
<a-form :form="form" :label-col="{ span: 6 }" :wrapper-col="{ span: 15 }"> <a-form :form="form" :label-col="{ span: 6 }" :wrapper-col="{ span: 15 }">
<a-form-item label="触发器名"> <a-form-item :label="$t('name')">
<a-input size="large" v-decorator="['name', { rules: [{ required: true, message: '请输入触发器名' }] }]"> <a-input size="large" v-decorator="['name', { rules: [{ required: true, message: $t('acl.triggerNameInput') }] }]">
</a-input> </a-input>
</a-form-item> </a-form-item>
<a-form-item label="资源名"> <a-form-item :label="$t('acl.resourceName')">
<a-input size="large" v-decorator="['wildcard']" placeholder="优先正则模式(次通配符)"> </a-input> <a-input size="large" v-decorator="['wildcard']" :placeholder="$t('acl.triggerTips1')"> </a-input>
</a-form-item> </a-form-item>
<a-form-item label="创建人"> <a-form-item :label="$t('acl.creator')">
<el-select :style="{ width: '100%' }" filterable multiple v-decorator="['uid']"> <el-select :style="{ width: '100%' }" filterable multiple v-decorator="['uid']">
<template v-for="role in roles"> <template v-for="role in roles">
<el-option v-if="role.uid" :key="role.id" :value="role.uid" :label="role.name">{{ role.name }}</el-option> <el-option v-if="role.uid" :key="role.id" :value="role.uid" :label="role.name">{{ role.name }}</el-option>
</template> </template>
</el-select> </el-select>
</a-form-item> </a-form-item>
<a-form-item label="资源类型"> <a-form-item :label="$t('acl.resourceType')">
<el-select <el-select
:style="{ width: '100%' }" :style="{ width: '100%' }"
@change="handleRTChange" @change="handleRTChange"
v-decorator="['resource_type_id', { rules: [{ required: true, message: '请选择资源类型' }] }]" v-decorator="['resource_type_id', { rules: [{ required: true, message: $t('acl.pleaseSelectType') }] }]"
> >
<el-option <el-option
v-for="resourceType in resourceTypeList" v-for="resourceType in resourceTypeList"
@ -34,25 +34,25 @@
:label="resourceType.name" :label="resourceType.name"
></el-option> ></el-option>
</el-select> </el-select>
<a-tooltip title="查看正则匹配结果"> <a-tooltip :title="$t('acl.viewMatchResult')">
<a class="trigger-form-pattern" @click="handlePattern"><a-icon type="eye"/></a> <a class="trigger-form-pattern" @click="handlePattern"><a-icon type="eye"/></a>
</a-tooltip> </a-tooltip>
</a-form-item> </a-form-item>
<a-form-item label="角色"> <a-form-item :label="$t('acl.role2')">
<el-select <el-select
:style="{ width: '100%' }" :style="{ width: '100%' }"
filterable filterable
multiple multiple
v-decorator="['roles', { rules: [{ required: true, message: '请选择角色' }] }]" v-decorator="['roles', { rules: [{ required: true, message: $t('acl.role_placeholder2') }] }]"
> >
<el-option v-for="role in roles" :key="role.id" :value="role.id" :label="role.name"></el-option> <el-option v-for="role in roles" :key="role.id" :value="role.id" :label="role.name"></el-option>
</el-select> </el-select>
</a-form-item> </a-form-item>
<a-form-item label="权限"> <a-form-item :label="$t('acl.permission')">
<el-select <el-select
:style="{ width: '100%' }" :style="{ width: '100%' }"
multiple multiple
v-decorator="['permissions', { rules: [{ required: true, message: '请选择权限' }] }]" v-decorator="['permissions', { rules: [{ required: true, message: $t('acl.permission_placeholder') }] }]"
> >
<el-option <el-option
v-for="perm in selectResourceTypePerms" v-for="perm in selectResourceTypePerms"
@ -62,13 +62,13 @@
></el-option> ></el-option>
</el-select> </el-select>
</a-form-item> </a-form-item>
<a-form-item label="启用/禁用"> <a-form-item :label="$t('acl.enable')/$t('acl.disable')">
<a-switch v-decorator="['enabled', { rules: [], valuePropName: 'checked', initialValue: true }]" /> <a-switch v-decorator="['enabled', { rules: [], valuePropName: 'checked', initialValue: true }]" />
</a-form-item> </a-form-item>
</a-form> </a-form>
<div class="custom-drawer-bottom-action"> <div class="custom-drawer-bottom-action">
<a-button @click="handleClose">取消</a-button> <a-button @click="handleClose">{{ $t('cancel') }}</a-button>
<a-button @click="handleSubmit" type="primary">提交</a-button> <a-button @click="handleSubmit" type="primary">{{ $t('submit') }}</a-button>
</div> </div>
<TriggerPattern ref="triggerPattern" :roles="roles" /> <TriggerPattern ref="triggerPattern" :roles="roles" />
</CustomDrawer> </CustomDrawer>
@ -159,13 +159,13 @@ export default {
if (this.triggerId) { if (this.triggerId) {
updateTrigger(this.triggerId, { ...values, app_id: this.app_id }).then((res) => { updateTrigger(this.triggerId, { ...values, app_id: this.app_id }).then((res) => {
this.visible = false this.visible = false
this.$message.success('修改成功!') this.$message.success(this.$t('updateSuccess'))
this.$emit('refresh') this.$emit('refresh')
}) })
} else { } else {
addTrigger({ ...values, app_id: this.app_id }).then((res) => { addTrigger({ ...values, app_id: this.app_id }).then((res) => {
this.visible = false this.visible = false
this.$message.success('创建成功!') this.$message.success(this.$t('addSuccess'))
this.$emit('refresh') this.$emit('refresh')
}) })
} }

View File

@ -16,23 +16,23 @@
resizable resizable
:height="`${windowHeight - 310}px`" :height="`${windowHeight - 310}px`"
> >
<vxe-column field="created_at" width="144px" title="操作时间"></vxe-column> <vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')"></vxe-column>
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column> <vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
<vxe-column field="operate_type" width="80px" title="操作"> <vxe-column field="operate_type" width="100px" :title="$t('operation')">
<template #default="{ row }"> <template #default="{ row }">
<a-tag :color="handleTagColor(row.operate_type)"> <a-tag :color="handleTagColor(row.operate_type)">
{{ operateTypeMap.get(row.operate_type) }} {{ operateTypeMap.get(row.operate_type) }}
</a-tag> </a-tag>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="trigger_id" width="250px" title="触发器"> <vxe-column field="trigger_id" width="250px" :title="$t('acl.trigger')">
<template #default="{ row }"> <template #default="{ row }">
<span> <span>
{{ row.current.name || row.origin.name }} {{ row.current.name || row.origin.name }}
</span> </span>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column title="描述"> <vxe-column :title="$t('desc')">
<template #default="{ row }"> <template #default="{ row }">
<p> <p>
{{ row.changeDescription }} {{ row.changeDescription }}
@ -95,13 +95,6 @@ export default {
app_id: this.$route.name.split('_')[0], app_id: this.$route.name.split('_')[0],
loading: true, loading: true,
tableData: [], tableData: [],
operateTypeMap: new Map([
['create', '新建'],
['update', '修改'],
['delete', '删除'],
['trigger_apply', '应用'],
['trigger_cancel', '取消'],
]),
colorMap: new Map([ colorMap: new Map([
['create', 'green'], ['create', 'green'],
['delete', 'red'], ['delete', 'red'],
@ -109,41 +102,6 @@ export default {
['trigger_apply', 'green'], ['trigger_apply', 'green'],
['trigger_cancel', 'red'], ['trigger_cancel', 'red'],
]), ]),
triggerTableAttrList: [
{
alias: '日期',
is_choice: false,
name: 'datetime',
value_type: '3',
},
{
alias: '操作员',
is_choice: true,
name: 'operate_uid',
value_type: '2',
choice_value: this.allUsers,
},
{
alias: '操作',
is_choice: true,
name: 'operate_type',
value_type: '2',
choice_value: [
{ 新建: 'create' },
{ 修改: 'update' },
{ 删除: 'delete' },
{ 应用: 'trigger_apply' },
{ 取消: 'trigger_cancel' },
],
},
{
alias: '触发器',
is_choice: true,
name: 'trigger_id',
value_type: '2',
choice_value: this.allTriggers,
},
],
queryParams: { queryParams: {
page: 1, page: 1,
page_size: 50, page_size: 50,
@ -164,12 +122,58 @@ export default {
}, },
}, },
computed: { computed: {
operateTypeMap() {
return new Map([
['create', this.$t('create')],
['update', this.$t('update')],
['delete', this.$t('delete')],
['trigger_apply', this.$t('acl.apply')],
['trigger_cancel', this.$t('cancel')],
])
},
windowHeight() { windowHeight() {
return this.$store.state.windowHeight return this.$store.state.windowHeight
}, },
tableDataLength() { tableDataLength() {
return this.tableData.length return this.tableData.length
}, },
triggerTableAttrList() {
return [
{
alias: this.$t('acl.date'),
is_choice: false,
name: 'datetime',
value_type: '3',
},
{
alias: this.$t('acl.operator'),
is_choice: true,
name: 'operate_uid',
value_type: '2',
choice_value: this.allUsers,
},
{
alias: this.$t('operation'),
is_choice: true,
name: 'operate_type',
value_type: '2',
choice_value: [
{ [this.$t('create')]: 'create' },
{ [this.$t('update')]: 'update' },
{ [this.$t('delete')]: 'delete' },
{ [this.$t('acl.apply')]: 'trigger_apply' },
{ [this.$t('cancel')]: 'trigger_cancel' },
],
},
{
alias: this.$t('acl.trigger'),
is_choice: true,
name: 'trigger_id',
value_type: '2',
choice_value: this.allTriggers,
},
]
},
}, },
methods: { methods: {
async getTable(queryParams) { async getTable(queryParams) {
@ -220,9 +224,9 @@ export default {
const str = item.current.roles const str = item.current.roles
const newArr = str.slice(1, str.length - 1).split(', ') const newArr = str.slice(1, str.length - 1).split(', ')
const newStr = newArr.map((i) => this.allRolesMap.get(Number(i))).join('') const newStr = newArr.map((i) => this.allRolesMap.get(Number(i))).join('')
item.changeDescription = `新增触发器${item.current.name}\n资源类型${this.allResourceTypesMap.get( item.changeDescription = `${this.$t('acl.addTrigger')}: ${item.current.name}\n${this.$t('acl.resourceType')}: ${this.allResourceTypesMap.get(
item.current.resource_type_id item.current.resource_type_id
)}资源名${item.current.wildcard}角色[${newStr}]\n权限${item.current.permissions}\n状态${ )}this.$t('acl.resourceName')${item.current.wildcard}${this.$t('acl.role2')}: [${newStr}]\n${this.$t('acl.permission')}: ${item.current.permissions}\n${this.$t('status')}: ${
item.current.enabled item.current.enabled
}` }`
break break
@ -234,24 +238,24 @@ export default {
const oldVal = item.origin[key] const oldVal = item.origin[key]
if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') { if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') {
if (oldVal === null) { if (oldVal === null) {
const str = ` ${key} : 改为 ${newVal} ` const str = ` ${key} : -> ${newVal} `
item.changeDescription += str item.changeDescription += str
} else { } else {
const str = ` ${key} : ${oldVal} 改为 ${newVal} ` const str = ` ${key} : ${oldVal} -> ${newVal} `
item.changeDescription += str item.changeDescription += ` ${key} : ${oldVal} -> ${newVal} `
} }
} }
} }
if (!item.changeDescription) item.changeDescription = '没有修改' if (!item.changeDescription) item.changeDescription = this.$t('acl.noChange')
break break
} }
case 'delete': { case 'delete': {
const str = item.origin.roles const str = item.origin.roles
const newArr = str.slice(1, str.length - 1).split(', ') const newArr = str.slice(1, str.length - 1).split(', ')
const newStr = newArr.map((i) => this.allRolesMap.get(Number(i))).join('') const newStr = newArr.map((i) => this.allRolesMap.get(Number(i))).join('')
item.changeDescription = `删除触发器${item.origin.name}\n资源类型${this.allResourceTypesMap.get( item.changeDescription = `${this.$t('acl.deleteTrigger')}: ${item.origin.name}\n${this.$t('acl.resourceType')}: ${this.allResourceTypesMap.get(
item.origin.resource_type_id item.origin.resource_type_id
)}资源名${item.origin.wildcard}角色[${newStr}]\n权限${item.origin.permissions}\n状态${ )}this.$t('acl.resourceName')${item.origin.wildcard}${this.$t('acl.role2')}: [${newStr}]\n${this.$t('acl.permission')}: ${item.origin.permissions}\n${this.$t('status')}: ${
item.origin.enabled item.origin.enabled
}` }`
break break
@ -260,9 +264,9 @@ export default {
const str = item.current.roles const str = item.current.roles
const newArr = str.slice(1, str.length - 1).split(', ') const newArr = str.slice(1, str.length - 1).split(', ')
const newStr = newArr.map((i) => this.allRolesMap.get(Number(i))).join('') const newStr = newArr.map((i) => this.allRolesMap.get(Number(i))).join('')
item.changeDescription = `应用触发器${item.current.name}\n资源类型${this.allResourceTypesMap.get( item.changeDescription = `${this.$t('acl.applyTrigger')}: ${item.current.name}\n${this.$t('acl.resourceType')}: ${this.allResourceTypesMap.get(
item.current.resource_type_id item.current.resource_type_id
)}资源名${item.current.wildcard}角色[${newStr}]\n权限${item.current.permissions}\n状态${ )}this.$t('acl.resourceName')${item.current.wildcard}${this.$t('acl.role2')}: [${newStr}]\n${this.$t('acl.permission')}: ${item.current.permissions}\n${this.$t('status')}: ${
item.current.enabled item.current.enabled
}` }`
break break
@ -271,9 +275,9 @@ export default {
const str = item.current.roles const str = item.current.roles
const newArr = str.slice(1, str.length - 1).split(', ') const newArr = str.slice(1, str.length - 1).split(', ')
const newStr = newArr.map((i) => this.allRolesMap.get(Number(i))).join('') const newStr = newArr.map((i) => this.allRolesMap.get(Number(i))).join('')
item.changeDescription = `取消触发器${item.current.name}\n资源类型${this.allResourceTypesMap.get( item.changeDescription = `${this.$t('acl.cancelTrigger')}: ${item.current.name}\n${this.$t('acl.resourceType')}: ${this.allResourceTypesMap.get(
item.current.resource_type_id item.current.resource_type_id
)}资源名${item.current.wildcard}角色[${newStr}]\n权限${item.current.permissions}\n状态${ )}this.$t('acl.resourceName')${item.current.wildcard}${this.$t('acl.role2')}: [${newStr}]\n${this.$t('acl.permission')}: ${item.current.permissions}\n${this.$t('status')}: ${
item.current.enabled item.current.enabled
}` }`
break break

View File

@ -1,7 +1,7 @@
<template> <template>
<CustomDrawer <CustomDrawer
:hasFooter="false" :hasFooter="false"
title="正则匹配结果" :title="$t('acl.viewMatchResult')"
:visible="patternVisible" :visible="patternVisible"
width="500" width="500"
@close=" @close="
@ -16,16 +16,16 @@
class="ops-stripe-table" class="ops-stripe-table"
:data="tableData" :data="tableData"
:max-height="`${windowHeight - 110}px`"> :max-height="`${windowHeight - 110}px`">
<vxe-table-column field="name" title="资源名"></vxe-table-column> <vxe-table-column field="name" :title="$t('acl.resourceName')"></vxe-table-column>
<vxe-table-column field="uid" title="创建人"> <vxe-table-column field="uid" :title="$t('acl.creator')">
<template #default="{row}"> <template #default="{row}">
{{ getRoleName(row.uid) }} {{ getRoleName(row.uid) }}
</template> </template>
</vxe-table-column> </vxe-table-column>
<vxe-table-column field="created_at" title="创建时间"></vxe-table-column> <vxe-table-column field="created_at" :title="$t('created_at')"></vxe-table-column>
<template slot="empty"> <template slot="empty">
<img :src="require(`@/assets/data_empty.png`)" /> <img :src="require(`@/assets/data_empty.png`)" />
<p style="font-size: 14px; line-height: 17px; color: rgba(0, 0, 0, 0.6)">暂无数据</p> <p style="font-size: 14px; line-height: 17px; color: rgba(0, 0, 0, 0.6)">{{ $t('noData') }}</p>
</template> </template>
</vxe-table> </vxe-table>
</CustomDrawer> </CustomDrawer>

View File

@ -8,33 +8,38 @@
width="500px" width="500px"
> >
<a-form :form="form" @submit="handleSubmit" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }"> <a-form :form="form" @submit="handleSubmit" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
<a-form-item label="用户名(英文)"> <a-form-item :label="$t('acl.username')">
<a-input <a-input
name="username" name="username"
placeholder="英文名" :placeholder="$t('acl.username_placeholder')"
v-decorator="['username', { rules: [{ required: true, message: '请输入用户名' }] }]" v-decorator="['username', { rules: [{ required: true, message: $t('acl.username_placeholder') }] }]"
/> />
</a-form-item> </a-form-item>
<a-form-item label="中文名"> <a-form-item :label="$t('acl.nickname')">
<a-input name="nickname" v-decorator="['nickname', { rules: [] }]" /> <a-input
name="nickname"
:placeholder="$t('acl.nickname_placeholder')"
v-decorator="['nickname', { rules: [] }]"
/>
</a-form-item> </a-form-item>
<a-form-item label="密码"> <a-form-item :label="$t('acl.password')">
<a-input <a-input
type="password" type="password"
name="password" name="password"
v-decorator="['password', { rules: [{ required: true, message: '请输入密码' }] }]" :placeholder="$t('acl.password_placeholder')"
v-decorator="['password', { rules: [{ required: true, message: $t('acl.password_placeholder') }] }]"
/> />
</a-form-item> </a-form-item>
<a-form-item label="部门"> <a-form-item :label="$t('acl.department')">
<a-input name="department" v-decorator="['department', { rules: [] }]" /> <a-input name="department" v-decorator="['department', { rules: [] }]" />
</a-form-item> </a-form-item>
<a-form-item label="小组"> <a-form-item :label="$t('acl.group')">
<a-input name="catalog" v-decorator="['catalog', { rules: [] }]" /> <a-input name="catalog" v-decorator="['catalog', { rules: [] }]" />
</a-form-item> </a-form-item>
<a-form-item label="邮箱"> <a-form-item :label="$t('acl.email')">
<a-input <a-input
name="email" name="email"
v-decorator="[ v-decorator="[
@ -43,11 +48,11 @@
rules: [ rules: [
{ {
type: 'email', type: 'email',
message: '请输入正确的邮箱!', message: $t('acl.email_placeholder'),
}, },
{ {
required: true, required: true,
message: '请输入邮箱', message: $t('acl.email_placeholder'),
}, },
], ],
}, },
@ -55,14 +60,14 @@
/> />
</a-form-item> </a-form-item>
<a-form-item label="手机号码"> <a-form-item :label="$t('acl.mobile')">
<a-input <a-input
name="mobile" name="mobile"
v-decorator="['mobile', { rules: [{ message: '请输入正确的手机号码', pattern: /^1\d{10}$/ }] }]" v-decorator="['mobile', { rules: [{ message: $t('acl.mobileTips'), pattern: /^1\d{10}$/ }] }]"
/> />
</a-form-item> </a-form-item>
<a-form-item label="是否锁定"> <a-form-item :label="$t('acl.isBlock')">
<a-switch @change="onChange" name="block" v-decorator="['block', { rules: [], valuePropName: 'checked' }]" /> <a-switch @change="onChange" name="block" v-decorator="['block', { rules: [], valuePropName: 'checked' }]" />
</a-form-item> </a-form-item>
@ -71,8 +76,8 @@
</a-form-item> </a-form-item>
<div class="custom-drawer-bottom-action"> <div class="custom-drawer-bottom-action">
<a-button @click="onClose">取消</a-button> <a-button @click="onClose">{{ $t('cancel') }}</a-button>
<a-button @click="handleSubmit" type="primary">确定</a-button> <a-button @click="handleSubmit" type="primary">{{ $t('confirm') }}</a-button>
</div> </div>
</a-form> </a-form>
</CustomDrawer> </CustomDrawer>
@ -85,7 +90,6 @@ export default {
name: 'AttributeForm', name: 'AttributeForm',
data() { data() {
return { return {
drawerTitle: '新增用户',
drawerVisible: false, drawerVisible: false,
} }
}, },
@ -94,7 +98,11 @@ export default {
this.form = this.$form.createForm(this) this.form = this.$form.createForm(this)
}, },
computed: {}, computed: {
drawerTitle() {
return this.$t('acl.addUser')
},
},
mounted() {}, mounted() {},
methods: { methods: {
handleCreate() { handleCreate() {
@ -142,7 +150,7 @@ export default {
}, },
updateUser(attrId, data) { updateUser(attrId, data) {
updateUserById(attrId, data).then((res) => { updateUserById(attrId, data).then((res) => {
this.$message.success(`更新成功`) this.$message.success(this.$t('updateSuccess'))
this.handleOk() this.handleOk()
this.onClose() this.onClose()
}) })
@ -151,17 +159,11 @@ export default {
createUser(data) { createUser(data) {
addUser(data).then((res) => { addUser(data).then((res) => {
this.$message.success(`添加成功`) this.$message.success(this.$t('addSuccess'))
this.handleOk() this.handleOk()
this.onClose() this.onClose()
}) })
// .catch(err => this.requestFailed(err))
}, },
// requestFailed (err) {
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
// this.$message.error(`${msg}`)
// }
}, },
watch: {}, watch: {},
props: { props: {

View File

@ -1,6 +1,6 @@
<template> <template>
<CustomDrawer :closable="true" :visible="visible" width="500px" @close="handleClose" title="组用户"> <CustomDrawer :closable="true" :visible="visible" width="500px" @close="handleClose" :title="$t('acl.groupUser')">
<a-form-item label="添加用户" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }"> <a-form-item :label="$t('acl.addUser')" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
<a-row> <a-row>
<a-col span="15"> <a-col span="15">
<el-select v-model="selectedChildrenRole" multiple collapse-tags size="small" filterable> <el-select v-model="selectedChildrenRole" multiple collapse-tags size="small" filterable>
@ -14,14 +14,14 @@
</el-select> </el-select>
</a-col> </a-col>
<a-col span="5" offset="1"> <a-col span="5" offset="1">
<a-button style="display: inline-block" @click="handleAddRole">确定</a-button> <a-button style="display: inline-block" @click="handleAddRole">{{ $t('confirm') }}</a-button>
</a-col> </a-col>
</a-row> </a-row>
</a-form-item> </a-form-item>
<a-card> <a-card>
<a-row :gutter="24" v-for="(record, index) in records" :key="record.id" :style="{ marginBottom: '5px' }"> <a-row :gutter="24" v-for="(record, index) in records" :key="record.id" :style="{ marginBottom: '5px' }">
<a-col :span="20">{{ index + 1 }}{{ record.nickname }}</a-col> <a-col :span="20">{{ index + 1 }}{{ record.nickname }}</a-col>
<a-col :span="4"><a-button type="danger" size="small" @click="handleRevokeUser(record)">移除</a-button></a-col> <a-col :span="4"><a-button type="danger" size="small" @click="handleRevokeUser(record)">{{ $t('acl.remove') }}</a-button></a-col>
</a-row> </a-row>
</a-card> </a-card>
</CustomDrawer> </CustomDrawer>
@ -63,34 +63,22 @@ export default {
this.visible = true this.visible = true
this.loadRecords(roleId) this.loadRecords(roleId)
}, },
// filterOption(input, option) {
// return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
// },
async handleAddRole() { async handleAddRole() {
// await this.selectedChildrenRole.forEach(item => {
// addParentRole(item, this.roleId, { app_id: this.$route.name.split('_')[0] }).then(res => {
// this.$message.success('添加成功')
// })
// // .catch(err=>{
// // this.$httpError(err)
// // })
// })
await addBatchParentRole(this.roleId, { await addBatchParentRole(this.roleId, {
child_ids: this.selectedChildrenRole, child_ids: this.selectedChildrenRole,
app_id: this.$route.name.split('_')[0], app_id: this.$route.name.split('_')[0],
}) })
this.loadRecords(this.roleId) this.loadRecords(this.roleId)
this.$message.success('添加完成') this.$message.success(this.$t('addSuccess'))
this.selectedChildrenRole = [] this.selectedChildrenRole = []
}, },
handleRevokeUser(record) { handleRevokeUser(record) {
const that = this const that = this
this.$confirm({ this.$confirm({
content: '是否确定要移除该用户', content: that.$t('acl.deleteUserConfirm'),
onOk() { onOk() {
delParentRole(record.role.id, that.roleId, { app_id: that.$route.name.split('_')[0] }).then((res) => { delParentRole(record.role.id, that.roleId, { app_id: that.$route.name.split('_')[0] }).then((res) => {
that.$message.success('删除成功!') that.$message.success(that.$t('deleteSuccess'))
that.loadRecords(that.roleId) that.loadRecords(that.roleId)
}) })
// .catch(err=>that.$httpError(err)) // .catch(err=>that.$httpError(err))

View File

@ -1,19 +1,19 @@
<template> <template>
<div class="acl-operation-history"> <div class="acl-operation-history">
<a-tabs default-active-key="1"> <a-tabs default-active-key="1">
<a-tab-pane key="1" tab="权限变更"> <a-tab-pane key="1" :tab="$t('acl.permissionChange')">
<permisson-table></permisson-table> <permisson-table></permisson-table>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="2" tab="角色变更"> <a-tab-pane key="2" :tab="$t('acl.roleChange')">
<role-history-table></role-history-table> <role-history-table></role-history-table>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="3" tab="资源变更"> <a-tab-pane key="3" :tab="$t('acl.resourceChange')">
<resource-history-table></resource-history-table> <resource-history-table></resource-history-table>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="4" tab="资源类型变更"> <a-tab-pane key="4" :tab="$t('acl.resourceTypeChange')">
<resource-type-history-table></resource-type-history-table> <resource-type-history-table></resource-type-history-table>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="5" tab="触发器变更"> <a-tab-pane key="5" :tab="$t('acl.triggerChange')">
<trigger-history-table></trigger-history-table> <trigger-history-table></trigger-history-table>
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>

View File

@ -22,22 +22,22 @@
:height="`${windowHeight - windowHeightMinus}px`" :height="`${windowHeight - windowHeightMinus}px`"
:scroll-y="{ enabled: false }" :scroll-y="{ enabled: false }"
> >
<vxe-column field="created_at" width="144px" title="操作时间"> <vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')">
<template #default="{ row }"> <template #default="{ row }">
<span>{{ row.deleted_at || row.updated_at || row.created_at }}</span> <span>{{ row.deleted_at || row.updated_at || row.created_at }}</span>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column> <vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
<vxe-column field="operate_type" width="80px" title="操作"> <vxe-column field="operate_type" width="100px" :title="$t('operation')">
<template #default="{ row }"> <template #default="{ row }">
<a-tag :color="row.operate_type === 'grant' ? 'green' : 'red'">{{ <a-tag :color="row.operate_type === 'grant' ? 'green' : 'red'">{{
operateTypeMap.get(row.operate_type) operateTypeMap.get(row.operate_type)
}}</a-tag> }}</a-tag>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="rid" title="用户"></vxe-column> <vxe-column field="rid" :title="$t('user')"></vxe-column>
<vxe-column field="resource_type_id" title="资源类型"></vxe-column> <vxe-column field="resource_type_id" :title="$t('acl.resourceType')"></vxe-column>
<vxe-column field="resources" title="资源"> <vxe-column field="resources" :title="$t('acl.resource')">
<template #default="{ row }"> <template #default="{ row }">
<template v-if="row.resource_ids.length > 0"> <template v-if="row.resource_ids.length > 0">
<a-tooltip placement="top"> <a-tooltip placement="top">
@ -56,14 +56,14 @@
</template> </template>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column title="权限"> <vxe-column :title="$t('acl.permission')">
<template #default="{ row }"> <template #default="{ row }">
<a-tag v-for="(perm, index) in row.permission_ids" :key="'perms_' + perm + index"> <a-tag v-for="(perm, index) in row.permission_ids" :key="'perms_' + perm + index">
{{ perm }} {{ perm }}
</a-tag> </a-tag>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="source" width="100px" title="来源"></vxe-column> <vxe-column field="source" width="100px" :title="$t('acl.source')"></vxe-column>
</vxe-table> </vxe-table>
<pager <pager
:current-page.sync="queryParams.page" :current-page.sync="queryParams.page"
@ -108,10 +108,6 @@ export default {
allRolesMap: new Map(), allRolesMap: new Map(),
allUsersMap: new Map(), allUsersMap: new Map(),
allResourceTypesMap: new Map(), allResourceTypesMap: new Map(),
operateTypeMap: new Map([
['grant', '授权'],
['revoke', '撤销'],
]),
queryParams: { queryParams: {
page: 1, page: 1,
page_size: 50, page_size: 50,
@ -120,57 +116,63 @@ export default {
}, },
permissionTableAttrList: [ permissionTableAttrList: [
{ {
alias: '日期', alias: this.$t('acl.date'),
is_choice: false, is_choice: false,
name: 'datetime', name: 'datetime',
value_type: '3', value_type: '3',
}, },
{ {
alias: '应用', alias: this.$t('acl.app'),
is_choice: true, is_choice: true,
name: 'app_id', name: 'app_id',
value_type: '2', value_type: '2',
choice_value: [], choice_value: [],
}, },
{ {
alias: '操作员', alias: this.$t('acl.operator'),
is_choice: true, is_choice: true,
name: 'operate_uid', name: 'operate_uid',
value_type: '2', value_type: '2',
choice_value: [], choice_value: [],
}, },
{ {
alias: '用户', alias: this.$t('user'),
is_choice: true, is_choice: true,
name: 'rid', name: 'rid',
value_type: '2', value_type: '2',
choice_value: [], choice_value: [],
}, },
{ {
alias: '资源类型', alias: this.$t('acl.resourceType'),
is_choice: true, is_choice: true,
name: 'resource_type_id', name: 'resource_type_id',
value_type: '2', value_type: '2',
choice_value: [], choice_value: [],
}, },
{ {
alias: '资源', alias: this.$t('acl.resource'),
is_choice: true, is_choice: true,
name: 'resource_id', name: 'resource_id',
value_type: '2', value_type: '2',
choice_value: [], choice_value: [],
}, },
{ {
alias: '操作', alias: this.$t('operation'),
is_choice: true, is_choice: true,
name: 'operate_type', name: 'operate_type',
value_type: '2', value_type: '2',
choice_value: [{ 授权: 'grant' }, { 撤销: 'revoke' }], choice_value: [{ [this.$t('grant')]: 'grant' }, { [this.$t('acl.cancel')]: 'revoke' }],
}, },
], ],
} }
}, },
computed: { computed: {
operateTypeMap() {
return new Map([
['grant', this.$t('grant')],
['revoke', this.$t('acl.cancel')],
])
},
windowHeight() { windowHeight() {
return this.$store.state.windowHeight return this.$store.state.windowHeight
}, },
@ -183,10 +185,10 @@ export default {
}, },
async created() { async created() {
this.$watch( this.$watch(
function() { function () {
return this.permissionTableAttrList[3].choice_value return this.permissionTableAttrList[3].choice_value
}, },
function() { function () {
delete this.$refs.child.queryParams.rid delete this.$refs.child.queryParams.rid
delete this.$refs.child.queryParams.resource_type_id delete this.$refs.child.queryParams.resource_type_id
delete this.$refs.child.queryParams.resource_id delete this.$refs.child.queryParams.resource_id

View File

@ -4,7 +4,7 @@
ref="child" ref="child"
:attrList="resourceTableAttrList" :attrList="resourceTableAttrList"
:hasSwitch="true" :hasSwitch="true"
switchValue="" :switchValue="$t('acl.group2')"
@onSwitchChange="onSwitchChange" @onSwitchChange="onSwitchChange"
@expandChange="handleExpandChange" @expandChange="handleExpandChange"
@search="handleSearch" @search="handleSearch"
@ -24,30 +24,30 @@
:data="tableData" :data="tableData"
:height="`${windowHeight - windowHeightMinus}px`" :height="`${windowHeight - windowHeightMinus}px`"
> >
<vxe-column field="created_at" width="144px" title="操作时间"></vxe-column> <vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')"></vxe-column>
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column> <vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
<vxe-column field="operate_type" width="80px" title="操作"> <vxe-column field="operate_type" width="100px" :title="$t('operation')">
<template #default="{ row }"> <template #default="{ row }">
<a-tag :color="handleTagColor(row.operate_type)"> <a-tag :color="handleTagColor(row.operate_type)">
{{ operateTypeMap.get(row.operate_type) }} {{ operateTypeMap.get(row.operate_type) }}
</a-tag> </a-tag>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="link_id" title="资源名"> <vxe-column field="link_id" :title="$t('acl.resouceName')">
<template #default="{ row }"> <template #default="{ row }">
<span> <span>
{{ row.current.name || row.origin.name }} {{ row.current.name || row.origin.name }}
</span> </span>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column title="描述"> <vxe-column :title="$t('desc')">
<template #default="{ row }"> <template #default="{ row }">
<p> <p>
{{ row.description }} {{ row.description }}
</p> </p>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="source" width="100px" title="来源"></vxe-column> <vxe-column field="source" width="100px" :title="$t('acl.source')"></vxe-column>
</vxe-table> </vxe-table>
<pager <pager
:current-page.sync="queryParams.page" :current-page.sync="queryParams.page"
@ -87,47 +87,6 @@ export default {
allApps: [], allApps: [],
allUsersMap: new Map(), allUsersMap: new Map(),
allResourcesMap: new Map(), allResourcesMap: new Map(),
resourceTableAttrList: [
{
alias: '日期',
is_choice: false,
name: 'datetime',
value_type: '3',
},
{
alias: '应用',
is_choice: true,
name: 'app_id',
value_type: '2',
choice_value: [],
},
{
alias: '操作员',
is_choice: true,
name: 'operate_uid',
value_type: '2',
choice_value: [],
},
{
alias: '资源名',
is_choice: true,
name: 'link_id',
value_type: '2',
choice_value: [],
},
{
alias: '操作',
is_choice: true,
name: 'operate_type',
value_type: '2',
choice_value: [{ 新建: 'create' }, { 修改: 'update' }, { 删除: 'delete' }],
},
],
operateTypeMap: new Map([
['create', '新建'],
['update', '修改'],
['delete', '删除'],
]),
colorMap: new Map([ colorMap: new Map([
['create', 'green'], ['create', 'green'],
['update', 'orange'], ['update', 'orange'],
@ -144,10 +103,10 @@ export default {
}, },
async created() { async created() {
this.$watch( this.$watch(
function() { function () {
return this.resourceTableAttrList[3].choice_value return this.resourceTableAttrList[3].choice_value
}, },
function() { function () {
delete this.$refs.child.queryParams.link_id delete this.$refs.child.queryParams.link_id
} }
) )
@ -158,6 +117,13 @@ export default {
this.$refs.xTable.$el.querySelector('.vxe-table--body-wrapper').scrollTop = 0 this.$refs.xTable.$el.querySelector('.vxe-table--body-wrapper').scrollTop = 0
}, },
computed: { computed: {
operateTypeMap() {
return new Map([
['create', this.$t('create')],
['update', this.$t('update')],
['delete', this.$t('delete')],
])
},
windowHeight() { windowHeight() {
return this.$store.state.windowHeight return this.$store.state.windowHeight
}, },
@ -167,6 +133,44 @@ export default {
tableDataLength() { tableDataLength() {
return this.tableData.length return this.tableData.length
}, },
resourceTableAttrList() {
return [
{
alias: this.$t('acl.date'),
is_choice: false,
name: 'datetime',
value_type: '3',
},
{
alias: this.$t('acl.app'),
is_choice: true,
name: 'app_id',
value_type: '2',
choice_value: [],
},
{
alias: this.$t('acl.operator'),
is_choice: true,
name: 'operate_uid',
value_type: '2',
choice_value: [],
},
{
alias: this.$t('acl.resourceName'),
is_choice: true,
name: 'link_id',
value_type: '2',
choice_value: [],
},
{
alias: this.$t('operation'),
is_choice: true,
name: 'operate_type',
value_type: '2',
choice_value: [{ [this.$t('create')]: 'create' }, { [this.$t('update')]: 'update' }, { [this.$t('delete')]: 'delete' }],
},
]
},
}, },
methods: { methods: {
async getTable(queryParams) { async getTable(queryParams) {
@ -347,7 +351,7 @@ export default {
switch (operate_type) { switch (operate_type) {
// create // create
case 'create': { case 'create': {
item.description = `新建资源${item.current.name}` item.description = `${this.$t('acl.newResource')}${item.current.name}`
break break
} }
case 'update': { case 'update': {
@ -357,10 +361,10 @@ export default {
const oldVal = item.origin[key] const oldVal = item.origin[key]
if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') { if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') {
if (oldVal === null) { if (oldVal === null) {
const str = ` ${key} : 改为 ${newVal} ` const str = ` ${key} : -> ${newVal} `
item.description += str item.description += str
} else { } else {
const str = ` ${key} : ${oldVal} 改为 ${newVal} ` const str = ` ${key} : ${oldVal} -> ${newVal} `
item.description += str item.description += str
} }
} }
@ -369,18 +373,18 @@ export default {
const currentResource_ids = item.currentResource_ids const currentResource_ids = item.currentResource_ids
if (!_.isEqual(originResource_ids, currentResource_ids)) { if (!_.isEqual(originResource_ids, currentResource_ids)) {
if (originResource_ids.length === 0) { if (originResource_ids.length === 0) {
const str = ` resource_ids : 新增 ${currentResource_ids} ` const str = ` resource_ids : ${this.$t('new')} ${currentResource_ids} `
item.description += str item.description += str
} else { } else {
const str = ` resource_ids : ${originResource_ids} 改为 ${currentResource_ids} ` const str = ` resource_ids : ${originResource_ids} -> ${currentResource_ids} `
item.description += str item.description += str
} }
} }
if (!item.description) item.description = '没有修改' if (!item.description) item.description = this.$t('acl.noChange')
break break
} }
case 'delete': { case 'delete': {
item.description = `删除资源${item.origin.name}` item.description = `${this.$t('acl.deleteResource')}${item.origin.name}`
break break
} }
} }

View File

@ -18,30 +18,30 @@
:loading="loading" :loading="loading"
:height="`${windowHeight - windowHeightMinus}px`" :height="`${windowHeight - windowHeightMinus}px`"
> >
<vxe-column field="created_at" width="144px" title="操作时间"></vxe-column> <vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')"></vxe-column>
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column> <vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
<vxe-column field="operate_type" width="80px" title="操作"> <vxe-column field="operate_type" width="100px" :title="$t('operation')">
<template #default="{ row }"> <template #default="{ row }">
<a-tag :color="handleTagColor(row.operate_type)"> <a-tag :color="handleTagColor(row.operate_type)">
{{ operateTypeMap.get(row.operate_type) }} {{ operateTypeMap.get(row.operate_type) }}
</a-tag> </a-tag>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="link_id" width="159px" title="资源类型名"> <vxe-column field="link_id" width="159px" :title="$t('acl.resourceTypeName')">
<template #default="{ row }"> <template #default="{ row }">
<span> <span>
{{ row.current.name || row.origin.name }} {{ row.current.name || row.origin.name }}
</span> </span>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column title="描述"> <vxe-column :title="$t('desc')">
<template #default="{ row }"> <template #default="{ row }">
<p> <p>
{{ row.changeDescription }} {{ row.changeDescription }}
</p> </p>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="source" width="100px" title="来源"></vxe-column> <vxe-column field="source" width="100px" :title="$t('acl.source')"></vxe-column>
</vxe-table> </vxe-table>
<pager <pager
:current-page.sync="queryParams.page" :current-page.sync="queryParams.page"
@ -78,47 +78,6 @@ export default {
allApps: [], allApps: [],
allUsersMap: new Map(), allUsersMap: new Map(),
allResourcesMap: new Map(), allResourcesMap: new Map(),
resourceTableAttrList: [
{
alias: '日期',
is_choice: false,
name: 'datetime',
value_type: '3',
},
{
alias: '应用',
is_choice: true,
name: 'app_id',
value_type: '2',
choice_value: [],
},
{
alias: '操作员',
is_choice: true,
name: 'operate_uid',
value_type: '2',
choice_value: [],
},
{
alias: '资源类型',
is_choice: true,
name: 'link_id',
value_type: '2',
choice_value: [],
},
{
alias: '操作',
is_choice: true,
name: 'operate_type',
value_type: '2',
choice_value: [{ 新建: 'create' }, { 修改: 'update' }, { 删除: 'delete' }],
},
],
operateTypeMap: new Map([
['create', '新建'],
['update', '修改'],
['delete', '删除'],
]),
colorMap: new Map([ colorMap: new Map([
['create', 'green'], ['create', 'green'],
['update', 'orange'], ['update', 'orange'],
@ -135,10 +94,10 @@ export default {
}, },
async created() { async created() {
this.$watch( this.$watch(
function() { function () {
return this.resourceTableAttrList[3].choice_value return this.resourceTableAttrList[3].choice_value
}, },
function() { function () {
delete this.$refs.child.queryParams.link_id delete this.$refs.child.queryParams.link_id
} }
) )
@ -149,6 +108,13 @@ export default {
this.$refs.xTable.$el.querySelector('.vxe-table--body-wrapper').scrollTop = 0 this.$refs.xTable.$el.querySelector('.vxe-table--body-wrapper').scrollTop = 0
}, },
computed: { computed: {
operateTypeMap() {
return new Map([
['create', this.$t('create')],
['update', this.$t('update')],
['delete', this.$t('delete')],
])
},
windowHeight() { windowHeight() {
return this.$store.state.windowHeight return this.$store.state.windowHeight
}, },
@ -158,6 +124,44 @@ export default {
tableDataLength() { tableDataLength() {
return this.tableData.length return this.tableData.length
}, },
resourceTableAttrList() {
return [
{
alias: this.$t('acl.date'),
is_choice: false,
name: 'datetime',
value_type: '3',
},
{
alias: this.$t('acl.app'),
is_choice: true,
name: 'app_id',
value_type: '2',
choice_value: [],
},
{
alias: this.$t('acl.operator'),
is_choice: true,
name: 'operate_uid',
value_type: '2',
choice_value: [],
},
{
alias: this.$t('acl.resourceType'),
is_choice: true,
name: 'link_id',
value_type: '2',
choice_value: [],
},
{
alias: this.$t('operation'),
is_choice: true,
name: 'operate_type',
value_type: '2',
choice_value: [{ [this.$t('create')]: 'create' }, { [this.$t('update')]: 'update' }, { [this.$t('delete')]: 'delete' }],
},
]
},
}, },
methods: { methods: {
async getTable(queryParams) { async getTable(queryParams) {
@ -283,10 +287,12 @@ export default {
switch (operate_type) { switch (operate_type) {
// create // create
case 'create': { case 'create': {
const description = item.current?.description === undefined ? '' : item.current?.description const description = item.current?.description === undefined ? this.$t('acl.none') : item.current?.description
const permission = const permission =
item.extra.permission_ids?.current === undefined ? '' : item.extra.permission_ids?.current item.extra.permission_ids?.current === undefined ? this.$t('acl.none') : item.extra.permission_ids?.current
item.changeDescription = `新增资源类型${item.current.name}\n描述${description}\n权限${permission}` item.changeDescription = `${this.$t('acl.addReourceType')}${item.current.name}\n${this.$t(
'desc'
)}${description}\n${this.$t('acl.permission')}${permission}`
break break
} }
case 'update': { case 'update': {
@ -296,27 +302,29 @@ export default {
const oldVal = item.origin[key] const oldVal = item.origin[key]
if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') { if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') {
if (oldVal === null || oldVal === '') { if (oldVal === null || oldVal === '') {
const str = ` ${key} : 改为 ${newVal} \n` const str = ` ${key} : -> ${newVal} \n`
item.changeDescription += str item.changeDescription += str
} else { } else {
const str = ` ${key} : ${oldVal} 改为 ${newVal} \n` const str = ` ${key} : ${oldVal} -> ${newVal} \n`
item.changeDescription += str item.changeDescription += str
} }
} }
} }
const currentPerms = const currentPerms =
item.extra.permission_ids?.current === undefined ? '' : item.extra.permission_ids?.current item.extra.permission_ids?.current === undefined ? this.$t('acl.none') : item.extra.permission_ids?.current
const originPerms = item.extra.permission_ids?.origin === undefined ? '' : item.extra.permission_ids?.origin const originPerms = item.extra.permission_ids?.origin === undefined ? this.$t('acl.none') : item.extra.permission_ids?.origin
if (!_.isEqual(currentPerms, originPerms)) { if (!_.isEqual(currentPerms, originPerms)) {
item.changeDescription += ` permission_ids : ${originPerms} 改为 ${currentPerms} ` item.changeDescription += ` permission_ids : ${originPerms} -> ${currentPerms} `
} }
if (!item.changeDescription) item.changeDescription = '没有修改' if (!item.changeDescription) item.changeDescription = this.$t('acl.noChange')
break break
} }
case 'delete': { case 'delete': {
const description = item.origin?.description === undefined ? '' : item.origin?.description const description = item.origin?.description === undefined ? this.$t('acl.none') : item.origin?.description
const permission = item.extra.permission_ids?.origin === undefined ? '' : item.extra.permission_ids?.origin const permission = item.extra.permission_ids?.origin === undefined ? this.$t('acl.none') : item.extra.permission_ids?.origin
item.changeDescription = `删除资源类型${item.origin.name}\n描述${description}\n权限${permission}` item.changeDescription = `${this.$t('acl.deleteResourceType')}: ${item.origin.name}\n${this.$t(
'desc'
)}${description}\n${this.$t('acl.permission')}: ${permission}`
break break
} }
} }

View File

@ -4,7 +4,7 @@
ref="child" ref="child"
:attrList="roleTableAttrList" :attrList="roleTableAttrList"
:hasSwitch="true" :hasSwitch="true"
switchValue="角色关系" :switchValue="$t('acl.roleRelation')"
@onSwitchChange="onSwitchChange" @onSwitchChange="onSwitchChange"
@search="handleSearch" @search="handleSearch"
@searchFormReset="searchFormReset" @searchFormReset="searchFormReset"
@ -19,16 +19,16 @@
:loading="loading" :loading="loading"
:height="`${windowHeight - 310}px`" :height="`${windowHeight - 310}px`"
> >
<vxe-column field="created_at" width="144px" title="操作时间"></vxe-column> <vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')"></vxe-column>
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column> <vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
<vxe-column field="operate_type" width="112px" title="操作"> <vxe-column field="operate_type" width="112px" :title="$t('operation')">
<template #default="{ row }"> <template #default="{ row }">
<template> <template>
<a-tag :color="handleTagColor(row.operate_type)">{{ operateTypeMap.get(row.operate_type) }}</a-tag> <a-tag :color="handleTagColor(row.operate_type)">{{ operateTypeMap.get(row.operate_type) }}</a-tag>
</template> </template>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column :title="checked ? '角色' : '角色'"> <vxe-column :title="checked ? $t('acl.role2') : $t('acl.role2')">
<template #default="{ row }"> <template #default="{ row }">
<template v-if="!checked"> <template v-if="!checked">
<a-tag color="blue">{{ row.current.name || row.origin.name }}</a-tag> <a-tag color="blue">{{ row.current.name || row.origin.name }}</a-tag>
@ -40,7 +40,7 @@
</template> </template>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column :title="checked ? '继承自' : '管理员'" :width="checked ? '350px' : '80px'"> <vxe-column :title="checked ? $t('acl.inheritedFrom') : $t('acl.admin')" :width="checked ? '350px' : '80px'">
<template #default="{ row }"> <template #default="{ row }">
<template v-if="!checked"> <template v-if="!checked">
<a-icon type="check" v-if="row.current.is_app_admin" /> <a-icon type="check" v-if="row.current.is_app_admin" />
@ -52,14 +52,14 @@
</template> </template>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column title="描述" v-if="!checked"> <vxe-column :title="$t('desc')" v-if="!checked">
<template #default="{ row }"> <template #default="{ row }">
<p> <p>
{{ row.description }} {{ row.description }}
</p> </p>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="source" width="100px" title="来源"></vxe-column> <vxe-column field="source" width="100px" :title="$t('acl.source')"></vxe-column>
</vxe-table> </vxe-table>
<pager <pager
:current-page.sync="queryParams.page" :current-page.sync="queryParams.page"
@ -94,13 +94,6 @@ export default {
allRoles: [], allRoles: [],
allRolesMap: new Map(), allRolesMap: new Map(),
allUsersMap: new Map(), allUsersMap: new Map(),
operateTypeMap: new Map([
['create', '新建'],
['delete', '删除'],
['update', '修改'],
['role_relation_add', '添加角色关系'],
['role_relation_delete', '删除角色关系'],
]),
colorMap: new Map([ colorMap: new Map([
['create', 'green'], ['create', 'green'],
['delete', 'red'], ['delete', 'red'],
@ -115,49 +108,60 @@ export default {
start: '', start: '',
end: '', end: '',
}, },
roleTableAttrList: [ }
},
computed: {
operateTypeMap() {
return new Map([
['create', this.$t('create')],
['update', this.$t('update')],
['delete', this.$t('delete')],
['role_relation_add', this.$t('acl.roleRelationAdd')],
['role_relation_delete', this.$t('acl.roleRelationDelete')],
])
},
windowHeight() {
return this.$store.state.windowHeight
},
tableDataLength() {
return this.tableData.length
},
roleTableAttrList() {
return [
{ {
alias: '日期', alias: this.$t('acl.date'),
is_choice: false, is_choice: false,
name: 'datetime', name: 'datetime',
value_type: '3', value_type: '3',
}, },
{ {
alias: '应用', alias: this.$t('acl.app'),
is_choice: true, is_choice: true,
name: 'app_id', name: 'app_id',
value_type: '2', value_type: '2',
choice_value: [], choice_value: [],
}, },
{ {
alias: '操作员', alias: this.$t('acl.operator'),
is_choice: true, is_choice: true,
name: 'operate_uid', name: 'operate_uid',
value_type: '2', value_type: '2',
choice_value: [], choice_value: [],
}, },
{ {
alias: '操作', alias: this.$t('operation'),
is_choice: true, is_choice: true,
name: 'operate_type', name: 'operate_type',
value_type: '2', value_type: '2',
choice_value: [ choice_value: [
{ 新建: 'create' }, { [this.$t('create')]: 'create' },
{ 修改: 'update' }, { [this.$t('update')]: 'update' },
{ 删除: 'delete' }, { [this.$t('delete')]: 'delete' },
{ 添加角色关系: 'role_relation_add' }, { [this.$t('acl.roleRelationAdd')]: 'role_relation_add' },
{ 删除角色关系: 'role_relation_delete' }, { [this.$t('acl.roleRelationDelete')]: 'role_relation_delete' },
], ],
}, },
], ]
}
},
computed: {
windowHeight() {
return this.$store.state.windowHeight
},
tableDataLength() {
return this.tableData.length
}, },
}, },
async created() { async created() {
@ -277,7 +281,7 @@ export default {
switch (operate_type) { switch (operate_type) {
// create // create
case 'create': { case 'create': {
item.description = `新建角色${item.current.name}` item.description = `${this.$t('acl.addRole')}${item.current.name}`
break break
} }
case 'update': { case 'update': {
@ -287,15 +291,15 @@ export default {
const oldVal = item.origin[key] const oldVal = item.origin[key]
if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') { if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') {
if (oldVal === null) { if (oldVal === null) {
const str = ` ${key} : 改为 ${newVal} ` const str = ` ${key} : -> ${newVal} `
item.description += str item.description += str
} else { } else {
const str = ` ${key} : ${oldVal} 改为 ${newVal} ` const str = ` ${key} : ${oldVal} -> ${newVal} `
item.description += str item.description += ` ${key} : ${oldVal} -> ${newVal} `
} }
} }
} }
if (!item.description) item.description = '没有修改' if (!item.description) item.description = this.$t('acl.noChange')
break break
} }
case 'delete': { case 'delete': {
@ -325,7 +329,7 @@ export default {
resourceMap.forEach((value, key) => { resourceMap.forEach((value, key) => {
permsArr.push(`${id2resources[key].name}${value}`) permsArr.push(`${id2resources[key].name}${value}`)
}) })
item.description = `继承者${child_ids}\n继承自${parent_ids}\n涉及资源及权限\n${permsArr.join(`\n`)}` item.description = `${this.$t('acl.heir')}${child_ids}\n${this.$t('acl.inheritedFrom')}${parent_ids}\n${this.$t('acl.involvingRP')}\n${permsArr.join(`\n`)}`
break break
} }
} }

View File

@ -18,23 +18,23 @@
:loading="loading" :loading="loading"
:height="`${windowHeight - windowHeightMinus}px`" :height="`${windowHeight - windowHeightMinus}px`"
> >
<vxe-column field="created_at" width="144px" title="操作时间"></vxe-column> <vxe-column field="created_at" width="144px" :title="$t('acl.operateTime')"></vxe-column>
<vxe-column field="operate_uid" width="130px" title="操作员"></vxe-column> <vxe-column field="operate_uid" width="130px" :title="$t('acl.operator')"></vxe-column>
<vxe-column field="operate_type" width="80px" title="操作"> <vxe-column field="operate_type" width="100px" :title="$t('operation')">
<template #default="{ row }"> <template #default="{ row }">
<a-tag :color="handleTagColor(row.operate_type)"> <a-tag :color="handleTagColor(row.operate_type)">
{{ operateTypeMap.get(row.operate_type) }} {{ operateTypeMap.get(row.operate_type) }}
</a-tag> </a-tag>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="trigger_id" width="250px" title="触发器"> <vxe-column field="trigger_id" width="250px" :title="$t('acl.trigger')">
<template #default="{ row }"> <template #default="{ row }">
<span> <span>
{{ row.current.name || row.origin.name }} {{ row.current.name || row.origin.name }}
</span> </span>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column title="描述"> <vxe-column :title="$t('desc')">
<template #default="{ row }"> <template #default="{ row }">
<p> <p>
{{ row.changeDescription }} {{ row.changeDescription }}
@ -64,6 +64,7 @@ import { getTriggers } from '@/modules/acl/api/trigger'
import { searchUser } from '@/modules/acl/api/user' import { searchUser } from '@/modules/acl/api/user'
import { searchApp } from '@/modules/acl/api/app' import { searchApp } from '@/modules/acl/api/app'
export default { export default {
name: 'TriggerHistoryTable',
components: { SearchForm, Pager }, components: { SearchForm, Pager },
data() { data() {
return { return {
@ -82,13 +83,6 @@ export default {
allResourceTypesMap: new Map(), allResourceTypesMap: new Map(),
allResourcesMap: new Map(), allResourcesMap: new Map(),
allTriggersMap: new Map(), allTriggersMap: new Map(),
operateTypeMap: new Map([
['create', '新建'],
['update', '修改'],
['delete', '删除'],
['trigger_apply', '应用'],
['trigger_cancel', '取消'],
]),
colorMap: new Map([ colorMap: new Map([
['create', 'green'], ['create', 'green'],
['delete', 'red'], ['delete', 'red'],
@ -96,48 +90,6 @@ export default {
['trigger_apply', 'green'], ['trigger_apply', 'green'],
['trigger_cancel', 'red'], ['trigger_cancel', 'red'],
]), ]),
triggerTableAttrList: [
{
alias: '日期',
is_choice: false,
name: 'datetime',
value_type: '3',
},
{
alias: '应用',
is_choice: true,
name: 'app_id',
value_type: '2',
choice_value: [],
},
{
alias: '操作员',
is_choice: true,
name: 'operate_uid',
value_type: '2',
choice_value: [],
},
{
alias: '触发器',
is_choice: true,
name: 'trigger_id',
value_type: '2',
choice_value: [],
},
{
alias: '操作',
is_choice: true,
name: 'operate_type',
value_type: '2',
choice_value: [
{ 新建: 'create' },
{ 修改: 'update' },
{ 删除: 'delete' },
{ 应用: 'trigger_apply' },
{ 取消: 'trigger_cancel' },
],
},
],
queryParams: { queryParams: {
page: 1, page: 1,
page_size: 50, page_size: 50,
@ -162,6 +114,15 @@ export default {
this.$refs.xTable.$el.querySelector('.vxe-table--body-wrapper').scrollTop = 0 this.$refs.xTable.$el.querySelector('.vxe-table--body-wrapper').scrollTop = 0
}, },
computed: { computed: {
operateTypeMap() {
return new Map([
['create', this.$t('create')],
['update', this.$t('update')],
['delete', this.$t('delete')],
['trigger_apply', this.$t('acl.apply')],
['trigger_cancel', this.$t('cancel')],
])
},
windowHeight() { windowHeight() {
return this.$store.state.windowHeight return this.$store.state.windowHeight
}, },
@ -171,6 +132,50 @@ export default {
tableDataLength() { tableDataLength() {
return this.tableData.length return this.tableData.length
}, },
triggerTableAttrList() {
return [
{
alias: this.$t('acl.date'),
is_choice: false,
name: 'datetime',
value_type: '3',
},
{
alias: this.$t('acl.app'),
is_choice: true,
name: 'app_id',
value_type: '2',
choice_value: [],
},
{
alias: this.$t('acl.operator'),
is_choice: true,
name: 'operate_uid',
value_type: '2',
choice_value: [],
},
{
alias: this.$t('acl.trigger'),
is_choice: true,
name: 'trigger_id',
value_type: '2',
choice_value: [],
},
{
alias: this.$t('operation'),
is_choice: true,
name: 'operate_type',
value_type: '2',
choice_value: [
{ [this.$t('create')]: 'create' },
{ [this.$t('update')]: 'update' },
{ [this.$t('delete')]: 'delete' },
{ [this.$t('acl.apply')]: 'trigger_apply' },
{ [this.$t('cancel')]: 'trigger_cancel' },
],
},
]
},
}, },
methods: { methods: {
async getTable(queryParams) { async getTable(queryParams) {
@ -270,9 +275,11 @@ export default {
const newArr = str.slice(1, str.length - 1).split(', ') const newArr = str.slice(1, str.length - 1).split(', ')
const newStr = newArr.map((i) => id2roles[i].name).join('') const newStr = newArr.map((i) => id2roles[i].name).join('')
const { name, resource_type_id, wildcard, permissions, enabled } = item.current const { name, resource_type_id, wildcard, permissions, enabled } = item.current
item.changeDescription = `新增触发器${name}\n资源类型${ item.changeDescription = `${this.$t('acl.addTrigger')}:${name}\n${this.$t('acl.resourceType')}: ${
id2resource_types[resource_type_id].name id2resource_types[resource_type_id].name
}资源名${wildcard || ''}角色[${newStr}]\n权限${permissions}\n状态${enabled}` }this.$t('acl.resourceName')${wildcard || ''}${this.$t(
'acl.role2'
)}:[${newStr}]\nthis.$t('acl.permssion')}: ${permissions}\n${this.$t('status')}: ${enabled}`
break break
} }
case 'update': { case 'update': {
@ -282,15 +289,15 @@ export default {
const oldVal = item.origin[key] const oldVal = item.origin[key]
if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') { if (!_.isEqual(newVal, oldVal) && key !== 'updated_at' && key !== 'deleted_at' && key !== 'created_at') {
if (oldVal === null) { if (oldVal === null) {
const str = ` ${key} : 改为 ${newVal} ` const str = ` ${key} : -> ${newVal} `
item.changeDescription += str item.changeDescription += str
} else { } else {
const str = ` ${key} : ${oldVal} 改为 ${newVal} ` const str = ` ${key} : ${oldVal} -> ${newVal} `
item.changeDescription += str item.changeDescription += ` ${key} :${oldVal} -> ${newVal} `
} }
} }
} }
if (!item.changeDescription) item.changeDescription = '没有修改' if (!item.changeDescription) item.changeDescription = this.$t('acl.noChange')
break break
} }
case 'delete': { case 'delete': {
@ -298,9 +305,11 @@ export default {
const newArr = str.slice(1, str.length - 1).split(', ') const newArr = str.slice(1, str.length - 1).split(', ')
const newStr = newArr.map((i) => id2roles[i].name).join('') const newStr = newArr.map((i) => id2roles[i].name).join('')
const { name, resource_type_id, wildcard, permissions, enabled } = item.origin const { name, resource_type_id, wildcard, permissions, enabled } = item.origin
item.changeDescription = `删除触发器${name}\n资源类型${ item.changeDescription = `${this.$t('acl.deleteTrigger')}: ${name}\n${this.$t('acl.resourceType')}: ${
id2resource_types[resource_type_id].name id2resource_types[resource_type_id].name
}资源名${wildcard || ''}角色[${newStr}]\n权限${permissions}\n状态${enabled}` }${this.$t('acl.resourceName')}: ${wildcard || ''}${this.$t(
'acl.role2'
)}:[${newStr}]\nthis.$t('acl.permssion')}: ${permissions}\n${this.$t('status')}: ${enabled}`
break break
} }
case 'trigger_apply': { case 'trigger_apply': {
@ -308,9 +317,11 @@ export default {
const newArr = str.slice(1, str.length - 1).split(', ') const newArr = str.slice(1, str.length - 1).split(', ')
const newStr = newArr.map((i) => id2roles[i].name).join('') const newStr = newArr.map((i) => id2roles[i].name).join('')
const { name, resource_type_id, wildcard, permissions, enabled } = item.current const { name, resource_type_id, wildcard, permissions, enabled } = item.current
item.changeDescription = `应用触发器${name}\n资源类型${ item.changeDescription = `${this.$t('acl.applyTrigger')}: ${name}\n${this.$t('acl.resourceType')}: ${
id2resource_types[resource_type_id].name id2resource_types[resource_type_id].name
}资源名${wildcard || ''}角色[${newStr}]\n权限${permissions}\n状态${enabled}` }${this.$t('acl.resourceName')}: ${wildcard || ''}${this.$t(
'acl.role2'
)}:[${newStr}]\nthis.$t('acl.permssion')}: ${permissions}\n${this.$t('status')}: ${enabled}`
break break
} }
case 'trigger_cancel': { case 'trigger_cancel': {
@ -318,9 +329,11 @@ export default {
const newArr = str.slice(1, str.length - 1).split(', ') const newArr = str.slice(1, str.length - 1).split(', ')
const newStr = newArr.map((i) => id2roles[i].name).join('') const newStr = newArr.map((i) => id2roles[i].name).join('')
const { name, resource_type_id, wildcard, permissions, enabled } = item.current const { name, resource_type_id, wildcard, permissions, enabled } = item.current
item.changeDescription = `取消触发器${name}\n资源类型${ item.changeDescription = `${this.$t('acl.cancelTrigger')}: ${name}\n${this.$t('acl.resourceType')}: ${
id2resource_types[resource_type_id].name id2resource_types[resource_type_id].name
}资源名${wildcard || ''}角色[${newStr}]\n权限${permissions}\n状态${enabled}` }${this.$t('acl.resourceName')}: ${wildcard || ''}${this.$t(
'acl.role2'
)}:[${newStr}]\nthis.$t('acl.permssion')}: ${permissions}\n${this.$t('status')}: ${enabled}`
break break
} }
} }

View File

@ -1,11 +1,13 @@
<template> <template>
<div class="acl-resource-types"> <div class="acl-resource-types">
<div class="acl-resource-types-header"> <div class="acl-resource-types-header">
<a-button @click="handleCreate" type="primary" style="margin-right: 0.3rem">{{ btnName }}</a-button> <a-button @click="handleCreate" type="primary" style="margin-right: 0.3rem">{{
$t('acl.addReourceType')
}}</a-button>
<a-input-search <a-input-search
class="ops-input" class="ops-input"
:style="{ display: 'inline', marginLeft: '10px', width: '200px' }" :style="{ display: 'inline', marginLeft: '10px', width: '200px' }"
placeholder="搜索 | 资源类型名" :placeholder="`${$t('search')} | ${$t('acl.resourceType')}`"
v-model="searchName" v-model="searchName"
allowClear allowClear
@search=" @search="
@ -28,28 +30,28 @@
<!-- 1 --> <!-- 1 -->
<vxe-table-column <vxe-table-column
field="name" field="name"
title="资源类型名" :title="$t('acl.resoureType')"
:min-width="175" :min-width="175"
fixed="left" fixed="left"
show-overflow show-overflow
></vxe-table-column> ></vxe-table-column>
<!-- 2 --> <!-- 2 -->
<vxe-table-column field="description" title="描述" :min-width="175"></vxe-table-column> <vxe-table-column field="description" :title="$t('desc')" :min-width="175"></vxe-table-column>
<!-- 3 --> <!-- 3 -->
<vxe-table-column field="id" title="权限" :min-width="300"> <vxe-table-column field="id" :title="$t('acl.permission')" :min-width="300">
<template #default="{ row }"> <template #default="{ row }">
<a-tag color="cyan" v-for="perm in id2perms[row.id]" :key="perm.id">{{ perm.name }}</a-tag> <a-tag color="cyan" v-for="perm in id2perms[row.id]" :key="perm.id">{{ perm.name }}</a-tag>
</template> </template>
</vxe-table-column> </vxe-table-column>
<!-- 4 --> <!-- 4 -->
<vxe-table-column field="action" title="操作" :width="100" fixed="right"> <vxe-table-column field="action" :title="$t('operation')" :width="100" fixed="right">
<template #default="{ row }"> <template #default="{ row }">
<a @click="handleEdit(row)"><a-icon type="edit"/></a> <a @click="handleEdit(row)"><a-icon type="edit"/></a>
<a-divider type="vertical" /> <a-divider type="vertical" />
<a-popconfirm title="确认删除?" @confirm="handleDelete(row)" okText="" cancelText=""> <a-popconfirm :title="$t('confirmDelete')" @confirm="handleDelete(row)">
<a style="color: red"><a-icon type="delete"/></a> <a style="color: red"><a-icon type="delete"/></a>
</a-popconfirm> </a-popconfirm>
</template> </template>
@ -87,42 +89,12 @@ export default {
loading: false, loading: false,
groups: [], groups: [],
id2perms: {}, id2perms: {},
btnName: '新增资源类型',
pageSizeOptions: [10, 25, 50, 100], pageSizeOptions: [10, 25, 50, 100],
tablePage: { tablePage: {
total: 0, total: 0,
currentPage: 1, currentPage: 1,
pageSize: 50, pageSize: 50,
}, },
tableColumns: [
{
title: '资源类型名',
field: 'name',
minWidth: '175px',
fixed: 'left',
showOverflow: 'tooltip',
},
{
title: '描述',
field: 'description',
minWidth: '175px',
},
{
title: '权限',
field: 'id',
minWidth: '300px',
slots: {
default: 'id_default',
},
},
{
title: '操作',
field: 'action',
minWidth: '175px',
slots: { default: 'action_default' },
fixed: 'right',
},
],
searchName: '', searchName: '',
} }
}, },
@ -200,15 +172,10 @@ export default {
}, },
deleteResourceType(id) { deleteResourceType(id) {
deleteResourceTypeById(id).then((res) => { deleteResourceTypeById(id).then((res) => {
this.$message.success(`删除成功`) this.$message.success(this.$t('deleteSuccess'))
this.handleOk() this.handleOk()
}) })
// .catch(err => this.requestFailed(err))
}, },
// requestFailed(err) {
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
// this.$message.error(`${msg}`)
// },
handlePageChange({ currentPage, pageSize }) { handlePageChange({ currentPage, pageSize }) {
this.tablePage.currentPage = currentPage this.tablePage.currentPage = currentPage
this.tablePage.pageSize = pageSize this.tablePage.pageSize = pageSize

View File

@ -6,10 +6,10 @@
</a-tabs> </a-tabs>
<div class="acl-resources-header"> <div class="acl-resources-header">
<a-space> <a-space>
<a-button @click="handleCreate" type="primary">{{ btnName }}</a-button> <a-button @click="handleCreate" type="primary">{{ $t('acl.addResource') }}</a-button>
<a-input-search <a-input-search
class="ops-input" class="ops-input"
placeholder="搜索 | 资源名" :placeholder="`${$t('search')} | ${$t('acl.resource')}`"
v-model="searchName" v-model="searchName"
@search=" @search="
() => { () => {
@ -20,10 +20,10 @@
></a-input-search> ></a-input-search>
<div v-if="!!selectedRows.length" class="ops-list-batch-action"> <div v-if="!!selectedRows.length" class="ops-list-batch-action">
<span @click="handleBatchPerm">授权</span> <span @click="handleBatchPerm">{{ $t('grant') }}</span>
<a-divider type="vertical" /> <a-divider type="vertical" />
<span @click="handleBatchRevoke">权限回收</span> <span @click="handleBatchRevoke">{{ $t('acl.revoke') }}</span>
<span>选取: {{ selectedRows.length }} </span> <span>{{ $t('selectRows', { rows: selectedRows.length }) }}</span>
</div> </div>
</a-space> </a-space>
@ -36,7 +36,7 @@
$refs.resourceBatchPerm.open(currentType.id) $refs.resourceBatchPerm.open(currentType.id)
} }
" "
>便捷授权</a-button >{{ $t('acl.convenient') }}</a-button
> >
<a-switch <a-switch
v-model="isGroup" v-model="isGroup"
@ -50,7 +50,7 @@
$refs.xTable && $refs.xTable.getVxetableRef().clearCheckboxReserve() $refs.xTable && $refs.xTable.getVxetableRef().clearCheckboxReserve()
} }
" "
un-checked-children="" :un-checked-children="$t('acl.group2')"
></a-switch> ></a-switch>
</a-space> </a-space>
</div> </div>
@ -62,62 +62,63 @@
:data="tableData" :data="tableData"
highlight-hover-row highlight-hover-row
:height="`${windowHeight - 250}px`" :height="`${windowHeight - 250}px`"
:checkbox-config="{ reserve: true }" :checkbox-config="{ reserve: true, highlight: true, range: true }"
@checkbox-change="changeCheckbox" @checkbox-change="changeCheckbox"
@checkbox-all="changeCheckbox" @checkbox-all="changeCheckbox"
@checkbox-range-end="onSelectRangeEnd"
ref="xTable" ref="xTable"
row-id="id" row-id="id"
show-overflow show-overflow
resizable resizable
> >
<!-- 1 --> <!-- 1 -->
<vxe-table-column type="checkbox" fixed="left" :width="45"></vxe-table-column> <vxe-table-column type="checkbox" fixed="left" :width="60"></vxe-table-column>
<!-- 2 --> <!-- 2 -->
<vxe-table-column field="name" title="资源名" :min-widh="150" fixed="left" show-overflow> <vxe-table-column field="name" :title="$t('acl.resourceName')" :min-widh="150" fixed="left" show-overflow>
<template #title="{ row }"> <template #title="{row}">
{{ row.isGroup ? '资源组名' : '资源名' }} {{ row.isGroup ? $t('acl.groupName') : $t('acl.resourceName') }}
</template> </template>
</vxe-table-column> </vxe-table-column>
<!-- 3 --> <!-- 3 -->
<vxe-table-column field="user" title="创建者" :min-widh="100"> </vxe-table-column> <vxe-table-column field="user" :title="$t('acl.creator')" :min-widh="100"> </vxe-table-column>
<!-- 4 --> <!-- 4 -->
<vxe-table-column field="created_at" title="创建时间" :min-widh="220" align="center"> </vxe-table-column> <vxe-table-column field="created_at" :title="$t('created_at')" :min-widh="220" align="center"> </vxe-table-column>
<!-- 5 --> <!-- 5 -->
<vxe-table-column field="updated_at" title="最后修改时间" :min-widh="220" fixed="center"> </vxe-table-column> <vxe-table-column field="updated_at" :title="$t('updated_at')" :min-widh="220" fixed="center"> </vxe-table-column>
<!-- 6 --> <!-- 6 -->
<vxe-table-column <vxe-table-column
field="action" field="action"
title="操作" :title="$t('operation')"
:min-widh="200" :min-widh="200"
fixed="right" fixed="right"
align="center" align="center"
show-overflow> show-overflow>
<template #default="{ row }"> <template #default="{row}">
<span v-show="isGroup"> <span v-show="isGroup">
<a @click="handleDisplayMember(row)">成员</a> <a @click="handleDisplayMember(row)">{{ $t('acl.member') }}</a>
<a-divider type="vertical" /> <a-divider type="vertical" />
<a @click="handleGroupEdit(row)">编辑</a> <a @click="handleGroupEdit(row)">{{ $t('edit') }}</a>
<a-divider type="vertical" /> <a-divider type="vertical" />
</span> </span>
<a-tooltip title="查看授权"> <a-tooltip :title="$t('acl.viewAuth')">
<a @click="handlePerm(row)"><a-icon type="eye" /></a> <a @click="handlePerm(row)"><a-icon type="eye"/></a>
</a-tooltip> </a-tooltip>
<a-divider type="vertical" /> <a-divider type="vertical" />
<a-tooltip title="授权"> <a-tooltip :title="$t('grant')">
<a :style="{ color: '#4bbb13' }" @click="handlePermManage(row)"> <a :style="{ color: '#4bbb13' }" @click="handlePermManage(row)">
<a-icon type="usergroup-add" /> <a-icon type="usergroup-add" />
</a> </a>
</a-tooltip> </a-tooltip>
<a-divider type="vertical" /> <a-divider type="vertical" />
<a-popconfirm title="确认删除?" @confirm="handleDelete(row)" @cancel="cancel" okText="" cancelText=""> <a-popconfirm :title="$t('confirmDelete')" @confirm="handleDelete(row)" @cancel="cancel" :okText="$t('yes')" :cancelText="$t('no')">
<a style="color: red"><a-icon type="delete" /></a> <a style="color: red"><a-icon type="delete"/></a>
</a-popconfirm> </a-popconfirm>
</template> </template>
</vxe-table-column> </vxe-table-column>
@ -135,9 +136,9 @@
</vxe-pager> </vxe-pager>
</a-spin> </a-spin>
</div> </div>
<div v-else style="text-align: center; margin-top: 20%"> <div v-else style="text-align: center;margin-top:20%">
<a-icon style="font-size: 50px; margin-bottom: 20px; color: orange" type="info-circle" /> <a-icon style="font-size:50px; margin-bottom: 20px; color: orange" type="info-circle" />
<h3>暂无类型信息请先添加资源类型</h3> <h3>{{ $t('acl.addTypeTips') }}</h3>
</div> </div>
<resourceForm ref="resourceForm" @fresh="handleOk"> </resourceForm> <resourceForm ref="resourceForm" @fresh="handleOk"> </resourceForm>
<resourcePermForm ref="resourcePermForm"> </resourcePermForm> <resourcePermForm ref="resourcePermForm"> </resourcePermForm>
@ -187,7 +188,6 @@ export default {
pageSize: 50, pageSize: 50,
}, },
tableData: [], tableData: [],
btnName: '新增资源',
isGroup: false, isGroup: false,
allResourceTypes: [], allResourceTypes: [],
currentType: { id: 0 }, currentType: { id: 0 },
@ -196,7 +196,6 @@ export default {
selectedRows: [], selectedRows: [],
} }
}, },
beforeCreate() { beforeCreate() {
this.form = this.$form.createForm(this) this.form = this.$form.createForm(this)
}, },
@ -281,22 +280,16 @@ export default {
deleteResource(id) { deleteResource(id) {
if (!this.isGroup) { if (!this.isGroup) {
deleteResourceById(id, { app_id: this.$route.name.split('_')[0] }).then((res) => { deleteResourceById(id, { app_id: this.$route.name.split('_')[0] }).then((res) => {
this.$message.success(`删除成功`) this.$message.success(this.$t('deleteSuccess'))
this.handleOk() this.handleOk()
}) })
// .catch(err => this.requestFailed(err))
} else { } else {
deleteResourceGroup(id).then((res) => { deleteResourceGroup(id).then((res) => {
this.$message.success(`删除成功`) this.$message.success(this.$t('deleteSuccess'))
this.handleOk() this.handleOk()
}) })
// .catch(err => this.requestFailed(err))
} }
}, },
// requestFailed(err) {
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
// this.$message.error(`${msg}`)
// },
cancel() {}, cancel() {},
handlePageChange({ currentPage, pageSize }) { handlePageChange({ currentPage, pageSize }) {
this.tablePage.currentPage = currentPage this.tablePage.currentPage = currentPage
@ -309,6 +302,10 @@ export default {
.getVxetableRef() .getVxetableRef()
.getCheckboxRecords() .getCheckboxRecords()
.concat(this.$refs.xTable.getVxetableRef().getCheckboxReserveRecords()) .concat(this.$refs.xTable.getVxetableRef().getCheckboxReserveRecords())
console.log(this.selectedRows)
},
onSelectRangeEnd({ records }) {
this.selectedRows = records
}, },
handleBatchPerm() { handleBatchPerm() {
this.$refs['resourcePermManageForm'].editPerm(this.selectedRows, this.isGroup) this.$refs['resourcePermManageForm'].editPerm(this.selectedRows, this.isGroup)
@ -322,7 +319,7 @@ export default {
}, },
}, },
watch: { watch: {
'$route.name': function (newName, oldName) { '$route.name': function(newName, oldName) {
this.isGroup = false this.isGroup = false
this.tablePage = { this.tablePage = {
total: 0, total: 0,

View File

@ -1,12 +1,12 @@
<template> <template>
<div class="acl-roles"> <div class="acl-roles">
<div class="acl-roles-header"> <div class="acl-roles-header">
<a-button @click="handleCreate" type="primary">{{ btnName }}</a-button> <a-button @click="handleCreate" type="primary">{{ $t('acl.addVisualRole') }}</a-button>
<a-input-search <a-input-search
class="ops-input" class="ops-input"
allowClear allowClear
:style="{ display: 'inline', marginLeft: '10px', width: '200px' }" :style="{ display: 'inline', marginLeft: '10px', width: '200px' }"
placeholder="搜索 | 角色名" :placeholder="`${$t('search')} | ${$t('acl.role')}`"
v-model="searchName" v-model="searchName"
@search=" @search="
() => { () => {
@ -15,7 +15,7 @@
} }
" "
></a-input-search> ></a-input-search>
<a-checkbox :checked="is_all" @click="handleClickBoxChange">所有角色</a-checkbox> <a-checkbox :checked="is_all" @click="handleClickBoxChange">{{ $t('acl.allRole') }}</a-checkbox>
</div> </div>
<a-spin :spinning="loading"> <a-spin :spinning="loading">
<ops-table <ops-table
@ -31,22 +31,23 @@
> >
<vxe-table-column <vxe-table-column
field="name" field="name"
title="角色名" :title="$t('acl.role')"
:min-width="150" :min-width="150"
align="left" align="left"
fixed="left" fixed="left"
sortable sortable
show-overflow> show-overflow
>
</vxe-table-column> </vxe-table-column>
<!-- 2 --> <!-- 2 -->
<vxe-table-column field="is_app_admin" title="管理员" :min-width="100" align="center"> <vxe-table-column field="is_app_admin" :title="$t('admin')" :min-width="100" align="center">
<template #default="{row}"> <template #default="{row}">
<a-icon type="check" v-if="row.is_app_admin" /> <a-icon type="check" v-if="row.is_app_admin" />
</template> </template>
</vxe-table-column> </vxe-table-column>
<vxe-table-column field="id" title="继承自" :min-width="150"> <vxe-table-column field="id" :title="$t('acl.inheritedFrom')" :min-width="150">
<template #default="{row}"> <template #default="{row}">
<a-tag color="cyan" v-for="role in id2parents[row.id]" :key="role.id">{{ role.name }}</a-tag> <a-tag color="cyan" v-for="role in id2parents[row.id]" :key="role.id">{{ role.name }}</a-tag>
</template> </template>
@ -54,12 +55,12 @@
<vxe-table-column <vxe-table-column
field="uid" field="uid"
title="虚拟角色" :title="$t('acl.visualRole')"
:width="100" :width="120"
align="center" align="center"
:filters="[ :filters="[
{ label: '', value: 1 }, { label: $t('yes'), value: 1 },
{ label: '', value: 0 }, { label: $t('no'), value: 0 },
]" ]"
:filterMultiple="false" :filterMultiple="false"
:filter-method=" :filter-method="
@ -69,14 +70,14 @@
" "
> >
<template #default="{row}"> <template #default="{row}">
{{ row.uid ? '' : '' }} {{ row.uid ? $t('no') : $t('yes') }}
</template> </template>
</vxe-table-column> </vxe-table-column>
<vxe-table-column field="action" title="操作" :width="120" fixed="right"> <vxe-table-column field="action" :title="$t('operation')" :width="120" fixed="right">
<template #default="{row}"> <template #default="{row}">
<a-space> <a-space>
<a-tooltip title="资源列表"> <a-tooltip :title="$t('acl.resourceList')">
<a <a
v-if="$route.name !== 'acl_roles'" v-if="$route.name !== 'acl_roles'"
@click="handleDisplayUserResource(row)" @click="handleDisplayUserResource(row)"
@ -85,12 +86,18 @@
/></a> /></a>
</a-tooltip> </a-tooltip>
<a-tooltip <a-tooltip
title="用户列表" :title="$t('acl.userList')"
v-if="!row.uid" v-if="!row.uid"
><a @click="handleDisplayUserUnderRole(row)"><a-icon type="team"/></a ><a @click="handleDisplayUserUnderRole(row)"><a-icon type="team"/></a
></a-tooltip> ></a-tooltip>
<a @click="handleEdit(row)"><a-icon type="edit"/></a> <a @click="handleEdit(row)"><a-icon type="edit"/></a>
<a-popconfirm title="确认删除?" @confirm="handleDelete(row)" @cancel="cancel" okText="" cancelText=""> <a-popconfirm
:title="$t('confirmDelete')"
@confirm="handleDelete(row)"
@cancel="cancel"
:okText="$t('yes')"
:cancelText="$t('no')"
>
<a style="color: red"><a-icon type="delete"/></a> <a style="color: red"><a-icon type="delete"/></a>
</a-popconfirm> </a-popconfirm>
</a-space> </a-space>
@ -138,52 +145,6 @@ export default {
currentPage: 1, currentPage: 1,
pageSize: 50, pageSize: 50,
}, },
tableColumns: [
{
title: '角色名',
field: 'name',
sortable: true,
minWidth: '150px',
fixed: 'left',
showOverflow: 'tooltip',
},
{
title: '管理员',
field: 'is_app_admin',
minWidth: '100px',
align: 'center',
slots: { default: 'is_app_admin_default' },
},
{
title: '继承自',
field: 'id',
minWidth: '150px',
slots: { default: 'inherit_default' },
},
{
title: '虚拟角色',
field: 'uid',
minWidth: '100px',
align: 'center',
filters: [
{ label: '', value: 1 },
{ label: '', value: 0 },
],
filterMultiple: false,
filterMethod: ({ value, row }) => {
return value === !row.uid
},
slots: { default: 'isVisualRole_default' },
},
{
title: '操作',
minWidth: '280px',
field: 'action',
fixed: 'right',
slots: { default: 'action_default' },
},
],
btnName: '新增虚拟角色',
is_all: this.$route.name === 'acl_roles', is_all: this.$route.name === 'acl_roles',
tableData: [], tableData: [],
allRoles: [], allRoles: [],
@ -286,15 +247,10 @@ export default {
deleteRole(id) { deleteRole(id) {
deleteRoleById(id, { app_id: this.$route.name.split('_')[0] }).then((res) => { deleteRoleById(id, { app_id: this.$route.name.split('_')[0] }).then((res) => {
this.$message.success(`删除成功`) this.$message.success(this.$t('deleteSuccess'))
this.handleOk() this.handleOk()
}) })
// .catch(err => this.requestFailed(err))
}, },
// requestFailed(err) {
// const msg = ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试'
// this.$message.error(`${msg}`)
// },
cancel(e) { cancel(e) {
return false return false
}, },

View File

@ -15,9 +15,9 @@
</a-form-model-item> </a-form-model-item>
<a-form-model-item label=" " :colon="false"> <a-form-model-item label=" " :colon="false">
<a-space> <a-space>
<a-button type="primary" @click="changeVisible">{{ !visible ? '查看' : '隐藏' }}</a-button> <a-button type="primary" @click="changeVisible">{{ !visible ? $t('view') : $t('hide') }}</a-button>
<a-button type="danger" ghost @click="handleSumbit">重置</a-button> <a-button type="danger" ghost @click="handleSumbit">{{ $t('reset') }}</a-button>
<!-- <a-button @click="handleCancel">取消</a-button> --> <!-- <a-button @click="handleCancel">{{ $t('cancel') }}</a-button> -->
</a-space> </a-space>
</a-form-model-item> </a-form-model-item>
</a-form-model> </a-form-model>
@ -62,13 +62,13 @@ export default {
handleSumbit() { handleSumbit() {
const that = this const that = this
this.$confirm({ this.$confirm({
title: '重置', title: that.$t('reset'),
content: '确定重置用户密钥?', content: that.$t('acl.confirmResetSecret'),
onOk() { onOk() {
that.$refs.secretKeyForm.validate((valid) => { that.$refs.secretKeyForm.validate((valid) => {
if (valid) { if (valid) {
updateSecret().then((res) => { updateSecret().then((res) => {
that.$message.success('重置成功') that.$message.success(that.$t('operateSuccess'))
const { key, secret } = res const { key, secret } = res
that.form = { key, secret } that.form = { key, secret }
}) })

View File

@ -1,11 +1,11 @@
<template> <template>
<div class="acl-trigger"> <div class="acl-trigger">
<div class="acl-trigger-header"> <div class="acl-trigger-header">
<a-button type="primary" @click="handleCreateTrigger">新增触发器</a-button> <a-button type="primary" @click="handleCreateTrigger">{{ $t('acl.addTrigger') }}</a-button>
<a-input-search <a-input-search
class="ops-input" class="ops-input"
:style="{ display: 'inline', marginLeft: '10px', width: '200px' }" :style="{ display: 'inline', marginLeft: '10px', width: '200px' }"
placeholder="搜索 | 名称" :placeholder="`${$t('search')} | ${$t('name')}`"
v-model="searchName" v-model="searchName"
allowClear allowClear
@search="filter" @search="filter"
@ -46,18 +46,18 @@
<a-tag v-for="(p, index) in row.permissions" :key="index">{{ p }}</a-tag> <a-tag v-for="(p, index) in row.permissions" :key="index">{{ p }}</a-tag>
</template> </template>
<template #enabled_default="{row}"> <template #enabled_default="{row}">
<a-tag v-if="row.enabled" color="#2db7f5">启用</a-tag> <a-tag v-if="row.enabled" color="#2db7f5">{{ $t('acl.enable') }}</a-tag>
<a-tag v-else color="grey">禁用</a-tag> <a-tag v-else color="grey">{{ $t('acl.disable') }}</a-tag>
</template> </template>
<template #action_default="{row}"> <template #action_default="{row}">
<a-space> <a-space>
<a-tooltip title="应用"> <a-tooltip :title="$t('acl.apply')">
<a @click="handleApplyTrigger(row)" :style="{ color: '#0f9d58' }"><a-icon type="appstore"/></a> <a @click="handleApplyTrigger(row)" :style="{ color: '#0f9d58' }"><a-icon type="appstore"/></a>
</a-tooltip> </a-tooltip>
<a-tooltip title="取消"> <a-tooltip :title="$t('cancel')">
<a @click="handleCancelTrigger(row)" :style="{ color: 'orange' }"><a-icon type="stop"/></a> <a @click="handleCancelTrigger(row)" :style="{ color: 'orange' }"><a-icon type="stop"/></a>
</a-tooltip> </a-tooltip>
<a-tooltip title="查看正则匹配结果"> <a-tooltip :title="$t('acl.viewMatchResult')">
<a @click="handlePattern(row)" :style="{ color: 'purple' }"><a-icon type="eye"/></a> <a @click="handlePattern(row)" :style="{ color: 'purple' }"><a-icon type="eye"/></a>
</a-tooltip> </a-tooltip>
<a @click="handleEditTrigger(row)"><a-icon type="edit"/></a> <a @click="handleEditTrigger(row)"><a-icon type="edit"/></a>
@ -67,7 +67,7 @@
<template slot="empty"> <template slot="empty">
<div> <div>
<img :style="{ width: '100px' }" :src="require('@/assets/data_empty.png')" /> <img :style="{ width: '100px' }" :src="require('@/assets/data_empty.png')" />
<div>暂无数据</div> <div>{{ $t('noData') }}</div>
</div> </div>
</template> </template>
</vxe-grid> </vxe-grid>
@ -102,9 +102,19 @@ export default {
triggers: [], triggers: [],
id2parents: [], id2parents: [],
id2perms: {}, id2perms: {},
tableColumns: [ }
},
computed: {
...mapState({
windowHeight: (state) => state.windowHeight,
}),
app_id() {
return this.$route.name.split('_')[0]
},
tableColumns() {
return [
{ {
title: '名称', title: this.$t('name'),
field: 'name', field: 'name',
sortable: true, sortable: true,
minWidth: '150px', minWidth: '150px',
@ -112,7 +122,7 @@ export default {
showOverflow: 'tooltip', showOverflow: 'tooltip',
}, },
{ {
title: '资源名', title: this.$t('acl.resource'),
field: 'wildcard', field: 'wildcard',
minWidth: '250px', minWidth: '250px',
showOverflow: 'tooltip', showOverflow: 'tooltip',
@ -121,15 +131,15 @@ export default {
}, },
}, },
{ {
title: '资源类型', title: this.$t('acl.resourceType'),
field: 'resource_type_id', field: 'resource_type_id',
minWidth: '100px', minWidth: '120px',
slots: { slots: {
default: 'resourceTypeRender_default', default: 'resourceTypeRender_default',
}, },
}, },
{ {
title: '创建人', title: this.$t('acl.creator'),
field: 'users', field: 'users',
minWidth: '150px', minWidth: '150px',
showOverflow: 'tooltip', showOverflow: 'tooltip',
@ -138,7 +148,7 @@ export default {
}, },
}, },
{ {
title: '角色', title: this.$t('acl.allRole'),
field: 'roles', field: 'roles',
minWidth: '150px', minWidth: '150px',
slots: { slots: {
@ -172,7 +182,7 @@ export default {
}, },
}, },
{ {
title: '权限', title: this.$t('acl.permission'),
field: 'permissions', field: 'permissions',
minWidth: '250px', minWidth: '250px',
slots: { slots: {
@ -180,7 +190,7 @@ export default {
}, },
}, },
{ {
title: '状态', title: this.$t('status'),
field: 'enabled', field: 'enabled',
minWidth: '100px', minWidth: '100px',
slots: { slots: {
@ -188,7 +198,7 @@ export default {
}, },
}, },
{ {
title: '操作', title: this.$t('operation'),
field: 'action', field: 'action',
width: '120px', width: '120px',
fixed: 'right', fixed: 'right',
@ -196,8 +206,8 @@ export default {
default: 'action_default', default: 'action_default',
}, },
}, },
], ]
} },
}, },
created() { created() {
this.loadRoles() this.loadRoles()
@ -206,15 +216,6 @@ export default {
beforeMount() { beforeMount() {
this.loadTriggers() this.loadTriggers()
}, },
computed: {
...mapState({
windowHeight: (state) => state.windowHeight,
}),
app_id() {
return this.$route.name.split('_')[0]
},
},
methods: { methods: {
loadTriggers() { loadTriggers() {
this.searchName = '' this.searchName = ''
@ -244,11 +245,11 @@ export default {
handleDeleteTrigger(record) { handleDeleteTrigger(record) {
const that = this const that = this
this.$confirm({ this.$confirm({
title: '删除', title: that.$t('warning'),
content: '确认删除该触发器吗?', content: that.$t('acl.confirmDeleteTrigger'),
onOk() { onOk() {
deleteTrigger(record.id).then((res) => { deleteTrigger(record.id).then((res) => {
that.$message.success('删除成功') that.$message.success(that.$t('deleteSuccess'))
that.loadTriggers() that.loadTriggers()
}) })
// .catch(err => that.$httpError(err)) // .catch(err => that.$httpError(err))
@ -258,11 +259,11 @@ export default {
handleApplyTrigger(record) { handleApplyTrigger(record) {
const that = this const that = this
this.$confirm({ this.$confirm({
title: '规则应用', title: that.$t('acl.ruleApply'),
content: '是否确定应用该触发器?', content: that.$t('acl.triggerTip1'),
onOk() { onOk() {
applyTrigger(record.id).then((res) => { applyTrigger(record.id).then((res) => {
that.$message.success('提交成功!') that.$message.success(that.$t('operateSuccess'))
}) })
// .catch(err => that.$httpError(err)) // .catch(err => that.$httpError(err))
}, },
@ -271,11 +272,11 @@ export default {
handleCancelTrigger(record) { handleCancelTrigger(record) {
const that = this const that = this
this.$confirm({ this.$confirm({
title: '规则应用', title: that.$t('acl.ruleApply'),
content: '是否取消应用该触发器?', content: that.$t('acl.triggerTip2'),
onOk() { onOk() {
cancelTrigger(record.id).then((res) => { cancelTrigger(record.id).then((res) => {
that.$message.success('提交成功!') that.$message.success(that.$t('operateSuccess'))
}) })
// .catch(err => that.$httpError(err)) // .catch(err => that.$httpError(err))
}, },

View File

@ -1,198 +1,202 @@
<template> <template>
<div class="acl-users"> <div class="acl-users">
<div class="acl-users-header"> <div class="acl-users-header">
<a-button v-if="isAclAdmin" @click="handleCreate" type="primary">{{ btnName }}</a-button> <a-button v-if="isAclAdmin" @click="handleCreate" type="primary">{{ btnName }}</a-button>
<a-input-search <a-input-search
class="ops-input" class="ops-input"
allowClear allowClear
:style="{ display: 'inline', marginLeft: '10px' }" :style="{ width: '300px', display: 'inline', marginLeft: '10px' }"
placeholder="搜索 | 用户名、中文名" :placeholder="`${$t('search')} | ${$t('acl.nickname')} 、 ${$t('acl.username')}`"
v-model="searchName" v-model="searchName"
></a-input-search> ></a-input-search>
</div> </div>
<a-spin :spinning="loading"> <a-spin :spinning="loading">
<vxe-grid <vxe-grid
stripe stripe
class="ops-stripe-table" class="ops-stripe-table"
:columns="tableColumns" :columns="tableColumns"
:data="tableData" :data="tableData"
show-overflow show-overflow
highlight-hover-row highlight-hover-row
:height="`${windowHeight - 165}px`" :height="`${windowHeight - 165}px`"
size="small" size="small"
> >
<template #block_default="{row}"> <template #block_default="{row}">
<a-icon type="lock" v-if="row.block" /> <a-icon type="lock" v-if="row.block" />
</template> </template>
<template #action_default="{row}"> <template #action_default="{row}">
<a-space> <a-space>
<a :disabled="isAclAdmin ? false : true" @click="handleEdit(row)"> <a :disabled="isAclAdmin ? false : true" @click="handleEdit(row)">
<a-icon type="edit" /> <a-icon type="edit" />
</a> </a>
<a-tooltip title="权限汇总"> <a-tooltip :title="$t('acl.summaryPermissions')">
<a @click="handlePermCollect(row)"><a-icon type="solution"/></a> <a @click="handlePermCollect(row)"><a-icon type="solution"/></a>
</a-tooltip> </a-tooltip>
<a-popconfirm :title="`确认删除【${row.nickname || row.username}】?`" @confirm="deleteUser(row.uid)"> <a-popconfirm :title="$t('confirmDelete')" @confirm="deleteUser(row.uid)">
<a :style="{ color: 'red' }"><ops-icon type="icon-xianxing-delete"/></a> <a :style="{ color: 'red' }"><ops-icon type="icon-xianxing-delete"/></a>
</a-popconfirm> </a-popconfirm>
</a-space> </a-space>
</template> </template>
</vxe-grid> </vxe-grid>
</a-spin> </a-spin>
<userForm ref="userForm" :handleOk="handleOk"> </userForm> <userForm ref="userForm" :handleOk="handleOk"> </userForm>
<perm-collect-form ref="permCollectForm"></perm-collect-form> <perm-collect-form ref="permCollectForm"></perm-collect-form>
</div> </div>
</template> </template>
<script> <script>
import { mapState } from 'vuex' import { mapState } from 'vuex'
import userForm from './module/userForm' import userForm from './module/userForm'
import PermCollectForm from './module/permCollectForm' import PermCollectForm from './module/permCollectForm'
import { deleteUserById, searchUser, getOnDutyUser } from '@/modules/acl/api/user' import { deleteUserById, searchUser, getOnDutyUser } from '@/modules/acl/api/user'
export default { export default {
name: 'Users', name: 'Users',
components: { components: {
userForm, userForm,
PermCollectForm, PermCollectForm,
}, },
data() { data() {
return { return {
loading: false, loading: false,
tableColumns: [ onDutuUids: [],
{ allUsers: [],
title: '用户名', tableData: [],
field: 'username', searchName: '',
sortable: true, }
minWidth: '100px', },
fixed: 'left', beforeCreate() {
}, this.form = this.$form.createForm(this)
{ },
title: '中文名', async beforeMount() {
field: 'nickname', this.loading = true
minWidth: '100px', await this.getOnDutyUser()
}, this.search()
{ },
title: '加入时间', computed: {
field: 'date_joined', ...mapState({
minWidth: '160px', windowHeight: (state) => state.windowHeight,
align: 'center', }),
sortable: true, isAclAdmin: function() {
}, if (this.$store.state.user.roles.permissions.filter((item) => item === 'acl_admin').length > 0) {
{ return true
title: '锁定', } else {
field: 'block', return false
width: '150px', }
align: 'center', },
slots: { tableColumns() {
default: 'block_default', return [
}, {
}, title: this.$t('acl.username'),
{ field: 'username',
title: '操作', sortable: true,
field: 'action', minWidth: '100px',
width: '150px', fixed: 'left',
fixed: 'right', },
align: 'center', {
slots: { title: this.$t('acl.nickname'),
default: 'action_default', field: 'nickname',
}, minWidth: '100px',
}, },
], {
onDutuUids: [], title: this.$t('acl.joined_at'),
btnName: '新增用户', field: 'date_joined',
allUsers: [], minWidth: '160px',
tableData: [], align: 'center',
searchName: '', sortable: true,
} },
}, {
beforeCreate() { title: this.$t('acl.block'),
this.form = this.$form.createForm(this) field: 'block',
}, width: '150px',
async beforeMount() { align: 'center',
this.loading = true slots: {
await this.getOnDutyUser() default: 'block_default',
this.search() },
}, },
computed: { {
...mapState({ title: this.$t('operation'),
windowHeight: (state) => state.windowHeight, field: 'action',
}), width: '150px',
isAclAdmin: function() { fixed: 'right',
if (this.$store.state.user.roles.permissions.filter((item) => item === 'acl_admin').length > 0) { align: 'center',
return true slots: {
} else { default: 'action_default',
return false },
} },
}, ]
}, },
watch: { btnName() {
searchName: { return this.$t('acl.addUser')
immediate: true, },
handler(newVal, oldVal) { },
if (newVal) { watch: {
this.tableData = this.allUsers.filter( searchName: {
(item) => immediate: true,
(item.username && item.username.toLowerCase().includes(newVal.toLowerCase())) || handler(newVal, oldVal) {
(item.nickname && item.nickname.toLowerCase().includes(newVal.toLowerCase())) if (newVal) {
) this.tableData = this.allUsers.filter(
} else { (item) =>
this.tableData = this.allUsers (item.username && item.username.toLowerCase().includes(newVal.toLowerCase())) ||
} (item.nickname && item.nickname.toLowerCase().includes(newVal.toLowerCase()))
}, )
}, } else {
}, this.tableData = this.allUsers
mounted() {}, }
inject: ['reload'], },
},
methods: { },
async getOnDutyUser() { mounted() {},
await getOnDutyUser().then((res) => { inject: ['reload'],
this.onDutuUids = res.map((i) => i.uid)
}) methods: {
}, async getOnDutyUser() {
search() { await getOnDutyUser().then((res) => {
searchUser({ page_size: 10000 }).then((res) => { this.onDutuUids = res.map((i) => i.uid)
const ret = res.users.filter((u) => this.onDutuUids.includes(u.uid)) })
this.allUsers = ret },
this.tableData = ret search() {
this.loading = false searchUser({ page_size: 10000 }).then((res) => {
}) const ret = res.users.filter((u) => this.onDutuUids.includes(u.uid))
}, this.allUsers = ret
handlePermCollect(record) { this.tableData = ret
this.$refs['permCollectForm'].collect(record) this.loading = false
}, })
handleEdit(record) { },
this.$refs.userForm.handleEdit(record) handlePermCollect(record) {
}, this.$refs['permCollectForm'].collect(record)
async handleOk() { },
this.searchName = '' handleEdit(record) {
await this.getOnDutyUser() this.$refs.userForm.handleEdit(record)
this.search() },
}, async handleOk() {
handleCreate() { this.searchName = ''
this.$refs.userForm.handleCreate() await this.getOnDutyUser()
}, this.search()
deleteUser(uid) { },
deleteUserById(uid).then((res) => { handleCreate() {
this.$message.success(`删除成功`) this.$refs.userForm.handleCreate()
this.handleOk() },
}) deleteUser(uid) {
}, deleteUserById(uid).then((res) => {
}, this.$message.success(this.$t('deleteSuccess'))
} this.handleOk()
</script> })
},
<style lang="less" scoped> },
.acl-users { }
border-radius: 15px; </script>
background-color: #fff;
height: calc(100vh - 64px); <style lang="less" scoped>
margin-bottom: -24px; .acl-users {
padding: 24px; border-radius: 15px;
.acl-users-header { background-color: #fff;
display: inline-flex; height: calc(100vh - 64px);
margin-bottom: 15px; margin-bottom: -24px;
} padding: 24px;
} .acl-users-header {
</style> display: inline-flex;
margin-bottom: 15px;
}
}
</style>