More translation

This commit is contained in:
Lorenzo
2025-06-27 01:31:31 +02:00
parent adc3ab7e0a
commit fc1084ce33
18 changed files with 2772 additions and 2253 deletions
@@ -1,150 +1,152 @@
import * as api from "./api.js";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { useI18n } from "vue-i18n";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
const list = await api.GetTree();
const { t } = useI18n();
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
const list = await api.GetTree();
return {
offset: 0,
records: list,
total: 10000,
limit: 10000
};
};
return {
offset: 0,
records: list,
total: 10000,
limit: 10000
};
};
async function afterChange() {
await permissionTreeDict.reloadDict();
}
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
const ret = await api.UpdateObj(form);
await afterChange();
return ret;
};
const delRequest = async ({ row }: DelReq) => {
const ret = await api.DelObj(row.id);
await afterChange();
return ret;
};
async function afterChange() {
await permissionTreeDict.reloadDict();
}
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
const ret = await api.UpdateObj(form);
await afterChange();
return ret;
};
const delRequest = async ({ row }: DelReq) => {
const ret = await api.DelObj(row.id);
await afterChange();
return ret;
};
const addRequest = async ({ form }: AddReq) => {
const ret = await api.AddObj(form);
await afterChange();
return ret;
};
const permissionTreeDict = dict({
url: "/sys/authority/permission/tree",
isTree: true,
value: "id",
label: "title",
async onReady({ dict }: any) {
dict.setData([{ id: -1, title: "根节点", children: dict.data }]);
}
});
return {
crudOptions: {
request: {
pageRequest,
addRequest,
editRequest,
delRequest
},
actionbar: {
show: false
},
toolbar: {
show: false
},
table: {
show: false
// scroll: { fixed: true }
},
rowHandle: {
fixed: "right"
},
search: {
show: false
},
pagination: {
show: false,
pageSize: 100000
},
columns: {
id: {
title: "id",
type: "number",
form: { show: false }, // 表单配置
column: {
width: 120,
sortable: "custom"
}
},
title: {
title: "权限名称",
type: "text",
form: {
rules: [
{ required: true, message: "请输入权限名称" },
{ max: 50, message: "最大50个字符" }
],
component: {
placeholder: "权限名称"
}
},
column: {
width: 200
}
},
const addRequest = async ({ form }: AddReq) => {
const ret = await api.AddObj(form);
await afterChange();
return ret;
};
const permissionTreeDict = dict({
url: "/sys/authority/permission/tree",
isTree: true,
value: "id",
label: "title",
async onReady({ dict }: any) {
dict.setData([{ id: -1, title: t("certd.rootNode"), children: dict.data }]);
}
});
return {
crudOptions: {
request: {
pageRequest,
addRequest,
editRequest,
delRequest
},
actionbar: {
show: false
},
toolbar: {
show: false
},
table: {
show: false
// scroll: { fixed: true }
},
rowHandle: {
fixed: "right"
},
search: {
show: false
},
pagination: {
show: false,
pageSize: 100000
},
columns: {
id: {
title: "id",
type: "number",
form: { show: false }, // 表单配置
column: {
width: 120,
sortable: "custom"
}
},
title: {
title: t("certd.permissionName"),
type: "text",
form: {
rules: [
{ required: true, message: t("certd.enterPermissionName") },
{ max: 50, message: t("certd.max50Chars") }
],
component: {
placeholder: t("certd.permissionName")
}
},
column: {
width: 200
}
},
permission: {
title: t("certd.permissionCode"),
type: "text",
column: {
width: 170
},
form: {
rules: [
{ required: true, message: t("certd.enterPermissionCode") },
{ max: 100, message: t("certd.max100Chars") }
],
component: {
placeholder: t("certd.examplePermissionCode")
}
}
},
sort: {
title: t("certd.sortOrder"),
type: "number",
column: {
width: 100
},
form: {
value: 100,
rules: [{ required: true, type: "number", message: t("certd.sortRequired") }]
}
},
parentId: {
title: t("certd.parentNode"),
type: "dict-tree",
column: {
width: 100
},
dict: permissionTreeDict,
form: {
value: -1,
component: {
multiple: false,
defaultExpandAll: true,
dict: { cache: false },
fieldNames: {
value: "id",
label: "title"
}
}
}
}
permission: {
title: "权限代码",
type: "text",
column: {
width: 170
},
form: {
rules: [
{ required: true, message: "请输入权限代码" },
{ max: 100, message: "最大100个字符" }
],
component: {
placeholder: "例如:sys:user:view"
}
}
},
sort: {
title: "排序",
type: "number",
column: {
width: 100
},
form: {
value: 100,
rules: [{ required: true, type: "number", message: "排序号必填" }]
}
},
parentId: {
title: "父节点",
type: "dict-tree",
column: {
width: 100
},
dict: permissionTreeDict,
form: {
value: -1,
component: {
multiple: false,
defaultExpandAll: true,
dict: { cache: false },
fieldNames: {
value: "id",
label: "title"
}
}
}
}
}
}
};
}
}
};
}
@@ -1,193 +1,194 @@
<template>
<a-tree
v-if="computedTree"
ref="treeRef"
class="fs-permission-tree"
:class="{ 'is-editable': editable }"
:selectable="false"
show-line
:show-icon="false"
:default-expand-all="true"
:tree-data="computedTree"
@check="onChecked"
>
<template #title="scope">
<div class="node-title-pane">
<div class="node-title">{{ scope.title }}</div>
<div v-if="editable === true" class="node-suffix">
<fs-icon v-if="actions.add !== false" :icon="$fsui.icons.add" @click.stop="add(scope)" />
<fs-icon v-if="actions.edit !== false && scope.id !== -1" :icon="$fsui.icons.edit" @click.stop="edit(scope)" />
<fs-icon v-if="actions.remove !== false && scope.id !== -1" :icon="$fsui.icons.remove" @click.stop="remove(scope)" />
</div>
</div>
</template>
</a-tree>
<a-tree v-if="computedTree" ref="treeRef" class="fs-permission-tree" :class="{ 'is-editable': editable }"
:selectable="false" show-line :show-icon="false" :default-expand-all="true" :tree-data="computedTree"
@check="onChecked">
<template #title="scope">
<div class="node-title-pane">
<div class="node-title">{{ scope.title }}</div>
<div v-if="editable === true" class="node-suffix">
<fs-icon v-if="actions.add !== false" :icon="$fsui.icons.add" @click.stop="add(scope)" />
<fs-icon v-if="actions.edit !== false && scope.id !== -1" :icon="$fsui.icons.edit"
@click.stop="edit(scope)" />
<fs-icon v-if="actions.remove !== false && scope.id !== -1" :icon="$fsui.icons.remove"
@click.stop="remove(scope)" />
</div>
</div>
</template>
</a-tree>
</template>
<script lang="ts">
import { utils } from "@fast-crud/fast-crud";
import { cloneDeep } from "lodash-es";
import { computed, defineComponent, ref } from "vue";
import { useI18n } from "vue-i18n";
export default defineComponent({
name: "FsPermissionTree",
props: {
/**
* 树形数据
* */
tree: {},
/**
* 是否可编辑
*/
editable: {
default: true
},
actions: {
default: {}
}
} as any,
emits: ["add", "edit", "remove"],
setup(props: any, ctx) {
const treeRef = ref();
const computedTree = computed(() => {
if (props.tree == null) {
return null;
}
const clone = cloneDeep(props.tree);
utils.deepdash.forEachDeep(clone, (value: any, key: any, pNode: any, context: any) => {
if (value == null) {
return;
}
if (!(value instanceof Object) || value instanceof Array) {
return;
}
if (value.class === "is-leaf") {
//处理过,无需再次处理
return;
}
value.class = "is-twig";
if (value.children != null && value.children.length > 0) {
return;
}
const parents = context.parents;
if (parents.length < 2) {
return;
}
const parent = parents[parents.length - 2].value;
//看parent下面的children,是否全部都没有children
for (const child of parent.children) {
if (child.children != null && child.children.length > 0) {
//存在child有children
return;
}
}
// 所有的子节点都没有children
parent.class = "is-twig"; // 连接叶子节点的末梢枝杈节点
let i = 0;
for (const child of parent.children) {
child.class = "is-leaf";
if (i !== 0) {
child.class += " leaf-after";
}
i++;
}
});
return [
{
title: "根节点",
id: -1,
children: clone
}
];
});
function add(scope: any) {
ctx.emit("add", scope.dataRef);
}
function edit(scope: any) {
ctx.emit("edit", scope.dataRef);
}
function remove(scope: any) {
ctx.emit("remove", scope.dataRef);
}
function onChecked(a: any, b: any, c: any) {
utils.logger.info("chedcked", a, b, c);
}
function getChecked() {
const checked = treeRef.value.checkedKeys;
const halfChecked = treeRef.value.halfCheckedKeys;
return {
checked,
halfChecked
};
}
return {
computedTree,
add,
edit,
remove,
treeRef,
onChecked,
getChecked
};
}
name: "FsPermissionTree",
props: {
/**
* 树形数据
* */
tree: {},
/**
* 是否可编辑
*/
editable: {
default: true
},
actions: {
default: {}
}
} as any,
emits: ["add", "edit", "remove"],
setup(props: any, ctx) {
const { t } = useI18n();
const treeRef = ref();
const computedTree = computed(() => {
if (props.tree == null) {
return null;
}
const clone = cloneDeep(props.tree);
utils.deepdash.forEachDeep(clone, (value: any, key: any, pNode: any, context: any) => {
if (value == null) {
return;
}
if (!(value instanceof Object) || value instanceof Array) {
return;
}
if (value.class === "is-leaf") {
//处理过,无需再次处理
return;
}
value.class = "is-twig";
if (value.children != null && value.children.length > 0) {
return;
}
const parents = context.parents;
if (parents.length < 2) {
return;
}
const parent = parents[parents.length - 2].value;
//看parent下面的children,是否全部都没有children
for (const child of parent.children) {
if (child.children != null && child.children.length > 0) {
//存在child有children
return;
}
}
// 所有的子节点都没有children
parent.class = "is-twig"; // 连接叶子节点的末梢枝杈节点
let i = 0;
for (const child of parent.children) {
child.class = "is-leaf";
if (i !== 0) {
child.class += " leaf-after";
}
i++;
}
});
return [
{
title: t("certd.rootNode"),
id: -1,
children: clone
}
];
});
function add(scope: any) {
ctx.emit("add", scope.dataRef);
}
function edit(scope: any) {
ctx.emit("edit", scope.dataRef);
}
function remove(scope: any) {
ctx.emit("remove", scope.dataRef);
}
function onChecked(a: any, b: any, c: any) {
utils.logger.info("chedcked", a, b, c);
}
function getChecked() {
const checked = treeRef.value.checkedKeys;
const halfChecked = treeRef.value.halfCheckedKeys;
return {
checked,
halfChecked
};
}
return {
computedTree,
add,
edit,
remove,
treeRef,
onChecked,
getChecked,
t
};
}
});
</script>
<style lang="less">
.fs-permission-tree {
.ant-tree-list-holder-inner {
flex-direction: row !important;
flex-wrap: wrap;
.is-twig {
width: 100%;
}
.ant-tree-list-holder-inner {
flex-direction: row !important;
flex-wrap: wrap;
.is-leaf {
//border-bottom: 1px solid #ddd;
&::before {
display: none;
}
.is-twig {
width: 100%;
}
&.leaf-after {
.ant-tree-indent-unit {
display: none;
}
}
.is-leaf {
.node-title-pane {
border-bottom: 1px solid #ddd;
}
}
}
//.is-twig ul {
// display: flex;
// flex-wrap: wrap;
//}
.node-title-pane {
display: flex;
.node-title {
width: 110px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
//border-bottom: 1px solid #ddd;
&::before {
display: none;
}
&.is-editable {
.ant-tree-title {
&:hover {
.node-suffix {
visibility: visible;
}
}
}
&.leaf-after {
.ant-tree-indent-unit {
display: none;
}
}
.node-suffix {
visibility: hidden;
> * {
margin-left: 3px;
}
}
}
.node-title-pane {
border-bottom: 1px solid #ddd;
}
}
}
//.is-twig ul {
// display: flex;
// flex-wrap: wrap;
//}
.node-title-pane {
display: flex;
.node-title {
width: 110px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
&.is-editable {
.ant-tree-title {
&:hover {
.node-suffix {
visibility: visible;
}
}
}
.node-suffix {
visibility: hidden;
>* {
margin-left: 3px;
}
}
}
}
</style>
@@ -1,76 +1,81 @@
<template>
<fs-page>
<template #header>
<div class="title">权限管理</div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding">
<a-button v-permission="'1sys:auth:per:add'" style="margin-left: 20px" @click="addHandle({})">
<fs-icon :icon="ui.icons.add"></fs-icon>
添加
</a-button>
<fs-permission-tree class="permission-tree mt-10" :tree="crudBinding.data" :checkable="false" :actions="permission" @add="addHandle" @edit="editHandle" @remove="removeHandle"></fs-permission-tree>
</fs-crud>
</fs-page>
<fs-page>
<template #header>
<div class="title">{{ t("certd.permissionManagement") }}</div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding">
<a-button v-permission="'1sys:auth:per:add'" style="margin-left: 20px" @click="addHandle({})">
<fs-icon :icon="ui.icons.add"></fs-icon>
{{ t("certd.adda") }}
</a-button>
<fs-permission-tree class="permission-tree mt-10" :tree="crudBinding.data" :checkable="false"
:actions="permission" @add="addHandle" @edit="editHandle" @remove="removeHandle"></fs-permission-tree>
</fs-crud>
</fs-page>
</template>
<script lang="ts">
import { defineComponent, onActivated, onMounted, ref } from "vue";
import createCrudOptions from "./crud.js";
import FsPermissionTree from "./fs-permission-tree.vue";
import { usePermission } from "/src/plugin/permission";
import { useFs, useUi } from "@fast-crud/fast-crud";
import { useI18n } from "vue-i18n";
export default defineComponent({
name: "AuthorityManager",
components: { FsPermissionTree },
setup() {
// 此处传入permission进行通用按钮权限设置,会通过commonOptions去设置actionbar和rowHandle的按钮的show属性
// 更多关于按钮权限的源代码设置,请参考 ./src/plugin/fast-crud/index.js 75-77行)
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { permission: "sys:auth:per" } });
name: "AuthorityManager",
components: { FsPermissionTree },
setup() {
// 此处传入permission进行通用按钮权限设置,会通过commonOptions去设置actionbar和rowHandle的按钮的show属性
// 更多关于按钮权限的源代码设置,请参考 ./src/plugin/fast-crud/index.js 75-77行)
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { permission: "sys:auth:per" } });
const { t } = useI18n();
// 页面打开后获取列表数据
onMounted(async () => {
await crudExpose.doRefresh();
});
onActivated(async () => {
await crudExpose.doRefresh();
});
// 页面打开后获取列表数据
onMounted(async () => {
await crudExpose.doRefresh();
});
onActivated(async () => {
await crudExpose.doRefresh();
});
const { ui } = useUi();
const { ui } = useUi();
//用户业务代码
//用户业务代码
async function addHandle(item: any) {
await crudExpose.openAdd({ row: { parentId: item?.id ?? -1 } });
}
async function editHandle(item: any) {
await crudExpose.openEdit({ row: item });
}
async function removeHandle(item: any) {
await crudExpose.doRemove({ row: { id: item.id }, index: null });
}
async function addHandle(item: any) {
await crudExpose.openAdd({ row: { parentId: item?.id ?? -1 } });
}
async function editHandle(item: any) {
await crudExpose.openEdit({ row: item });
}
async function removeHandle(item: any) {
await crudExpose.doRemove({ row: { id: item.id }, index: null });
}
const { hasPermissions } = usePermission();
const permission = ref({
add: hasPermissions("1sys:auth:per:add"),
edit: hasPermissions("1sys:auth:per:edit"),
remove: hasPermissions("1sys:auth:per:remove"),
});
const { hasPermissions } = usePermission();
const permission = ref({
add: hasPermissions("1sys:auth:per:add"),
edit: hasPermissions("1sys:auth:per:edit"),
remove: hasPermissions("1sys:auth:per:remove"),
});
return {
ui,
crudBinding,
crudRef,
addHandle,
editHandle,
removeHandle,
permission,
};
},
return {
ui,
crudBinding,
crudRef,
addHandle,
editHandle,
removeHandle,
permission,
t
};
},
});
</script>
<style lang="less">
.permission-tree {
margin-left: 20px;
margin-left: 20px;
}
</style>
@@ -1,84 +1,86 @@
import * as api from "./api";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { useI18n } from "vue-i18n";
export default function ({ crudExpose, context: { authz } }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {
return await api.DelObj(row.id);
};
const { t } = useI18n();
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {
return await api.DelObj(row.id);
};
const addRequest = async ({ form }: AddReq) => {
return await api.AddObj(form);
};
return {
crudOptions: {
request: {
pageRequest,
addRequest,
editRequest,
delRequest
},
rowHandle: {
width: 300,
buttons: {
authz: {
type: "link",
text: "授权",
async click(context) {
await authz.authzOpen(context.record.id);
}
}
}
},
columns: {
id: {
title: "id",
type: "text",
form: { show: false }, // 表单配置
column: {
width: 70,
sorter: true
}
},
name: {
title: "角色名称",
type: "text",
search: { show: true },
form: {
rules: [
{ required: true, message: "请输入角色名称" },
{ max: 50, message: "最大50个字符" }
]
}, // 表单配置
column: {
sorter: true
}
},
createTime: {
title: "创建时间",
type: "datetime",
column: {
sorter: true
},
form: {
show: false
}
},
updateTime: {
title: "更新时间",
type: "datetime",
column: {
sorter: true
},
form: { show: false } // 表单配置
}
}
}
};
const addRequest = async ({ form }: AddReq) => {
return await api.AddObj(form);
};
return {
crudOptions: {
request: {
pageRequest,
addRequest,
editRequest,
delRequest
},
rowHandle: {
width: 300,
buttons: {
authz: {
type: "link",
text: "授权",
async click(context) {
await authz.authzOpen(context.record.id);
}
}
}
},
columns: {
id: {
title: "id",
type: "text",
form: { show: false }, // 表单配置
column: {
width: 70,
sorter: true
}
},
name: {
title: t("certd.roleName"),
type: "text",
search: { show: true },
form: {
rules: [
{ required: true, message: t("certd.enterRoleName") },
{ max: 50, message: t("certd.max50Chars") }
]
}, // 表单配置
column: {
sorter: true
}
},
createTime: {
title: t("certd.createTime"),
type: "datetime",
column: {
sorter: true
},
form: {
show: false
}
},
updateTime: {
title: t("certd.updateTime"),
type: "datetime",
column: {
sorter: true
},
form: { show: false } // 表单配置
}
}
}
};
}
@@ -1,15 +1,18 @@
<template>
<fs-page>
<template #header>
<div class="title">角色管理</div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding" />
<a-modal v-model:open="authzDialogVisible" width="860px" title="分配权限" @ok="updatePermission">
<fs-permission-tree ref="permissionTreeRef" v-model:checked-keys="checkedKeys" :tree="permissionTreeData" :editable="false" checkable :replace-fields="{ key: 'id', label: 'title' }"> </fs-permission-tree>
</a-modal>
</fs-page>
<fs-page>
<template #header>
<div class="title">{{ t("certd.roleManagement") }}</div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding" />
<a-modal v-model:open="authzDialogVisible" width="860px" :title="t('certd.assignPermissions')"
@ok="updatePermission">
<fs-permission-tree ref="permissionTreeRef" v-model:checked-keys="checkedKeys" :tree="permissionTreeData"
:editable="false" checkable :replace-fields="{ key: 'id', label: 'title' }"> </fs-permission-tree>
</a-modal>
</fs-page>
</template>
<script lang="ts">
import { defineComponent, onActivated, onMounted, ref } from "vue";
import { useFs } from "@fast-crud/fast-crud";
@@ -19,103 +22,106 @@ import * as api from "./api";
import { message } from "ant-design-vue";
import FsPermissionTree from "../permission/fs-permission-tree.vue";
import { UseCrudPermissionCompProps, UseCrudPermissionExtraProps } from "/@/plugin/permission";
import { useI18n } from "vue-i18n";
function useAuthz() {
const checkedKeys = ref();
const checkedKeys = ref();
const permissionTreeData = ref();
const permissionTreeData = ref();
const permissionTreeRef = ref();
const authzDialogVisible = ref(false);
const permissionTreeRef = ref();
const authzDialogVisible = ref(false);
const currentRoleId = ref();
const currentRoleId = ref();
// 如果勾选节点中存在非叶子节点,tree组件会将其所有子节点全部勾选
// 所以要找出所有叶子节点,仅勾选叶子节点,tree组件会将父节点同步勾选
function getAllCheckedLeafNodeId(tree: any, checkedIds: any, temp: any) {
for (let i = 0; i < tree.length; i++) {
const item = tree[i];
if (item.children && item.children.length !== 0) {
getAllCheckedLeafNodeId(item.children, checkedIds, temp);
} else {
if (checkedIds.indexOf(item.id) !== -1) {
temp.push(item.id);
}
}
}
return temp;
}
function authzClose() {
authzDialogVisible.value = false;
}
async function authzOpen(roleId: any) {
permissionTreeData.value = await permissionApi.GetTree();
checkedKeys.value = [];
currentRoleId.value = roleId;
// this.treeData = ret.data
await updateChecked(roleId);
authzDialogVisible.value = true;
}
async function updateChecked(roleId: any) {
let checkedIds = await api.getPermissionIds(roleId);
// 找出所有的叶子节点
checkedIds = getAllCheckedLeafNodeId(permissionTreeData.value, checkedIds, []);
checkedKeys.value = checkedIds;
}
async function updatePermission() {
const roleId = currentRoleId.value;
const { checked, halfChecked } = permissionTreeRef.value.getChecked();
const allChecked = [...checked, ...halfChecked];
await api.DoAuthz(roleId, allChecked);
authzClose();
//await updateChecked(roleId);
// 如果勾选节点中存在非叶子节点,tree组件会将其所有子节点全部勾选
// 所以要找出所有叶子节点,仅勾选叶子节点,tree组件会将父节点同步勾选
function getAllCheckedLeafNodeId(tree: any, checkedIds: any, temp: any) {
for (let i = 0; i < tree.length; i++) {
const item = tree[i];
if (item.children && item.children.length !== 0) {
getAllCheckedLeafNodeId(item.children, checkedIds, temp);
} else {
if (checkedIds.indexOf(item.id) !== -1) {
temp.push(item.id);
}
}
}
return temp;
}
function authzClose() {
authzDialogVisible.value = false;
}
async function authzOpen(roleId: any) {
permissionTreeData.value = await permissionApi.GetTree();
checkedKeys.value = [];
currentRoleId.value = roleId;
// this.treeData = ret.data
await updateChecked(roleId);
authzDialogVisible.value = true;
}
async function updateChecked(roleId: any) {
let checkedIds = await api.getPermissionIds(roleId);
// 找出所有的叶子节点
checkedIds = getAllCheckedLeafNodeId(permissionTreeData.value, checkedIds, []);
checkedKeys.value = checkedIds;
}
async function updatePermission() {
const roleId = currentRoleId.value;
const { checked, halfChecked } = permissionTreeRef.value.getChecked();
const allChecked = [...checked, ...halfChecked];
await api.DoAuthz(roleId, allChecked);
authzClose();
//await updateChecked(roleId);
message.success("授权成功");
}
message.success("授权成功");
}
return {
authzOpen,
updatePermission,
authzDialogVisible,
permissionTreeData,
checkedKeys,
permissionTreeRef,
};
return {
authzOpen,
updatePermission,
authzDialogVisible,
permissionTreeData,
checkedKeys,
permissionTreeRef,
};
}
export default defineComponent({
name: "RoleManager",
components: { FsPermissionTree },
setup() {
//授权配置
const authz = useAuthz();
const permission: UseCrudPermissionCompProps = {
prefix: "sys:auth:role", //权限代码前缀
extra: ({ hasActionPermission }: UseCrudPermissionExtraProps): any => {
//额外按钮权限控制
return { rowHandle: { buttons: { authz: { show: hasActionPermission("authz") } } } };
},
};
name: "RoleManager",
components: { FsPermissionTree },
setup() {
//授权配置
const { t } = useI18n();
const authz = useAuthz();
const permission: UseCrudPermissionCompProps = {
prefix: "sys:auth:role", //权限代码前缀
extra: ({ hasActionPermission }: UseCrudPermissionExtraProps): any => {
//额外按钮权限控制
return { rowHandle: { buttons: { authz: { show: hasActionPermission("authz") } } } };
},
};
// 初始化crud配置
// 此处传入permission进行通用按钮权限设置,会通过commonOptions去设置actionbar和rowHandle的按钮的show属性
// 更多关于按钮权限的源代码设置,请参考 ./src/plugin/fast-crud/index.js 75-77行)
// 初始化crud配置
// 此处传入permission进行通用按钮权限设置,会通过commonOptions去设置actionbar和rowHandle的按钮的show属性
// 更多关于按钮权限的源代码设置,请参考 ./src/plugin/fast-crud/index.js 75-77行)
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { authz, permission } });
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { authz, permission } });
// 页面打开后获取列表数据
onMounted(() => {
crudExpose.doRefresh();
});
// 页面打开后获取列表数据
onMounted(() => {
crudExpose.doRefresh();
});
onActivated(async () => {
await crudExpose.doRefresh();
});
return {
crudBinding,
crudRef,
...authz,
};
},
onActivated(async () => {
await crudExpose.doRefresh();
});
return {
crudBinding,
crudRef,
...authz,
t
};
},
});
</script>
@@ -42,18 +42,18 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
fixed: "right",
buttons: {
unlock: {
title: "解除登录锁定",
title: t("certd.unlockLogin"),
text: null,
type: "link",
icon: "ion:lock-open-outline",
click: async ({ row }) => {
Modal.confirm({
title: "提示",
content: "确定要解除该用户的登录锁定吗?",
title: t("certd.notice"),
content: t("certd.confirmUnlock"),
onOk: async () => {
await api.Unlock(row.id);
notification.success({
message: "解除成功",
message: t("certd.unlockSuccess"),
});
},
});
@@ -78,7 +78,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
},
},
createTime: {
title: "创建时间",
title: t("certd.createTime"),
type: "datetime",
form: { show: false }, // 表单配置
column: {
@@ -96,13 +96,13 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
// }
// },
username: {
title: "用户名",
title: t("certd.username"),
type: "text",
search: { show: true }, // 开启查询
form: {
rules: [
{ required: true, message: "请输入用户名" },
{ max: 50, message: "最大50个字符" },
{ required: true, message: t("certd.enterUsername") },
{ max: 50, message: t("certd.max50Chars") },
],
},
editForm: { component: { disabled: false } },
@@ -112,18 +112,18 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
},
},
password: {
title: "密码",
title: t("certd.password"),
type: "text",
key: "password",
column: {
show: false,
},
form: {
rules: [{ max: 50, message: "最大50个字符" }],
rules: [{ max: 50, message: t("certd.max50Chars") }],
component: {
showPassword: true,
},
helper: "填写则修改密码",
helper: t("certd.modifyPasswordIfFilled"),
},
},
nickName: {
@@ -138,11 +138,11 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
},
},
email: {
title: "邮箱",
title: t("certd.emaila"),
type: "text",
search: { show: true }, // 开启查询
form: {
rules: [{ max: 50, message: "最大50个字符" }],
rules: [{ max: 50, message: t("certd.max50Chars") }],
},
column: {
sorter: true,
@@ -150,11 +150,11 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
},
},
mobile: {
title: "手机号",
title: t("certd.mobile"),
type: "text",
search: { show: true }, // 开启查询
form: {
rules: [{ max: 50, message: "最大50个字符" }],
rules: [{ max: 50, message: t("certd.max50Chars") }],
},
column: {
sorter: true,
@@ -162,12 +162,11 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
},
},
avatar: {
title: "头像",
title: t("certd.avatar"),
type: "cropper-uploader",
column: {
width: 70,
component: {
//设置高度,修复操作列错位的问题
style: {
height: "30px",
width: "auto",
@@ -205,12 +204,12 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
},
},
status: {
title: "状态",
title: t("certd.status"),
type: "dict-switch",
dict: dict({
data: [
{ label: "启用", value: 1, color: "green" },
{ label: "禁用", value: 0, color: "red" },
{ label: t("certd.enabled"), value: 1, color: "green" },
{ label: t("certd.disabled"), value: 0, color: "red" },
],
}),
column: {
@@ -220,7 +219,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
},
},
validTime: {
title: "有效期",
title: t("certd.validTime"),
type: "date",
form: {
show: userValidTimeEnabled,
@@ -235,7 +234,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return "";
}
if (value < dayjs().valueOf()) {
return <a-tag color={"red"}></a-tag>;
return <a-tag color={"red"}>{t("certd.expired")}</a-tag>;
}
const date = dayjs(value).format("YYYY-MM-DD");
return (
@@ -257,17 +256,17 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
},
},
remark: {
title: "备注",
title: t("certd.remark"),
type: "text",
column: {
sorter: true,
},
form: {
rules: [{ max: 100, message: "最大100个字符" }],
rules: [{ max: 100, message: t("certd.max100Chars") }],
},
},
roles: {
title: "角色",
title: t("certd.roles"),
type: "dict-select",
dict: dict({
url: "/sys/authority/role/list",