【V3.5.0】1、【新增】轻量级定时任务 SmartJob;2、【新增】站内信;3、【新增】个人中心;4、【新增】岗位管理;5、【优化】部门员工管理

This commit is contained in:
zhuoda
2024-07-16 00:23:42 +08:00
parent 8fdcf13f86
commit e0c2b5a176
505 changed files with 59750 additions and 1113 deletions
@@ -0,0 +1,157 @@
<!--
* 角色 数据范围
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-12 22:34:00
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
*
-->
<template>
<div>
<div class="btn-group">
<a-button class="button-style" type="primary" @click="updateDataScope" v-privilege="'system:role:dataScope:update'"> 保存 </a-button>
<a-button class="button-style" @click="getDataScope"> 刷新 </a-button>
</div>
<a-row class="header">
<a-col class="tab-margin" :span="4">业务单据</a-col>
<a-col class="tab-data" :span="8">查看数据范围</a-col>
<a-col class="tab-margin" :span="12" />
</a-row>
<div class="data-container">
<a-row class="data" align="middle" justify="center" v-for="(item, index) in dataScopeList" :key="item.dataScopeType">
<a-col class="tab-margin" :span="4">
{{ item.dataScopeTypeName }}
</a-col>
<a-col class="tab-data" :span="8">
<a-radio-group v-model:value="selectedDataScopeList[index].viewType">
<a-radio
v-for="scope in item.viewTypeList"
:key="`${item.dataScopeType}-${scope.viewType}`"
class="radio-style"
:value="scope.viewType"
>{{ scope.viewTypeName }}</a-radio
>
</a-radio-group>
</a-col>
<a-col class="tab-margin tab-desc" :span="12">
<p>{{ item.dataScopeTypeDesc }}</p>
</a-col>
</a-row>
</div>
</div>
</template>
<script setup>
import { message } from 'ant-design-vue';
import _ from 'lodash';
import { inject, onMounted, ref, watch } from 'vue';
import { roleApi } from '/src/api/system/role-api';
import { smartSentry } from '/src/lib/smart-sentry';
const props = defineProps({
value: Number,
});
defineEmits(['update:value']);
// ----------------------- 显示 ---------------------------------
let selectRoleId = inject('selectRoleId');
let dataScopeList = ref([]);
let selectedDataScopeList = ref([]);
watch(
() => selectRoleId.value,
() => getRoleDataScope()
);
onMounted(getDataScope);
// 获取系统支持的所有种类的数据范围
async function getDataScope() {
let result = await roleApi.getDataScopeList();
dataScopeList.value = result.data;
selectedDataScopeList.value = [];
dataScopeList.value.forEach((item) => {
selectedDataScopeList.value.push({
viewType: undefined,
dataScopeType: item.dataScopeType,
});
});
getRoleDataScope();
}
// 获取数据范围根据角色id,并赋予选中状态
async function getRoleDataScope() {
let result = await roleApi.getDataScopeByRoleId(selectRoleId.value);
let data = result.data;
selectedDataScopeList.value = [];
dataScopeList.value.forEach((item) => {
let find = data.find((e) => e.dataScopeType == item.dataScopeType);
selectedDataScopeList.value.push({
viewType: find ? find.viewType : undefined,
dataScopeType: item.dataScopeType,
});
});
}
// ----------------------- 数据范围更新 ---------------------------------
// 更新
async function updateDataScope() {
try {
let data = {
roleId: selectRoleId.value,
dataScopeItemList: selectedDataScopeList.value.filter((e) => !_.isUndefined(e.viewType)),
};
await roleApi.updateDataScope(data);
message.success('保存成功');
getDataScope();
} catch (e) {
smartSentry.captureError(e);
}
}
</script>
<style scoped lang="less">
.btn-group {
text-align: right;
}
.button-style {
margin: 0 10px;
}
.header {
border-bottom: 1px solid #f2f2f2;
font-weight: 600;
margin: 10px 0px;
}
.tab-data {
margin: 10px 0px;
}
.data-container {
height: 680px;
overflow-y: scroll;
}
.data {
border-bottom: 1px solid #f2f2f2;
margin: 10px 0px;
}
.radio-style {
display: block;
height: 30px;
line-height: 30px;
}
.tab-margin {
text-align: center;
margin: 10px 0px;
}
.tab-desc {
line-height: 30px;
font-size: 16px;
text-align: left;
}
</style>
@@ -0,0 +1,274 @@
<!--
* 角色 员工 列表
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-12 22:34:00
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
*
-->
<template>
<div>
<div class="header">
<div>
关键字
<a-input style="width: 250px" v-model:value="queryForm.keywords" placeholder="姓名/手机号/登录账号" />
<a-button class="button-style" v-if="selectRoleId" type="primary" @click="onSearch">搜索</a-button>
<a-button class="button-style" v-if="selectRoleId" type="default" @click="resetQueryRoleEmployee">重置</a-button>
</div>
<div>
<a-button class="button-style" v-if="selectRoleId" type="primary" @click="addRoleEmployee" v-privilege="'system:role:employee:add'"
>添加员工</a-button
>
<a-button
class="button-style"
v-if="selectRoleId"
type="primary"
danger
@click="batchDelete"
v-privilege="'system:role:employee:batch:delete'"
>批量移除</a-button
>
</div>
</div>
<a-table
:loading="tableLoading"
:dataSource="tableData"
:columns="columns"
:pagination="false"
:scroll="{ y: 400 }"
rowKey="employeeId"
:row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }"
size="small"
bordered
>
<template #bodyCell="{ text, record, column }">
<template v-if="column.dataIndex === 'disabledFlag'">
<a-tag :color="text ? 'error' : 'processing'">{{ text ? '禁用' : '启用' }}</a-tag>
</template>
<template v-else-if="column.dataIndex === 'gender'">
<span>{{ $smartEnumPlugin.getDescByValue('GENDER_ENUM', text) }}</span>
</template>
<template v-if="column.dataIndex === 'operate'">
<a @click="deleteEmployeeRole(record.employeeId)" v-privilege="'system:role:employee:delete'">移除</a>
</template>
</template>
</a-table>
<div class="smart-query-table-page">
<a-pagination
showSizeChanger
showQuickJumper
show-less-items
:pageSizeOptions="PAGE_SIZE_OPTIONS"
:defaultPageSize="queryForm.pageSize"
v-model:current="queryForm.pageNum"
v-model:pageSize="queryForm.pageSize"
:total="total"
@change="queryRoleEmployee"
@showSizeChange="queryRoleEmployee"
:show-total="showTableTotal"
/>
</div>
<EmployeeTableSelectModal ref="selectEmployeeModal" @selectData="selectData" />
</div>
</template>
<script setup>
import { message, Modal } from 'ant-design-vue';
import _ from 'lodash';
import { computed, inject, onMounted, reactive, ref, watch } from 'vue';
import { roleApi } from '/src/api/system/role-api';
import { PAGE_SIZE, showTableTotal, PAGE_SIZE_OPTIONS } from '/src/constants/common-const';
import { SmartLoading } from '/src/components/framework/smart-loading';
import EmployeeTableSelectModal from '/src/components/system/employee-table-select-modal/index.vue';
import { smartSentry } from '/src/lib/smart-sentry';
// ----------------------- 以下是字段定义 emits props ---------------------
let selectRoleId = inject('selectRoleId');
// ----------------------- 员工列表:显示和搜索 ------------------------
watch(
() => selectRoleId.value,
() => queryRoleEmployee()
);
onMounted(queryRoleEmployee);
const defaultQueryForm = {
pageNum: 1,
pageSize: PAGE_SIZE,
roleId: undefined,
keywords: undefined,
};
// 查询表单
const queryForm = reactive({ ...defaultQueryForm });
// 总数
const total = ref(0);
// 表格数据
const tableData = ref([]);
// 表格loading效果
const tableLoading = ref(false);
function resetQueryRoleEmployee() {
queryForm.keywords = '';
queryRoleEmployee();
}
function onSearch() {
queryForm.pageNum = 1;
queryRoleEmployee();
}
async function queryRoleEmployee() {
try {
tableLoading.value = true;
queryForm.roleId = selectRoleId.value;
let res = await roleApi.queryRoleEmployee(queryForm);
tableData.value = res.data.list;
total.value = res.data.total;
} catch (e) {
smartSentry.captureError(e);
} finally {
tableLoading.value = false;
}
}
const columns = reactive([
{
title: '姓名',
dataIndex: 'actualName',
},
{
title: '手机号',
dataIndex: 'phone',
},
{
title: '登录账号',
dataIndex: 'loginName',
},
{
title: '部门',
dataIndex: 'departmentName',
},
{
title: '状态',
dataIndex: 'disabledFlag',
},
{
title: '操作',
dataIndex: 'operate',
width: 60,
},
]);
// ----------------------- 添加成员 ---------------------------------
const selectEmployeeModal = ref();
async function addRoleEmployee() {
let res = await roleApi.getRoleAllEmployee(selectRoleId.value);
let selectedIdList = res.data.map((e) => e.roleId) || [];
selectEmployeeModal.value.showModal(selectedIdList);
}
async function selectData(list) {
if (_.isEmpty(list)) {
message.warning('请选择角色人员');
return;
}
SmartLoading.show();
try {
let params = {
employeeIdList: list,
roleId: selectRoleId.value,
};
await roleApi.batchAddRoleEmployee(params);
message.success('添加成功');
await queryRoleEmployee();
} catch (e) {
smartSentry.captureError(e);
} finally {
SmartLoading.hide();
}
}
// ----------------------- 移除成员 ---------------------------------
// 删除角色成员方法
async function deleteEmployeeRole(employeeId) {
Modal.confirm({
title: '提示',
content: '确定要删除该角色成员么?',
okText: '确定',
okType: 'danger',
async onOk() {
SmartLoading.show();
try {
await roleApi.deleteEmployeeRole(employeeId, selectRoleId.value);
message.success('移除成功');
await queryRoleEmployee();
} catch (e) {
smartSentry.captureError(e);
} finally {
SmartLoading.hide();
}
},
cancelText: '取消',
onCancel() {},
});
}
// ----------------------- 批量删除 ---------------------------------
const selectedRowKeyList = ref([]);
const hasSelected = computed(() => selectedRowKeyList.value.length > 0);
function onSelectChange(selectedRowKeys) {
selectedRowKeyList.value = selectedRowKeys;
}
// 批量移除
function batchDelete() {
if (!hasSelected.value) {
message.warning('请选择要删除的角色成员');
return;
}
Modal.confirm({
title: '提示',
content: '确定移除这些角色成员吗?',
okText: '确定',
okType: 'danger',
async onOk() {
SmartLoading.show();
try {
let params = {
employeeIdList: selectedRowKeyList.value,
roleId: selectRoleId.value,
};
await roleApi.batchRemoveRoleEmployee(params);
message.success('移除成功');
selectedRowKeyList.value = [];
await queryRoleEmployee();
} catch (e) {
smartSentry.captureError(e);
} finally {
SmartLoading.hide();
}
},
cancelText: '取消',
onCancel() {},
});
}
</script>
<style scoped lang="less">
.header {
display: flex;
align-items: center;
justify-content: space-between;
margin: 20px 0;
}
.button-style {
margin: 0 10px;
}
</style>
@@ -0,0 +1,116 @@
<!--
* 角色 表单
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-12 22:34:00
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
*
-->
<template>
<a-modal :title="form.roleId ? '编辑角色' : '添加角色'" :width="600" :open="modalVisible" @cancel="onClose" :footer="null">
<a-form ref="formRef" :model="form" :rules="rules" :labelCol="{ span: 4 }">
<a-form-item label="角色名称" name="roleName">
<a-input style="width: 100%" placeholder="请输入角色名称" v-model:value="form.roleName" />
</a-form-item>
<a-form-item label="角色编码" name="roleCode">
<a-input style="width: 100%" placeholder="请输入角色编码" v-model:value="form.roleCode" />
</a-form-item>
<a-form-item label="角色备注">
<a-input style="width: 100%" placeholder="请输入角色备注" v-model:value="form.remark" />
</a-form-item>
</a-form>
<div class="footer">
<a-button style="margin-right: 8px" @click="onClose">取消</a-button>
<a-button type="primary" @click="submitForm">提交</a-button>
</div>
</a-modal>
</template>
<script setup>
import { message } from 'ant-design-vue';
import { reactive, ref } from 'vue';
import { roleApi } from '/src/api/system/role-api';
import { smartSentry } from '/src/lib/smart-sentry';
import { SmartLoading } from '/src/components/framework/smart-loading';
// ----------------------- 以下是字段定义 emits props ---------------------
let emits = defineEmits(['refresh']);
defineExpose({
showModal,
});
// ----------------------- modal 显示与隐藏 ---------------------
const modalVisible = ref(false);
function showModal(role) {
Object.assign(form, formDefault);
if (role) {
Object.assign(form, role);
}
modalVisible.value = true;
}
function onClose() {
Object.assign(form, formDefault);
modalVisible.value = false;
}
// ----------------------- 表单 ---------------------
const formRef = ref();
const formDefault = {
roleId: undefined,
remark: undefined,
roleCode: undefined,
roleName: undefined,
};
let form = reactive({ ...formDefault });
// 表单规则
const rules = {
roleName: [{ required: true, message: '请输入角色名称' }],
roleCode: [{ required: true, message: '请输入角色编码' }],
};
// 提交表单
async function submitForm() {
formRef.value
.validate()
.then(async () => {
SmartLoading.show();
try {
if (form.roleId) {
await roleApi.updateRole(form);
} else {
await roleApi.addRole(form);
}
message.info(`${form.roleId ? '编辑' : '添加'}成功`);
emits('refresh');
onClose();
} catch (e) {
smartSentry.captureError(e);
} finally {
SmartLoading.hide();
}
})
.catch((error) => {
message.error('参数验证错误,请仔细填写表单数据!');
});
}
</script>
<style scoped lang="less">
.footer {
width: 100%;
border-top: 1px solid #e9e9e9;
padding: 10px 16px;
background: #fff;
text-align: right;
z-index: 1;
}
</style>
@@ -0,0 +1,116 @@
<!--
* 角色 列表
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-12 22:34:00
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
*
-->
<template>
<a-card title="角色列表" class="role-container" style="padding: 0">
<template #extra>
<a-button type="primary" size="small" @click="showRoleFormModal" v-privilege="'system:role:add'">添加</a-button>
</template>
<a-menu mode="vertical" v-model:selectedKeys="selectedKeys">
<a-menu-item v-for="item in roleList" :key="item.roleId">
<a-popover placement="right">
<template #content>
<div style="display: flex; flex-direction: column">
<a-button type="text" @click="deleteRole(item.roleId)" v-privilege="'system:role:delete'">删除</a-button>
<a-button type="text" @click="showRoleFormModal(item)" v-privilege="'system:role:update'">编辑</a-button>
</div>
</template>
{{ item.roleName }}
</a-popover>
</a-menu-item>
</a-menu>
</a-card>
<RoleFormModal ref="roleFormModal" @refresh="queryAllRole" />
</template>
<script setup>
import { message, Modal } from 'ant-design-vue';
import _ from 'lodash';
import { computed, onMounted, ref } from 'vue';
import { roleApi } from '/src/api/system/role-api';
import { SmartLoading } from '/src/components/framework/smart-loading';
import RoleFormModal from '../role-form-modal/index.vue';
import { smartSentry } from '/src/lib/smart-sentry';
// ----------------------- 角色列表显示 ---------------------
const roleList = ref([]);
onMounted(queryAllRole);
// 查询列表
async function queryAllRole() {
let res = await roleApi.queryAll();
roleList.value = res.data;
if (!_.isEmpty(res.data) && res.data[0].roleId) {
selectedKeys.value = [res.data[0].roleId];
}
}
let selectedKeys = ref([]);
const selectRoleId = computed(() => {
if (!selectedKeys.value && _.isEmpty(selectedKeys.value)) {
return null;
}
return selectedKeys.value[0];
});
// ----------------------- 添加、修改、删除 ---------------------------------
const roleFormModal = ref();
// 显示表单框
function showRoleFormModal(role) {
roleFormModal.value.showModal(role);
}
// 删除角色
function deleteRole(roleId) {
if (!roleId) {
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除该角色么?',
okText: '确定',
okType: 'danger',
async onOk() {
SmartLoading.show();
try {
await roleApi.deleteRole(roleId);
message.info('删除成功');
queryAllRole();
} catch (e) {
smartSentry.captureError(e);
} finally {
SmartLoading.hide();
}
},
cancelText: '取消',
onCancel() {},
});
}
// ----------------------- 以下是暴露的方法内容 ----------------------------
defineExpose({
selectRoleId,
});
</script>
<style scoped lang="less">
.role-container {
height: 100%;
overflow-y: auto;
:deep(.ant-card-body) {
padding: 5px;
}
}
.ant-menu-inline,
.ant-menu-vertical,
.ant-menu-vertical-left {
border-right: none;
}
</style>
@@ -0,0 +1,44 @@
<!--
* 角色 设置
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-12 22:34:00
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
*
-->
<template>
<a-card class="role-container">
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="1" tab="角色-功能权限">
<RoleTree />
</a-tab-pane>
<a-tab-pane key="2" tab="角色-数据范围">
<RoleDataScope />
</a-tab-pane>
<a-tab-pane key="3" tab="角色-员工列表">
<RoleEmployeeList />
</a-tab-pane>
</a-tabs>
</a-card>
</template>
<script setup>
import { ref } from 'vue';
import RoleDataScope from '../role-data-scope/index.vue';
import RoleEmployeeList from '../role-employee-list/index.vue';
import RoleTree from '../role-tree/index.vue';
defineProps({
value: Number,
});
defineEmits(['update:value']);
let activeKey = ref();
</script>
<style scoped lang="less">
.role-container {
height: 100%;
}
</style>
@@ -0,0 +1,78 @@
:deep(.ant-checkbox-group) {
width: 100%;
}
.tree-header {
display: flex;
align-items: center;
justify-content: space-between;
margin: 20px 0;
}
.col-desc {
margin: 20px 0;
font-size: 15px;
color: #95a5a6;
padding: 0 20px;
}
.button-style {
margin: 20px 0 20px 0;
padding-left: 20px;
text-align: right;
}
.check-right {
margin-right: 20px;
}
.row-border {
border: 1px solid #f0f0f0;
}
.col-border {
line-height: 50px;
padding-left: 20px;
border-right: 1px solid #f0f0f0;
}
.col-left {
line-height: 50px;
padding-left: 40px;
border-right: 1px solid #f0f0f0;
}
.col-right {
padding-left: 20px;
border-right: 1px solid #f0f0f0;
}
.checked-box {
padding: 0 15px;
:deep(ul li::marker) {
content: '';
}
:deep(ul) {
padding: 0;
margin: 0;
li {
list-style: none;
padding: 0;
margin: 10px 0;
.menu {
border-bottom: 1px solid rgb(240, 240, 240);
display: flex;
align-items: center;
line-height: 25px;
}
.point {
display: flex;
align-items: center;
.point-label {
flex: 1;
padding-left: 40px;
border-left: 1px rgb(240, 240, 240) solid;
}
}
.checked-box-label {
min-width: 150px;
}
}
}
}
@@ -0,0 +1,74 @@
<!--
* 角色 树形结构
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-12 22:34:00
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
*
-->
<template>
<div>
<div class="tree-header">
<p>设置角色对应的功能操作后台管理权限</p>
<a-button v-if="selectRoleId" type="primary" @click="saveChange" v-privilege="'system:role:menu:update'"> 保存 </a-button>
</div>
<!-- 功能权限勾选部分 -->
<RoleTreeCheckbox :tree="tree" />
</div>
</template>
<script setup>
import { inject, ref, watch } from 'vue';
import { message } from 'ant-design-vue';
import _ from 'lodash';
import RoleTreeCheckbox from './role-tree-checkbox.vue';
import { roleMenuApi } from '/src/api/system/role-menu-api';
import { useRoleStore } from '/src/store/modules/system/role';
import { SmartLoading } from '/src/components/framework/smart-loading';
import { smartSentry } from '/src/lib/smart-sentry';
let roleStore = useRoleStore();
let tree = ref();
let selectRoleId = inject('selectRoleId');
watch(selectRoleId, () => getRoleSelectedMenu(), {
immediate: true,
});
async function getRoleSelectedMenu() {
if (!selectRoleId.value) {
return;
}
let res = await roleMenuApi.getRoleSelectedMenu(selectRoleId.value);
let data = res.data;
if (_.isEmpty(roleStore.treeMap)) {
roleStore.initTreeMap(data.menuTreeList || []);
}
roleStore.initCheckedData(data.selectedMenuId || []);
tree.value = data.menuTreeList;
}
async function saveChange() {
let checkedData = roleStore.checkedData;
if (_.isEmpty(checkedData)) {
message.error('还未选择任何权限');
return;
}
let params = {
roleId: selectRoleId.value,
menuIdList: checkedData,
};
SmartLoading.show();
try {
await roleMenuApi.updateRoleMenu(params);
message.success('保存成功');
} catch (error) {
smartSentry.captureError(error);
} finally {
SmartLoading.hide();
}
}
</script>
<style scoped lang="less">
@import 'index.less';
</style>
@@ -0,0 +1,49 @@
<!--
* 角色
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-12 22:34:00
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
*
-->
<template>
<div style="overflow: auto">
<a-checkbox-group v-model:value="checkedData">
<div class="checked-box">
<ul>
<!--li 菜单模块 start-->
<RoleTreeMenu :tree="props.tree" :index="0" />
<!--li 菜单模块 end-->
</ul>
</div>
</a-checkbox-group>
</div>
</template>
<script setup>
import { ref, watch } from 'vue';
import { useRoleStore } from '/src/store/modules/system/role';
import RoleTreeMenu from './role-tree-menu.vue';
let props = defineProps({
tree: {
type: Array,
default: [],
},
});
defineEmits(['update:value']);
let roleStore = useRoleStore();
let checkedData = ref();
watch(
() => roleStore.checkedData,
(e) => (checkedData.value = e),
{
deep: true,
}
);
</script>
<style scoped lang="less">
@import 'index.less';
</style>
@@ -0,0 +1,64 @@
<!--
* 角色 菜单
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-12 22:34:00
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
*
-->
<template>
<li v-for="module in props.tree" :key="module.menuId">
<div class="menu" :style="{ marginLeft: `${props.index * 4}%` }">
<a-checkbox @change="selectCheckbox(module)" class="checked-box-label" :value="module.menuId">{{ module.menuName }} </a-checkbox>
<div v-if="module.children && module.children.some((e) => e.menuType == MENU_TYPE_ENUM.POINTS.value)">
<RoleTreePoint :tree="module.children" @selectCheckbox="selectCheckbox" />
</div>
</div>
<template v-if="module.children && !module.children.some((e) => e.menuType == MENU_TYPE_ENUM.POINTS.value)">
<RoleTreeMenu :tree="module.children" :index="props.index + 1" />
</template>
</li>
</template>
<script setup>
import { MENU_TYPE_ENUM } from '/src/constants/system/menu-const';
import { useRoleStore } from '/src/store/modules/system/role';
import RoleTreePoint from './role-tree-point.vue';
import RoleTreeMenu from './role-tree-menu.vue';
const props = defineProps({
tree: {
type: Array,
default: [],
},
index: {
type: Number,
default: 0,
},
});
defineEmits(['update:value']);
let roleStore = useRoleStore();
function selectCheckbox(module) {
if (!module.menuId) {
return;
}
// 是否勾选
let checkedData = roleStore.checkedData;
let findIndex = checkedData.indexOf(module.menuId);
// 选中
if (findIndex == -1) {
// 选中本级以及子级
roleStore.addCheckedDataAndChildren(module);
// 选中上级
roleStore.selectUpperLevel(module);
// 是否有关联菜单 有则选中
if (module.contextMenuId) {
roleStore.addCheckedData(module.contextMenuId);
}
} else {
// 取消选中本级以及子级
roleStore.deleteCheckedDataAndChildren(module);
}
}
</script>
@@ -0,0 +1,33 @@
<!--
* 角色 功能点
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-12 22:34:00
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
*
-->
<template>
<div class="point">
<div class="point-label">
<template v-for="module in props.tree" :key="module.menuId">
<a-checkbox @change="emits('selectCheckbox', module)" :value="module.menuId">{{ module.menuName }} </a-checkbox>
</template>
</div>
</div>
</template>
<script setup>
const props = defineProps({
tree: {
type: Array,
default: [],
},
index: {
type: Number,
default: 0,
},
});
let emits = defineEmits(['selectCheckbox']);
</script>
<style scoped lang="less"></style>
@@ -0,0 +1,48 @@
<!--
* 角色 管理
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-12 22:34:00
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
*
-->
<template>
<div class="height100">
<a-row :gutter="10" type="flex" class="height100">
<a-col flex="200px">
<RoleList ref="roleList" />
</a-col>
<a-col flex="1" class="role-setting">
<RoleSetting />
</a-col>
</a-row>
</div>
</template>
<script setup>
import { computed, provide, ref } from 'vue';
import RoleList from './components/role-list/index.vue';
import RoleSetting from './components/role-setting/index.vue';
defineProps({
value: Object,
});
defineEmits(['update:value']);
let roleList = ref();
const selectRoleId = computed(() => {
if (!roleList.value) {
return null;
}
return roleList.value.selectRoleId;
});
provide('selectRoleId', selectRoleId);
</script>
<style scoped lang="less">
.height100 {
height: 100%;
}
.role-setting {
width: calc(100% - 250px);
}
</style>