update
init
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<Description @register="registerDesc" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, inject, onMounted, watch } from 'vue';
|
||||
import { queryIdTree } from '../depart.user.api';
|
||||
import { useBaseInfoForm } from '../depart.user.data';
|
||||
import { Description, useDescription } from '/@/components/Description/index';
|
||||
|
||||
const prefixCls = inject('prefixCls');
|
||||
const props = defineProps({
|
||||
data: { require: true, type: Object },
|
||||
});
|
||||
const treeData = ref([]);
|
||||
const { descItems } = useBaseInfoForm(treeData);
|
||||
|
||||
const [registerDesc, { setDescProps }] = useDescription({
|
||||
data: props.data,
|
||||
schema: descItems,
|
||||
column: 1,
|
||||
labelStyle: {
|
||||
width: '180px',
|
||||
},
|
||||
});
|
||||
|
||||
function setData(data) {
|
||||
setDescProps({ data });
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
watch(
|
||||
() => props.data,
|
||||
() => setData(props.data),
|
||||
{ immediate: true }
|
||||
);
|
||||
});
|
||||
// 动态查询 parentId 组件的 treeData
|
||||
queryIdTree().then((data) => (treeData.value = data));
|
||||
</script>
|
||||
@@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<BasicDrawer
|
||||
title="部门角色权限配置"
|
||||
:width="650"
|
||||
:loading="loading"
|
||||
showFooter
|
||||
okText="保存并关闭"
|
||||
@ok="onSubmit(true)"
|
||||
@close="onClose"
|
||||
@register="registerDrawer"
|
||||
>
|
||||
<div>
|
||||
<a-spin :spinning="loading">
|
||||
<template v-if="treeData.length > 0">
|
||||
<BasicTree
|
||||
title="所拥有的部门权限"
|
||||
toolbar
|
||||
checkable
|
||||
:treeData="treeData"
|
||||
:checkedKeys="checkedKeys"
|
||||
:selectedKeys="selectedKeys"
|
||||
:expandedKeys="expandedKeys"
|
||||
:checkStrictly="checkStrictly"
|
||||
:clickRowToExpand="false"
|
||||
@check="onCheck"
|
||||
@expand="onExpand"
|
||||
@select="onSelect"
|
||||
>
|
||||
<template #title="{ slotTitle, ruleFlag }">
|
||||
<span>{{ slotTitle }}</span>
|
||||
<Icon v-if="ruleFlag" icon="ant-design:align-left-outlined" style="margin-left: 5px; color: red" />
|
||||
</template>
|
||||
</BasicTree>
|
||||
</template>
|
||||
<a-empty v-else description="无可配置部门权限" />
|
||||
</a-spin>
|
||||
</div>
|
||||
|
||||
<template #centerFooter>
|
||||
<a-button :loading="loading" ghost type="primary" @click="onSubmit(false)">仅保存</a-button>
|
||||
</template>
|
||||
</BasicDrawer>
|
||||
<DepartRoleDataRuleDrawer @register="registerDataRuleDrawer" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { BasicTree } from '/@/components/Tree/index';
|
||||
import { BasicDrawer, useDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
import DepartRoleDataRuleDrawer from './DepartRoleDataRuleDrawer.vue';
|
||||
import { queryTreeListForDeptRole, queryDeptRolePermission, saveDeptRolePermission } from '../depart.user.api';
|
||||
|
||||
defineEmits(['register']);
|
||||
const { createMessage } = useMessage();
|
||||
const loading = ref(false);
|
||||
const departId = ref('');
|
||||
const roleId = ref('');
|
||||
const treeData = ref<Array<any>>([]);
|
||||
const checkedKeys = ref<Array<any>>([]);
|
||||
const lastCheckedKeys = ref<Array<any>>([]);
|
||||
const expandedKeys = ref<Array<any>>([]);
|
||||
const selectedKeys = ref<Array<any>>([]);
|
||||
const allTreeKeys = ref<Array<any>>([]);
|
||||
const checkStrictly = ref(true);
|
||||
|
||||
// 注册抽屉组件
|
||||
const [registerDrawer, { closeDrawer }] = useDrawerInner((data) => {
|
||||
roleId.value = data.record.id;
|
||||
departId.value = data.record.departId;
|
||||
loadData();
|
||||
});
|
||||
// 注册数据规则授权弹窗抽屉
|
||||
const [registerDataRuleDrawer, dataRuleDrawer] = useDrawer();
|
||||
|
||||
async function loadData() {
|
||||
try {
|
||||
loading.value = true;
|
||||
// 用户角色授权功能,查询菜单权限树
|
||||
const { ids, treeList } = await queryTreeListForDeptRole({ departId: departId.value });
|
||||
if (ids.length > 0) {
|
||||
allTreeKeys.value = ids;
|
||||
expandedKeys.value = ids;
|
||||
treeData.value = treeList;
|
||||
// 查询角色授权
|
||||
checkedKeys.value = await queryDeptRolePermission({ roleId: roleId.value });
|
||||
lastCheckedKeys.value = [checkedKeys.value];
|
||||
} else {
|
||||
reset();
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 重置页面
|
||||
function reset() {
|
||||
treeData.value = [];
|
||||
expandedKeys.value = [];
|
||||
checkedKeys.value = [];
|
||||
lastCheckedKeys.value = [];
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
// tree勾选复选框事件
|
||||
function onCheck(event) {
|
||||
if (checkStrictly.value) {
|
||||
checkedKeys.value = event.checked;
|
||||
} else {
|
||||
checkedKeys.value = event;
|
||||
}
|
||||
}
|
||||
|
||||
// tree展开事件
|
||||
function onExpand($expandedKeys) {
|
||||
expandedKeys.value = $expandedKeys;
|
||||
}
|
||||
|
||||
// tree选中事件
|
||||
function onSelect($selectedKeys, { selectedNodes }) {
|
||||
if (selectedNodes[0]?.ruleFlag) {
|
||||
let functionId = $selectedKeys[0];
|
||||
dataRuleDrawer.openDrawer(true, { roleId, departId, functionId });
|
||||
}
|
||||
selectedKeys.value = [];
|
||||
}
|
||||
|
||||
function doClose() {
|
||||
reset();
|
||||
closeDrawer();
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
reset();
|
||||
}
|
||||
|
||||
async function onSubmit(exit) {
|
||||
try {
|
||||
loading.value = true;
|
||||
let params = {
|
||||
roleId: roleId.value,
|
||||
permissionIds: checkedKeys.value.join(','),
|
||||
lastpermissionIds: lastCheckedKeys.value.join(','),
|
||||
};
|
||||
await saveDeptRolePermission(params);
|
||||
if (exit) {
|
||||
doClose();
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
if (!exit) {
|
||||
loadData();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<BasicDrawer title="数据规则/按钮权限配置" :width="365" @close="onClose" @register="registerDrawer">
|
||||
<a-spin :spinning="loading">
|
||||
<a-tabs defaultActiveKey="1">
|
||||
<a-tab-pane tab="数据规则" key="1">
|
||||
<a-checkbox-group v-model:value="dataRuleChecked" v-if="dataRuleList.length > 0">
|
||||
<a-row>
|
||||
<a-col :span="24" v-for="(item, index) in dataRuleList" :key="'dr' + index">
|
||||
<a-checkbox :value="item.id">{{ item.ruleName }}</a-checkbox>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<div style="width: 100%; margin-top: 15px">
|
||||
<a-button
|
||||
type="primary"
|
||||
:loading="loading"
|
||||
:size="'small'"
|
||||
preIcon="ant-design:save-filled"
|
||||
@click="saveDataRuleForRole"
|
||||
>
|
||||
<span>点击保存</span>
|
||||
</a-button>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-checkbox-group>
|
||||
<a-empty v-else description="无配置信息" />
|
||||
</a-tab-pane>
|
||||
<!--<a-tab-pane tab="按钮权限" key="2">敬请期待!!!</a-tab-pane>-->
|
||||
</a-tabs>
|
||||
</a-spin>
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, unref } from 'vue';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
|
||||
import { queryDepartRoleDataRule, saveDepartRoleDataRule } from '../depart.user.api';
|
||||
|
||||
defineEmits(['register']);
|
||||
const loading = ref<boolean>(false);
|
||||
const departId = ref('');
|
||||
const functionId = ref('');
|
||||
const roleId = ref('');
|
||||
const dataRuleList = ref<Array<any>>([]);
|
||||
const dataRuleChecked = ref<Array<any>>([]);
|
||||
|
||||
// 注册抽屉组件
|
||||
const [registerDrawer, { closeDrawer }] = useDrawerInner((data) => {
|
||||
roleId.value = unref(data.roleId);
|
||||
departId.value = unref(data.departId);
|
||||
functionId.value = unref(data.functionId);
|
||||
loadData();
|
||||
});
|
||||
|
||||
async function loadData() {
|
||||
try {
|
||||
loading.value = true;
|
||||
const { datarule, drChecked } = await queryDepartRoleDataRule(functionId, departId, roleId);
|
||||
dataRuleList.value = datarule;
|
||||
if (drChecked) {
|
||||
dataRuleChecked.value = drChecked.split(',');
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function saveDataRuleForRole() {
|
||||
let params = {
|
||||
permissionId: functionId.value,
|
||||
roleId: roleId.value,
|
||||
dataRuleIds: dataRuleChecked.value.join(','),
|
||||
};
|
||||
saveDepartRoleDataRule(params);
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
doReset();
|
||||
}
|
||||
|
||||
function doReset() {
|
||||
functionId.value = '';
|
||||
roleId.value = '';
|
||||
dataRuleList.value = [];
|
||||
dataRuleChecked.value = [];
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,196 @@
|
||||
<template>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button preIcon="ant-design:plus-outlined" type="primary" @click="addDepartRole">添加部门角色</a-button>
|
||||
<template v-if="selectedRowKeys.length > 0">
|
||||
<a-divider type="vertical" />
|
||||
<a-dropdown>
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="onDeleteDepartRoleBatch">
|
||||
<icon icon="ant-design:delete-outlined" />
|
||||
<span>删除</span>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button>
|
||||
<span>批量操作 </span>
|
||||
<icon icon="akar-icons:chevron-down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
</template>
|
||||
<!-- 插槽:行内操作按钮 -->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 添加部门弹窗 -->
|
||||
<DepartRoleModal :departId="departId" @register="registerFormModal" @success="onFormModalSuccess" />
|
||||
<DepartRoleAuthDrawer @register="registerAuthDrawer" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { inject, ref, unref, watch, computed, onMounted } from 'vue';
|
||||
|
||||
import { ActionItem, BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
|
||||
import DepartRoleModal from './DepartRoleModal.vue';
|
||||
import DepartRoleAuthDrawer from './DepartRoleAuthDrawer.vue';
|
||||
import { deleteBatchDepartRole, departRoleList } from '../depart.user.api';
|
||||
import { departRoleColumns, departRoleSearchFormSchema } from '../depart.user.data';
|
||||
import { ColEx } from '/@/components/Form/src/types';
|
||||
|
||||
const prefixCls = inject('prefixCls');
|
||||
const props = defineProps({
|
||||
data: { require: true, type: Object },
|
||||
});
|
||||
defineEmits(['register']);
|
||||
// 当前选中的部门ID,可能会为空,代表未选择部门
|
||||
const departId = computed(() => props.data?.id);
|
||||
|
||||
// 自适应列配置
|
||||
const adaptiveColProps: Partial<ColEx> = {
|
||||
xs: 24, // <576px
|
||||
sm: 24, // ≥576px
|
||||
md: 24, // ≥768px
|
||||
lg: 12, // ≥992px
|
||||
xl: 12, // ≥1200px
|
||||
xxl: 8, // ≥1600px
|
||||
};
|
||||
// 列表页面公共参数、方法
|
||||
const { tableContext, createMessage } = useListPage({
|
||||
tableProps: {
|
||||
api: departRoleList,
|
||||
columns: departRoleColumns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
labelWidth: 100,
|
||||
schemas: departRoleSearchFormSchema,
|
||||
baseColProps: adaptiveColProps,
|
||||
labelAlign: 'left',
|
||||
labelCol: {
|
||||
xs: 24,
|
||||
sm: 24,
|
||||
md: 24,
|
||||
lg: 9,
|
||||
xl: 7,
|
||||
xxl: 6,
|
||||
},
|
||||
wrapperCol: {},
|
||||
// 操作按钮配置
|
||||
actionColOptions: {
|
||||
...adaptiveColProps,
|
||||
style: { textAlign: 'left' },
|
||||
},
|
||||
},
|
||||
// 请求之前对参数做处理
|
||||
beforeFetch(params) {
|
||||
params.deptId = departId.value;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// 注册 ListTable
|
||||
const [registerTable, { reload, setProps, setLoading, updateTableDataRecord }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
|
||||
// 注册Form弹窗
|
||||
const [registerFormModal, formModal] = useModal();
|
||||
// 注册授权弹窗抽屉
|
||||
const [registerAuthDrawer, authDrawer] = useDrawer();
|
||||
|
||||
// 监听 data 更改,重新加载数据
|
||||
watch(
|
||||
() => props.data,
|
||||
() => reload()
|
||||
);
|
||||
onMounted(() => {
|
||||
reload();
|
||||
});
|
||||
|
||||
// 清空选择的行
|
||||
function clearSelection() {
|
||||
selectedRowKeys.value = [];
|
||||
}
|
||||
|
||||
// 添加部门角色
|
||||
function addDepartRole() {
|
||||
formModal.openModal(true, {
|
||||
isUpdate: false,
|
||||
record: {},
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑部门角色
|
||||
function editDepartRole(record) {
|
||||
formModal.openModal(true, {
|
||||
isUpdate: true,
|
||||
record: record,
|
||||
});
|
||||
}
|
||||
|
||||
// 授权部门角色
|
||||
function permissionDepartRole(record) {
|
||||
authDrawer.openDrawer(true, { record });
|
||||
}
|
||||
|
||||
// 批量删除部门角色
|
||||
async function deleteDepartRole(idList, confirm) {
|
||||
if (!departId.value) {
|
||||
createMessage.warning('请先选择一个部门');
|
||||
} else {
|
||||
setLoading(true);
|
||||
let ids = unref(idList).join(',');
|
||||
try {
|
||||
await deleteBatchDepartRole({ ids }, confirm);
|
||||
return reload();
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
// 批量删除部门角色事件
|
||||
async function onDeleteDepartRoleBatch() {
|
||||
try {
|
||||
await deleteDepartRole(selectedRowKeys, true);
|
||||
// 批量删除成功后清空选择
|
||||
clearSelection();
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
// 表单弹窗成功后的回调
|
||||
function onFormModalSuccess({ isUpdate, values }) {
|
||||
isUpdate ? updateTableDataRecord(values.id, values) : reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record): ActionItem[] {
|
||||
return [{ label: '编辑', onClick: editDepartRole.bind(null, record) }];
|
||||
}
|
||||
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record): ActionItem[] {
|
||||
return [
|
||||
{ label: '授权', onClick: permissionDepartRole.bind(null, record) },
|
||||
{
|
||||
label: '删除',
|
||||
color: 'error',
|
||||
popConfirm: {
|
||||
title: '确认要删除吗?',
|
||||
confirm: deleteDepartRole.bind(null, [record.id], false),
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<BasicModal :title="title" :width="800" v-bind="$attrs" @ok="handleOk" @register="registerModal">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, inject, ref, unref } from 'vue';
|
||||
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
// noinspection ES6UnusedImports
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
|
||||
import { saveOrUpdateDepartRole } from '../depart.user.api';
|
||||
import { departRoleModalFormSchema } from '../depart.user.data';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
const props = defineProps({
|
||||
// 当前部门ID
|
||||
departId: { require: true, type: String },
|
||||
});
|
||||
const prefixCls = inject('prefixCls');
|
||||
// 当前是否是更新模式
|
||||
const isUpdate = ref<boolean>(true);
|
||||
// 当前的弹窗数据
|
||||
const model = ref<object>({});
|
||||
const title = computed(() => (isUpdate.value ? '编辑部门角色' : '新增部门角色'));
|
||||
|
||||
//注册表单
|
||||
const [registerForm, { resetFields, setFieldsValue, validate, updateSchema }] = useForm({
|
||||
schemas: departRoleModalFormSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
|
||||
// 注册弹窗
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
await resetFields();
|
||||
isUpdate.value = unref(data?.isUpdate);
|
||||
// 无论新增还是编辑,都可以设置表单值
|
||||
let record = unref(data?.record);
|
||||
if (typeof record === 'object') {
|
||||
model.value = record;
|
||||
await setFieldsValue({ ...record });
|
||||
}
|
||||
});
|
||||
|
||||
//提交事件
|
||||
async function handleOk() {
|
||||
try {
|
||||
setModalProps({ confirmLoading: true });
|
||||
let values = await validate();
|
||||
values.departId = unref(props.departId);
|
||||
//提交表单
|
||||
await saveOrUpdateDepartRole(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success', { isUpdate: unref(isUpdate), values });
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<BasicDrawer title="部门角色分配" :width="365" @close="onClose" @register="registerDrawer">
|
||||
<a-spin :spinning="loading">
|
||||
<template v-if="desformList.length > 0">
|
||||
<a-checkbox-group v-model:value="designNameValue">
|
||||
<a-row>
|
||||
<a-col :span="24" v-for="item of desformList">
|
||||
<a-checkbox :value="item.id">{{ item.roleName }}</a-checkbox>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-checkbox-group>
|
||||
<div style="width: 100%; margin-top: 15px">
|
||||
<a-button type="primary" :loading="loading" :size="'small'" preIcon="ant-design:save-filled" @click="onSubmit">
|
||||
<span>点击保存</span>
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<a-empty v-else description="无配置信息" />
|
||||
</a-spin>
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, unref } from 'vue';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
|
||||
import { queryDepartRoleByUserId, queryDepartRoleUserList, saveDepartRoleUser } from '../depart.user.api';
|
||||
|
||||
defineEmits(['register']);
|
||||
const loading = ref<boolean>(false);
|
||||
const userId = ref('');
|
||||
const departId = ref('');
|
||||
const oldRoleId = ref('');
|
||||
const desformList = ref<Array<any>>([]);
|
||||
const designNameValue = ref<Array<any>>([]);
|
||||
|
||||
// 注册抽屉组件
|
||||
const [registerDrawer, { closeDrawer }] = useDrawerInner((data) => {
|
||||
userId.value = unref(data.userId);
|
||||
departId.value = unref(data.departId);
|
||||
loadData();
|
||||
});
|
||||
|
||||
async function loadData() {
|
||||
try {
|
||||
loading.value = true;
|
||||
const params = {
|
||||
departId: departId.value,
|
||||
userId: userId.value,
|
||||
};
|
||||
// 查询 DepartRole
|
||||
const [$desformList, $departRoleList] = await Promise.all([queryDepartRoleUserList(params), queryDepartRoleByUserId(params)]);
|
||||
desformList.value = $desformList;
|
||||
designNameValue.value = $departRoleList.map((item) => item.droleId);
|
||||
oldRoleId.value = designNameValue.value.join(',');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function onSubmit() {
|
||||
try {
|
||||
loading.value = true;
|
||||
await saveDepartRoleUser({
|
||||
userId: userId.value,
|
||||
newRoleId: designNameValue.value.join(','),
|
||||
oldRoleId: oldRoleId.value,
|
||||
});
|
||||
doClose();
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
doReset();
|
||||
}
|
||||
|
||||
function doClose() {
|
||||
doReset();
|
||||
closeDrawer();
|
||||
}
|
||||
|
||||
function doReset() {
|
||||
userId.value = '';
|
||||
departId.value = '';
|
||||
oldRoleId.value = '';
|
||||
desformList.value = [];
|
||||
designNameValue.value = [];
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<div class="bg-white m-4 mr-0 overflow-hidden">
|
||||
<a-spin :spinning="loading">
|
||||
<template v-if="userIdentity === '2'">
|
||||
<!--组织机构树-->
|
||||
<BasicTree
|
||||
v-if="!treeReloading"
|
||||
title="部门列表"
|
||||
toolbar
|
||||
search
|
||||
showLine
|
||||
:checkStrictly="true"
|
||||
:clickRowToExpand="false"
|
||||
:treeData="treeData"
|
||||
:selectedKeys="selectedKeys"
|
||||
:expandedKeys="expandedKeys"
|
||||
:autoExpandParent="autoExpandParent"
|
||||
@select="onSelect"
|
||||
@expand="onExpand"
|
||||
@search="onSearch"
|
||||
/>
|
||||
</template>
|
||||
<a-empty v-else description="普通员工无此权限" />
|
||||
</a-spin>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { inject, nextTick, ref } from 'vue';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { BasicTree } from '/@/components/Tree';
|
||||
import { queryMyDepartTreeList, searchByKeywords } from '../depart.user.api';
|
||||
|
||||
const prefixCls = inject('prefixCls');
|
||||
const emit = defineEmits(['select']);
|
||||
const { createMessage } = useMessage();
|
||||
|
||||
let loading = ref<boolean>(false);
|
||||
// 部门树列表数据
|
||||
let treeData = ref<any[]>([]);
|
||||
// 当前展开的项
|
||||
let expandedKeys = ref<any[]>([]);
|
||||
// 当前选中的项
|
||||
let selectedKeys = ref<any[]>([]);
|
||||
// 是否自动展开父级
|
||||
let autoExpandParent = ref<boolean>(true);
|
||||
// 用户身份
|
||||
let userIdentity = ref<string>('2');
|
||||
// 树组件重新加载
|
||||
let treeReloading = ref<boolean>(false);
|
||||
|
||||
// 加载部门信息
|
||||
function loadDepartTreeData() {
|
||||
loading.value = true;
|
||||
treeData.value = [];
|
||||
queryMyDepartTreeList()
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
if (Array.isArray(res.result)) {
|
||||
treeData.value = res.result;
|
||||
userIdentity.value = res.message;
|
||||
autoExpandParentNode();
|
||||
}
|
||||
} else {
|
||||
createMessage.warning(res.message);
|
||||
}
|
||||
})
|
||||
.finally(() => (loading.value = false));
|
||||
}
|
||||
|
||||
loadDepartTreeData();
|
||||
|
||||
// 自动展开父节点,只展开一级
|
||||
function autoExpandParentNode() {
|
||||
let keys: Array<any> = [];
|
||||
treeData.value.forEach((item, index) => {
|
||||
if (item.children && item.children.length > 0) {
|
||||
keys.push(item.key);
|
||||
}
|
||||
if (index === 0) {
|
||||
// 默认选中第一个
|
||||
setSelectedKey(item.id, item);
|
||||
}
|
||||
});
|
||||
if (keys.length > 0) {
|
||||
reloadTree();
|
||||
expandedKeys.value = keys;
|
||||
}
|
||||
}
|
||||
|
||||
// 重新加载树组件,防止无法默认展开数据
|
||||
async function reloadTree() {
|
||||
await nextTick();
|
||||
treeReloading.value = true;
|
||||
await nextTick();
|
||||
treeReloading.value = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前选中的行
|
||||
*/
|
||||
function setSelectedKey(key: string, data?: object) {
|
||||
selectedKeys.value = [key];
|
||||
if (data) {
|
||||
emit('select', data);
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索事件
|
||||
function onSearch(value: string) {
|
||||
if (value) {
|
||||
loading.value = true;
|
||||
searchByKeywords({ keyWord: value, myDeptSearch: '1' })
|
||||
.then((result) => {
|
||||
if (Array.isArray(result)) {
|
||||
treeData.value = result;
|
||||
} else {
|
||||
createMessage.warning('未查询到部门信息');
|
||||
treeData.value = [];
|
||||
}
|
||||
})
|
||||
.finally(() => (loading.value = false));
|
||||
} else {
|
||||
loadDepartTreeData();
|
||||
}
|
||||
}
|
||||
|
||||
// 树选择事件
|
||||
function onSelect(selKeys, event) {
|
||||
if (selKeys.length > 0 && selectedKeys.value[0] !== selKeys[0]) {
|
||||
setSelectedKey(selKeys[0], event.selectedNodes[0]);
|
||||
} else {
|
||||
// 这样可以防止用户取消选择
|
||||
setSelectedKey(selectedKeys.value[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// 树展开事件
|
||||
function onExpand(keys) {
|
||||
expandedKeys.value = keys;
|
||||
autoExpandParent.value = false;
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
/*升级antd3后,查询框与树贴的太近,样式优化*/
|
||||
:deep(.jeecg-tree-header) {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,229 @@
|
||||
<template>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button preIcon="ant-design:plus-outlined" type="primary" @click="selectAddUser">添加已有用户</a-button>
|
||||
<a-button preIcon="ant-design:plus-outlined" type="primary" @click="createUser">新建用户</a-button>
|
||||
<template v-if="selectedRowKeys.length > 0">
|
||||
<a-dropdown>
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="onUnlinkDepartUserBatch">
|
||||
<icon icon="bx:bx-unlink" />
|
||||
<span>取消关联</span>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button>
|
||||
<span>批量操作 </span>
|
||||
<icon icon="akar-icons:chevron-down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
</template>
|
||||
<!-- 插槽:行内操作按钮 -->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<UserDrawer @register="registerDrawer" @success="onUserDrawerSuccess" />
|
||||
<DepartRoleUserAuthDrawer @register="registerUserAuthDrawer" />
|
||||
<UserSelectModal rowKey="id" @register="registerSelUserModal" @getSelectResult="onSelectUserOk" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, inject, ref, unref, watch } from 'vue';
|
||||
import { ActionItem, BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
|
||||
import UserDrawer from '/@/views/system/user/UserDrawer.vue';
|
||||
import UserSelectModal from '/@/components/Form/src/jeecg/components/modal/UserSelectModal.vue';
|
||||
import DepartRoleUserAuthDrawer from './DepartRoleUserAuthDrawer.vue';
|
||||
import { departUserList, linkDepartUserBatch, unlinkDepartUserBatch } from '../depart.user.api';
|
||||
import { userInfoColumns, userInfoSearchFormSchema } from '../depart.user.data';
|
||||
import { ColEx } from '/@/components/Form/src/types';
|
||||
|
||||
const prefixCls = inject('prefixCls');
|
||||
const props = defineProps({
|
||||
data: { require: true, type: Object },
|
||||
});
|
||||
// 当前选中的部门ID,可能会为空,代表未选择部门
|
||||
const departId = computed(() => props.data?.id);
|
||||
|
||||
// 自适应列配置
|
||||
const adaptiveColProps: Partial<ColEx> = {
|
||||
xs: 24, // <576px
|
||||
sm: 24, // ≥576px
|
||||
md: 24, // ≥768px
|
||||
lg: 12, // ≥992px
|
||||
xl: 12, // ≥1200px
|
||||
xxl: 8, // ≥1600px
|
||||
};
|
||||
// 列表页面公共参数、方法
|
||||
const { tableContext, createMessage } = useListPage({
|
||||
tableProps: {
|
||||
api: departUserList,
|
||||
columns: userInfoColumns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
schemas: userInfoSearchFormSchema,
|
||||
baseColProps: adaptiveColProps,
|
||||
labelAlign: 'left',
|
||||
labelCol: {
|
||||
xs: 24,
|
||||
sm: 24,
|
||||
md: 24,
|
||||
lg: 9,
|
||||
xl: 7,
|
||||
xxl: 5,
|
||||
},
|
||||
wrapperCol: {},
|
||||
// 操作按钮配置
|
||||
actionColOptions: {
|
||||
...adaptiveColProps,
|
||||
style: { textAlign: 'left' },
|
||||
},
|
||||
},
|
||||
// 请求之前对参数做处理
|
||||
beforeFetch(params) {
|
||||
params.depId = departId.value;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// 注册 ListTable
|
||||
const [registerTable, { reload, setProps, setLoading, updateTableDataRecord }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
() => reload()
|
||||
);
|
||||
//注册drawer
|
||||
const [registerDrawer, { openDrawer, setDrawerProps }] = useDrawer();
|
||||
const [registerUserAuthDrawer, userAuthDrawer] = useDrawer();
|
||||
// 注册用户选择 modal
|
||||
const [registerSelUserModal, selUserModal] = useModal();
|
||||
|
||||
// 清空选择的行
|
||||
function clearSelection() {
|
||||
selectedRowKeys.value = [];
|
||||
}
|
||||
|
||||
// 查看部门角色
|
||||
function showDepartRole(record) {
|
||||
userAuthDrawer.openDrawer(true, { userId: record.id, departId });
|
||||
}
|
||||
|
||||
// 创建用户
|
||||
function createUser() {
|
||||
if (!departId.value) {
|
||||
createMessage.warning('请先选择一个部门');
|
||||
} else {
|
||||
openDrawer(true, {
|
||||
isUpdate: false,
|
||||
departDisabled: true,
|
||||
// 初始化负责部门
|
||||
nextDepartOptions: { value: props.data?.key, label: props.data?.title },
|
||||
record: {
|
||||
activitiSync: 1,
|
||||
userIdentity: 1,
|
||||
selecteddeparts: departId.value,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 查看用户详情
|
||||
function showUserDetail(record) {
|
||||
openDrawer(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
departDisabled: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑用户信息
|
||||
function editUserInfo(record) {
|
||||
openDrawer(true, { isUpdate: true, record, departDisabled: true });
|
||||
}
|
||||
|
||||
// 选择添加已有用户
|
||||
function selectAddUser() {
|
||||
selUserModal.openModal();
|
||||
}
|
||||
|
||||
// 批量取消关联部门和用户之间的关系
|
||||
async function unlinkDepartUser(idList, confirm) {
|
||||
if (!departId.value) {
|
||||
createMessage.warning('请先选择一个部门');
|
||||
} else {
|
||||
setLoading(true);
|
||||
let userIds = unref(idList).join(',');
|
||||
try {
|
||||
await unlinkDepartUserBatch({ depId: departId.value, userIds }, confirm);
|
||||
return reload();
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
// 批量取消关联事件
|
||||
async function onUnlinkDepartUserBatch() {
|
||||
try {
|
||||
await unlinkDepartUser(selectedRowKeys, true);
|
||||
// 批量删除成功后清空选择
|
||||
clearSelection();
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
// 选择用户成功
|
||||
async function onSelectUserOk(options, userIdList) {
|
||||
if (userIdList.length > 0) {
|
||||
try {
|
||||
setLoading(true);
|
||||
await linkDepartUserBatch(departId.value, userIdList);
|
||||
reload();
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户抽屉表单成功回调
|
||||
*/
|
||||
function onUserDrawerSuccess({ isUpdate, values }) {
|
||||
isUpdate ? updateTableDataRecord(values.id, values) : reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record): ActionItem[] {
|
||||
return [{ label: '编辑', onClick: editUserInfo.bind(null, record) }];
|
||||
}
|
||||
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record): ActionItem[] {
|
||||
return [
|
||||
{ label: '部门角色', onClick: showDepartRole.bind(null, record) },
|
||||
{ label: '用户详情', onClick: showUserDetail.bind(null, record) },
|
||||
{
|
||||
label: '取消关联',
|
||||
color: 'error',
|
||||
popConfirm: {
|
||||
title: '确认取消关联吗?',
|
||||
confirm: unlinkDepartUser.bind(null, [record.id], false),
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user