mirror of
https://gitee.com/log4j/pig-ui.git
synced 2024-12-23 05:40:20 +08:00
✨ Introducing new features. 增加app客户管理,角色管理等
This commit is contained in:
parent
b4aabe36d6
commit
c8306ca5fd
64
src/api/app/approle.ts
Normal file
64
src/api/app/approle.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import request from "/@/utils/request";
|
||||
|
||||
export function fetchList(query: any) {
|
||||
return request({
|
||||
url: '/admin/approle/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function list() {
|
||||
return request({
|
||||
url: '/admin/approle/list',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function addObj(obj: any) {
|
||||
return request({
|
||||
url: '/admin/approle',
|
||||
method: 'post',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
|
||||
export function getObj(id: string) {
|
||||
return request({
|
||||
url: '/admin/approle/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function delObj(id: string) {
|
||||
return request({
|
||||
url: '/admin/approle/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function putObj(obj: any) {
|
||||
return request({
|
||||
url: '/admin/approle',
|
||||
method: 'put',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchRoleTree(roleId: string) {
|
||||
return request({
|
||||
url: '/admin/appmenu/tree/' + roleId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function permissionUpd(roleId: string, menuIds: string) {
|
||||
return request({
|
||||
url: '/admin/approle/menu',
|
||||
method: 'put',
|
||||
data: {
|
||||
roleId: roleId,
|
||||
menuIds: menuIds
|
||||
}
|
||||
})
|
||||
}
|
39
src/api/app/approlemenu.ts
Normal file
39
src/api/app/approlemenu.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import request from "/@/utils/request";
|
||||
|
||||
export function fetchList(query: any) {
|
||||
return request({
|
||||
url: '/admin/approlemenu/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function addObj(obj: any) {
|
||||
return request({
|
||||
url: '/admin/approlemenu',
|
||||
method: 'post',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
|
||||
export function getObj(id:string) {
|
||||
return request({
|
||||
url: '/admin/approlemenu/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function delObj(id:string) {
|
||||
return request({
|
||||
url: '/admin/approlemenu/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function putObj(obj: string) {
|
||||
return request({
|
||||
url: '/admin/approlemenu',
|
||||
method: 'put',
|
||||
data: obj
|
||||
})
|
||||
}
|
39
src/api/app/appuser.ts
Normal file
39
src/api/app/appuser.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import request from "/@/utils/request"
|
||||
|
||||
export function fetchList(query: any) {
|
||||
return request({
|
||||
url: '/admin/appuser/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function addObj(obj: any) {
|
||||
return request({
|
||||
url: '/admin/appuser',
|
||||
method: 'post',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
|
||||
export function getObj(id: string) {
|
||||
return request({
|
||||
url: '/admin/appuser/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function delObj(id: string) {
|
||||
return request({
|
||||
url: '/admin/appuser/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function putObj(obj: any) {
|
||||
return request({
|
||||
url: '/admin/appuser',
|
||||
method: 'put',
|
||||
data: obj
|
||||
})
|
||||
}
|
39
src/api/app/appuserrole.ts
Normal file
39
src/api/app/appuserrole.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import request from "/@/utils/request"
|
||||
|
||||
export function fetchList(query: any) {
|
||||
return request({
|
||||
url: '/admin/appuserrole/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function addObj(obj: any) {
|
||||
return request({
|
||||
url: '/admin/appuserrole',
|
||||
method: 'post',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
|
||||
export function getObj(id: string) {
|
||||
return request({
|
||||
url: '/admin/appuserrole/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function delObj(id: string) {
|
||||
return request({
|
||||
url: '/admin/appuserrole/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function putObj(obj: any) {
|
||||
return request({
|
||||
url: '/admin/appuserrole',
|
||||
method: 'put',
|
||||
data: obj
|
||||
})
|
||||
}
|
@ -39,7 +39,7 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20" v-if="state.ruleForm.menuType !== '1'">
|
||||
<el-form-item :label="$t('sysmenu.keepAlive')" prop="keepAlive">
|
||||
<el-form-item :label="$t('sysmenu.visible')" prop="visible">
|
||||
<el-radio-group v-model="state.ruleForm.visible">
|
||||
<el-radio-button label="1">显示</el-radio-button>
|
||||
<el-radio-button label="0">隐藏</el-radio-button>
|
||||
|
@ -5,7 +5,7 @@ export default {
|
||||
sortOrder: 'sortOrder',
|
||||
path: 'path',
|
||||
menuType: 'menuType',
|
||||
keepAlive: 'keepAlive',
|
||||
visible: 'visible',
|
||||
permission: 'permission',
|
||||
inputNameTip: 'input name',
|
||||
parentId: 'parent menu'
|
||||
|
@ -5,7 +5,7 @@ export default {
|
||||
sortOrder: '排序',
|
||||
path: '路由路径',
|
||||
menuType: '菜单类型',
|
||||
keepAlive: '缓冲',
|
||||
visible: '显示状态',
|
||||
permission: '权限标识',
|
||||
inputNameTip: '请输入菜单名称',
|
||||
parentId: '上级菜单'
|
||||
|
@ -19,15 +19,14 @@
|
||||
<el-table-column prop="path" :label="$t('appmenu.path')" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column :label="$t('appmenu.menuType')" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.menuType === '0'" type="success">左菜单</el-tag>
|
||||
<el-tag v-if="scope.row.menuType === '2'" type="success">顶菜单</el-tag>
|
||||
<el-tag v-if="scope.row.menuType === '1'" type="info">按钮</el-tag>
|
||||
<el-tag v-if="scope.row.menuType === '0'" type="success">页面</el-tag>
|
||||
<el-tag v-if="scope.row.menuType === '2'" type="success">按钮</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('appmenu.keepAlive')" show-overflow-tooltip>
|
||||
<el-table-column :label="$t('appmenu.visible')" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.keepAlive === '0'" type="info">关闭</el-tag>
|
||||
<el-tag v-if="scope.row.keepAlive === '1'" type="success">开启</el-tag>
|
||||
<el-tag v-if="scope.row.visible === '0'" type="info">关闭</el-tag>
|
||||
<el-tag v-if="scope.row.visible === '1'" type="success">开启</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="permission" :label="$t('appmenu.permission')"
|
||||
|
156
src/views/app/approle/form.vue
Normal file
156
src/views/app/approle/form.vue
Normal file
@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<el-dialog :title="form.roleId ? $t('common.editBtn') : $t('common.addBtn')" v-model="visible"
|
||||
:close-on-click-modal="false" draggable>
|
||||
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px">
|
||||
<el-row :gutter="35">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="角色名称" prop="roleName">
|
||||
<el-input v-model="form.roleName" placeholder="请输入角色名称" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="角色标识" prop="roleCode">
|
||||
<el-input v-model="form.roleCode" placeholder="请输入角色标识" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="角色描述" prop="roleDesc">
|
||||
<el-input v-model="form.roleDesc" type="textarea" placeholder="请输入角色描述" maxlength="150"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false" >{{ $t('common.cancelButtonText') }}</el-button>
|
||||
<el-button type="primary" @click="onSubmit" >{{ $t('common.confirmButtonText') }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="systemRoleDialog">import { rule } from '/@/utils/validate';
|
||||
|
||||
// 定义子组件向父组件传值/事件
|
||||
const emit = defineEmits(['refresh']);
|
||||
import { useMessage } from "/@/hooks/message";
|
||||
import { getObj, addObj, putObj } from '/@/api/app/approle'
|
||||
import { useI18n } from "vue-i18n"
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref();
|
||||
const deptTreeRef = ref()
|
||||
const visible = ref(false)
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
roleId: '',
|
||||
roleName: '',
|
||||
roleCode: '',
|
||||
roleDesc: '',
|
||||
dsType: 0,
|
||||
dsScope: ''
|
||||
});
|
||||
|
||||
// 页面对应元数据
|
||||
const dataForm = reactive({
|
||||
deptData: [],
|
||||
checkedDsScope: [],
|
||||
deptProps: {
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}
|
||||
});
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = ref(
|
||||
{
|
||||
roleName: [
|
||||
{ required: true, message: '角色名称不能为空', trigger: 'blur' },
|
||||
{ min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }
|
||||
],
|
||||
roleCode: [
|
||||
{ required: true, message: '角色标识不能为空', trigger: 'blur' },
|
||||
{ min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' },
|
||||
{ validator: rule.validatorKey, trigger: 'blur' }
|
||||
],
|
||||
roleDesc: [{ max: 128, message: '长度在 128 个字符内', trigger: 'blur' }],
|
||||
dsType: [{ required: true, message: "请选择数据权限类型", trigger: "blur" }]
|
||||
}
|
||||
)
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = (id: string) => {
|
||||
visible.value = true
|
||||
form.roleId = ''
|
||||
|
||||
// 重置表单数据
|
||||
if (dataFormRef.value) {
|
||||
dataFormRef.value.resetFields()
|
||||
}
|
||||
|
||||
// 获取角色信息
|
||||
if (id) {
|
||||
form.roleId = id
|
||||
getRoleData(id)
|
||||
}
|
||||
};
|
||||
|
||||
// 提交
|
||||
const onSubmit = () => {
|
||||
if (form.dsType === 1) {
|
||||
form.dsScope = deptTreeRef.value.getCheckedKeys().join(',')
|
||||
} else {
|
||||
form.dsScope = ''
|
||||
}
|
||||
|
||||
dataFormRef.value.validate((valid: boolean) => {
|
||||
if (!valid) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 更新
|
||||
if (form.roleId) {
|
||||
putObj(form).then(() => {
|
||||
useMessage().success(t('common.editSuccessText'))
|
||||
visible.value = false // 关闭弹窗
|
||||
emit('refresh')
|
||||
}).catch((err: any) => {
|
||||
useMessage().error(err.msg)
|
||||
})
|
||||
} else {
|
||||
addObj(form).then(() => {
|
||||
useMessage().success(t('common.addSuccessText'))
|
||||
visible.value = false // 关闭弹窗
|
||||
emit('refresh')
|
||||
}).catch((err: any) => {
|
||||
useMessage().error(err.msg)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
};
|
||||
|
||||
// 初始化角色数据
|
||||
const getRoleData = (id: string) => {
|
||||
// 获取部门数据
|
||||
getObj(id).then((res: any) => {
|
||||
Object.assign(form, res.data)
|
||||
if (res.data.dsScope) {
|
||||
dataForm.checkedDsScope = (res.data.dsScope).split(',')
|
||||
} else {
|
||||
dataForm.checkedDsScope = []
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
8
src/views/app/approle/i18n/en.ts
Normal file
8
src/views/app/approle/i18n/en.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export default {
|
||||
approle: {
|
||||
index: 'index',
|
||||
roleName: 'roleName',
|
||||
inputRoleNameTip: 'input roleName',
|
||||
permissionTip: 'grant',
|
||||
}
|
||||
}
|
8
src/views/app/approle/i18n/zh-cn.ts
Normal file
8
src/views/app/approle/i18n/zh-cn.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export default {
|
||||
approle: {
|
||||
index: '序号',
|
||||
roleName: '角色名',
|
||||
inputRoleNameTip: '请输入角色名称',
|
||||
permissionTip: '授权',
|
||||
}
|
||||
}
|
148
src/views/app/approle/index.vue
Normal file
148
src/views/app/approle/index.vue
Normal file
@ -0,0 +1,148 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<el-card shadow="hover" class="layout-padding-auto">
|
||||
<el-row shadow="hover" v-show="showSearch" class="mb8">
|
||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true">
|
||||
<el-form-item :label="$t('approle.roleName')" prop="roleName">
|
||||
<el-input :placeholder="$t('approle.inputRoleNameTip')" v-model="state.queryForm.roleName"
|
||||
style="max-width: 180px" />
|
||||
</el-form-item>
|
||||
<el-form-item class="ml2">
|
||||
<el-button icon="search" type="primary" @click="getDataList">
|
||||
{{ $t('common.queryBtn') }}
|
||||
</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">{{ $t('common.resetBtn') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button icon="folder-add" type="primary" class="ml10" @click="roleDialogRef.openDialog()" v-auth="'app_approle_add'">
|
||||
{{ $t('common.addBtn') }}
|
||||
</el-button>
|
||||
<el-button icon="upload-filled" type="primary" class="ml10" @click="excelUploadRef.show()" v-auth="'app_approle_export'">
|
||||
{{ $t('common.importBtn') }}
|
||||
</el-button>
|
||||
<el-button icon="Download" type="primary" class="ml10" @click="exportExcel">
|
||||
{{ $t('common.exportBtn') }}
|
||||
</el-button>
|
||||
<el-button :disabled="multiple" icon="Delete" type="primary" class="ml10" v-auth="'app_approle_del'"
|
||||
@click="handleDelete(undefined)">
|
||||
{{ $t('common.delBtn') }}
|
||||
</el-button>
|
||||
<right-toolbar v-model:showSearch="showSearch" class="ml10" style="float: right;margin-right: 20px"
|
||||
@queryTable="getDataList"></right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
<el-table :data="state.dataList" v-loading="state.loading" style="width: 100%"
|
||||
@selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<el-table-column type="index" label="序号" width="80" />
|
||||
<el-table-column prop="roleName" label="角色名称" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="roleCode" label="角色标识" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="roleDesc" label="角色描述" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column :label="$t('common.action')" width="150">
|
||||
<template #default="scope">
|
||||
<el-button text type="primary" v-auth="'app_approle_edit'"
|
||||
@click="roleDialogRef.openDialog(scope.row.roleId)">{{ $t('common.editBtn') }}</el-button>
|
||||
|
||||
<el-button text type="primary" v-auth="'app_approle_del'" @click="handleDelete(scope.row)">{{
|
||||
$t('common.delBtn')
|
||||
}}</el-button>
|
||||
|
||||
<el-button text type="primary" @click="permessionRef.openDialog(scope.row)" v-auth="'app_approle_perm'">{{
|
||||
$t('approle.permissionTip')
|
||||
}}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" v-bind="state.pagination" />
|
||||
</el-card>
|
||||
|
||||
<!-- 角色编辑、新增 -->
|
||||
<role-dialog ref="roleDialogRef" @refresh="getDataList()" />
|
||||
<!-- 导入角色 -->
|
||||
<upload-excel ref="excelUploadRef" :title="$t('sysuser.importUserTip')" url="/admin/role/import"
|
||||
temp-url="/admin/sys-file/local/file/role.xlsx" @refreshDataList="getDataList" />
|
||||
<!-- 授权 -->
|
||||
<permession ref="permessionRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="systemRole">
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj } from "/@/api/app/approle";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
// 引入组件
|
||||
const RoleDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||
const Permession = defineAsyncComponent(() => import('./permession.vue'))
|
||||
const { t } = useI18n()
|
||||
|
||||
// 定义变量内容
|
||||
const roleDialogRef = ref()
|
||||
const permessionRef = ref()
|
||||
const excelUploadRef = ref()
|
||||
const queryRef = ref()
|
||||
const showSearch = ref(true)
|
||||
// 多选rows
|
||||
const selectObjs = ref([])
|
||||
// 是否可以多选
|
||||
const multiple = ref(true)
|
||||
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
roleName: ''
|
||||
},
|
||||
pageList: fetchList // H
|
||||
});
|
||||
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
downBlobFile
|
||||
} = useTable(state)
|
||||
|
||||
|
||||
// 清空搜索条件
|
||||
const resetQuery = () => {
|
||||
queryRef.value.resetFields()
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 多选事件
|
||||
const handleSelectionChange = (val: any) => {
|
||||
selectObjs.value = val
|
||||
multiple.value = !val.length
|
||||
}
|
||||
|
||||
// 导出excel
|
||||
const exportExcel = () => {
|
||||
downBlobFile('/admin/approle/export', state.queryForm, 'approle.xlsx')
|
||||
}
|
||||
|
||||
// 删除角色
|
||||
const handleDelete = (row: any) => {
|
||||
if (!row) {
|
||||
selectObjs.value.forEach((val: any) => {
|
||||
handleDelete(val)
|
||||
});
|
||||
return
|
||||
}
|
||||
|
||||
useMessageBox().confirm(`${t('common.delConfirmText')}:${row.roleName}?`)
|
||||
.then(() => {
|
||||
delObj(row.roleId).then(() => {
|
||||
getDataList();
|
||||
useMessage().success(t('common.delSuccessText'));
|
||||
}).catch((err: any) => {
|
||||
useMessage().error(err.msg)
|
||||
})
|
||||
})
|
||||
};
|
||||
</script>
|
112
src/views/app/approle/permession.vue
Normal file
112
src/views/app/approle/permession.vue
Normal file
@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<div class="system-role-dialog-container">
|
||||
<el-dialog :title="state.dialog.title" v-model="state.dialog.isShowDialog" :close-on-click-modal="false" draggable>
|
||||
<el-tree
|
||||
ref="menuTree"
|
||||
:data="state.treeData"
|
||||
:default-checked-keys="state.checkedKeys"
|
||||
:check-strictly="false"
|
||||
:props="state.defaultProps"
|
||||
class="filter-tree"
|
||||
node-key="id"
|
||||
highlight-current
|
||||
show-checkbox
|
||||
default-expand-all/>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="onCancel" size="default">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default">{{ state.dialog.submitTxt }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="role-permession">
|
||||
import {fetchRoleTree, permissionUpd} from '/@/api/app/approle'
|
||||
import {pageList} from '/@/api/app/appmenu'
|
||||
import {useMessage} from "/@/hooks/message";
|
||||
import {Ref} from "vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const {t} = useI18n();
|
||||
|
||||
|
||||
const menuTree = ref()
|
||||
|
||||
const state = reactive({
|
||||
checkedKeys: [] as any[],
|
||||
treeData: [] as any[],
|
||||
defaultProps: {
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
},
|
||||
roleId: '',
|
||||
dialog: {
|
||||
isShowDialog: false,
|
||||
title: '分配权限',
|
||||
submitTxt: '更新',
|
||||
},
|
||||
});
|
||||
|
||||
const checkedKeys: Ref<any[]> = ref([])
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = (row: any) => {
|
||||
state.checkedKeys = []
|
||||
state.treeData = []
|
||||
checkedKeys.value = []
|
||||
state.roleId = row.roleId
|
||||
fetchRoleTree(row.roleId).then(res => {
|
||||
checkedKeys.value = res.data
|
||||
return pageList()
|
||||
}).then(r => {
|
||||
state.treeData = r.data
|
||||
state.checkedKeys = resolveAllEunuchNodeId(state.treeData, checkedKeys.value, [])
|
||||
})
|
||||
state.dialog.isShowDialog = true;
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.dialog.isShowDialog = false;
|
||||
};
|
||||
// 取消
|
||||
const onCancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
const onSubmit = () => {
|
||||
const menuIds = menuTree.value.getCheckedKeys().join(',').concat(',').concat(menuTree.value.getHalfCheckedKeys().join(','))
|
||||
permissionUpd(state.roleId, menuIds).then(() => {
|
||||
state.dialog.isShowDialog = false;
|
||||
useMessage().success(t('common.editSuccessText'))
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
const resolveAllEunuchNodeId = (json: any[], idArr: any[], temp: any[]) => {
|
||||
for (let i = 0; i < json.length; i++) {
|
||||
const item = json[i]
|
||||
// 国际化
|
||||
item.name = t(item.name)
|
||||
// 存在子节点,递归遍历;不存在子节点,将json的id添加到临时数组中
|
||||
if (item.children && item.children.length !== 0) {
|
||||
resolveAllEunuchNodeId(item.children, idArr, temp)
|
||||
} else {
|
||||
temp.push(idArr.filter(id => id === item.id))
|
||||
}
|
||||
}
|
||||
return temp
|
||||
}
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
209
src/views/app/appuser/form.vue
Normal file
209
src/views/app/appuser/form.vue
Normal file
@ -0,0 +1,209 @@
|
||||
<template>
|
||||
<div class="system-user-dialog-container">
|
||||
<el-dialog :title="dataForm.userId ? $t('common.editBtn') : $t('common.addBtn')" v-model="visible"
|
||||
:close-on-click-modal="false" draggable>
|
||||
<el-form ref="dataFormRef" :model="dataForm" :rules="dataRules" size="default" label-width="90px">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item :label="$t('appuser.username')" prop="username">
|
||||
<el-input v-model="dataForm.username" placeholder="请输入用户名" :disabled="dataForm.userId !== ''"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item :label="$t('appuser.password')" prop="password">
|
||||
<el-input v-model="dataForm.password" type="password" placeholder="请输入密码" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item :label="$t('appuser.name')" prop="name">
|
||||
<el-input v-model="dataForm.name" placeholder="请输入姓名" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item :label="$t('appuser.phone')" prop="phone">
|
||||
<el-input v-model="dataForm.phone" placeholder="请输入手机号" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item :label="$t('appuser.role')" prop="role">
|
||||
<el-select v-model="dataForm.role" placeholder="请选择角色" clearable class="w100" multiple>
|
||||
<el-option v-for="item in roleData" :key="item.roleId" :label="item.roleName" :value="item.roleId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item :label="$t('appuser.email')" prop="email">
|
||||
<el-input v-model="dataForm.email" placeholder="请输入邮箱" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item :label="$t('appuser.nickname')" prop="nickname">
|
||||
<el-input v-model="dataForm.nickname" placeholder="请输入昵称" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item :label="$t('appuser.lockFlag')" prop="lockFlag">
|
||||
<el-radio-group v-model="dataForm.lockFlag">
|
||||
<el-radio :label="item.value" v-for="(item, index) in lock_flag" border :key="index">{{ item.label }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false" size="default">{{ $t('common.cancelButtonText') }}</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default">{{ $t('common.confirmButtonText') }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="systemUserDialog">
|
||||
import { getObj, addObj, putObj } from '/@/api/app/appuser'
|
||||
import { list as roleList } from '/@/api/app/approle'
|
||||
import { useDict } from "/@/hooks/dict";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
// 定义刷新表格emit
|
||||
const emit = defineEmits(['refresh']);
|
||||
// @ts-ignore
|
||||
const { lock_flag } = useDict('lock_flag')
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref();
|
||||
const visible = ref(false)
|
||||
const roleData = ref<any[]>([])
|
||||
|
||||
const dataForm = reactive({
|
||||
userId: '',
|
||||
username: '',
|
||||
password: '' as String | undefined,
|
||||
salt: '',
|
||||
wxOpenid: '',
|
||||
qqOpenid: '',
|
||||
lockFlag: '0',
|
||||
phone: '' as String | undefined,
|
||||
deptId: '',
|
||||
roleList: [],
|
||||
postList: [],
|
||||
nickname: '',
|
||||
name: '',
|
||||
email: '',
|
||||
post: [] as String[],
|
||||
role: [] as String[],
|
||||
});
|
||||
|
||||
|
||||
const dataRules = ref(
|
||||
{
|
||||
username: [{ required: true, message: "用户名不能为空", trigger: "blur" }, {
|
||||
min: 5,
|
||||
max: 20,
|
||||
message: "用户名称长度必须介于 5 和 20 之间",
|
||||
trigger: "blur"
|
||||
}],
|
||||
password: [{ required: true, message: "密码不能为空", trigger: "blur" }, {
|
||||
min: 6,
|
||||
max: 20,
|
||||
message: "用户密码长度必须介于 6 和 20 之间",
|
||||
trigger: "blur"
|
||||
}],
|
||||
name: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
|
||||
role: [{ required: true, message: "角色不能为空", trigger: "blur" }],
|
||||
phone: [{ required: true, message: "手机号不能为空", trigger: "blur" }, {
|
||||
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
|
||||
message: "请输入正确的手机号码",
|
||||
trigger: "blur"
|
||||
}],
|
||||
email: [{ type: "email", message: "请输入正确的邮箱地址", trigger: ["blur", "change"] }]
|
||||
}
|
||||
)
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = (id: string) => {
|
||||
visible.value = true
|
||||
dataForm.userId = ''
|
||||
|
||||
// 重置表单数据
|
||||
if (dataFormRef.value) {
|
||||
dataFormRef.value.resetFields()
|
||||
}
|
||||
|
||||
// 修改获取用户信息
|
||||
if (id) {
|
||||
dataForm.userId = id
|
||||
getUserData(id)
|
||||
}
|
||||
getRoleData()
|
||||
};
|
||||
|
||||
// 提交
|
||||
const onSubmit = () => {
|
||||
dataFormRef.value.validate((valid: boolean) => {
|
||||
if (!valid) {
|
||||
return false
|
||||
}
|
||||
// 更新方法
|
||||
if (dataForm.userId) {
|
||||
if (dataForm.phone && dataForm.phone.indexOf("*") >= 0) {
|
||||
dataForm.phone = undefined
|
||||
}
|
||||
if (dataForm.password && dataForm.password.indexOf("******") >= 0) {
|
||||
dataForm.password = undefined
|
||||
}
|
||||
putObj(dataForm).then(() => {
|
||||
useMessage().success(t('common.editSuccessText'))
|
||||
visible.value = false; // 关闭弹窗
|
||||
emit('refresh');
|
||||
}).catch(err => {
|
||||
useMessage().error(err.msg)
|
||||
})
|
||||
} else { // 新增方法
|
||||
if (dataForm.phone && dataForm.phone.indexOf("*") > 0) {
|
||||
dataForm.phone = undefined
|
||||
}
|
||||
addObj(dataForm).then(() => {
|
||||
useMessage().success(t('common.addSuccessText'))
|
||||
visible.value = false // 关闭弹窗
|
||||
emit('refresh')
|
||||
}).catch(err => {
|
||||
useMessage().error(err.msg)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
};
|
||||
|
||||
// 初始化部门数据
|
||||
const getUserData = (id: string) => {
|
||||
// 获取部门数据
|
||||
getObj(id).then(res => {
|
||||
Object.assign(dataForm, res.data)
|
||||
dataForm.password = '******'
|
||||
if (res.data.roleList) {
|
||||
dataForm.role = []
|
||||
res.data.roleList.map((item: any) => {
|
||||
dataForm.role.push(item.roleId)
|
||||
})
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
// 角色数据
|
||||
const getRoleData = () => {
|
||||
roleList().then(res => {
|
||||
roleData.value = res.data
|
||||
})
|
||||
}
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
20
src/views/app/appuser/i18n/en.ts
Normal file
20
src/views/app/appuser/i18n/en.ts
Normal file
@ -0,0 +1,20 @@
|
||||
export default {
|
||||
appuser: {
|
||||
index: 'index',
|
||||
username: 'username',
|
||||
name: 'name',
|
||||
phone: 'phone',
|
||||
post: 'post',
|
||||
role: 'role',
|
||||
lockFlag: 'lockFlag',
|
||||
createTime: 'createTime',
|
||||
password: 'password',
|
||||
dept: 'dept',
|
||||
email: 'email',
|
||||
nickname: 'nickname',
|
||||
inputUsernameTip: 'input username',
|
||||
inputPhoneTip: 'input phone',
|
||||
inputNameTip: 'input name',
|
||||
importUserTip: 'user import'
|
||||
}
|
||||
}
|
21
src/views/app/appuser/i18n/zh-cn.ts
Normal file
21
src/views/app/appuser/i18n/zh-cn.ts
Normal file
@ -0,0 +1,21 @@
|
||||
export default {
|
||||
appuser: {
|
||||
index: '序号',
|
||||
username: '用户名',
|
||||
name: '姓名',
|
||||
phone: '手机号',
|
||||
post: '岗位',
|
||||
role: '角色',
|
||||
lockFlag: '状态',
|
||||
createTime: '创建时间',
|
||||
password: '密码',
|
||||
dept: '部门',
|
||||
email: '邮箱',
|
||||
nickname: '昵称',
|
||||
inputUsernameTip: '请输入用户名',
|
||||
inputPhoneTip: '请输入手机号',
|
||||
inputNameTip: '请输入姓名',
|
||||
importUserTip: '用户导入'
|
||||
},
|
||||
|
||||
}
|
166
src/views/app/appuser/index.vue
Normal file
166
src/views/app/appuser/index.vue
Normal file
@ -0,0 +1,166 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<el-card shadow="hover" class="layout-padding-auto">
|
||||
<el-row v-show="showSearch" class="mb8">
|
||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true">
|
||||
<el-form-item :label="$t('appuser.username')" prop="username">
|
||||
<el-input v-model="state.queryForm.username" :placeholder="$t('appuser.inputUsernameTip')" clearable
|
||||
style="width: 240px" @keyup.enter="getDataList" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('appuser.phone')" prop="phone">
|
||||
<el-input v-model="state.queryForm.phone" :placeholder="$t('appuser.inputPhoneTip')" clearable
|
||||
style="width: 240px" @keyup.enter="getDataList" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="getDataList">{{ $t('common.queryBtn') }}</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">{{ $t('common.resetBtn') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button icon="folder-add" type="primary" class="ml10" @click="userDialogRef.openDialog()"
|
||||
v-auth="'sys_user_add'">
|
||||
{{ $t('common.addBtn') }}
|
||||
</el-button>
|
||||
<el-button icon="upload-filled" type="primary" class="ml10" @click="excelUploadRef.show()"
|
||||
v-auth="'sys_user_add'">
|
||||
{{ $t('common.importBtn') }}
|
||||
</el-button>
|
||||
<el-button icon="Download" type="primary" class="ml10" @click="exportExcel" v-auth="'sys_user_export'">
|
||||
{{ $t('common.exportBtn') }}
|
||||
</el-button>
|
||||
<el-button :disabled="multiple" icon="Delete" type="primary" class="ml10" v-auth="'sys_user_del'"
|
||||
@click="handleDelete(undefined)">
|
||||
{{ $t('common.delBtn') }}
|
||||
</el-button>
|
||||
<right-toolbar v-model:showSearch="showSearch" class="ml10" style="float: right;margin-right: 20px"
|
||||
@queryTable="getDataList"></right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
<el-table :data="state.dataList" v-loading="state.loading" style="width: 100%"
|
||||
@selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<el-table-column type="index" :label="$t('appuser.index')" width="80" />
|
||||
<el-table-column prop="username" :label="$t('appuser.username')" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="name" :label="$t('appuser.name')" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="phone" :label="$t('appuser.phone')" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column :label="$t('appuser.role')" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<el-tag v-for="(item, index) in scope.row.roleList" type="success" :key="index">{{ item.roleName }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('appuser.lockFlag')" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<dict-tag :options="lock_flag" :value="scope.row.lockFlag"></dict-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" :label="$t('appuser.createTime')"
|
||||
show-overflow-tooltip></el-table-column>
|
||||
<el-table-column :label="$t('common.action')" width="100">
|
||||
<template #default="scope">
|
||||
<el-button text type="primary" @click="userDialogRef.openDialog(scope.row.userId)"
|
||||
v-auth="'sys_user_edit'"> {{
|
||||
$t('common.editBtn')
|
||||
}}
|
||||
</el-button>
|
||||
<el-button text type="primary" @click="handleDelete(scope.row)" v-auth="'sys_user_del'">
|
||||
{{ $t('common.delBtn') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" v-bind="state.pagination">
|
||||
</pagination>
|
||||
|
||||
</el-card>
|
||||
<user-form ref="userDialogRef" @refresh="getDataList()" />
|
||||
|
||||
<upload-excel ref="excelUploadRef" :title="$t('appuser.importUserTip')" url="/admin/user/import"
|
||||
temp-url="/admin/sys-file/local/file/user.xlsx" @refreshDataList="getDataList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="systemUser">
|
||||
import { fetchList, delObj } from '/@/api/app/appuser'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useDict } from '/@/hooks/dict'
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
// 动态引入组件
|
||||
const UserForm = defineAsyncComponent(() => import('./form.vue'));
|
||||
|
||||
const { lock_flag } = useDict('lock_flag')
|
||||
const { t } = useI18n()
|
||||
|
||||
// 定义变量内容
|
||||
const userDialogRef = ref();
|
||||
const excelUploadRef = ref();
|
||||
const queryRef = ref();
|
||||
const showSearch = ref(true)
|
||||
|
||||
|
||||
// 多选rows
|
||||
const selectObjs = ref([]);
|
||||
// 是否可以多选
|
||||
const multiple = ref(true);
|
||||
|
||||
// 定义表格查询、后台调用的API
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
username: '',
|
||||
phone: ''
|
||||
},
|
||||
pageList: fetchList
|
||||
});
|
||||
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
downBlobFile
|
||||
} = useTable(state)
|
||||
|
||||
// 清空搜索条件
|
||||
const resetQuery = () => {
|
||||
queryRef.value.resetFields()
|
||||
getDataList()
|
||||
}
|
||||
|
||||
|
||||
// 多选事件
|
||||
const handleSelectionChange = (val: any) => {
|
||||
selectObjs.value = val
|
||||
multiple.value = !val.length
|
||||
}
|
||||
|
||||
// 导出excel
|
||||
const exportExcel = () => {
|
||||
downBlobFile('/admin/appuser/export', state.queryForm, 'users.xlsx')
|
||||
}
|
||||
|
||||
// 删除用户
|
||||
const handleDelete = (row: any) => {
|
||||
if (!row) {
|
||||
selectObjs.value.forEach(val => {
|
||||
handleDelete(val)
|
||||
});
|
||||
return
|
||||
}
|
||||
|
||||
useMessageBox().confirm(`${t('common.delConfirmText')}:${row.username} ?`).then(() => {
|
||||
// 删除用户的接口
|
||||
delObj(row.userId).then(() => {
|
||||
getDataList();
|
||||
useMessage().success(t('common.delSuccessText'))
|
||||
}).catch(err => {
|
||||
useMessage().error(err.msg)
|
||||
})
|
||||
})
|
||||
};
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user