Merge branch 'dev'
This commit is contained in:
commit
88857fd01d
31
ReadMe.md
31
ReadMe.md
|
@ -32,21 +32,19 @@
|
|||
- [运行项目](https://www.bilibili.com/video/BV1qodHYzErA/?spm_id_from=333.1387.homepage.video_card.click&vd_source=d42b5b664efb958be39eef8ee1196a7e)
|
||||
- [前端部署](https://www.bilibili.com/video/BV1BddHYgEPq/?spm_id_from=333.1387.homepage.video_card.click&vd_source=d42b5b664efb958be39eef8ee1196a7e)
|
||||
- [后端部署](https://www.bilibili.com/video/BV1BddHYgEFt/?spm_id_from=333.1387.homepage.video_card.click&vd_source=d42b5b664efb958be39eef8ee1196a7e)
|
||||
- [Bunny v0.0.1 代码生成器](https://www.bilibili.com/video/BV1qddHYgErv/?spm_id_from=333.1387.homepage.video_card.click)
|
||||
- [代码生成器](https://www.bilibili.com/video/BV1d4Lxz9E3j/?vd_source=d42b5b664efb958be39eef8ee1196a7e)
|
||||
|
||||
**Github地址**
|
||||
|
||||
- 权限后端:https://github.com/BunnyMaster/bunny-admin-server
|
||||
- 权限前端:https://github.com/BunnyMaster/bunny-admin-web
|
||||
- 代码生成器前端:https://github.com/BunnyMaster/generator-code-web
|
||||
- 代码生成器后端:https://github.com/BunnyMaster/generator-code-server
|
||||
- 代码生成器端:https://github.com/BunnyMaster/generator-code-server
|
||||
|
||||
**`Gitee`地址**
|
||||
**Gitee地址**
|
||||
|
||||
- 权限后端:https://gitee.com/BunnyBoss/bunny-admin-server
|
||||
- 权限前端:https://gitee.com/BunnyBoss/bunny-admin-web
|
||||
- 代码生成器前端:https://gitee.com/BunnyBoss/generator-code-web
|
||||
- 代码生成器后端:https://gitee.com/BunnyBoss/generator-code-server
|
||||
- 代码生成器端:https://gitee.com/BunnyBoss/generator-code-server
|
||||
|
||||
## 🚀 项目简介
|
||||
|
||||
|
@ -83,6 +81,21 @@
|
|||

|
||||

|
||||
|
||||
## :tipping_hand_man:用法提示
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> 多语言使用提示:
|
||||
>
|
||||
> 虽然直接让用户操作JSON文件有一定门槛(多数用户不熟悉JSON格式),但在多语言项目开发中,JSON格式具有独特优势:
|
||||
>
|
||||
> 1. 结构化特性 - 纯文本格式便于AI解析处理
|
||||
> 2. 高效翻译流程:
|
||||
> - 开发者只需完成中文版本
|
||||
> - 上传JSON文件至AI翻译工具
|
||||
> - 简单指令即可批量生成英文/繁体中文/韩语等版本
|
||||
> 3. 显著节省开发时间 - 实现"一次编写,多语言适配"的高效工作流
|
||||
|
||||
## 🔐 权限控制体系
|
||||
|
||||

|
||||
|
@ -240,10 +253,10 @@ docker compose up -d
|
|||
|
||||
## 📈 后续规划
|
||||
|
||||
- [ ] 权限级别拖拽
|
||||
- [ ] 权限树型结构动态添加、更新、删除
|
||||
- [x] 权限级别拖拽
|
||||
- [x] 权限树型结构动态添加、更新、删除
|
||||
- [ ] 用户设置持久化存储到数据库
|
||||
- [ ] 权限弹窗页面优化
|
||||
- [x] 权限弹窗页面优化
|
||||
- [x] 后端文档注释完善
|
||||
- [x] 系统监控后端返回403停止请求
|
||||
- [x] 优化用户配置权限逻辑,配置后热更新逻辑等
|
||||
|
|
|
@ -8,7 +8,7 @@ export const defaultConfig: AxiosRequestConfig = {
|
|||
// 默认请求地址
|
||||
baseURL: '/api',
|
||||
// 设置超时时间
|
||||
timeout: 6000,
|
||||
timeout: 19000,
|
||||
// @ts-expect-error
|
||||
retry: 3, //设置全局重试请求次数(最多重试几次请求)
|
||||
retryDelay: 3000, //设置全局请求间隔
|
||||
|
|
|
@ -43,9 +43,14 @@ export const getSystemApiInfoList = () => {
|
|||
return http.request<BaseResult<any>>('get', 'permission/private/getSystemApiInfoList');
|
||||
};
|
||||
|
||||
/** 权限---更新权限 */
|
||||
/** 权限---批量修改权限父级 */
|
||||
export const updatePermissionListByParentId = (data: any) => {
|
||||
return http.request<BaseResult<object>>('put', 'permission/update/permissionListByParentId', { data });
|
||||
return http.request<BaseResult<object>>('patch', 'permission/update/permissionListByParentId', { data });
|
||||
};
|
||||
|
||||
/** 权限---批量更新权限 */
|
||||
export const updatePermissionBatch = (data: any) => {
|
||||
return http.request<BaseResult<object>>('patch', 'permission/update/permissionBatch', { data });
|
||||
};
|
||||
|
||||
/** 角色和权限---根据角色id获取权限内容 */
|
||||
|
|
|
@ -74,7 +74,6 @@ export const userI18nStore = defineStore('i18nStore', {
|
|||
|
||||
/* 用文件更新多语言 */
|
||||
async editI18nByFile(data: any) {
|
||||
console.log(data);
|
||||
const result = await uploadI18nFile(data);
|
||||
return storeMessage(result);
|
||||
},
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
getSystemApiInfoList,
|
||||
importPermission,
|
||||
updatePermission,
|
||||
updatePermissionBatch,
|
||||
updatePermissionListByParentId,
|
||||
} from '@/api/v1/system/power';
|
||||
import { pageSizes } from '@/enums/baseConstant';
|
||||
|
@ -57,7 +58,6 @@ export const usePermissionStore = defineStore('PermissionStore', {
|
|||
const data = { ...this.pagination, ...this.form };
|
||||
delete data.pageSizes;
|
||||
delete data.total;
|
||||
delete data.background;
|
||||
|
||||
// 获取权限列表
|
||||
const result = await getPermissionPage(data);
|
||||
|
@ -117,5 +117,11 @@ export const usePermissionStore = defineStore('PermissionStore', {
|
|||
const result = await updatePermissionListByParentId(data);
|
||||
return storeMessage(result);
|
||||
},
|
||||
|
||||
/* 批量更新权限 */
|
||||
async updatePermissionBatch(data: any) {
|
||||
const result = await updatePermissionBatch(data);
|
||||
return storeMessage(result);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -23,7 +23,6 @@ function onResetPassword() {
|
|||
|
||||
addDialog({
|
||||
title: `修改密码`,
|
||||
width: '30%',
|
||||
draggable: true,
|
||||
closeOnClickModal: false,
|
||||
fullscreenIcon: true,
|
||||
|
|
|
@ -97,8 +97,9 @@ onMounted(() => {
|
|||
</ReAuth>
|
||||
|
||||
<PureTableBar :columns="columns" :title="$t('emailTemplate')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||
<!-- 新增 -->
|
||||
<template #buttons>
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="primary" @click="onAdd">
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ export function onAdd() {
|
|||
|
||||
addDialog({
|
||||
title: `${$t('addNew')}${$t('emailTemplate')}`,
|
||||
width: '30%',
|
||||
props: {
|
||||
formInline: {
|
||||
templateName: undefined,
|
||||
|
@ -38,7 +37,18 @@ export function onAdd() {
|
|||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () => h(EmailTemplateDialog, { ref: formRef }),
|
||||
contentRenderer: () =>
|
||||
h(EmailTemplateDialog, {
|
||||
ref: formRef,
|
||||
formInline: {
|
||||
templateName: undefined,
|
||||
emailUser: undefined,
|
||||
subject: undefined,
|
||||
isDefault: false,
|
||||
body: undefined,
|
||||
type: undefined,
|
||||
},
|
||||
}),
|
||||
beforeSure: (done, { options }) => {
|
||||
const form = options.props.formInline as FormItemProps;
|
||||
formRef.value.formRef.validate(async (valid: any) => {
|
||||
|
@ -59,7 +69,6 @@ export function onUpdate(row: any) {
|
|||
|
||||
addDialog({
|
||||
title: `${$t('modify')}${$t('emailTemplate')}`,
|
||||
width: '30%',
|
||||
props: {
|
||||
formInline: {
|
||||
templateName: row.templateName,
|
||||
|
@ -73,7 +82,18 @@ export function onUpdate(row: any) {
|
|||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () => h(EmailTemplateDialog, { ref: formRef }),
|
||||
contentRenderer: () =>
|
||||
h(EmailTemplateDialog, {
|
||||
ref: formRef,
|
||||
formInline: {
|
||||
templateName: row.templateName,
|
||||
emailUser: row.emailUser,
|
||||
subject: row.subject,
|
||||
isDefault: row.isDefault,
|
||||
body: row.body,
|
||||
type: row.type,
|
||||
},
|
||||
}),
|
||||
beforeSure: (done, { options }) => {
|
||||
const form = options.props.formInline as FormItemProps;
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ onMounted(() => {
|
|||
|
||||
<PureTableBar :columns="columns" :title="$t('email_user_send_config')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||
<template #buttons>
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="primary" @click="onAdd">
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ export async function onSearch() {
|
|||
export function onAdd() {
|
||||
addDialog({
|
||||
title: `${$t('addNew')}${$t('emailUsers')}`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: {
|
||||
email: undefined,
|
||||
|
@ -58,7 +58,7 @@ export function onAdd() {
|
|||
export function onUpdate(row: any) {
|
||||
addDialog({
|
||||
title: `${$t('modify')}${$t('emailUsers')}`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: {
|
||||
email: row.email,
|
||||
|
|
|
@ -70,7 +70,7 @@ onMounted(() => {
|
|||
|
||||
<PureTableBar :columns="columns" :title="$t('menuIcon')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||
<template #buttons>
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="primary" @click="onAdd">
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ export async function onSearch() {
|
|||
export function onAdd() {
|
||||
addDialog({
|
||||
title: `${$t('addNew')} ${$t('menuIcon')}`,
|
||||
width: '30%',
|
||||
|
||||
props: { formInline: { confirmText: '' } },
|
||||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
|
@ -45,7 +45,7 @@ export function onAdd() {
|
|||
export function onUpdate(row: any) {
|
||||
addDialog({
|
||||
title: `${$t('modify')} ${$t('menuIcon')}`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: {
|
||||
iconCode: row.iconCode,
|
||||
|
|
|
@ -333,7 +333,7 @@ onMounted(() => {
|
|||
|
||||
<!-- 提交内容 -->
|
||||
<re-col v-if="hasAuth(auth.update)" :sm="24" :value="24" :xs="24">
|
||||
<el-form-item>
|
||||
<el-form-item label-width="0">
|
||||
<el-button class="w-full" plain type="primary" @click="submitForm(ruleFormRef)">
|
||||
{{ $t('modifyingConfiguration') }}
|
||||
</el-button>
|
||||
|
|
|
@ -76,9 +76,11 @@ onMounted(() => {
|
|||
<el-input v-model="i18nStore.form.typeName" :placeholder="`${$t('input')}${$t('i18n.typeName')}`" class="!w-[180px]" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<!-- 表格頂部搜索 -->
|
||||
<el-button :icon="useRenderIcon('ri/search-line')" :loading="i18nStore.loading" type="primary" @click="onSearch">
|
||||
{{ $t('search') }}
|
||||
</el-button>
|
||||
<!-- 表格頂部重置 -->
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(pageFormRef)">
|
||||
{{ $t('buttons.reset') }}
|
||||
</el-button>
|
||||
|
@ -95,7 +97,9 @@ onMounted(() => {
|
|||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<!-- 到處為JSON -->
|
||||
<el-dropdown-item @click="downloadI18nSetting('json')">{{ $t('download_json') }}</el-dropdown-item>
|
||||
<!--導出爲Excel-->
|
||||
<el-dropdown-item @click="downloadI18nSetting('excel')">{{ $t('download_excel') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
|
@ -113,7 +117,7 @@ onMounted(() => {
|
|||
</el-dropdown>
|
||||
|
||||
<!-- 添加多语言 -->
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="primary" @click="onAdd">
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
|
@ -148,12 +152,14 @@ onMounted(() => {
|
|||
@page-size-change="onPageSizeChange"
|
||||
@page-current-change="onCurrentPageChange"
|
||||
>
|
||||
<!-- 創建用戶名 -->
|
||||
<template #createUser="{ row }">
|
||||
<el-button v-show="row.createUser" link type="primary" @click="selectUserinfo(row.createUser)">
|
||||
{{ row.createUsername }}
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<!-- 更新用戶名 -->
|
||||
<template #updateUser="{ row }">
|
||||
<el-button v-show="row.updateUser" link type="primary" @click="selectUserinfo(row.updateUser)">
|
||||
{{ row.updateUsername }}
|
||||
|
@ -161,9 +167,12 @@ onMounted(() => {
|
|||
</template>
|
||||
|
||||
<template #operation="{ row }">
|
||||
<!-- 修改 -->
|
||||
<el-button v-if="hasAuth(auth.update)" :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)">
|
||||
{{ $t('modify') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 刪除確認 -->
|
||||
<el-popconfirm v-if="hasAuth(auth.deleted)" :title="`${$t('confirmDelete')} ${row.translation}`" @confirm="onDelete(row)">
|
||||
<template #reference>
|
||||
<el-button :icon="useRenderIcon(Delete)" :size="size" class="reset-margin" link type="primary">
|
||||
|
|
|
@ -29,7 +29,7 @@ export const updateI18nSetting = (fileType: string) => {
|
|||
|
||||
addDialog({
|
||||
title: $t('update_multilingual'),
|
||||
width: '30%',
|
||||
|
||||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
|
@ -51,7 +51,7 @@ export const updateI18nSetting = (fileType: string) => {
|
|||
export const onAdd = () => {
|
||||
addDialog({
|
||||
title: $t('addMultilingual'),
|
||||
width: '30%',
|
||||
|
||||
props: { formInline: { keyName: '', translation: '', typeName: '' } },
|
||||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
|
@ -107,7 +107,7 @@ export const onUpdate = (row: any) => {
|
|||
|
||||
addDialog({
|
||||
title: $t('update_multilingual'),
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: { keyName: row.keyName, translation: row.translation, typeName: row.typeName },
|
||||
},
|
||||
|
|
|
@ -50,7 +50,7 @@ onMounted(() => {
|
|||
|
||||
<PureTableBar :columns="columns" :title="$t('i18n_type')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||
<template #buttons>
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="primary" @click="onAdd">
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
</template>
|
||||
|
|
|
@ -19,7 +19,7 @@ export async function onSearch() {
|
|||
export function onAdd() {
|
||||
addDialog({
|
||||
title: `添加多语言类型`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: { typeName: '', summary: '', isDefault: false },
|
||||
},
|
||||
|
@ -45,7 +45,7 @@ export function onAdd() {
|
|||
export function onUpdate(row: any) {
|
||||
addDialog({
|
||||
title: `修改多语言类型`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: {
|
||||
typeName: row.typeName,
|
||||
|
|
|
@ -151,7 +151,7 @@ onMounted(() => {
|
|||
|
||||
<!-- 简介 -->
|
||||
<el-form-item :label="$t('summary')" prop="summary">
|
||||
<el-input v-model="formState.summary" :autosize="{ minRows: 3, maxRows: 6 }" maxlength="200" minlength="4" show-word-limit type="textarea" />
|
||||
<el-input v-model="formState.summary" :autosize="{ minRows: 3, maxRows: 6 }" maxlength="100" minlength="4" show-word-limit type="textarea" />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 消息等级 -->
|
||||
|
|
|
@ -23,7 +23,7 @@ defineExpose({ formRef });
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<el-card shadow="never" style="height: calc(100vh - 200px); overflow: auto">
|
||||
<el-card shadow="never" style="height: calc(100vh - 300px); overflow: auto">
|
||||
<div class="split-pane">
|
||||
<SplitPane :splitSet="settingLR">
|
||||
<template #paneL>
|
||||
|
@ -120,7 +120,7 @@ defineExpose({ formRef });
|
|||
|
||||
<!-- 简介 -->
|
||||
<el-form-item :label="$t('summary')" prop="summary">
|
||||
<el-input v-model="updateMessage.summary" :autosize="{ minRows: 3, maxRows: 6 }" maxlength="200" minlength="10" show-word-limit type="textarea" />
|
||||
<el-input v-model="updateMessage.summary" :autosize="{ minRows: 3, maxRows: 6 }" maxlength="50" minlength="10" show-word-limit type="textarea" />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 消息等级 -->
|
||||
|
|
|
@ -91,7 +91,7 @@ onMounted(() => {
|
|||
|
||||
<PureTableBar :columns="columns" title="系统消息类型" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||
<template #buttons>
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="primary" @click="onAdd">
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ export async function onSearch() {
|
|||
export function onAdd() {
|
||||
addDialog({
|
||||
title: `${$t('addNew')}${$t('messageType')}`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: {
|
||||
status: true,
|
||||
|
@ -53,7 +53,7 @@ export function onAdd() {
|
|||
export function onUpdate(row: any) {
|
||||
addDialog({
|
||||
title: `${$t('modify')}${$t('messageType')}`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: {
|
||||
status: row.status,
|
||||
|
|
|
@ -21,7 +21,7 @@ export async function onSearch() {
|
|||
export function onView(row: any) {
|
||||
addDialog({
|
||||
title: `${$t('view')}${$t('quartzExecuteLog')}`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: {
|
||||
jobName: row.jobName,
|
||||
|
|
|
@ -21,7 +21,7 @@ export async function onSearch() {
|
|||
export function onView(row: any) {
|
||||
addDialog({
|
||||
title: `${$t('view')}${$t('userLoginLog')}`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: {
|
||||
userId: row.userId,
|
||||
|
|
|
@ -81,7 +81,7 @@ onMounted(() => {
|
|||
|
||||
<PureTableBar :columns="columns" :title="$t('schedulersGroup')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||
<template #buttons>
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="primary" @click="onAdd">
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ export async function onSearch() {
|
|||
export function onAdd() {
|
||||
addDialog({
|
||||
title: `${$t('addNew')}${$t('schedulersGroup')}`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: {
|
||||
groupName: undefined,
|
||||
|
@ -51,7 +51,7 @@ export function onAdd() {
|
|||
export function onUpdate(row: any) {
|
||||
addDialog({
|
||||
title: `${$t('modify')}${$t('schedulersGroup')}`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: {
|
||||
groupName: row.groupName,
|
||||
|
|
|
@ -78,7 +78,7 @@ onMounted(() => {
|
|||
|
||||
<PureTableBar :columns="columns" title="Schedulers视图" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||
<template #buttons>
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="primary" @click="onAdd">
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
</template>
|
||||
|
@ -119,7 +119,8 @@ onMounted(() => {
|
|||
</template>
|
||||
|
||||
<template #operation="{ row }">
|
||||
<el-button :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)">
|
||||
<!-- 修改 -->
|
||||
<el-button v-if="hasAuth(auth.update)" :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)">
|
||||
{{ $t('modify') }}
|
||||
</el-button>
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ export const auth = {
|
|||
// 添加操作
|
||||
add: ['schedulers::add'],
|
||||
// 暂停
|
||||
update: ['schedulers::update'],
|
||||
pause: ['schedulers::update'],
|
||||
// 恢复
|
||||
resume: ['schedulers::update'],
|
||||
|
|
|
@ -20,7 +20,7 @@ export async function onSearch() {
|
|||
export function onAdd() {
|
||||
addDialog({
|
||||
title: `${$t('addNew')}${$t('schedulers')}`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: {
|
||||
jobName: undefined,
|
||||
|
@ -52,7 +52,7 @@ export function onAdd() {
|
|||
export function onUpdate(row: any) {
|
||||
addDialog({
|
||||
title: `${$t('modify')}${$t('schedulers')}`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: {
|
||||
jobName: row.jobName,
|
||||
|
|
|
@ -151,7 +151,7 @@ onMounted(() => {
|
|||
|
||||
<PureTableBar :columns="columns" :title="$t('userinfo')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||
<template #buttons>
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="primary" @click="onAdd">
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ export function onAdd() {
|
|||
isAddUserinfo.value = true;
|
||||
addDialog({
|
||||
title: `${$t('addNew')}${$t('adminUser')}`,
|
||||
width: '30%',
|
||||
props: {
|
||||
formInline: {
|
||||
username: undefined,
|
||||
|
@ -70,7 +69,22 @@ export function onAdd() {
|
|||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () => h(AdminUserDialog, { ref: formRef }),
|
||||
contentRenderer: () =>
|
||||
h(AdminUserDialog, {
|
||||
ref: formRef,
|
||||
formInline: {
|
||||
username: undefined,
|
||||
nickname: undefined,
|
||||
email: undefined,
|
||||
phone: undefined,
|
||||
password: undefined,
|
||||
avatar: undefined,
|
||||
sex: undefined,
|
||||
summary: undefined,
|
||||
status: false,
|
||||
deptId: undefined,
|
||||
},
|
||||
}),
|
||||
beforeSure: (done, { options }) => {
|
||||
const form = options.props.formInline as FormItemProps;
|
||||
formRef.value.formRef.validate(async (valid: any) => {
|
||||
|
@ -90,7 +104,6 @@ export function onUpdate(row: any) {
|
|||
isAddUserinfo.value = false;
|
||||
addDialog({
|
||||
title: `${$t('modify')}${$t('adminUser')}`,
|
||||
width: '30%',
|
||||
props: {
|
||||
formInline: {
|
||||
username: row.username,
|
||||
|
@ -108,7 +121,22 @@ export function onUpdate(row: any) {
|
|||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () => h(AdminUserDialog, { ref: formRef }),
|
||||
contentRenderer: () =>
|
||||
h(AdminUserDialog, {
|
||||
ref: formRef,
|
||||
formInline: {
|
||||
username: row.username,
|
||||
nickname: row.nickname,
|
||||
email: row.email,
|
||||
phone: row.phone,
|
||||
password: row.password,
|
||||
avatar: row.avatar,
|
||||
sex: row.sex,
|
||||
summary: row.summary,
|
||||
status: row.status,
|
||||
deptId: row.deptId,
|
||||
},
|
||||
}),
|
||||
beforeSure: (done, { options }) => {
|
||||
const form = options.props.formInline as FormItemProps;
|
||||
formRef.value.formRef.validate(async (valid: any) => {
|
||||
|
@ -149,12 +177,12 @@ export const onDeleteBatch = async () => {
|
|||
|
||||
addDialog({
|
||||
title: $t('deleteBatchTip'),
|
||||
width: '30%',
|
||||
|
||||
props: { formInline: { confirmText: '' } },
|
||||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () => h(DeleteBatchDialog, { ref: formDeletedBatchRef }),
|
||||
contentRenderer: () => h(DeleteBatchDialog, { ref: formDeletedBatchRef, formInline: { confirmText: '' } }),
|
||||
beforeSure: (done, { options }) => {
|
||||
formDeletedBatchRef.value.formDeletedBatchRef.validate(async (valid: any) => {
|
||||
if (!valid) return;
|
||||
|
@ -229,7 +257,7 @@ export const onUploadAvatar = (row: any) => {
|
|||
export const onResetPassword = (row: any) => {
|
||||
addDialog({
|
||||
title: `${$t('buttons.reset')} ${row.username} ${$t('userPassword')}`,
|
||||
width: '30%',
|
||||
|
||||
draggable: true,
|
||||
closeOnClickModal: false,
|
||||
fullscreenIcon: true,
|
||||
|
|
|
@ -79,7 +79,7 @@ onMounted(() => {
|
|||
@refresh="onSearch"
|
||||
>
|
||||
<template #buttons>
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="primary" @click="onAdd()">
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd()">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ export async function onSearch() {
|
|||
export function onAdd(parentId: number = 0) {
|
||||
addDialog({
|
||||
title: `${$t('addNew')}${$t('dept')}`,
|
||||
width: '30%',
|
||||
props: {
|
||||
formInline: {
|
||||
parentId,
|
||||
|
@ -33,7 +32,16 @@ export function onAdd(parentId: number = 0) {
|
|||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () => h(DeptDialog, { ref: formRef }),
|
||||
contentRenderer: () =>
|
||||
h(DeptDialog, {
|
||||
ref: formRef,
|
||||
formInline: {
|
||||
parentId,
|
||||
manager: undefined,
|
||||
deptName: undefined,
|
||||
summary: undefined,
|
||||
},
|
||||
}),
|
||||
beforeSure: (done, { options }) => {
|
||||
const form = options.props.formInline as FormItemProps;
|
||||
formRef.value.formRef.validate(async (valid: any) => {
|
||||
|
@ -52,7 +60,7 @@ export function onAdd(parentId: number = 0) {
|
|||
export function onUpdate(row: any) {
|
||||
addDialog({
|
||||
title: `${$t('modify')}${$t('dept')}`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: {
|
||||
parentId: row.parentId,
|
||||
|
@ -64,7 +72,16 @@ export function onUpdate(row: any) {
|
|||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () => h(DeptDialog, { ref: formRef }),
|
||||
contentRenderer: () =>
|
||||
h(DeptDialog, {
|
||||
ref: formRef,
|
||||
formInline: {
|
||||
parentId: row.parentId,
|
||||
manager: row.manager ? row.manager.split(',') : row.manager,
|
||||
deptName: row.deptName,
|
||||
summary: row.summary,
|
||||
},
|
||||
}),
|
||||
beforeSure: (done, { options }) => {
|
||||
const form = options.props.formInline as FormItemProps;
|
||||
formRef.value.formRef.validate(async (valid: any) => {
|
||||
|
|
|
@ -85,22 +85,23 @@ onMounted(() => {
|
|||
|
||||
<PureTableBar :columns="columns" :title="$t('system_file')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||
<template #buttons>
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="primary" @click="onAdd">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 批量下载 -->
|
||||
<el-button
|
||||
v-if="hasAuth(auth.download)"
|
||||
:disabled="!(selectRows.length > 0)"
|
||||
:icon="useRenderIcon(Download)"
|
||||
plain
|
||||
type="success"
|
||||
type="primary"
|
||||
@click="onDownloadBatch"
|
||||
>
|
||||
{{ $t('download_batch') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 新增 -->
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 批量删除按钮 -->
|
||||
<el-button v-if="hasAuth(auth.delete)" :disabled="!(selectRows.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDeleteBatch">
|
||||
{{ $t('deleteBatches') }}
|
||||
|
|
|
@ -25,7 +25,7 @@ export async function onSearch() {
|
|||
export function onAdd() {
|
||||
addDialog({
|
||||
title: `${$t('addNew')}${$t('files')}`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: {
|
||||
filepath: undefined,
|
||||
|
@ -69,7 +69,7 @@ export function onAdd() {
|
|||
export function onUpdate(row: any) {
|
||||
addDialog({
|
||||
title: `${$t('modify')}${$t('files')}`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: {
|
||||
filename: row.filename,
|
||||
|
|
|
@ -72,7 +72,7 @@ onMounted(() => {
|
|||
>
|
||||
<template #buttons>
|
||||
<!-- 添加菜单 -->
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="primary" @click="onAdd()">
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd()">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@ export const clearAllRolesSelect = async () => {
|
|||
|
||||
addDialog({
|
||||
title: $t('doubleCheck'),
|
||||
width: '30%',
|
||||
|
||||
draggable: true,
|
||||
closeOnClickModal: false,
|
||||
fullscreenIcon: true,
|
||||
|
|
|
@ -76,7 +76,7 @@ defineExpose({ formRef });
|
|||
:filter-node-method="filterMethod"
|
||||
:props="{ label: 'summary' }"
|
||||
accordion
|
||||
class="my-2 py-1 h-[220px] overflow-y-auto"
|
||||
class="my-2 py-1 h-[350px] overflow-y-auto"
|
||||
highlight-current
|
||||
node-key="path"
|
||||
@node-click="onNodeClick"
|
|
@ -0,0 +1,114 @@
|
|||
<script lang="ts" setup>
|
||||
import { onMounted, ref, toRaw } from 'vue';
|
||||
import type { TreeInstance } from 'element-plus';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { usePermissionStore } from '@/store/system/power';
|
||||
import { TreeNode } from 'element-plus/es/components/tree-v2/src/types';
|
||||
import { handleTree } from '@pureadmin/utils';
|
||||
|
||||
interface Tree {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
form: {
|
||||
list: any;
|
||||
};
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
form: () => ({
|
||||
list: [],
|
||||
}),
|
||||
});
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
const treeRef = ref<TreeInstance>();
|
||||
const powerStore = usePermissionStore();
|
||||
const form = ref(props.form);
|
||||
// 所有的权限列表
|
||||
const powerList = ref([]);
|
||||
// 加载
|
||||
const isLoading = ref(false);
|
||||
|
||||
/* 加载系统接口列表 */
|
||||
const onSearch = async () => {
|
||||
isLoading.value = true;
|
||||
await powerStore.loadPermissionList();
|
||||
powerList.value = handleTree(powerStore.allPowerList);
|
||||
isLoading.value = false;
|
||||
};
|
||||
|
||||
/* 搜索名称 */
|
||||
const filterMethod = (value: string, data: Tree) => {
|
||||
if (!value) return true;
|
||||
return data.summary.includes(value);
|
||||
};
|
||||
|
||||
/* 节点拖拽完成 */
|
||||
const onNodeDragEnd = (source: TreeNode, target: TreeNode, event: Event) => {
|
||||
const current = source.data;
|
||||
const parent = target.parent.data;
|
||||
|
||||
// 如果为父级找不到parentId
|
||||
if (parent.id) {
|
||||
current.parentId = parent.id;
|
||||
} else {
|
||||
current.parentId = '0';
|
||||
}
|
||||
const data = toRaw(current);
|
||||
form.value.list.push(data);
|
||||
|
||||
// 为数组去重,以最后添加为准
|
||||
const map = new Map();
|
||||
const array = form.value.list;
|
||||
for (const item of array) {
|
||||
map.set(item['id'], item);
|
||||
}
|
||||
form.value.list = Array.from(map.values());
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
onSearch();
|
||||
});
|
||||
defineExpose({ formRef });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
v-loading="isLoading"
|
||||
:data="powerList"
|
||||
:expand-on-click-node="true"
|
||||
:filter-node-method="filterMethod"
|
||||
:props="{ label: 'powerName' }"
|
||||
class="my-2 py-1 h-[530px] overflow-y-auto"
|
||||
draggable
|
||||
highlight-current
|
||||
node-key="path"
|
||||
@nodeDragEnd="onNodeDragEnd"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<el-tooltip :content="data.powerCode">
|
||||
<span>{{ node.label }}</span>
|
||||
</el-tooltip>
|
||||
<div class="custom-tree-node">
|
||||
<el-text type="primary">{{ data.requestUrl }}</el-text>
|
||||
<el-text type="danger">{{ data.requestMethod }}</el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #empty>
|
||||
<ElEmpty />
|
||||
</template>
|
||||
</el-tree>
|
||||
</template>
|
||||
<style scoped>
|
||||
.custom-tree-node {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
|
@ -20,6 +20,8 @@ import EditPen from '~icons/ep/edit-pen';
|
|||
import Refresh from '~icons/ep/refresh';
|
||||
import AddFill from '~icons/ri/add-circle-line';
|
||||
import Upload from '~icons/ri/upload-line';
|
||||
import More from '~icons/ep/more-filled';
|
||||
import PermissionSortDialog from '@/views/system/permission/components/permission-sort-dialog.vue';
|
||||
|
||||
defineOptions({ name: 'PermissionManger' });
|
||||
|
||||
|
@ -62,13 +64,12 @@ const downloadPermission = (type: string) => {
|
|||
/* 导入权限 */
|
||||
const uploadPermission = async (type: string) => {
|
||||
addDialog({
|
||||
title: `${$t('modify')}${$t('role')}`,
|
||||
width: '30%',
|
||||
title: `${$t('modify')}${$t('power')}`,
|
||||
props: { form: { file: undefined } },
|
||||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () => h(FileUploadDialog, { ref: formRef }),
|
||||
contentRenderer: () => h(FileUploadDialog, { ref: formRef, form: { file: undefined } }),
|
||||
beforeSure: (done, { options }) => {
|
||||
const form = options.props.form;
|
||||
formRef.value.formRef.validate(async (valid: any) => {
|
||||
|
@ -84,6 +85,25 @@ const uploadPermission = async (type: string) => {
|
|||
},
|
||||
});
|
||||
};
|
||||
|
||||
/* 更新排序 */
|
||||
const onUpdateSort = () => {
|
||||
addDialog({
|
||||
title: `${$t('modify')}权限排序`,
|
||||
props: { form: { list: [] } },
|
||||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () => h(PermissionSortDialog, { form: { list: [] } }),
|
||||
beforeSure: async (done, { options }) => {
|
||||
const form = options.props.form;
|
||||
await powerStore.updatePermissionBatch(form.list);
|
||||
done();
|
||||
await onSearch();
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
onSearch();
|
||||
});
|
||||
|
@ -150,26 +170,28 @@ onMounted(() => {
|
|||
</el-dropdown>
|
||||
|
||||
<!-- 添加权限按钮 -->
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="primary" @click="onAdd()">
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd()">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 批量更新父级id -->
|
||||
<el-button
|
||||
v-if="hasAuth(auth.update)"
|
||||
:disabled="!(powerIds.length > 0)"
|
||||
:icon="useRenderIcon(EditPen)"
|
||||
plain
|
||||
type="primary"
|
||||
@click="onUpdateBatchParent"
|
||||
>
|
||||
{{ $t('update_batches_parent') }}
|
||||
</el-button>
|
||||
<el-dropdown v-if="hasAuth(auth.update)" class="ml-1" type="primary">
|
||||
<el-button :icon="useRenderIcon(More)" plain type="primary">更多操作</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<!-- 批量更新父级id -->
|
||||
<el-dropdown-item v-if="hasAuth(auth.update)" :icon="useRenderIcon(EditPen)" @click="onUpdateSort">拖拽排序</el-dropdown-item>
|
||||
<!-- 批量更新父级id -->
|
||||
<el-dropdown-item v-if="hasAuth(auth.update)" :disabled="!(powerIds.length > 0)" :icon="useRenderIcon(EditPen)" @click="onUpdateBatchParent">
|
||||
{{ $t('update_batches_parent') }}
|
||||
</el-dropdown-item>
|
||||
|
||||
<!-- 批量删除按钮 -->
|
||||
<el-button v-if="hasAuth(auth.delete)" :disabled="!(powerIds.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDeleteBatch">
|
||||
{{ $t('deleteBatches') }}
|
||||
</el-button>
|
||||
<!-- 批量删除按钮 -->
|
||||
<el-dropdown-item v-if="hasAuth(auth.delete)" :disabled="!(powerIds.length > 0)" :icon="useRenderIcon(Delete)" @click="onDeleteBatch">
|
||||
{{ $t('deleteBatches') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
||||
<template v-slot="{ size, dynamicColumns }">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { addDialog } from '@/components/ReDialog/index';
|
||||
import PowerDialog from '@/views/system/permission/components/power-dialog.vue';
|
||||
import PermissionFromDialog from '@/views/system/permission/components/permission-from-dialog.vue';
|
||||
import { usePermissionStore } from '@/store/system/power';
|
||||
import { h, reactive, ref } from 'vue';
|
||||
import { messageBox } from '@/utils/message';
|
||||
|
@ -25,7 +25,7 @@ export async function onSearch() {
|
|||
export function onAdd(parentId = 0) {
|
||||
addDialog({
|
||||
title: `${$t('addNew')}${$t('power')}`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: {
|
||||
parentId,
|
||||
|
@ -38,7 +38,17 @@ export function onAdd(parentId = 0) {
|
|||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () => h(PowerDialog, { ref: formRef }),
|
||||
contentRenderer: () =>
|
||||
h(PermissionFromDialog, {
|
||||
ref: formRef,
|
||||
formInline: {
|
||||
parentId,
|
||||
powerCode: undefined,
|
||||
powerName: undefined,
|
||||
requestUrl: undefined,
|
||||
requestMethod: undefined,
|
||||
},
|
||||
}),
|
||||
beforeSure: (done, { options }) => {
|
||||
const form = options.props.formInline as FormItemProps;
|
||||
formRef.value.formRef.validate(async (valid: any) => {
|
||||
|
@ -57,7 +67,7 @@ export function onAdd(parentId = 0) {
|
|||
export function onUpdate(row: any) {
|
||||
addDialog({
|
||||
title: `${$t('modify')}${$t('power')}`,
|
||||
width: '30%',
|
||||
|
||||
props: {
|
||||
formInline: {
|
||||
parentId: row.parentId,
|
||||
|
@ -70,7 +80,17 @@ export function onUpdate(row: any) {
|
|||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () => h(PowerDialog, { ref: formRef }),
|
||||
contentRenderer: () =>
|
||||
h(PermissionFromDialog, {
|
||||
ref: formRef,
|
||||
formInline: {
|
||||
parentId: row.parentId,
|
||||
powerCode: row.powerCode,
|
||||
powerName: row.powerName,
|
||||
requestUrl: row.requestUrl,
|
||||
requestMethod: row.requestMethod,
|
||||
},
|
||||
}),
|
||||
beforeSure: (done, { options }) => {
|
||||
const form = options.props.formInline as FormItemProps;
|
||||
formRef.value.formRef.validate(async (valid: any) => {
|
||||
|
@ -132,7 +152,7 @@ export const onUpdateBatchParent = async () => {
|
|||
await powerStore.loadPermissionList();
|
||||
addDialog({
|
||||
title: $t('update_batches_parent'),
|
||||
width: '30%',
|
||||
|
||||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
|
|
|
@ -73,7 +73,7 @@ const downloadRoleExcel = () => {
|
|||
const onUpdateByFile = () => {
|
||||
addDialog({
|
||||
title: `${$t('modify')}${$t('role')}`,
|
||||
width: '30%',
|
||||
|
||||
props: { form: { file: undefined } },
|
||||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
|
@ -139,7 +139,7 @@ onMounted(() => {
|
|||
{{ $t('file_import') }}
|
||||
</el-button>
|
||||
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="primary" @click="onAdd">
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ export async function onSearch() {
|
|||
export function onAdd() {
|
||||
addDialog({
|
||||
title: `${$t('addNew')}${$t('role')}`,
|
||||
width: '30%',
|
||||
|
||||
props: { formInline: { roleCode: undefined, description: undefined } },
|
||||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
|
@ -58,7 +58,7 @@ export function onAdd() {
|
|||
export function onUpdate(row: any) {
|
||||
addDialog({
|
||||
title: `${$t('modify')}${$t('role')}`,
|
||||
width: '30%',
|
||||
|
||||
props: { formInline: { roleCode: row.roleCode, description: row.description } },
|
||||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
|
|
Loading…
Reference in New Issue