update: 部门管理

This commit is contained in:
easy 2023-02-10 18:13:41 +08:00
parent db05307557
commit 025c2c430a
4 changed files with 525 additions and 26 deletions

View File

@ -0,0 +1,327 @@
<template>
<a-modal
class="add-device-or-product-dialog-container"
title="绑定"
width="1440px"
@ok="dialog.handleOk"
cancelText="取消"
okText="确定"
v-model:visible="dialog.visible.value"
>
<a-row>
<exclamation-circle-outlined /> 只能分配有共享权限的资产数据
</a-row>
<a-row>
<span>批量配置</span>
<a-switch v-model:checked="bulkBool" />
</a-row>
<a-row v-show="bulkBool">
<a-checkbox-group v-model:value="bulkList" :options="options" />
</a-row>
<Search :columns="query.columns" @search="query.search" />
<JTable
ref="tableRef"
:request="table.requestFun"
:gridColumn="2"
model="CARD"
:params="query.params.value"
:rowSelection="{
selectedRowKeys: table._selectedRowKeys.value,
}"
@cancelSelect="table.cancelSelect"
>
<template #card="slotProps">
<CardBox
:value="slotProps"
:actions="[{ key: 1 }]"
v-bind="slotProps"
:active="
table._selectedRowKeys.value.includes(slotProps.id)
"
@click="table.onSelectChange"
:status="slotProps.state?.value"
:statusText="slotProps.state?.text"
:statusNames="{
online: 'success',
offline: 'error',
notActive: 'warning',
}"
>
<template #img>
<slot name="img">
<img
:src="getImage('/device-product.png')"
style="cursor: pointer"
/>
</slot>
</template>
<template #content>
<h3 class="card-item-content-title">
{{ slotProps.name }}
</h3>
<a-row>
<a-col :span="12">
<div class="card-item-content-text">ID</div>
<div
style="cursor: pointer"
class="card-item-content-value"
>
{{ slotProps.id }}
</div>
</a-col>
<a-col :span="12">
<div class="card-item-content-text">
资产权限
</div>
<div
style="cursor: pointer"
class="card-item-content-value"
>
{{
table.getPermissLabel(
slotProps.permission,
)
}}
</div>
</a-col>
</a-row>
</template>
</CardBox>
</template>
</JTable>
</a-modal>
</template>
<script setup lang="ts">
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { getImage } from '@/utils/comm';
import {
getDeviceOrProductList_api,
getPermission_api,
} from '@/api/system/department';
const props = defineProps<{
parentId: string;
allPermission: dictType;
assetType: 'product' | 'device';
}>();
//
const dialog = {
visible: ref<boolean>(false),
handleOk: () => {
// formRef.value?.validate().then(() => {
// form.submit();
// });
dialog.changeVisible();
},
//
changeVisible: () => {
dialog.visible.value = !dialog.visible.value;
},
};
const bulkBool = ref<boolean>(true);
const bulkList = ref<string[]>(['read']);
const options = computed(() =>
props.allPermission.map((item) => ({
label: item.name,
value: item.id,
disabled: item.id === 'read',
})),
);
const query = {
columns: [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
ellipsis: true,
fixed: 'left',
search: {
type: 'string',
},
},
{
title: '名称',
dataIndex: 'name',
key: 'name',
ellipsis: true,
fixed: 'left',
search: {
type: 'string',
},
},
{
title: '状态',
dataIndex: 'state',
key: 'state',
ellipsis: true,
fixed: 'left',
search: {
type: 'select',
options: [
{
label: '在线',
value: 'online',
},
{
label: '离线',
value: 'offline',
},
{
label: '禁用',
value: 'notActive',
},
],
},
},
],
params: ref({}),
search: (params: any) => {
query.params.value = params;
},
};
const table = {
_selectedRowKeys: ref<string[]>([]),
selectedRows: [] as any[],
//
getPermissLabel: (values: string[]) => {
const permissionList = props.allPermission;
if (permissionList.length < 1 || values.length < 1) return '';
const result = values.map(
(key) => permissionList.find((item) => item.id === key)?.name,
);
return result.join(',');
},
//
onSelectChange: (row: any) => {
const selectedRowKeys = table._selectedRowKeys.value;
const index = selectedRowKeys.indexOf(row.id);
if (index === -1) {
selectedRowKeys.push(row.id);
table.selectedRows.push(row);
} else {
selectedRowKeys.splice(index, 1);
table.selectedRows.splice(index, 1);
}
},
//
cancelSelect: () => {
table._selectedRowKeys.value = [];
table.selectedRows = [];
},
//
getData: (params: object, parentId: string) =>
new Promise((resolve) => {
getDeviceOrProductList_api(params).then((resp: any) => {
type resultType = {
data: any[];
total: number;
pageSize: number;
pageIndex: number;
};
const { pageIndex, pageSize, total, data } =
resp.result as resultType;
const ids = data.map((item) => item.id);
getPermission_api(ids, parentId).then((perResp: any) => {
const permissionObj = {};
perResp.result.forEach((item: any) => {
permissionObj[item.assetId] =
props.allPermission.filter((permission) =>
item.allPermissions.includes(
(permissionId: string) =>
permissionId === permission.id,
),
);
});
data.forEach(
(item) => (item.permission = permissionObj[item.id]),
);
resolve({
code: 200,
result: {
data: data,
pageIndex,
pageSize,
total,
},
status: 200,
});
});
});
}),
//
requestFun: async (oParams: any) => {
table._selectedRowKeys.value = [];
table.selectedRows = [];
if (props.parentId) {
const terms = [
{
terms: [
{
column: 'id',
termType: 'dim-assets$not',
value: {
assetType: props.assetType,
targets: [
{
type: 'org',
id: props.parentId,
},
],
},
},
],
},
];
if (oParams.terms && oParams.terms.length > 0)
terms.unshift({ terms: oParams.terms });
const params = {
...oParams,
sorts: [{ name: 'createTime', order: 'desc' }],
terms,
};
const resp: any = await table.getData(params, props.parentId);
console.log(resp.result);
return {
code: resp.status,
result: resp.result,
status: resp.status,
};
} else {
return {
code: 200,
result: {
data: [],
pageIndex: 0,
pageSize: 0,
total: 0,
},
status: 200,
};
}
},
};
//
defineExpose({
openDialog: dialog.changeVisible,
});
</script>
<style lang="less" scoped>
.add-device-or-product-dialog-container {
.ant-spin-nested-loading {
height: calc(100vh - 440px);
overflow-y: auto;
}
}
</style>

