parent
29d34de052
commit
978570f1e0
13 changed files with 100 additions and 954 deletions
@ -1,49 +0,0 @@ |
|||||||
<template> |
|
||||||
<dialog-form |
|
||||||
:name="$t('menu.user.group')" |
|
||||||
:queryBean="queryGroup" |
|
||||||
:createBean="createGroup" |
|
||||||
:updateBean="updateGroup" |
|
||||||
:deleteBean="deleteGroup" |
|
||||||
:beanId="beanId" |
|
||||||
:beanIds="beanIds" |
|
||||||
:focus="focus" |
|
||||||
:initValues="() => ({ type: 2 })" |
|
||||||
:toValues="(bean) => ({ ...bean })" |
|
||||||
:disableDelete="(bean) => bean.id <= 10" |
|
||||||
perms="group" |
|
||||||
:model-value="modelValue" |
|
||||||
@update:model-value="$emit('update:modelValue', $event)" |
|
||||||
@finished="$emit('finished')" |
|
||||||
> |
|
||||||
<template #default="{ values }"> |
|
||||||
<el-form-item prop="name" :label="$t('group.name')" :rules="{ required: true, message: () => $t('v.required') }"> |
|
||||||
<el-input v-model="values.name" ref="focus" maxlength="50"></el-input> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="description" :label="$t('group.description')"> |
|
||||||
<el-input v-model="values.description" maxlength="255"></el-input> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="type" :label="$t('group.type')" :rules="{ required: true, message: () => $t('v.required') }"> |
|
||||||
<el-select v-model="values.type" :disabled="values.type === 1"> |
|
||||||
<el-option v-for="n in [1, 2]" :key="n" :disabled="n === 1" :label="$t(`group.type.${n}`)" :value="n"></el-option> |
|
||||||
</el-select> |
|
||||||
</el-form-item> |
|
||||||
</template> |
|
||||||
</dialog-form> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script lang="ts"> |
|
||||||
import { defineComponent, ref } from 'vue'; |
|
||||||
import { queryGroup, createGroup, updateGroup, deleteGroup } from '@/api/user'; |
|
||||||
import DialogForm from '@/components/DialogForm.vue'; |
|
||||||
|
|
||||||
export default defineComponent({ |
|
||||||
components: { DialogForm }, |
|
||||||
props: { modelValue: { type: Boolean, required: true }, beanId: { required: true }, beanIds: { type: Array, required: true } }, |
|
||||||
emits: { 'update:modelValue': null, finished: null }, |
|
||||||
setup() { |
|
||||||
const focus = ref<any>(); |
|
||||||
return { queryGroup, createGroup, updateGroup, deleteGroup, focus }; |
|
||||||
}, |
|
||||||
}); |
|
||||||
</script> |
|
@ -1,158 +0,0 @@ |
|||||||
<template> |
|
||||||
<div> |
|
||||||
<div class="mb-3"> |
|
||||||
<query-form :params="params" |
|
||||||
@search="handleSearch" |
|
||||||
@reset="handleReset"> |
|
||||||
<query-item :label="$t('group.name')" |
|
||||||
name="Q_Contains_name"></query-item> |
|
||||||
<query-item :label="$t('group.description')" |
|
||||||
name="Q_Contains_description"></query-item> |
|
||||||
</query-form> |
|
||||||
</div> |
|
||||||
<div> |
|
||||||
<el-button type="primary" |
|
||||||
:disabled="perm('group:create')" |
|
||||||
:icon="Plus" |
|
||||||
@click="handleAdd">{{ $t('add') }}</el-button> |
|
||||||
<el-popconfirm :title="$t('confirmDelete')" |
|
||||||
@confirm="handleDelete(selection.map((row) => row.id))"> |
|
||||||
<template #reference> |
|
||||||
<el-button :disabled="selection.filter((row) => deletable(row.id)).length <= 0 || perm('group:delete')" |
|
||||||
:icon="Delete">{{ $t('delete') }}</el-button> |
|
||||||
</template> |
|
||||||
</el-popconfirm> |
|
||||||
<list-move class="ml-2" |
|
||||||
:disabled="selection.length <= 0 || filtered || perm('org:update')" |
|
||||||
@move="(type) => move(selection, type)" /> |
|
||||||
<column-setting name="group" |
|
||||||
class="ml-2" /> |
|
||||||
</div> |
|
||||||
<div class="block mt-3"> |
|
||||||
<el-table ref="table" |
|
||||||
v-loading="loading" |
|
||||||
:data="data" |
|
||||||
@selection-change="(rows) => (selection = rows)" |
|
||||||
@row-dblclick="(row) => handleEdit(row.id)" |
|
||||||
@sort-change="handleSort"> |
|
||||||
<column-list name="group"> |
|
||||||
<el-table-column type="selection" |
|
||||||
width="50"></el-table-column> |
|
||||||
<el-table-column property="id" |
|
||||||
label="ID" |
|
||||||
width="64" |
|
||||||
sortable="custom"></el-table-column> |
|
||||||
<el-table-column property="name" |
|
||||||
:label="$t('group.name')" |
|
||||||
sortable="custom" |
|
||||||
show-overflow-tooltip></el-table-column> |
|
||||||
<el-table-column property="description" |
|
||||||
:label="$t('group.description')" |
|
||||||
min-width="150" |
|
||||||
sortable="custom" |
|
||||||
show-overflow-tooltip></el-table-column> |
|
||||||
<el-table-column property="type" |
|
||||||
:label="$t('group.type')" |
|
||||||
sortable="custom" |
|
||||||
show-overflow-tooltip |
|
||||||
:formatter="(row) => $t(`group.type.${row.type}`)" /> |
|
||||||
<el-table-column :label="$t('table.action')"> |
|
||||||
<template #default="{ row }"> |
|
||||||
<el-button type="text" |
|
||||||
:disabled="perm('group:update')" |
|
||||||
@click="handleEdit(row.id)" |
|
||||||
size="small">{{ $t('edit') }}</el-button> |
|
||||||
<el-popconfirm :title="$t('confirmDelete')" |
|
||||||
@confirm="handleDelete([row.id])"> |
|
||||||
<template #reference> |
|
||||||
<el-button type="text" |
|
||||||
:disabled="!deletable(row.id) || perm('group:delete')" |
|
||||||
size="small">{{ $t('delete') }}</el-button> |
|
||||||
</template> |
|
||||||
</el-popconfirm> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
</column-list> |
|
||||||
</el-table> |
|
||||||
</div> |
|
||||||
<group-form v-model="formVisible" |
|
||||||
:beanId="beanId" |
|
||||||
:beanIds="beanIds" |
|
||||||
@finished="fetchData" /> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script setup lang="ts"> |
|
||||||
import { computed, onMounted, ref } from 'vue'; |
|
||||||
import { ElMessage } from 'element-plus'; |
|
||||||
import { Plus, Delete } from '@element-plus/icons-vue'; |
|
||||||
import { useI18n } from 'vue-i18n'; |
|
||||||
import { perm } from '@/store/useCurrentUser'; |
|
||||||
import { moveList, toParams, resetParams } from '@/utils/common'; |
|
||||||
import { deleteGroup, queryGroupList, updateGroupOrder } from '@/api/user'; |
|
||||||
import { ColumnList, ColumnSetting } from '@/components/TableList'; |
|
||||||
import { QueryForm, QueryItem } from '@/components/QueryForm'; |
|
||||||
import ListMove from '@/components/ListMove.vue'; |
|
||||||
import GroupForm from './GroupForm.vue'; |
|
||||||
|
|
||||||
const { t } = useI18n(); |
|
||||||
const params = ref<any>({}); |
|
||||||
const sort = ref<any>(); |
|
||||||
const table = ref<any>(); |
|
||||||
const data = ref<any[]>([]); |
|
||||||
const selection = ref<any[]>([]); |
|
||||||
const loading = ref<boolean>(false); |
|
||||||
const formVisible = ref<boolean>(false); |
|
||||||
const beanId = ref<number>(); |
|
||||||
const beanIds = computed(() => data.value.map((row) => row.id)); |
|
||||||
const filtered = ref<boolean>(false); |
|
||||||
const fetchData = async () => { |
|
||||||
loading.value = true; |
|
||||||
try { |
|
||||||
data.value = await queryGroupList({ ...toParams(params.value), Q_OrderBy: sort.value }); |
|
||||||
filtered.value = Object.values(params.value).filter((v) => v !== undefined && v !== '').length > 0 || sort.value !== undefined; |
|
||||||
} finally { |
|
||||||
loading.value = false; |
|
||||||
} |
|
||||||
}; |
|
||||||
onMounted(fetchData); |
|
||||||
|
|
||||||
const handleSort = ({ column, prop, order }: { column: any; prop: string; order: string }) => { |
|
||||||
if (prop) { |
|
||||||
sort.value = (column.sortBy ?? prop) + (order === 'descending' ? '_desc' : ''); |
|
||||||
} else { |
|
||||||
sort.value = undefined; |
|
||||||
} |
|
||||||
fetchData(); |
|
||||||
}; |
|
||||||
const handleSearch = () => fetchData(); |
|
||||||
const handleReset = () => { |
|
||||||
table.value.clearSort(); |
|
||||||
resetParams(params.value); |
|
||||||
sort.value = undefined; |
|
||||||
fetchData(); |
|
||||||
}; |
|
||||||
|
|
||||||
const handleAdd = () => { |
|
||||||
beanId.value = undefined; |
|
||||||
formVisible.value = true; |
|
||||||
}; |
|
||||||
const handleEdit = (id: number) => { |
|
||||||
beanId.value = id; |
|
||||||
formVisible.value = true; |
|
||||||
}; |
|
||||||
const deletable = (id: number) => id > 10; |
|
||||||
const handleDelete = async (ids: number[]) => { |
|
||||||
const deletableIds = ids.filter((id) => deletable(id)); |
|
||||||
if (deletableIds.length > 0) { |
|
||||||
await deleteGroup(deletableIds); |
|
||||||
fetchData(); |
|
||||||
ElMessage.success(t('success')); |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
const move = async (selected: any[], type: 'top' | 'up' | 'down' | 'bottom') => { |
|
||||||
const list = moveList(selected, data.value, type); |
|
||||||
await updateGroupOrder(list.map((item: any) => item.id)); |
|
||||||
}; |
|
||||||
</script> |
|
@ -1,66 +0,0 @@ |
|||||||
<template> |
|
||||||
<dialog-form ref="form" |
|
||||||
:name="$t('menu.user.role')" |
|
||||||
:queryBean="queryRole" |
|
||||||
:createBean="createRole" |
|
||||||
:updateBean="updateRole" |
|
||||||
:deleteBean="deleteRole" |
|
||||||
:beanId="beanId" |
|
||||||
:beanIds="beanIds" |
|
||||||
:focus="focus" |
|
||||||
:initValues="() => ({})" |
|
||||||
:toValues="(bean) => ({ ...bean })" |
|
||||||
:disableDelete="(bean) => bean.id <= 1" |
|
||||||
perms="role" |
|
||||||
:model-value="modelValue" |
|
||||||
@update:model-value="$emit('update:modelValue', $event)" |
|
||||||
@finished="$emit('finished')" |
|
||||||
@beanChange="(bean) => tree?.setCheckedKeys(bean.permission?.split(',') ?? [])" |
|
||||||
@beforeSubmit=" |
|
||||||
(values) => |
|
||||||
(values.permission = [...tree.getHalfCheckedNodes(), ...tree.getCheckedNodes()] |
|
||||||
.filter((item) => item.perms) |
|
||||||
.map((item) => item.perms?.join(',')) |
|
||||||
.join(',')) |
|
||||||
"> |
|
||||||
<template #default="{ values }"> |
|
||||||
<el-form-item prop="name" |
|
||||||
:label="$t('role.name')" |
|
||||||
:rules="{ required: true, message: () => $t('v.required') }"> |
|
||||||
<el-input v-model="values.name" |
|
||||||
ref="focus" |
|
||||||
maxlength="50"></el-input> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="description" |
|
||||||
:label="$t('role.description')"> |
|
||||||
<el-input v-model="values.description" |
|
||||||
maxlength="255"></el-input> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item prop="permission" |
|
||||||
:label="$t('role.permission')"> |
|
||||||
<el-tree ref="tree" |
|
||||||
:data="perms" |
|
||||||
node-key="key" |
|
||||||
@check="form.setUnsaved(true)" |
|
||||||
show-checkbox |
|
||||||
default-expand-all |
|
||||||
check-on-click-node /> |
|
||||||
</el-form-item> |
|
||||||
</template> |
|
||||||
</dialog-form> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script setup lang="ts"> |
|
||||||
import { ref } from 'vue'; |
|
||||||
import { queryRole, createRole, updateRole, deleteRole } from '@/api/user'; |
|
||||||
import { getPermsTreeData } from '@/data'; |
|
||||||
import DialogForm from '@/components/DialogForm.vue'; |
|
||||||
|
|
||||||
defineProps({ modelValue: { type: Boolean, required: true }, beanId: { required: true }, beanIds: { type: Array, required: true } }); |
|
||||||
defineEmits({ 'update:modelValue': null, finished: null }); |
|
||||||
|
|
||||||
const focus = ref<any>(); |
|
||||||
const tree = ref<any>(); |
|
||||||
const form = ref<any>(); |
|
||||||
const perms = getPermsTreeData(); |
|
||||||
</script> |
|
@ -1,117 +0,0 @@ |
|||||||
<template> |
|
||||||
<div> |
|
||||||
<div class="mb-3"> |
|
||||||
<query-form :params="params" @search="handleSearch" @reset="handleReset"> |
|
||||||
<query-item :label="$t('role.name')" name="Q_Contains_name"></query-item> |
|
||||||
<query-item :label="$t('role.description')" name="Q_Contains_description"></query-item> |
|
||||||
</query-form> |
|
||||||
</div> |
|
||||||
<div> |
|
||||||
<el-button type="primary" :icon="Plus" @click="handleAdd">{{ $t('add') }}</el-button> |
|
||||||
<el-popconfirm :title="$t('confirmDelete')" @confirm="handleDelete(selection.map((row) => row.id))"> |
|
||||||
<template #reference> |
|
||||||
<el-button :disabled="selection.length <= 0" :icon="Delete">{{ $t('delete') }}</el-button> |
|
||||||
</template> |
|
||||||
</el-popconfirm> |
|
||||||
<list-move class="ml-2" :disabled="selection.length <= 0 || filtered || perm('role:update')" @move="(type) => move(selection, type)" /> |
|
||||||
<column-setting name="role" class="ml-2" /> |
|
||||||
</div> |
|
||||||
<el-table |
|
||||||
ref="table" |
|
||||||
v-loading="loading" |
|
||||||
:data="data" |
|
||||||
@selection-change="(rows) => (selection = rows)" |
|
||||||
@row-dblclick="(row) => handleEdit(row.id)" |
|
||||||
@sort-change="handleSort" |
|
||||||
class="mt-3 shadow bg-white" |
|
||||||
> |
|
||||||
<column-list name="role"> |
|
||||||
<el-table-column type="selection" width="50"></el-table-column> |
|
||||||
<el-table-column property="id" label="ID" width="64" sortable="custom"></el-table-column> |
|
||||||
<el-table-column property="name" :label="$t('role.name')" sortable="custom" show-overflow-tooltip></el-table-column> |
|
||||||
<el-table-column property="description" :label="$t('role.description')" sortable="custom" show-overflow-tooltip></el-table-column> |
|
||||||
<el-table-column :label="$t('table.action')"> |
|
||||||
<template #default="{ row }"> |
|
||||||
<el-button type="text" @click="handleEdit(row.id)" size="small">{{ $t('edit') }}</el-button> |
|
||||||
<el-popconfirm :title="$t('confirmDelete')" @confirm="handleDelete([row.id])"> |
|
||||||
<template #reference> |
|
||||||
<el-button type="text" size="small">{{ $t('delete') }}</el-button> |
|
||||||
</template> |
|
||||||
</el-popconfirm> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
</column-list> |
|
||||||
</el-table> |
|
||||||
<role-form v-model="formVisible" :beanId="beanId" :beanIds="beanIds" @finished="fetchData" /> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script setup lang="ts"> |
|
||||||
import { computed, onMounted, ref } from 'vue'; |
|
||||||
import { ElMessage } from 'element-plus'; |
|
||||||
import { Plus, Delete } from '@element-plus/icons-vue'; |
|
||||||
import { useI18n } from 'vue-i18n'; |
|
||||||
import { perm } from '@/store/useCurrentUser'; |
|
||||||
import { deleteRole, queryRoleList, updateRoleOrder } from '@/api/user'; |
|
||||||
import { moveList, toParams, resetParams } from '@/utils/common'; |
|
||||||
import { ColumnList, ColumnSetting } from '@/components/TableList'; |
|
||||||
import { QueryForm, QueryItem } from '@/components/QueryForm'; |
|
||||||
import ListMove from '@/components/ListMove.vue'; |
|
||||||
import RoleForm from './RoleForm.vue'; |
|
||||||
|
|
||||||
const { t } = useI18n(); |
|
||||||
const params = ref<any>({}); |
|
||||||
const sort = ref<any>(); |
|
||||||
const table = ref<any>(); |
|
||||||
const data = ref<Array<any>>([]); |
|
||||||
const selection = ref<Array<any>>([]); |
|
||||||
const loading = ref<boolean>(false); |
|
||||||
const formVisible = ref<boolean>(false); |
|
||||||
const beanId = ref<number>(); |
|
||||||
const beanIds = computed(() => data.value.map((row) => row.id)); |
|
||||||
const filtered = ref<boolean>(false); |
|
||||||
const fetchData = async () => { |
|
||||||
loading.value = true; |
|
||||||
try { |
|
||||||
data.value = await queryRoleList({ ...toParams(params.value), Q_OrderBy: sort.value }); |
|
||||||
filtered.value = Object.values(params.value).filter((v) => v !== undefined && v !== '').length > 0 || sort.value !== undefined; |
|
||||||
} finally { |
|
||||||
loading.value = false; |
|
||||||
} |
|
||||||
}; |
|
||||||
onMounted(fetchData); |
|
||||||
|
|
||||||
const handleSort = ({ column, prop, order }: { column: any; prop: string; order: string }) => { |
|
||||||
if (prop) { |
|
||||||
sort.value = (column.sortBy ?? prop) + (order === 'descending' ? '_desc' : ''); |
|
||||||
} else { |
|
||||||
sort.value = undefined; |
|
||||||
} |
|
||||||
fetchData(); |
|
||||||
}; |
|
||||||
const handleSearch = () => fetchData(); |
|
||||||
const handleReset = () => { |
|
||||||
table.value.clearSort(); |
|
||||||
resetParams(params.value); |
|
||||||
sort.value = undefined; |
|
||||||
fetchData(); |
|
||||||
}; |
|
||||||
|
|
||||||
const handleAdd = () => { |
|
||||||
beanId.value = undefined; |
|
||||||
formVisible.value = true; |
|
||||||
}; |
|
||||||
const handleEdit = (id: number) => { |
|
||||||
beanId.value = id; |
|
||||||
formVisible.value = true; |
|
||||||
}; |
|
||||||
const handleDelete = async (ids: number[]) => { |
|
||||||
await deleteRole(ids); |
|
||||||
fetchData(); |
|
||||||
ElMessage.success(t('success')); |
|
||||||
}; |
|
||||||
const move = async (selected: any[], type: 'top' | 'up' | 'down' | 'bottom') => { |
|
||||||
const list = moveList(selected, data.value, type); |
|
||||||
await updateRoleOrder(list.map((item) => item.id)); |
|
||||||
}; |
|
||||||
</script> |
|
@ -1,248 +0,0 @@ |
|||||||
<template> |
|
||||||
<dialog-form :name="$t('menu.user.user')" |
|
||||||
:queryBean="queryUser" |
|
||||||
:createBean="createUser" |
|
||||||
:updateBean="updateUser" |
|
||||||
:deleteBean="deleteUser" |
|
||||||
:beanId="beanId" |
|
||||||
:beanIds="beanIds" |
|
||||||
:focus="focus" |
|
||||||
:initValues="() => ({ gender: 'm', roleIds: [] })" |
|
||||||
:toValues="(bean) => ({ ...bean, roleIds: bean.roleList.map((item:any) => item.id) })" |
|
||||||
:disableDelete="(bean) => bean.id <= 1" |
|
||||||
perms="user" |
|
||||||
:model-value="modelValue" |
|
||||||
@update:model-value="$emit('update:modelValue', $event)" |
|
||||||
@finished="$emit('finished')" |
|
||||||
large> |
|
||||||
<template #default="{ values, bean, isEdit }"> |
|
||||||
<el-row> |
|
||||||
<el-col :span="12"> |
|
||||||
<el-form-item prop="username" |
|
||||||
:label="$t('user.username')" |
|
||||||
:rules="[ |
|
||||||
{ required: true, message: () => $t('v.required') }, |
|
||||||
{ |
|
||||||
asyncValidator: async (rule, value, callback) => { |
|
||||||
if (value !== bean.username && !(await usernameValidation(value))) { |
|
||||||
callback($t('user.error.usernameExist')); |
|
||||||
} |
|
||||||
}, |
|
||||||
}, |
|
||||||
]"> |
|
||||||
<el-input v-model="values.username" |
|
||||||
ref="focus" |
|
||||||
maxlength="50"></el-input> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="12"> |
|
||||||
<el-form-item prop="realName" |
|
||||||
:label="$t('user.realName')"> |
|
||||||
<el-input v-model="values.realName" |
|
||||||
maxlength="50"></el-input> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="12"> |
|
||||||
<el-form-item prop="plainPassword" |
|
||||||
:label="$t('user.plainPassword')" |
|
||||||
:rules="[{ required: !isEdit, message: () => $t('v.required') }]"> |
|
||||||
<el-input v-model="values.plainPassword" |
|
||||||
maxlength="50" |
|
||||||
show-password></el-input> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="12"> |
|
||||||
<el-form-item prop="passwordAgain" |
|
||||||
:label="$t('user.passwordAgain')" |
|
||||||
:rules="[ |
|
||||||
{ required: !isEdit, message: () => $t('v.required') }, |
|
||||||
{ |
|
||||||
validator: (rule, value, callback) => { |
|
||||||
if (value != values.plainPassword) { |
|
||||||
callback($t('user.error.passwordNotMatch')); |
|
||||||
} else { |
|
||||||
callback(); |
|
||||||
} |
|
||||||
}, |
|
||||||
trigger: 'blur', |
|
||||||
}, |
|
||||||
]"> |
|
||||||
<el-input v-model="values.passwordAgain" |
|
||||||
maxlength="50" |
|
||||||
show-password></el-input> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="12"> |
|
||||||
<el-form-item prop="mobile" |
|
||||||
:label="$t('user.mobile')" |
|
||||||
:rules="[ |
|
||||||
{ |
|
||||||
asyncValidator: async (rule, value, callback) => { |
|
||||||
if (value !== bean.mobile && !(await mobileValidation(value))) { |
|
||||||
callback($t('user.error.mobileExist')); |
|
||||||
} |
|
||||||
}, |
|
||||||
}, |
|
||||||
]"> |
|
||||||
<el-input v-model="values.mobile" |
|
||||||
maxlength="50"></el-input> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="12"> |
|
||||||
<el-form-item prop="email" |
|
||||||
:label="$t('user.email')" |
|
||||||
:rules="[ |
|
||||||
{ |
|
||||||
asyncValidator: async (rule, value, callback) => { |
|
||||||
if (value !== bean.email && !(await emailValidation(value))) { |
|
||||||
callback($t('user.error.emailExist')); |
|
||||||
} |
|
||||||
}, |
|
||||||
}, |
|
||||||
]"> |
|
||||||
<el-input v-model="values.email" |
|
||||||
maxlength="50"></el-input> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="12"> |
|
||||||
<el-form-item prop="groupId" |
|
||||||
:label="$t('user.group')" |
|
||||||
:rules="{ required: true, message: () => $t('v.required') }"> |
|
||||||
<el-select v-model="values.groupId"> |
|
||||||
<el-option v-for="item in groupList" |
|
||||||
:key="item.id" |
|
||||||
:value="item.id" |
|
||||||
:label="item.name"></el-option> |
|
||||||
</el-select> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="12"> |
|
||||||
<el-form-item prop="orgId" |
|
||||||
:label="$t('user.org')" |
|
||||||
:rules="{ required: true, message: () => $t('v.required') }"> |
|
||||||
<el-cascader v-model="values.orgId" |
|
||||||
:options="orgList" |
|
||||||
:props="{ value: 'id', label: 'name', checkStrictly: true }" |
|
||||||
@change="(value) => (values.orgId = value[value.length - 1])"></el-cascader> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="24"> |
|
||||||
<el-form-item prop="roleIds" |
|
||||||
:label="$t('user.role')"> |
|
||||||
<el-checkbox-group v-model="values.roleIds"> |
|
||||||
<el-checkbox v-for="item in roleList" |
|
||||||
:key="item.id" |
|
||||||
:label="item.id">{{ item.name }}</el-checkbox> |
|
||||||
</el-checkbox-group> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="12"> |
|
||||||
<el-form-item prop="rank" |
|
||||||
:rules="[ |
|
||||||
{ required: true, message: () => $t('v.required') }, |
|
||||||
{ type: 'integer', message: () => $t('v.integer') }, |
|
||||||
]"> |
|
||||||
<template #label><label-tip message="user.rank" /></template> |
|
||||||
<el-input v-model.number="values.rank" |
|
||||||
maxlength="4"></el-input> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="12"> |
|
||||||
<el-form-item prop="gender" |
|
||||||
:label="$t('user.gender')" |
|
||||||
:rules="{ required: true, message: () => $t('v.required') }"> |
|
||||||
<el-radio-group v-model="values.gender"> |
|
||||||
<el-radio :label="'m'">{{ $t('gender.male') }}</el-radio> |
|
||||||
<el-radio :label="'f'">{{ $t('gender.female') }}</el-radio> |
|
||||||
<el-radio :label="'n'">{{ $t('gender.none') }}</el-radio> |
|
||||||
</el-radio-group> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="12"> |
|
||||||
<el-form-item prop="location" |
|
||||||
:label="$t('user.location')"> |
|
||||||
<el-input v-model="values.location" |
|
||||||
maxlength="255"></el-input> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="12"> |
|
||||||
<el-form-item prop="birthday" |
|
||||||
:label="$t('user.birthday')"> |
|
||||||
<el-date-picker v-model="values.birthday" |
|
||||||
type="date"></el-date-picker> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="24"> |
|
||||||
<el-form-item prop="bio" |
|
||||||
:label="$t('user.bio')"> |
|
||||||
<el-input v-model="values.bio" |
|
||||||
type="textarea" |
|
||||||
:rows="3" |
|
||||||
maxlength="2000"></el-input> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="12" |
|
||||||
v-if="isEdit"> |
|
||||||
<el-form-item prop="created" |
|
||||||
:label="$t('user.created')"> |
|
||||||
<el-date-picker v-model="values.created" |
|
||||||
type="datetime" |
|
||||||
disabled></el-date-picker> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="12" |
|
||||||
v-if="isEdit"> |
|
||||||
<el-form-item prop="loginDate" |
|
||||||
:label="$t('user.loginDate')"> |
|
||||||
<el-date-picker v-model="values.loginDate" |
|
||||||
type="datetime" |
|
||||||
disabled></el-date-picker> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="12" |
|
||||||
v-if="isEdit"> |
|
||||||
<el-form-item prop="loginIp" |
|
||||||
:label="$t('user.loginIp')"> |
|
||||||
<el-input v-model="values.loginIp" |
|
||||||
disabled></el-input> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="12" |
|
||||||
v-if="isEdit"> |
|
||||||
<el-form-item prop="loginCount" |
|
||||||
:label="$t('user.loginCount')"> |
|
||||||
<el-input v-model="values.loginCount" |
|
||||||
disabled></el-input> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
</el-row> |
|
||||||
</template> |
|
||||||
</dialog-form> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script setup lang="ts"> |
|
||||||
import { onMounted, ref } from 'vue'; |
|
||||||
import { queryUser, createUser, updateUser, deleteUser, usernameValidation, emailValidation, mobileValidation, queryGroupList, queryOrgList, queryRoleList } from '@/api/user'; |
|
||||||
import { toTree } from '@/utils/tree'; |
|
||||||
import DialogForm from '@/components/DialogForm.vue'; |
|
||||||
import LabelTip from '@/components/LabelTip.vue'; |
|
||||||
|
|
||||||
defineProps({ modelValue: { type: Boolean, required: true }, beanId: { required: true }, beanIds: { type: Array, required: true } }); |
|
||||||
defineEmits({ 'update:modelValue': null, finished: null }); |
|
||||||
|
|
||||||
const focus = ref<any>(); |
|
||||||
const groupList = ref<any[]>([]); |
|
||||||
const orgList = ref<any[]>([]); |
|
||||||
const roleList = ref<any[]>([]); |
|
||||||
onMounted(() => { |
|
||||||
queryGroupList({ Q_EQ_type: 2 }).then((result) => { |
|
||||||
groupList.value = result; |
|
||||||
}); |
|
||||||
queryOrgList().then((result) => { |
|
||||||
orgList.value = toTree(result); |
|
||||||
}); |
|
||||||
queryRoleList().then((result) => { |
|
||||||
roleList.value = result; |
|
||||||
}); |
|
||||||
}); |
|
||||||
</script> |
|
@ -1,259 +0,0 @@ |
|||||||
<template> |
|
||||||
<div> |
|
||||||
<div class="mb-3"> |
|
||||||
<query-form :params="params" |
|
||||||
@search="handleSearch" |
|
||||||
@reset="handleReset"> |
|
||||||
<query-item :label="$t('user.username')" |
|
||||||
name="Q_Contains_username"></query-item> |
|
||||||
<query-item :label="$t('user.mobile')" |
|
||||||
name="Q_Contains_mobile"></query-item> |
|
||||||
<query-item :label="$t('user.email')" |
|
||||||
name="Q_Contains_email"></query-item> |
|
||||||
<query-item :label="$t('user.rank')" |
|
||||||
name="Q_GE_rank,Q_LE_rank" |
|
||||||
type="number"></query-item> |
|
||||||
<query-item :label="$t('user.created')" |
|
||||||
name="Q_GE_@userExt-created_DateTime,Q_LE_@userExt-created_DateTime" |
|
||||||
type="datetime"></query-item> |
|
||||||
<query-item :label="$t('user.status')" |
|
||||||
name="Q_In_status_Int" |
|
||||||
:options="[0, 1].map((item) => ({ label: $t(`user.status.${item}`), value: item }))"></query-item> |
|
||||||
</query-form> |
|
||||||
</div> |
|
||||||
<div> |
|
||||||
<el-button type="primary" |
|
||||||
:icon="Plus" |
|
||||||
@click="handleAdd">{{ $t('add') }}</el-button> |
|
||||||
<el-popconfirm :title="$t('confirmDelete')" |
|
||||||
@confirm="handleDelete(selection.map((row) => row.id))"> |
|
||||||
<template #reference> |
|
||||||
<el-button :disabled="selection.length <= 0 || perm('user:delete')" |
|
||||||
:icon="Delete">{{ $t('delete') }}</el-button> |
|
||||||
</template> |
|
||||||
</el-popconfirm> |
|
||||||
<column-setting name="user" |
|
||||||
class="ml-2" /> |
|
||||||
</div> |
|
||||||
<div class="block mt-3"> |
|
||||||
<el-table ref="table" |
|
||||||
v-loading="loading" |
|
||||||
:data="data" |
|
||||||
@selection-change="(rows) => (selection = rows)" |
|
||||||
@row-dblclick="(row) => handleEdit(row.id)" |
|
||||||
@sort-change="handleSort"> |
|
||||||
<column-list name="user"> |
|
||||||
<el-table-column type="selection" |
|
||||||
:selectable="deletable" |
|
||||||
width="50"></el-table-column> |
|
||||||
<el-table-column property="id" |
|
||||||
label="ID" |
|
||||||
width="64" |
|
||||||
sortable="custom"></el-table-column> |
|
||||||
<el-table-column property="username" |
|
||||||
:label="$t('user.username')" |
|
||||||
sortable="custom" |
|
||||||
min-width="100"></el-table-column> |
|
||||||
<el-table-column property="mobile" |
|
||||||
:label="$t('user.mobile')" |
|
||||||
sortable="custom" |
|
||||||
display="none" |
|
||||||
min-width="100" |
|
||||||
show-overflow-tooltip></el-table-column> |
|
||||||
<el-table-column property="email" |
|
||||||
:label="$t('user.email')" |
|
||||||
sortable="custom" |
|
||||||
display="none" |
|
||||||
min-width="100" |
|
||||||
show-overflow-tooltip></el-table-column> |
|
||||||
<el-table-column property="realName" |
|
||||||
:label="$t('user.realName')" |
|
||||||
sort-by="@userExt-realName" |
|
||||||
sortable="custom" |
|
||||||
min-width="100" |
|
||||||
show-overflow-tooltip /> |
|
||||||
<el-table-column property="gender" |
|
||||||
:label="$t('user.gender')" |
|
||||||
sort-by="@userExt-gender" |
|
||||||
sortable="custom" |
|
||||||
display="none"> |
|
||||||
<template #default="{ row }">{{ $t(`gender.${row.gender}`) }}</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column property="created" |
|
||||||
:label="$t('user.created')" |
|
||||||
sort-by="@userExt-created" |
|
||||||
sortable="custom" |
|
||||||
display="none" |
|
||||||
width="170"> |
|
||||||
<template #default="{ row }">{{ dayjs(row.created).format('YYYY-MM-DD HH:mm:ss') }}</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column property="birthday" |
|
||||||
:label="$t('user.birthday')" |
|
||||||
sort-by="@userExt-birthday" |
|
||||||
sortable="custom" |
|
||||||
display="none" |
|
||||||
width="110"> |
|
||||||
<template #default="{ row }">{{ dayjs(row.birthday).format('YYYY-MM-DD') }}</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column property="loginDate" |
|
||||||
:label="$t('user.loginDate')" |
|
||||||
sort-by="@userExt-loginDate" |
|
||||||
sortable="custom" |
|
||||||
display="none" |
|
||||||
width="170"> |
|
||||||
<template #default="{ row }">{{ dayjs(row.loginDate).format('YYYY-MM-DD HH:mm:ss') }}</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column property="loginIp" |
|
||||||
:label="$t('user.loginIp')" |
|
||||||
sort-by="@userExt-loginIp" |
|
||||||
sortable="custom" |
|
||||||
display="none" |
|
||||||
show-overflow-tooltip /> |
|
||||||
<el-table-column property="loginCount" |
|
||||||
:label="$t('user.loginCount')" |
|
||||||
sort-by="@userExt-loginCount" |
|
||||||
sortable="custom" |
|
||||||
display="none" |
|
||||||
show-overflow-tooltip /> |
|
||||||
<el-table-column property="org.name" |
|
||||||
:label="$t('user.org')" |
|
||||||
sort-by="org-name" |
|
||||||
sortable="custom" |
|
||||||
show-overflow-tooltip></el-table-column> |
|
||||||
<el-table-column property="roles" |
|
||||||
:label="$t('user.role')" |
|
||||||
show-overflow-tooltip> |
|
||||||
<template #default="{ row }"> |
|
||||||
<el-space> |
|
||||||
<span v-for="item in row.roleList" |
|
||||||
:key="item.id">{{ item.name }}</span> |
|
||||||
</el-space> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column property="group.name" |
|
||||||
:label="$t('user.group')" |
|
||||||
sort-by="group-name" |
|
||||||
sortable="custom" |
|
||||||
show-overflow-tooltip></el-table-column> |
|
||||||
<el-table-column property="rank" |
|
||||||
:label="$t('user.rank')" |
|
||||||
sortable="custom" |
|
||||||
show-overflow-tooltip></el-table-column> |
|
||||||
<el-table-column property="status" |
|
||||||
:label="$t('user.status')" |
|
||||||
sortable="custom" |
|
||||||
show-overflow-tooltip> |
|
||||||
<template #default="{ row }"> |
|
||||||
<el-tag v-if="row.status === 0" |
|
||||||
type="success" |
|
||||||
size="small">{{ $t(`user.status.${row.status}`) }}</el-tag> |
|
||||||
<el-tag v-if="row.status === 1" |
|
||||||
type="danger" |
|
||||||
size="small">{{ $t(`user.status.${row.status}`) }}</el-tag> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column :label="$t('table.action')"> |
|
||||||
<template #default="{ row }"> |
|
||||||
<el-button type="text" |
|
||||||
@click="handleEdit(row.id)" |
|
||||||
:disabled="perm('user:show')" |
|
||||||
size="small">{{ $t('edit') }}</el-button> |
|
||||||
<el-popconfirm :title="$t('confirmDelete')" |
|
||||||
@confirm="handleDelete([row.id])"> |
|
||||||
<template #reference> |
|
||||||
<el-button type="text" |
|
||||||
:disabled="!deletable(row) || perm('user:delete')" |
|
||||||
size="small">{{ $t('delete') }}</el-button> |
|
||||||
</template> |
|
||||||
</el-popconfirm> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
</column-list> |
|
||||||
</el-table> |
|
||||||
<el-pagination v-model:currentPage="currentPage" |
|
||||||
v-model:pageSize="pageSize" |
|
||||||
:total="total" |
|
||||||
:page-sizes="pageSizes" |
|
||||||
:layout="pageLayout" |
|
||||||
@size-change="fetchData()" |
|
||||||
@current-change="fetchData()" |
|
||||||
small |
|
||||||
background |
|
||||||
class="px-3 py-2 justify-end"></el-pagination> |
|
||||||
</div> |
|
||||||
<user-form v-model="formVisible" |
|
||||||
:beanId="beanId" |
|
||||||
:beanIds="beanIds" |
|
||||||
@finished="fetchData" /> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script setup lang="ts"> |
|
||||||
import { computed, onMounted, ref } from 'vue'; |
|
||||||
import { ElMessage } from 'element-plus'; |
|
||||||
import { Plus, Delete } from '@element-plus/icons-vue'; |
|
||||||
import { useI18n } from 'vue-i18n'; |
|
||||||
import dayjs from 'dayjs'; |
|
||||||
import { perm } from '@/store/useCurrentUser'; |
|
||||||
import { pageSizes, pageLayout, toParams, resetParams } from '@/utils/common'; |
|
||||||
import { deleteUser, queryUserPage } from '@/api/user'; |
|
||||||
import { ColumnList, ColumnSetting } from '@/components/TableList'; |
|
||||||
import { QueryForm, QueryItem } from '@/components/QueryForm'; |
|
||||||
import UserForm from './UserForm.vue'; |
|
||||||
|
|
||||||
const { t } = useI18n(); |
|
||||||
const params = ref<any>({}); |
|
||||||
const sort = ref<any>(); |
|
||||||
const currentPage = ref<number>(1); |
|
||||||
const pageSize = ref<number>(10); |
|
||||||
const total = ref<number>(0); |
|
||||||
const table = ref<any>(); |
|
||||||
const data = ref<Array<any>>([]); |
|
||||||
const selection = ref<Array<any>>([]); |
|
||||||
const loading = ref<boolean>(false); |
|
||||||
const formVisible = ref<boolean>(false); |
|
||||||
const beanId = ref<number>(); |
|
||||||
const beanIds = computed(() => data.value.map((row) => row.id)); |
|
||||||
const fetchData = async () => { |
|
||||||
loading.value = true; |
|
||||||
try { |
|
||||||
const { content, totalElements } = await queryUserPage({ ...toParams(params.value), Q_OrderBy: sort.value, page: currentPage.value, pageSize: pageSize.value }); |
|
||||||
data.value = content; |
|
||||||
total.value = totalElements; |
|
||||||
} finally { |
|
||||||
loading.value = false; |
|
||||||
} |
|
||||||
}; |
|
||||||
onMounted(fetchData); |
|
||||||
|
|
||||||
const handleSort = ({ column, prop, order }: { column: any; prop: string; order: string }) => { |
|
||||||
if (prop) { |
|
||||||
sort.value = (column.sortBy ?? prop) + (order === 'descending' ? '_desc' : ''); |
|
||||||
} else { |
|
||||||
sort.value = undefined; |
|
||||||
} |
|
||||||
fetchData(); |
|
||||||
}; |
|
||||||
const handleSearch = () => fetchData(); |
|
||||||
const handleReset = () => { |
|
||||||
table.value.clearSort(); |
|
||||||
resetParams(params.value); |
|
||||||
sort.value = undefined; |
|
||||||
fetchData(); |
|
||||||
}; |
|
||||||
|
|
||||||
const handleAdd = () => { |
|
||||||
beanId.value = undefined; |
|
||||||
formVisible.value = true; |
|
||||||
}; |
|
||||||
const handleEdit = (id: number) => { |
|
||||||
beanId.value = id; |
|
||||||
formVisible.value = true; |
|
||||||
}; |
|
||||||
const handleDelete = async (ids: number[]) => { |
|
||||||
await deleteUser(ids); |
|
||||||
fetchData(); |
|
||||||
ElMessage.success(t('success')); |
|
||||||
}; |
|
||||||
const deletable = (bean: any) => bean.id > 1; |
|
||||||
</script> |
|
Loading…
Reference in new issue