update: 组织管理
This commit is contained in:
parent
09a3873546
commit
db05307557
|
@ -1,10 +1,18 @@
|
||||||
import server from '@/utils/request';
|
import server from '@/utils/request';
|
||||||
|
|
||||||
// 获取tree数据-第一层
|
// 获取部门数据
|
||||||
export const getTreeData_api = (data:object) => server.post(`/organization/_all/tree`, data);
|
export const getTreeData_api = (data:object) => server.post(`/organization/_all/tree`, data);
|
||||||
// 新增部门
|
// 新增部门
|
||||||
export const addDepartment_api = (data:object) => server.post(`/organization`, data);
|
export const addDepartment_api = (data:object) => server.post(`/organization`, data);
|
||||||
// 更新部门
|
// 更新部门
|
||||||
export const updateDepartment_api = (data:object) => server.patch(`/organization`, data);
|
export const updateDepartment_api = (data:object) => server.patch(`/organization`, data);
|
||||||
// 删除部门
|
// 删除部门
|
||||||
export const delDepartment_api = (id:string) => server.remove(`/organization/${id}`);
|
export const delDepartment_api = (id:string) => server.remove(`/organization/${id}`);
|
||||||
|
|
||||||
|
|
||||||
|
// 获取产品列表
|
||||||
|
export const getDeviceOrProductList_api = (data:object) => server.post(`/device-product/_query`, data);
|
||||||
|
// 根据产品的id获取产品的权限
|
||||||
|
export const getPermission_api = (ids:object, id:string) => server.post(`/assets/bindings/product/org/${id}/_query`, ids);
|
||||||
|
// 获取产品的权限字典
|
||||||
|
export const getPermissionDict_api = () => server.get(`/assets/bindings/product/permissions`);
|
|
@ -0,0 +1,141 @@
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
v-model:visible="dialog.visible"
|
||||||
|
:title="dialog.title"
|
||||||
|
width="520px"
|
||||||
|
@ok="dialog.handleOk"
|
||||||
|
class="edit-dialog-container"
|
||||||
|
cancelText="取消"
|
||||||
|
okText="确定"
|
||||||
|
:confirmLoading="form.loading"
|
||||||
|
>
|
||||||
|
<a-form ref="formRef" :model="form.data" layout="vertical">
|
||||||
|
<a-form-item name="parentId" label="上级组织">
|
||||||
|
<a-tree-select
|
||||||
|
v-model:value="form.data.parentId"
|
||||||
|
style="width: 100%"
|
||||||
|
placeholder="请选择上级组织"
|
||||||
|
:tree-data="props.treeData"
|
||||||
|
:field-names="{ value: 'id' }"
|
||||||
|
>
|
||||||
|
<template #title="{ name }"> {{ name }} </template>
|
||||||
|
</a-tree-select>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
name="name"
|
||||||
|
label="名称"
|
||||||
|
:rules="[
|
||||||
|
{ required: true, message: '请输入名称' },
|
||||||
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="form.data.name"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
name="sortIndex"
|
||||||
|
label="排序"
|
||||||
|
:rules="[{ required: true, message: '请输入排序' }]"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="form.data.sortIndex"
|
||||||
|
placeholder="请输入排序"
|
||||||
|
:maxlength="64"
|
||||||
|
@blur="form.checkSort"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { FormInstance } from 'ant-design-vue';
|
||||||
|
import {cloneDeep} from 'lodash-es'
|
||||||
|
import {
|
||||||
|
addDepartment_api,
|
||||||
|
updateDepartment_api,
|
||||||
|
} from '@/api/system/department';
|
||||||
|
|
||||||
|
const emits = defineEmits(['refresh']);
|
||||||
|
const props = defineProps<{
|
||||||
|
treeData: any[];
|
||||||
|
}>();
|
||||||
|
// 弹窗相关
|
||||||
|
const dialog = reactive({
|
||||||
|
title: '',
|
||||||
|
visible: false,
|
||||||
|
handleOk: () => {
|
||||||
|
formRef.value?.validate().then(() => {
|
||||||
|
form.submit();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 控制弹窗的打开与关闭
|
||||||
|
changeVisible: (status: boolean, row: any = {}) => {
|
||||||
|
if (row.id) {
|
||||||
|
dialog.title = '编辑';
|
||||||
|
form.data = cloneDeep(row);
|
||||||
|
} else if (row.parentId) {
|
||||||
|
dialog.title = '新增子组织';
|
||||||
|
form.data = {
|
||||||
|
name: '',
|
||||||
|
sortIndex: ((row.children && row.children.length) || 0) + 1,
|
||||||
|
parentId: row.parentId,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
dialog.title = '新增';
|
||||||
|
form.data = {
|
||||||
|
name: '',
|
||||||
|
sortIndex: props.treeData.length + 1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
form.beforeSortIndex = form.data.sortIndex;
|
||||||
|
dialog.visible = status;
|
||||||
|
nextTick(() => {
|
||||||
|
formRef.value?.clearValidate();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// 表单相关
|
||||||
|
const formRef = ref<FormInstance>();
|
||||||
|
const form = reactive({
|
||||||
|
loading: false,
|
||||||
|
data: {} as formType,
|
||||||
|
beforeSortIndex: '' as string | number,
|
||||||
|
|
||||||
|
checkSort: (e: any) => {
|
||||||
|
const value = e.target.value.match(/^[0-9]*/)[0];
|
||||||
|
if (value) {
|
||||||
|
form.data.sortIndex = value;
|
||||||
|
form.beforeSortIndex = value;
|
||||||
|
} else form.data.sortIndex = form.beforeSortIndex;
|
||||||
|
},
|
||||||
|
|
||||||
|
submit: () => {
|
||||||
|
form.loading = true;
|
||||||
|
const api = form.data.id ? updateDepartment_api : addDepartment_api;
|
||||||
|
api(form.data)
|
||||||
|
.then(() => {
|
||||||
|
emits('refresh');
|
||||||
|
dialog.changeVisible(false);
|
||||||
|
})
|
||||||
|
.finally(() => (form.loading = false));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
type formType = {
|
||||||
|
id?: string;
|
||||||
|
parentId?: string;
|
||||||
|
name: string;
|
||||||
|
sortIndex: string | number;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 将打开弹窗的操作暴露给父组件
|
||||||
|
defineExpose({
|
||||||
|
openDialog: dialog.changeVisible,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
|
@ -0,0 +1,214 @@
|
||||||
|
<template>
|
||||||
|
<div class="left-tree-container">
|
||||||
|
<a-input
|
||||||
|
v-model:value="searchValue"
|
||||||
|
@change="search"
|
||||||
|
placeholder="请输入组织名称"
|
||||||
|
class="search-input"
|
||||||
|
>
|
||||||
|
<template #suffix>
|
||||||
|
<search-outlined />
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
<a-button type="primary" @click="openDialog" class="add-btn">
|
||||||
|
新增
|
||||||
|
</a-button>
|
||||||
|
<a-tree
|
||||||
|
:tree-data="treeData"
|
||||||
|
v-model:selected-keys="selectedKeys"
|
||||||
|
:fieldNames="{ key: 'id' }"
|
||||||
|
v-loading="loading"
|
||||||
|
>
|
||||||
|
<template #title="{ name, data }">
|
||||||
|
<span>{{ name }}</span>
|
||||||
|
<span class="func-btns">
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>编辑</template>
|
||||||
|
<a-button style="padding: 0" type="link">
|
||||||
|
<edit-outlined @click="openDialog(data)" />
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>新增子组织</template>
|
||||||
|
<a-button style="padding: 0" type="link">
|
||||||
|
<plus-circle-outlined
|
||||||
|
style="margin: 0 8px"
|
||||||
|
@click="
|
||||||
|
openDialog({
|
||||||
|
...data,
|
||||||
|
id: '',
|
||||||
|
parentId: data.id,
|
||||||
|
})
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
|
||||||
|
<a-popconfirm
|
||||||
|
title="确认删除"
|
||||||
|
ok-text="确定"
|
||||||
|
cancel-text="取消"
|
||||||
|
@confirm="delDepartment(data.id)"
|
||||||
|
>
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>删除</template>
|
||||||
|
<a-button style="padding: 0" type="link">
|
||||||
|
<delete-outlined />
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-popconfirm>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</a-tree>
|
||||||
|
|
||||||
|
<!-- 编辑弹窗 -->
|
||||||
|
<EditDepartmentDialog
|
||||||
|
:tree-data="sourceTree"
|
||||||
|
ref="editDialogRef"
|
||||||
|
@refresh="getTree"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { getTreeData_api, delDepartment_api } from '@/api/system/department';
|
||||||
|
import { debounce, cloneDeep, omit } from 'lodash-es';
|
||||||
|
import { ArrayToTree } from '@/utils/utils';
|
||||||
|
import EditDepartmentDialog from './EditDepartmentDialog.vue';
|
||||||
|
|
||||||
|
import {
|
||||||
|
SearchOutlined,
|
||||||
|
EditOutlined,
|
||||||
|
PlusCircleOutlined,
|
||||||
|
DeleteOutlined,
|
||||||
|
} from '@ant-design/icons-vue';
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
|
const emits = defineEmits(['change']);
|
||||||
|
const searchValue = ref('');// 搜索内容
|
||||||
|
const loading = ref<boolean>(false); // 数据加载状态
|
||||||
|
const sourceTree = ref<any[]>([]); // 源数据
|
||||||
|
const treeMap = new Map(); // 数据的map版本
|
||||||
|
const treeData = ref<any[]>([]); // 展示的数据
|
||||||
|
const selectedKeys = ref<string[]>([]); // 当前选中的项
|
||||||
|
|
||||||
|
getTree();
|
||||||
|
watch(selectedKeys, (n) => {
|
||||||
|
emits('change', n[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
function getTree() {
|
||||||
|
loading.value = true;
|
||||||
|
const params = {
|
||||||
|
paging: false,
|
||||||
|
sorts: [{ name: 'sortIndex', order: 'asc' }],
|
||||||
|
} as any;
|
||||||
|
if (searchValue.value) {
|
||||||
|
params.terms = [
|
||||||
|
{ column: 'name$LIKE', value: `%${searchValue.value}%` },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
getTreeData_api(params)
|
||||||
|
.then((resp: any) => {
|
||||||
|
selectedKeys.value = [resp.result[0].id];
|
||||||
|
sourceTree.value = resp.result; // 报存源数据
|
||||||
|
handleTreeMap(resp.result); // 将树形结构转换为map结构
|
||||||
|
treeData.value = resp.result; // 第一次不用进行过滤
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const search = debounce(() => {
|
||||||
|
const key = searchValue.value;
|
||||||
|
const treeArray = new Map();
|
||||||
|
if (key) {
|
||||||
|
const searchTree: string[] = [];
|
||||||
|
treeMap.forEach((item) => {
|
||||||
|
if (item.name.includes(key)) {
|
||||||
|
searchTree.push(item.parentId);
|
||||||
|
treeArray.set(item.id, item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dig(searchTree);
|
||||||
|
treeData.value = ArrayToTree(cloneDeep([...treeArray.values()]));
|
||||||
|
} else {
|
||||||
|
treeData.value = ArrayToTree(cloneDeep([...treeMap.values()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
function dig(_data: any[]): any {
|
||||||
|
const pIds: string[] = [];
|
||||||
|
if (!_data.length) return;
|
||||||
|
_data.forEach((item) => {
|
||||||
|
if (treeMap.has(item)) {
|
||||||
|
const _item = treeMap.get(item);
|
||||||
|
pIds.push(_item.parentId);
|
||||||
|
treeArray.set(item, _item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
// 将树形数组转化为map形式,以便筛选时操作
|
||||||
|
function handleTreeMap(_data: any[]) {
|
||||||
|
if (_data) {
|
||||||
|
_data.map((item) => {
|
||||||
|
treeMap.set(item.id, omit(cloneDeep(item), ['children']));
|
||||||
|
if (item.children) {
|
||||||
|
handleTreeMap(item.children);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 删除部门
|
||||||
|
function delDepartment(id: string) {
|
||||||
|
delDepartment_api(id).then(() => {
|
||||||
|
message.success('操作成功');
|
||||||
|
getTree();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 弹窗
|
||||||
|
const editDialogRef = ref(); // 新增弹窗实例
|
||||||
|
const openDialog = (row: any = {}) => {
|
||||||
|
editDialogRef.value.openDialog(true, row);
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.left-tree-container {
|
||||||
|
padding-right: 24px;
|
||||||
|
|
||||||
|
.add-btn {
|
||||||
|
margin: 24px 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-tree-treenode) {
|
||||||
|
width: 100%;
|
||||||
|
.ant-tree-node-content-wrapper {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
|
||||||
|
.ant-tree-title {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
.func-btns {
|
||||||
|
display: none;
|
||||||
|
font-size: 14px;
|
||||||
|
.ant-btn {
|
||||||
|
height: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
.func-btns {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
设备
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,52 @@
|
||||||
|
<template>
|
||||||
|
<div class="department-container">
|
||||||
|
<a-card class="department-content">
|
||||||
|
<div class="left">
|
||||||
|
<LeftTree @change="id=>departmentId = id" />
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<a-tabs v-model:activeKey="activeKey">
|
||||||
|
<a-tab-pane key="product" tab="产品">
|
||||||
|
<Product :parentId="departmentId" />
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane key="device" tab="设备">
|
||||||
|
<Device />
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane key="user" tab="用户">
|
||||||
|
<User />
|
||||||
|
</a-tab-pane>
|
||||||
|
</a-tabs>
|
||||||
|
</div>
|
||||||
|
</a-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="Department">
|
||||||
|
import LeftTree from './components/LeftTree.vue';
|
||||||
|
import Product from './product/index.vue';
|
||||||
|
import Device from './device/index.vue';
|
||||||
|
import User from './user/index.vue';
|
||||||
|
|
||||||
|
const activeKey = ref<'product' | 'device' | 'user'>('product');
|
||||||
|
|
||||||
|
const departmentId = ref<string>('')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.department-container {
|
||||||
|
padding: 24px;
|
||||||
|
.department-content {
|
||||||
|
:deep(.ant-card-body) {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
flex-basis: 300px;
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,279 @@
|
||||||
|
<template>
|
||||||
|
<div class="product-container">
|
||||||
|
<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,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #headerTitle>
|
||||||
|
<a-space>
|
||||||
|
<a-button type="primary" @click="table.clickAdd">
|
||||||
|
新增
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #card="slotProps">
|
||||||
|
<CardBox
|
||||||
|
:value="slotProps"
|
||||||
|
:actions="[{ key: 1 }]"
|
||||||
|
v-bind="slotProps"
|
||||||
|
:active="
|
||||||
|
table._selectedRowKeys.value.includes(slotProps.id)
|
||||||
|
"
|
||||||
|
: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')" />
|
||||||
|
</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>{{ slotProps.deviceType?.text }}</div>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<div class="card-item-content-text">
|
||||||
|
资产权限
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{
|
||||||
|
table.permissionList.value.length &&
|
||||||
|
table.getPermissLabel(
|
||||||
|
slotProps.permission,
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</template>
|
||||||
|
<template #actions>
|
||||||
|
<a-button @click="table.clickEdit(slotProps)">
|
||||||
|
<AIcon type="EditOutlined" />
|
||||||
|
</a-button>
|
||||||
|
<a-popconfirm
|
||||||
|
title="是否解除绑定"
|
||||||
|
ok-text="确定"
|
||||||
|
cancel-text="取消"
|
||||||
|
@confirm="table.clickUnBind"
|
||||||
|
><a-button>
|
||||||
|
<AIcon type="DisconnectOutlined" />
|
||||||
|
</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
</template>
|
||||||
|
</CardBox>
|
||||||
|
</template>
|
||||||
|
</JTable>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="product">
|
||||||
|
import { ActionsType } from '@/components/Table';
|
||||||
|
import { getImage } from '@/utils/comm';
|
||||||
|
|
||||||
|
import {
|
||||||
|
getDeviceOrProductList_api,
|
||||||
|
getPermission_api,
|
||||||
|
getPermissionDict_api,
|
||||||
|
} from '@/api/system/department';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
parentId: String,
|
||||||
|
});
|
||||||
|
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 tableRef = ref();
|
||||||
|
const table = {
|
||||||
|
columns: [],
|
||||||
|
_selectedRowKeys: ref<string[]>([]),
|
||||||
|
permissionList: ref<dictType>([]),
|
||||||
|
|
||||||
|
init: () => {
|
||||||
|
table.getPermissionDict();
|
||||||
|
watch(
|
||||||
|
() => props.parentId,
|
||||||
|
() => {
|
||||||
|
nextTick(() => {
|
||||||
|
tableRef.value.reload();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
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 '';
|
||||||
|
const result = values.map(
|
||||||
|
(key) => permissionList.find((item) => item.id === key)?.name,
|
||||||
|
);
|
||||||
|
return result.join(',');
|
||||||
|
},
|
||||||
|
onSelectChange: (keys: string[]) => {
|
||||||
|
table._selectedRowKeys.value = [...keys];
|
||||||
|
},
|
||||||
|
getData: (params: object, parentId: string) =>
|
||||||
|
new Promise((resolve) => {
|
||||||
|
getDeviceOrProductList_api(params).then((resp) => {
|
||||||
|
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] = item.grantedPermissions;
|
||||||
|
});
|
||||||
|
data.forEach(
|
||||||
|
(item) => (item.permission = permissionObj[item.id]),
|
||||||
|
);
|
||||||
|
|
||||||
|
resolve({
|
||||||
|
code: 200,
|
||||||
|
result: {
|
||||||
|
data: data,
|
||||||
|
pageIndex,
|
||||||
|
pageSize,
|
||||||
|
total,
|
||||||
|
},
|
||||||
|
status: 200,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
requestFun: async (oParams: any) => {
|
||||||
|
if (props.parentId) {
|
||||||
|
const params = {
|
||||||
|
...oParams,
|
||||||
|
sorts: [{ name: 'createTime', order: 'desc' }],
|
||||||
|
terms: [
|
||||||
|
...oParams.terms,
|
||||||
|
{
|
||||||
|
column: 'id',
|
||||||
|
termType: 'dim-assets',
|
||||||
|
value: {
|
||||||
|
assetType: 'product',
|
||||||
|
targets: [
|
||||||
|
{
|
||||||
|
type: 'org',
|
||||||
|
id: props.parentId,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clickAdd: () => {},
|
||||||
|
clickEdit: (row: any) => {},
|
||||||
|
clickUnBind: (row: any) => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
table.init();
|
||||||
|
|
||||||
|
type dictType = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}[];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
用户
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
Loading…
Reference in New Issue