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/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/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)
|
- [后端部署](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地址**
|
**Github地址**
|
||||||
|
|
||||||
- 权限后端:https://github.com/BunnyMaster/bunny-admin-server
|
- 权限后端:https://github.com/BunnyMaster/bunny-admin-server
|
||||||
- 权限前端:https://github.com/BunnyMaster/bunny-admin-web
|
- 权限前端: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-server
|
||||||
- 权限前端:https://gitee.com/BunnyBoss/bunny-admin-web
|
- 权限前端: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] 后端文档注释完善
|
||||||
- [x] 系统监控后端返回403停止请求
|
- [x] 系统监控后端返回403停止请求
|
||||||
- [x] 优化用户配置权限逻辑,配置后热更新逻辑等
|
- [x] 优化用户配置权限逻辑,配置后热更新逻辑等
|
||||||
|
|
|
@ -8,7 +8,7 @@ export const defaultConfig: AxiosRequestConfig = {
|
||||||
// 默认请求地址
|
// 默认请求地址
|
||||||
baseURL: '/api',
|
baseURL: '/api',
|
||||||
// 设置超时时间
|
// 设置超时时间
|
||||||
timeout: 6000,
|
timeout: 19000,
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
retry: 3, //设置全局重试请求次数(最多重试几次请求)
|
retry: 3, //设置全局重试请求次数(最多重试几次请求)
|
||||||
retryDelay: 3000, //设置全局请求间隔
|
retryDelay: 3000, //设置全局请求间隔
|
||||||
|
|
|
@ -43,9 +43,14 @@ export const getSystemApiInfoList = () => {
|
||||||
return http.request<BaseResult<any>>('get', 'permission/private/getSystemApiInfoList');
|
return http.request<BaseResult<any>>('get', 'permission/private/getSystemApiInfoList');
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 权限---更新权限 */
|
/** 权限---批量修改权限父级 */
|
||||||
export const updatePermissionListByParentId = (data: any) => {
|
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获取权限内容 */
|
/** 角色和权限---根据角色id获取权限内容 */
|
||||||
|
|
|
@ -74,7 +74,6 @@ export const userI18nStore = defineStore('i18nStore', {
|
||||||
|
|
||||||
/* 用文件更新多语言 */
|
/* 用文件更新多语言 */
|
||||||
async editI18nByFile(data: any) {
|
async editI18nByFile(data: any) {
|
||||||
console.log(data);
|
|
||||||
const result = await uploadI18nFile(data);
|
const result = await uploadI18nFile(data);
|
||||||
return storeMessage(result);
|
return storeMessage(result);
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
getSystemApiInfoList,
|
getSystemApiInfoList,
|
||||||
importPermission,
|
importPermission,
|
||||||
updatePermission,
|
updatePermission,
|
||||||
|
updatePermissionBatch,
|
||||||
updatePermissionListByParentId,
|
updatePermissionListByParentId,
|
||||||
} from '@/api/v1/system/power';
|
} from '@/api/v1/system/power';
|
||||||
import { pageSizes } from '@/enums/baseConstant';
|
import { pageSizes } from '@/enums/baseConstant';
|
||||||
|
@ -57,7 +58,6 @@ export const usePermissionStore = defineStore('PermissionStore', {
|
||||||
const data = { ...this.pagination, ...this.form };
|
const data = { ...this.pagination, ...this.form };
|
||||||
delete data.pageSizes;
|
delete data.pageSizes;
|
||||||
delete data.total;
|
delete data.total;
|
||||||
delete data.background;
|
|
||||||
|
|
||||||
// 获取权限列表
|
// 获取权限列表
|
||||||
const result = await getPermissionPage(data);
|
const result = await getPermissionPage(data);
|
||||||
|
@ -117,5 +117,11 @@ export const usePermissionStore = defineStore('PermissionStore', {
|
||||||
const result = await updatePermissionListByParentId(data);
|
const result = await updatePermissionListByParentId(data);
|
||||||
return storeMessage(result);
|
return storeMessage(result);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/* 批量更新权限 */
|
||||||
|
async updatePermissionBatch(data: any) {
|
||||||
|
const result = await updatePermissionBatch(data);
|
||||||
|
return storeMessage(result);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,7 +23,6 @@ function onResetPassword() {
|
||||||
|
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `修改密码`,
|
title: `修改密码`,
|
||||||
width: '30%',
|
|
||||||
draggable: true,
|
draggable: true,
|
||||||
closeOnClickModal: false,
|
closeOnClickModal: false,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
|
|
|
@ -97,8 +97,9 @@ onMounted(() => {
|
||||||
</ReAuth>
|
</ReAuth>
|
||||||
|
|
||||||
<PureTableBar :columns="columns" :title="$t('emailTemplate')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
<PureTableBar :columns="columns" :title="$t('emailTemplate')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||||
|
<!-- 新增 -->
|
||||||
<template #buttons>
|
<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') }}
|
{{ $t('addNew') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@ export function onAdd() {
|
||||||
|
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('addNew')}${$t('emailTemplate')}`,
|
title: `${$t('addNew')}${$t('emailTemplate')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
templateName: undefined,
|
templateName: undefined,
|
||||||
|
@ -38,7 +37,18 @@ export function onAdd() {
|
||||||
draggable: true,
|
draggable: true,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
closeOnClickModal: false,
|
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 }) => {
|
beforeSure: (done, { options }) => {
|
||||||
const form = options.props.formInline as FormItemProps;
|
const form = options.props.formInline as FormItemProps;
|
||||||
formRef.value.formRef.validate(async (valid: any) => {
|
formRef.value.formRef.validate(async (valid: any) => {
|
||||||
|
@ -59,7 +69,6 @@ export function onUpdate(row: any) {
|
||||||
|
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('modify')}${$t('emailTemplate')}`,
|
title: `${$t('modify')}${$t('emailTemplate')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
templateName: row.templateName,
|
templateName: row.templateName,
|
||||||
|
@ -73,7 +82,18 @@ export function onUpdate(row: any) {
|
||||||
draggable: true,
|
draggable: true,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
closeOnClickModal: false,
|
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 }) => {
|
beforeSure: (done, { options }) => {
|
||||||
const form = options.props.formInline as FormItemProps;
|
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">
|
<PureTableBar :columns="columns" :title="$t('email_user_send_config')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||||
<template #buttons>
|
<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') }}
|
{{ $t('addNew') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ export async function onSearch() {
|
||||||
export function onAdd() {
|
export function onAdd() {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('addNew')}${$t('emailUsers')}`,
|
title: `${$t('addNew')}${$t('emailUsers')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
email: undefined,
|
email: undefined,
|
||||||
|
@ -58,7 +58,7 @@ export function onAdd() {
|
||||||
export function onUpdate(row: any) {
|
export function onUpdate(row: any) {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('modify')}${$t('emailUsers')}`,
|
title: `${$t('modify')}${$t('emailUsers')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
email: row.email,
|
email: row.email,
|
||||||
|
|
|
@ -70,7 +70,7 @@ onMounted(() => {
|
||||||
|
|
||||||
<PureTableBar :columns="columns" :title="$t('menuIcon')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
<PureTableBar :columns="columns" :title="$t('menuIcon')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||||
<template #buttons>
|
<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') }}
|
{{ $t('addNew') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ export async function onSearch() {
|
||||||
export function onAdd() {
|
export function onAdd() {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('addNew')} ${$t('menuIcon')}`,
|
title: `${$t('addNew')} ${$t('menuIcon')}`,
|
||||||
width: '30%',
|
|
||||||
props: { formInline: { confirmText: '' } },
|
props: { formInline: { confirmText: '' } },
|
||||||
draggable: true,
|
draggable: true,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
|
@ -45,7 +45,7 @@ export function onAdd() {
|
||||||
export function onUpdate(row: any) {
|
export function onUpdate(row: any) {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('modify')} ${$t('menuIcon')}`,
|
title: `${$t('modify')} ${$t('menuIcon')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
iconCode: row.iconCode,
|
iconCode: row.iconCode,
|
||||||
|
|
|
@ -333,7 +333,7 @@ onMounted(() => {
|
||||||
|
|
||||||
<!-- 提交内容 -->
|
<!-- 提交内容 -->
|
||||||
<re-col v-if="hasAuth(auth.update)" :sm="24" :value="24" :xs="24">
|
<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)">
|
<el-button class="w-full" plain type="primary" @click="submitForm(ruleFormRef)">
|
||||||
{{ $t('modifyingConfiguration') }}
|
{{ $t('modifyingConfiguration') }}
|
||||||
</el-button>
|
</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-input v-model="i18nStore.form.typeName" :placeholder="`${$t('input')}${$t('i18n.typeName')}`" class="!w-[180px]" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
|
<!-- 表格頂部搜索 -->
|
||||||
<el-button :icon="useRenderIcon('ri/search-line')" :loading="i18nStore.loading" type="primary" @click="onSearch">
|
<el-button :icon="useRenderIcon('ri/search-line')" :loading="i18nStore.loading" type="primary" @click="onSearch">
|
||||||
{{ $t('search') }}
|
{{ $t('search') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<!-- 表格頂部重置 -->
|
||||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(pageFormRef)">
|
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(pageFormRef)">
|
||||||
{{ $t('buttons.reset') }}
|
{{ $t('buttons.reset') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
@ -95,7 +97,9 @@ onMounted(() => {
|
||||||
</el-button>
|
</el-button>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
|
<!-- 到處為JSON -->
|
||||||
<el-dropdown-item @click="downloadI18nSetting('json')">{{ $t('download_json') }}</el-dropdown-item>
|
<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-item @click="downloadI18nSetting('excel')">{{ $t('download_excel') }}</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
|
@ -113,7 +117,7 @@ onMounted(() => {
|
||||||
</el-dropdown>
|
</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') }}
|
{{ $t('addNew') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
|
@ -148,12 +152,14 @@ onMounted(() => {
|
||||||
@page-size-change="onPageSizeChange"
|
@page-size-change="onPageSizeChange"
|
||||||
@page-current-change="onCurrentPageChange"
|
@page-current-change="onCurrentPageChange"
|
||||||
>
|
>
|
||||||
|
<!-- 創建用戶名 -->
|
||||||
<template #createUser="{ row }">
|
<template #createUser="{ row }">
|
||||||
<el-button v-show="row.createUser" link type="primary" @click="selectUserinfo(row.createUser)">
|
<el-button v-show="row.createUser" link type="primary" @click="selectUserinfo(row.createUser)">
|
||||||
{{ row.createUsername }}
|
{{ row.createUsername }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- 更新用戶名 -->
|
||||||
<template #updateUser="{ row }">
|
<template #updateUser="{ row }">
|
||||||
<el-button v-show="row.updateUser" link type="primary" @click="selectUserinfo(row.updateUser)">
|
<el-button v-show="row.updateUser" link type="primary" @click="selectUserinfo(row.updateUser)">
|
||||||
{{ row.updateUsername }}
|
{{ row.updateUsername }}
|
||||||
|
@ -161,9 +167,12 @@ onMounted(() => {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #operation="{ row }">
|
<template #operation="{ row }">
|
||||||
|
<!-- 修改 -->
|
||||||
<el-button v-if="hasAuth(auth.update)" :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') }}
|
{{ $t('modify') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
|
<!-- 刪除確認 -->
|
||||||
<el-popconfirm v-if="hasAuth(auth.deleted)" :title="`${$t('confirmDelete')} ${row.translation}`" @confirm="onDelete(row)">
|
<el-popconfirm v-if="hasAuth(auth.deleted)" :title="`${$t('confirmDelete')} ${row.translation}`" @confirm="onDelete(row)">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-button :icon="useRenderIcon(Delete)" :size="size" class="reset-margin" link type="primary">
|
<el-button :icon="useRenderIcon(Delete)" :size="size" class="reset-margin" link type="primary">
|
||||||
|
|
|
@ -29,7 +29,7 @@ export const updateI18nSetting = (fileType: string) => {
|
||||||
|
|
||||||
addDialog({
|
addDialog({
|
||||||
title: $t('update_multilingual'),
|
title: $t('update_multilingual'),
|
||||||
width: '30%',
|
|
||||||
draggable: true,
|
draggable: true,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
closeOnClickModal: false,
|
closeOnClickModal: false,
|
||||||
|
@ -51,7 +51,7 @@ export const updateI18nSetting = (fileType: string) => {
|
||||||
export const onAdd = () => {
|
export const onAdd = () => {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: $t('addMultilingual'),
|
title: $t('addMultilingual'),
|
||||||
width: '30%',
|
|
||||||
props: { formInline: { keyName: '', translation: '', typeName: '' } },
|
props: { formInline: { keyName: '', translation: '', typeName: '' } },
|
||||||
draggable: true,
|
draggable: true,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
|
@ -107,7 +107,7 @@ export const onUpdate = (row: any) => {
|
||||||
|
|
||||||
addDialog({
|
addDialog({
|
||||||
title: $t('update_multilingual'),
|
title: $t('update_multilingual'),
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: { keyName: row.keyName, translation: row.translation, typeName: row.typeName },
|
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">
|
<PureTableBar :columns="columns" :title="$t('i18n_type')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||||
<template #buttons>
|
<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') }}
|
{{ $t('addNew') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -19,7 +19,7 @@ export async function onSearch() {
|
||||||
export function onAdd() {
|
export function onAdd() {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `添加多语言类型`,
|
title: `添加多语言类型`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: { typeName: '', summary: '', isDefault: false },
|
formInline: { typeName: '', summary: '', isDefault: false },
|
||||||
},
|
},
|
||||||
|
@ -45,7 +45,7 @@ export function onAdd() {
|
||||||
export function onUpdate(row: any) {
|
export function onUpdate(row: any) {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `修改多语言类型`,
|
title: `修改多语言类型`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
typeName: row.typeName,
|
typeName: row.typeName,
|
||||||
|
|
|
@ -151,7 +151,7 @@ onMounted(() => {
|
||||||
|
|
||||||
<!-- 简介 -->
|
<!-- 简介 -->
|
||||||
<el-form-item :label="$t('summary')" prop="summary">
|
<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>
|
</el-form-item>
|
||||||
|
|
||||||
<!-- 消息等级 -->
|
<!-- 消息等级 -->
|
||||||
|
|
|
@ -23,7 +23,7 @@ defineExpose({ formRef });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<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">
|
<div class="split-pane">
|
||||||
<SplitPane :splitSet="settingLR">
|
<SplitPane :splitSet="settingLR">
|
||||||
<template #paneL>
|
<template #paneL>
|
||||||
|
@ -120,7 +120,7 @@ defineExpose({ formRef });
|
||||||
|
|
||||||
<!-- 简介 -->
|
<!-- 简介 -->
|
||||||
<el-form-item :label="$t('summary')" prop="summary">
|
<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>
|
</el-form-item>
|
||||||
|
|
||||||
<!-- 消息等级 -->
|
<!-- 消息等级 -->
|
||||||
|
|
|
@ -91,7 +91,7 @@ onMounted(() => {
|
||||||
|
|
||||||
<PureTableBar :columns="columns" title="系统消息类型" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
<PureTableBar :columns="columns" title="系统消息类型" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||||
<template #buttons>
|
<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') }}
|
{{ $t('addNew') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ export async function onSearch() {
|
||||||
export function onAdd() {
|
export function onAdd() {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('addNew')}${$t('messageType')}`,
|
title: `${$t('addNew')}${$t('messageType')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
status: true,
|
status: true,
|
||||||
|
@ -53,7 +53,7 @@ export function onAdd() {
|
||||||
export function onUpdate(row: any) {
|
export function onUpdate(row: any) {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('modify')}${$t('messageType')}`,
|
title: `${$t('modify')}${$t('messageType')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
status: row.status,
|
status: row.status,
|
||||||
|
|
|
@ -21,7 +21,7 @@ export async function onSearch() {
|
||||||
export function onView(row: any) {
|
export function onView(row: any) {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('view')}${$t('quartzExecuteLog')}`,
|
title: `${$t('view')}${$t('quartzExecuteLog')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
jobName: row.jobName,
|
jobName: row.jobName,
|
||||||
|
|
|
@ -21,7 +21,7 @@ export async function onSearch() {
|
||||||
export function onView(row: any) {
|
export function onView(row: any) {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('view')}${$t('userLoginLog')}`,
|
title: `${$t('view')}${$t('userLoginLog')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
userId: row.userId,
|
userId: row.userId,
|
||||||
|
|
|
@ -81,7 +81,7 @@ onMounted(() => {
|
||||||
|
|
||||||
<PureTableBar :columns="columns" :title="$t('schedulersGroup')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
<PureTableBar :columns="columns" :title="$t('schedulersGroup')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||||
<template #buttons>
|
<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') }}
|
{{ $t('addNew') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ export async function onSearch() {
|
||||||
export function onAdd() {
|
export function onAdd() {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('addNew')}${$t('schedulersGroup')}`,
|
title: `${$t('addNew')}${$t('schedulersGroup')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
groupName: undefined,
|
groupName: undefined,
|
||||||
|
@ -51,7 +51,7 @@ export function onAdd() {
|
||||||
export function onUpdate(row: any) {
|
export function onUpdate(row: any) {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('modify')}${$t('schedulersGroup')}`,
|
title: `${$t('modify')}${$t('schedulersGroup')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
groupName: row.groupName,
|
groupName: row.groupName,
|
||||||
|
|
|
@ -78,7 +78,7 @@ onMounted(() => {
|
||||||
|
|
||||||
<PureTableBar :columns="columns" title="Schedulers视图" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
<PureTableBar :columns="columns" title="Schedulers视图" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||||
<template #buttons>
|
<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') }}
|
{{ $t('addNew') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
@ -119,7 +119,8 @@ onMounted(() => {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #operation="{ row }">
|
<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') }}
|
{{ $t('modify') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ export const auth = {
|
||||||
// 添加操作
|
// 添加操作
|
||||||
add: ['schedulers::add'],
|
add: ['schedulers::add'],
|
||||||
// 暂停
|
// 暂停
|
||||||
|
update: ['schedulers::update'],
|
||||||
pause: ['schedulers::update'],
|
pause: ['schedulers::update'],
|
||||||
// 恢复
|
// 恢复
|
||||||
resume: ['schedulers::update'],
|
resume: ['schedulers::update'],
|
||||||
|
|
|
@ -20,7 +20,7 @@ export async function onSearch() {
|
||||||
export function onAdd() {
|
export function onAdd() {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('addNew')}${$t('schedulers')}`,
|
title: `${$t('addNew')}${$t('schedulers')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
jobName: undefined,
|
jobName: undefined,
|
||||||
|
@ -52,7 +52,7 @@ export function onAdd() {
|
||||||
export function onUpdate(row: any) {
|
export function onUpdate(row: any) {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('modify')}${$t('schedulers')}`,
|
title: `${$t('modify')}${$t('schedulers')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
jobName: row.jobName,
|
jobName: row.jobName,
|
||||||
|
|
|
@ -151,7 +151,7 @@ onMounted(() => {
|
||||||
|
|
||||||
<PureTableBar :columns="columns" :title="$t('userinfo')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
<PureTableBar :columns="columns" :title="$t('userinfo')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||||
<template #buttons>
|
<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') }}
|
{{ $t('addNew') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,6 @@ export function onAdd() {
|
||||||
isAddUserinfo.value = true;
|
isAddUserinfo.value = true;
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('addNew')}${$t('adminUser')}`,
|
title: `${$t('addNew')}${$t('adminUser')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
username: undefined,
|
username: undefined,
|
||||||
|
@ -70,7 +69,22 @@ export function onAdd() {
|
||||||
draggable: true,
|
draggable: true,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
closeOnClickModal: false,
|
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 }) => {
|
beforeSure: (done, { options }) => {
|
||||||
const form = options.props.formInline as FormItemProps;
|
const form = options.props.formInline as FormItemProps;
|
||||||
formRef.value.formRef.validate(async (valid: any) => {
|
formRef.value.formRef.validate(async (valid: any) => {
|
||||||
|
@ -90,7 +104,6 @@ export function onUpdate(row: any) {
|
||||||
isAddUserinfo.value = false;
|
isAddUserinfo.value = false;
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('modify')}${$t('adminUser')}`,
|
title: `${$t('modify')}${$t('adminUser')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
username: row.username,
|
username: row.username,
|
||||||
|
@ -108,7 +121,22 @@ export function onUpdate(row: any) {
|
||||||
draggable: true,
|
draggable: true,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
closeOnClickModal: false,
|
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 }) => {
|
beforeSure: (done, { options }) => {
|
||||||
const form = options.props.formInline as FormItemProps;
|
const form = options.props.formInline as FormItemProps;
|
||||||
formRef.value.formRef.validate(async (valid: any) => {
|
formRef.value.formRef.validate(async (valid: any) => {
|
||||||
|
@ -149,12 +177,12 @@ export const onDeleteBatch = async () => {
|
||||||
|
|
||||||
addDialog({
|
addDialog({
|
||||||
title: $t('deleteBatchTip'),
|
title: $t('deleteBatchTip'),
|
||||||
width: '30%',
|
|
||||||
props: { formInline: { confirmText: '' } },
|
props: { formInline: { confirmText: '' } },
|
||||||
draggable: true,
|
draggable: true,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
closeOnClickModal: false,
|
closeOnClickModal: false,
|
||||||
contentRenderer: () => h(DeleteBatchDialog, { ref: formDeletedBatchRef }),
|
contentRenderer: () => h(DeleteBatchDialog, { ref: formDeletedBatchRef, formInline: { confirmText: '' } }),
|
||||||
beforeSure: (done, { options }) => {
|
beforeSure: (done, { options }) => {
|
||||||
formDeletedBatchRef.value.formDeletedBatchRef.validate(async (valid: any) => {
|
formDeletedBatchRef.value.formDeletedBatchRef.validate(async (valid: any) => {
|
||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
|
@ -229,7 +257,7 @@ export const onUploadAvatar = (row: any) => {
|
||||||
export const onResetPassword = (row: any) => {
|
export const onResetPassword = (row: any) => {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('buttons.reset')} ${row.username} ${$t('userPassword')}`,
|
title: `${$t('buttons.reset')} ${row.username} ${$t('userPassword')}`,
|
||||||
width: '30%',
|
|
||||||
draggable: true,
|
draggable: true,
|
||||||
closeOnClickModal: false,
|
closeOnClickModal: false,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
|
|
|
@ -79,7 +79,7 @@ onMounted(() => {
|
||||||
@refresh="onSearch"
|
@refresh="onSearch"
|
||||||
>
|
>
|
||||||
<template #buttons>
|
<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') }}
|
{{ $t('addNew') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ export async function onSearch() {
|
||||||
export function onAdd(parentId: number = 0) {
|
export function onAdd(parentId: number = 0) {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('addNew')}${$t('dept')}`,
|
title: `${$t('addNew')}${$t('dept')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
parentId,
|
parentId,
|
||||||
|
@ -33,7 +32,16 @@ export function onAdd(parentId: number = 0) {
|
||||||
draggable: true,
|
draggable: true,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
closeOnClickModal: false,
|
closeOnClickModal: false,
|
||||||
contentRenderer: () => h(DeptDialog, { ref: formRef }),
|
contentRenderer: () =>
|
||||||
|
h(DeptDialog, {
|
||||||
|
ref: formRef,
|
||||||
|
formInline: {
|
||||||
|
parentId,
|
||||||
|
manager: undefined,
|
||||||
|
deptName: undefined,
|
||||||
|
summary: undefined,
|
||||||
|
},
|
||||||
|
}),
|
||||||
beforeSure: (done, { options }) => {
|
beforeSure: (done, { options }) => {
|
||||||
const form = options.props.formInline as FormItemProps;
|
const form = options.props.formInline as FormItemProps;
|
||||||
formRef.value.formRef.validate(async (valid: any) => {
|
formRef.value.formRef.validate(async (valid: any) => {
|
||||||
|
@ -52,7 +60,7 @@ export function onAdd(parentId: number = 0) {
|
||||||
export function onUpdate(row: any) {
|
export function onUpdate(row: any) {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('modify')}${$t('dept')}`,
|
title: `${$t('modify')}${$t('dept')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
parentId: row.parentId,
|
parentId: row.parentId,
|
||||||
|
@ -64,7 +72,16 @@ export function onUpdate(row: any) {
|
||||||
draggable: true,
|
draggable: true,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
closeOnClickModal: false,
|
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 }) => {
|
beforeSure: (done, { options }) => {
|
||||||
const form = options.props.formInline as FormItemProps;
|
const form = options.props.formInline as FormItemProps;
|
||||||
formRef.value.formRef.validate(async (valid: any) => {
|
formRef.value.formRef.validate(async (valid: any) => {
|
||||||
|
|
|
@ -85,22 +85,23 @@ onMounted(() => {
|
||||||
|
|
||||||
<PureTableBar :columns="columns" :title="$t('system_file')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
<PureTableBar :columns="columns" :title="$t('system_file')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||||
<template #buttons>
|
<template #buttons>
|
||||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="primary" @click="onAdd">
|
|
||||||
{{ $t('addNew') }}
|
|
||||||
</el-button>
|
|
||||||
|
|
||||||
<!-- 批量下载 -->
|
<!-- 批量下载 -->
|
||||||
<el-button
|
<el-button
|
||||||
v-if="hasAuth(auth.download)"
|
v-if="hasAuth(auth.download)"
|
||||||
:disabled="!(selectRows.length > 0)"
|
:disabled="!(selectRows.length > 0)"
|
||||||
:icon="useRenderIcon(Download)"
|
:icon="useRenderIcon(Download)"
|
||||||
plain
|
plain
|
||||||
type="success"
|
type="primary"
|
||||||
@click="onDownloadBatch"
|
@click="onDownloadBatch"
|
||||||
>
|
>
|
||||||
{{ $t('download_batch') }}
|
{{ $t('download_batch') }}
|
||||||
</el-button>
|
</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">
|
<el-button v-if="hasAuth(auth.delete)" :disabled="!(selectRows.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDeleteBatch">
|
||||||
{{ $t('deleteBatches') }}
|
{{ $t('deleteBatches') }}
|
||||||
|
|
|
@ -25,7 +25,7 @@ export async function onSearch() {
|
||||||
export function onAdd() {
|
export function onAdd() {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('addNew')}${$t('files')}`,
|
title: `${$t('addNew')}${$t('files')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
filepath: undefined,
|
filepath: undefined,
|
||||||
|
@ -69,7 +69,7 @@ export function onAdd() {
|
||||||
export function onUpdate(row: any) {
|
export function onUpdate(row: any) {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('modify')}${$t('files')}`,
|
title: `${$t('modify')}${$t('files')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
filename: row.filename,
|
filename: row.filename,
|
||||||
|
|
|
@ -72,7 +72,7 @@ onMounted(() => {
|
||||||
>
|
>
|
||||||
<template #buttons>
|
<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') }}
|
{{ $t('addNew') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,7 @@ export const clearAllRolesSelect = async () => {
|
||||||
|
|
||||||
addDialog({
|
addDialog({
|
||||||
title: $t('doubleCheck'),
|
title: $t('doubleCheck'),
|
||||||
width: '30%',
|
|
||||||
draggable: true,
|
draggable: true,
|
||||||
closeOnClickModal: false,
|
closeOnClickModal: false,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
|
|
|
@ -76,7 +76,7 @@ defineExpose({ formRef });
|
||||||
:filter-node-method="filterMethod"
|
:filter-node-method="filterMethod"
|
||||||
:props="{ label: 'summary' }"
|
:props="{ label: 'summary' }"
|
||||||
accordion
|
accordion
|
||||||
class="my-2 py-1 h-[220px] overflow-y-auto"
|
class="my-2 py-1 h-[350px] overflow-y-auto"
|
||||||
highlight-current
|
highlight-current
|
||||||
node-key="path"
|
node-key="path"
|
||||||
@node-click="onNodeClick"
|
@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 Refresh from '~icons/ep/refresh';
|
||||||
import AddFill from '~icons/ri/add-circle-line';
|
import AddFill from '~icons/ri/add-circle-line';
|
||||||
import Upload from '~icons/ri/upload-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' });
|
defineOptions({ name: 'PermissionManger' });
|
||||||
|
|
||||||
|
@ -62,13 +64,12 @@ const downloadPermission = (type: string) => {
|
||||||
/* 导入权限 */
|
/* 导入权限 */
|
||||||
const uploadPermission = async (type: string) => {
|
const uploadPermission = async (type: string) => {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('modify')}${$t('role')}`,
|
title: `${$t('modify')}${$t('power')}`,
|
||||||
width: '30%',
|
|
||||||
props: { form: { file: undefined } },
|
props: { form: { file: undefined } },
|
||||||
draggable: true,
|
draggable: true,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
closeOnClickModal: false,
|
closeOnClickModal: false,
|
||||||
contentRenderer: () => h(FileUploadDialog, { ref: formRef }),
|
contentRenderer: () => h(FileUploadDialog, { ref: formRef, form: { file: undefined } }),
|
||||||
beforeSure: (done, { options }) => {
|
beforeSure: (done, { options }) => {
|
||||||
const form = options.props.form;
|
const form = options.props.form;
|
||||||
formRef.value.formRef.validate(async (valid: any) => {
|
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(() => {
|
onMounted(() => {
|
||||||
onSearch();
|
onSearch();
|
||||||
});
|
});
|
||||||
|
@ -150,26 +170,28 @@ onMounted(() => {
|
||||||
</el-dropdown>
|
</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') }}
|
{{ $t('addNew') }}
|
||||||
</el-button>
|
</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 -->
|
<!-- 批量更新父级id -->
|
||||||
<el-button
|
<el-dropdown-item v-if="hasAuth(auth.update)" :icon="useRenderIcon(EditPen)" @click="onUpdateSort">拖拽排序</el-dropdown-item>
|
||||||
v-if="hasAuth(auth.update)"
|
<!-- 批量更新父级id -->
|
||||||
:disabled="!(powerIds.length > 0)"
|
<el-dropdown-item v-if="hasAuth(auth.update)" :disabled="!(powerIds.length > 0)" :icon="useRenderIcon(EditPen)" @click="onUpdateBatchParent">
|
||||||
:icon="useRenderIcon(EditPen)"
|
|
||||||
plain
|
|
||||||
type="primary"
|
|
||||||
@click="onUpdateBatchParent"
|
|
||||||
>
|
|
||||||
{{ $t('update_batches_parent') }}
|
{{ $t('update_batches_parent') }}
|
||||||
</el-button>
|
</el-dropdown-item>
|
||||||
|
|
||||||
<!-- 批量删除按钮 -->
|
<!-- 批量删除按钮 -->
|
||||||
<el-button v-if="hasAuth(auth.delete)" :disabled="!(powerIds.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDeleteBatch">
|
<el-dropdown-item v-if="hasAuth(auth.delete)" :disabled="!(powerIds.length > 0)" :icon="useRenderIcon(Delete)" @click="onDeleteBatch">
|
||||||
{{ $t('deleteBatches') }}
|
{{ $t('deleteBatches') }}
|
||||||
</el-button>
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-slot="{ size, dynamicColumns }">
|
<template v-slot="{ size, dynamicColumns }">
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { addDialog } from '@/components/ReDialog/index';
|
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 { usePermissionStore } from '@/store/system/power';
|
||||||
import { h, reactive, ref } from 'vue';
|
import { h, reactive, ref } from 'vue';
|
||||||
import { messageBox } from '@/utils/message';
|
import { messageBox } from '@/utils/message';
|
||||||
|
@ -25,7 +25,7 @@ export async function onSearch() {
|
||||||
export function onAdd(parentId = 0) {
|
export function onAdd(parentId = 0) {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('addNew')}${$t('power')}`,
|
title: `${$t('addNew')}${$t('power')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
parentId,
|
parentId,
|
||||||
|
@ -38,7 +38,17 @@ export function onAdd(parentId = 0) {
|
||||||
draggable: true,
|
draggable: true,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
closeOnClickModal: false,
|
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 }) => {
|
beforeSure: (done, { options }) => {
|
||||||
const form = options.props.formInline as FormItemProps;
|
const form = options.props.formInline as FormItemProps;
|
||||||
formRef.value.formRef.validate(async (valid: any) => {
|
formRef.value.formRef.validate(async (valid: any) => {
|
||||||
|
@ -57,7 +67,7 @@ export function onAdd(parentId = 0) {
|
||||||
export function onUpdate(row: any) {
|
export function onUpdate(row: any) {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('modify')}${$t('power')}`,
|
title: `${$t('modify')}${$t('power')}`,
|
||||||
width: '30%',
|
|
||||||
props: {
|
props: {
|
||||||
formInline: {
|
formInline: {
|
||||||
parentId: row.parentId,
|
parentId: row.parentId,
|
||||||
|
@ -70,7 +80,17 @@ export function onUpdate(row: any) {
|
||||||
draggable: true,
|
draggable: true,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
closeOnClickModal: false,
|
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 }) => {
|
beforeSure: (done, { options }) => {
|
||||||
const form = options.props.formInline as FormItemProps;
|
const form = options.props.formInline as FormItemProps;
|
||||||
formRef.value.formRef.validate(async (valid: any) => {
|
formRef.value.formRef.validate(async (valid: any) => {
|
||||||
|
@ -132,7 +152,7 @@ export const onUpdateBatchParent = async () => {
|
||||||
await powerStore.loadPermissionList();
|
await powerStore.loadPermissionList();
|
||||||
addDialog({
|
addDialog({
|
||||||
title: $t('update_batches_parent'),
|
title: $t('update_batches_parent'),
|
||||||
width: '30%',
|
|
||||||
draggable: true,
|
draggable: true,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
closeOnClickModal: false,
|
closeOnClickModal: false,
|
||||||
|
|
|
@ -73,7 +73,7 @@ const downloadRoleExcel = () => {
|
||||||
const onUpdateByFile = () => {
|
const onUpdateByFile = () => {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('modify')}${$t('role')}`,
|
title: `${$t('modify')}${$t('role')}`,
|
||||||
width: '30%',
|
|
||||||
props: { form: { file: undefined } },
|
props: { form: { file: undefined } },
|
||||||
draggable: true,
|
draggable: true,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
|
@ -139,7 +139,7 @@ onMounted(() => {
|
||||||
{{ $t('file_import') }}
|
{{ $t('file_import') }}
|
||||||
</el-button>
|
</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') }}
|
{{ $t('addNew') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ export async function onSearch() {
|
||||||
export function onAdd() {
|
export function onAdd() {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('addNew')}${$t('role')}`,
|
title: `${$t('addNew')}${$t('role')}`,
|
||||||
width: '30%',
|
|
||||||
props: { formInline: { roleCode: undefined, description: undefined } },
|
props: { formInline: { roleCode: undefined, description: undefined } },
|
||||||
draggable: true,
|
draggable: true,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
|
@ -58,7 +58,7 @@ export function onAdd() {
|
||||||
export function onUpdate(row: any) {
|
export function onUpdate(row: any) {
|
||||||
addDialog({
|
addDialog({
|
||||||
title: `${$t('modify')}${$t('role')}`,
|
title: `${$t('modify')}${$t('role')}`,
|
||||||
width: '30%',
|
|
||||||
props: { formInline: { roleCode: row.roleCode, description: row.description } },
|
props: { formInline: { roleCode: row.roleCode, description: row.description } },
|
||||||
draggable: true,
|
draggable: true,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
|
|
Loading…
Reference in New Issue