View File

@ -0,0 +1,41 @@
<template>
<a-modal
class="edit-permission-dialog-container"
title="编辑"
width="500px"
@ok="dialog.handleOk"
cancelText="取消"
okText="确定"
v-model:visible="dialog.visible.value"
>
</a-modal>
</template>
<script setup lang="ts">
const props = defineProps({
parentId: String,
});
//
const dialog = {
visible: ref<boolean>(false),
handleOk: () => {
// formRef.value?.validate().then(() => {
// form.submit();
// });
dialog.changeVisible()
},
//
changeVisible: (ids?:string[], permissionList?:string[]) => {
console.log(ids, permissionList);
dialog.visible.value = !dialog.visible.value;
},
};
//
defineExpose({
openDialog: dialog.changeVisible,
});
</script>
<style scoped></style>

View File

@ -3,21 +3,44 @@
<Search :columns="query.columns" @search="query.search" />
<JTable
ref="tableRef"
:columns="table.columns"
:request="table.requestFun"
:gridColumn="2"
model="CARD"
:params="query.params.value"
:rowSelection="{
selectedRowKeys: table._selectedRowKeys,
onChange: table.onSelectChange,
selectedRowKeys: table._selectedRowKeys.value,
}"
@cancelSelect="table.cancelSelect"
>
<template #headerTitle>
<a-space>
<a-button type="primary" @click="table.clickAdd">
新增
<plus-outlined />资产分配
</a-button>
<a-dropdown trigger="hover">
<a-button>批量操作</a-button>
<template #overlay>
<a-menu>
<a-menu-item>
<a-popconfirm
title="是否批量解除绑定"
ok-text="确定"
cancel-text="取消"
@confirm="table.clickUnBind()"
>
<a-button>
<DisconnectOutlined /> 批量解绑
</a-button>
</a-popconfirm>
</a-menu-item>
<a-menu-item>
<a-button @click="table.clickEdit()">
<EditOutlined /> 批量编辑
</a-button>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-space>
</template>
@ -29,6 +52,7 @@
:active="
table._selectedRowKeys.value.includes(slotProps.id)
"
@click="table.onSelectChange"
:status="slotProps.state?.value"
:statusText="slotProps.state?.text"
:statusNames="{
@ -39,7 +63,10 @@
>
<template #img>
<slot name="img">
<img :src="getImage('/device-product.png')" />
<img
:src="getImage('/device-product.png')"
style="cursor: pointer"
/>
</slot>
</template>
<template #content>
@ -49,13 +76,21 @@
<a-row>
<a-col :span="12">
<div class="card-item-content-text">ID</div>
<div>{{ slotProps.deviceType?.text }}</div>
<div
style="cursor: pointer"
class="card-item-content-value"
>
{{ slotProps.id }}
</div>
</a-col>
<a-col :span="12">
<div class="card-item-content-text">
资产权限
</div>
<div>
<div
style="cursor: pointer"
class="card-item-content-value"
>
{{
table.permissionList.value.length &&
table.getPermissLabel(
@ -67,7 +102,10 @@
</a-row>
</template>
<template #actions>
<a-button @click="table.clickEdit(slotProps)">
<a-button
@click="table.clickEdit(slotProps)"
style="margin-right: 10px"
>
<AIcon type="EditOutlined" />
</a-button>
<a-popconfirm
@ -83,22 +121,39 @@
</CardBox>
</template>
</JTable>
<div class="dialogs">
<AddDeviceOrProductDialog
ref="addDialogRef"
:parent-id="props.parentId"
:all-permission="table.permissionList.value"
asset-type="product"
/>
<EditPermissionDialog ref="editDialogRef" :parent-id="props.parentId" />
</div>
</div>
</template>
<script setup lang="ts" name="product">
import { ActionsType } from '@/components/Table';
import {
PlusOutlined,
EditOutlined,
DisconnectOutlined,
} from '@ant-design/icons-vue';
import AddDeviceOrProductDialog from '../components/AddDeviceOrProductDialog.vue';
import EditPermissionDialog from '../components/EditPermissionDialog.vue';
import { getImage } from '@/utils/comm';
import {
getDeviceOrProductList_api,
getPermission_api,
getPermissionDict_api,
} from '@/api/system/department';
const props = defineProps({
parentId: String,
});
import {dictType} from '../typing.d.ts'
const props = defineProps<{
parentId:string
}>();
const query = {
columns: [
{
@ -154,8 +209,8 @@ const query = {
const tableRef = ref();
const table = {
columns: [],
_selectedRowKeys: ref<string[]>([]),
selectedRows: [] as any[],
permissionList: ref<dictType>([]),
init: () => {
@ -170,11 +225,13 @@ const table = {
);
},
//
getPermissionDict: () => {
getPermissionDict_api().then((resp: any) => {
table.permissionList.value = resp.result;
});
},
//
getPermissLabel: (values: string[]) => {
const permissionList = table.permissionList.value;
if (permissionList.length < 1 || values.length < 1) return '';
@ -183,9 +240,25 @@ const table = {
);
return result.join(',');
},
onSelectChange: (keys: string[]) => {
table._selectedRowKeys.value = [...keys];
//
onSelectChange: (row: any) => {
const selectedRowKeys = table._selectedRowKeys.value;
const index = selectedRowKeys.indexOf(row.id);
if (index === -1) {
selectedRowKeys.push(row.id);
table.selectedRows.push(row);
} else {
selectedRowKeys.splice(index, 1);
table.selectedRows.splice(index, 1);
}
},
//
cancelSelect: () => {
table._selectedRowKeys.value = [];
table.selectedRows = [];
},
//
getData: (params: object, parentId: string) =>
new Promise((resolve) => {
getDeviceOrProductList_api(params).then((resp) => {
@ -220,7 +293,10 @@ const table = {
});
});
}),
//
requestFun: async (oParams: any) => {
table._selectedRowKeys.value = [];
table.selectedRows = [];
if (props.parentId) {
const params = {
...oParams,
@ -243,8 +319,6 @@ const table = {
],
};
const resp: any = await table.getData(params, props.parentId);
console.log(resp.result);
return {
code: resp.status,
result: resp.result,
@ -263,17 +337,70 @@ const table = {
};
}
},
clickAdd: () => {},
clickEdit: (row: any) => {},
clickUnBind: (row: any) => {},
clickAdd: () => {
addDialogRef.value && addDialogRef.value.openDialog();
},
clickEdit: (row?: any) => {
const ids = row ? row.id : [...table._selectedRowKeys.value];
if (row || table.selectedRows.length === 1) {
const permissionList =
row?.permission || table.selectedRows[0].permission;
return (
editDialogRef.value &&
editDialogRef.value.openDialog(ids, permissionList)
);
} else if (table.selectedRows.length === 0) return;
const permissionList = table.selectedRows.map(
(item) => item.permission,
);
const mixPermissionList = table.getMixed(permissionList);
editDialogRef.value &&
editDialogRef.value.openDialog(ids, mixPermissionList);
},
clickUnBind: (row?: any) => {},
/**
* 获取多个数组的交集
* @param permissionList
*/
getMixed: (permissionList: string[][]) => {
if (permissionList.length === 1) return permissionList[0];
const obj = {};
const result: string[] = [];
permissionList.forEach((items) => {
items.forEach((item) => {
if (obj[item]) obj[item]++;
else obj[item] = 1;
if (obj[item] === permissionList.length) result.push(item);
});
});
return result;
},
};
const addDialogRef = ref();
const editDialogRef = ref();
table.init();
type dictType = {
id: string;
name: string;
}[];
</script>
<style scoped></style>
<style lang="less" scoped>
.product-container {
.card {
.card-warp {
&.active {
.card-item-content-value {
color: #2f54eb;
}
}
}
.card-tools {
.ant-btn {
color: #252525;
}
}
}
}
</style>

View File

@ -0,0 +1,4 @@
type dictType = {
id: string;
name: string;
}[];