😎1、恢复角色批量设置用户 2、调整首页等待条样式 3、增加获取指定机构子树API 4、升级依赖

This commit is contained in:
zuohuaijun 2025-03-07 23:59:21 +08:00
parent 9f18a5e7e5
commit df50d8de1c
6 changed files with 156 additions and 27 deletions

View File

@ -94,6 +94,19 @@ public class SysOrgService : IDynamicApiController, ITransient
} }
} }
/// <summary>
/// 获取指定层级机构树 🔖
/// </summary>
/// <param name="pid"></param>
/// <param name="level"></param>
/// <returns></returns>
[DisplayName("获取指定层级机构树")]
public async Task<List<SysOrg>> GetChildTree(long pid, int level)
{
var iSugarQueryable = _sysOrgRep.AsQueryable().OrderBy(u => new { u.OrderNo });
return await iSugarQueryable.Where(u => u.Level < level).ToTreeAsync(u => u.Children, u => u.Pid, pid);
}
/// <summary> /// <summary>
/// 增加机构 🔖 /// 增加机构 🔖
/// </summary> /// </summary>

View File

@ -24,7 +24,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="3.2.0" /> <PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.13.0" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.13.0" />
<PackageReference Include="Rezero.Api" Version="1.7.14" /> <PackageReference Include="Rezero.Api" Version="1.7.14" />
</ItemGroup> </ItemGroup>

View File

@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" media="print" href="/print-lock.css" /> <link rel="stylesheet" type="text/css" media="print" href="/print-lock.css" />
<link rel="icon" id="favicon" href="data:;base64,=" /> <link rel="icon" id="favicon" href="data:;base64,=" />
<title>Loading...</title> <title>loading</title>
<style> <style>
.loading-wrapper { .loading-wrapper {
position: fixed; position: fixed;
@ -25,23 +25,29 @@
.loading-wrapper.hide { .loading-wrapper.hide {
display: none; display: none;
} }
.loader { .loader {
width: 120px; width: 15px;
height: 20px; aspect-ratio: 1;
border-radius: 20px; background: #000;
background: border-radius: 50%;
repeating-linear-gradient(135deg, #010101 0 10px, #f9d62b 0 20px) 0/0% no-repeat, animation: l6 1s infinite linear alternate;
repeating-linear-gradient(135deg, #ddd 0 10px, #eee 0 20px) 0/100%;
animation: l3 2s infinite;
} }
.loading-text { @keyframes l6 {
margin-top: 20px; 0% {
font-size: 16px; box-shadow:
color: #666; 15px 0,
-25px 0;
}
50% {
box-shadow:
15px 0,
-15px 0;
} }
@keyframes l3 {
100% { 100% {
background-size: 100%; box-shadow:
25px 0,
-15px 0;
} }
} }
</style> </style>
@ -50,7 +56,6 @@
<body> <body>
<div class="loading-wrapper"> <div class="loading-wrapper">
<div class="loader"></div> <div class="loader"></div>
<div class="loading-text">Loading......</div>
</div> </div>
<div id="app"></div> <div id="app"></div>
<script src="/config.js"></script> <script src="/config.js"></script>

View File

@ -2,7 +2,7 @@
"name": "admin.net.pro", "name": "admin.net.pro",
"type": "module", "type": "module",
"version": "2.4.33", "version": "2.4.33",
"lastBuildTime": "2025.03.05", "lastBuildTime": "2025.03.07",
"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架", "description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",
"author": "zuohuaijun", "author": "zuohuaijun",
"license": "MIT", "license": "MIT",
@ -29,14 +29,14 @@
"@wangeditor/editor-for-vue": "^5.1.12", "@wangeditor/editor-for-vue": "^5.1.12",
"animate.css": "^4.1.1", "animate.css": "^4.1.1",
"async-validator": "^4.2.5", "async-validator": "^4.2.5",
"axios": "^1.8.1", "axios": "^1.8.2",
"countup.js": "^2.8.0", "countup.js": "^2.8.0",
"cropperjs": "^1.6.2", "cropperjs": "^1.6.2",
"crypto-js": "^4.2.0", "crypto-js": "^4.2.0",
"echarts": "^5.6.0", "echarts": "^5.6.0",
"echarts-gl": "^2.0.9", "echarts-gl": "^2.0.9",
"echarts-wordcloud": "^2.1.0", "echarts-wordcloud": "^2.1.0",
"element-plus": "^2.9.5", "element-plus": "^2.9.6",
"exceljs": "^4.4.0", "exceljs": "^4.4.0",
"ezuikit-js": "^8.1.7", "ezuikit-js": "^8.1.7",
"gcoord": "^1.0.7", "gcoord": "^1.0.7",
@ -61,7 +61,7 @@
"screenfull": "^6.0.2", "screenfull": "^6.0.2",
"sm-crypto-v2": "^1.9.3", "sm-crypto-v2": "^1.9.3",
"sortablejs": "^1.15.6", "sortablejs": "^1.15.6",
"splitpanes": "^3.1.8", "splitpanes": "^4.0.0",
"vcrontab-3": "^3.3.22", "vcrontab-3": "^3.3.22",
"vform3-builds": "^3.0.10", "vform3-builds": "^3.0.10",
"vue": "^3.5.13", "vue": "^3.5.13",
@ -69,25 +69,25 @@
"vue-demi": "0.14.10", "vue-demi": "0.14.10",
"vue-draggable-plus": "^0.6.0", "vue-draggable-plus": "^0.6.0",
"vue-grid-layout": "3.0.0-beta1", "vue-grid-layout": "3.0.0-beta1",
"vue-i18n": "^11.1.1", "vue-i18n": "^11.1.2",
"vue-json-pretty": "^2.4.0", "vue-json-pretty": "^2.4.0",
"vue-plugin-hiprint": "^0.0.59-beta2", "vue-plugin-hiprint": "^0.0.59-beta2",
"vue-router": "^4.5.0", "vue-router": "^4.5.0",
"vue-signature-pad": "^3.0.2", "vue-signature-pad": "^3.0.2",
"vue3-flag-icons": "^0.0.3", "vue3-flag-icons": "^0.0.3",
"vue3-tree-org": "^4.2.2", "vue3-tree-org": "^4.2.2",
"vxe-pc-ui": "^4.4.2", "vxe-pc-ui": "^4.4.7",
"vxe-table": "^4.10.0", "vxe-table": "^4.10.0",
"vxe-table-plugin-element": "^4.0.4", "vxe-table-plugin-element": "^4.0.4",
"vxe-table-plugin-export-xlsx": "^4.0.7", "vxe-table-plugin-export-xlsx": "^4.0.7",
"xe-utils": "^3.7.2", "xe-utils": "^3.7.4",
"xlsx-js-style": "^1.2.0" "xlsx-js-style": "^1.2.0"
}, },
"devDependencies": { "devDependencies": {
"@iconify/vue": "^4.3.0", "@iconify/vue": "^4.3.0",
"@plugin-web-update-notification/vite": "^2.0.0", "@plugin-web-update-notification/vite": "^2.0.0",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/node": "^20.17.22", "@types/node": "^20.17.23",
"@types/nprogress": "^0.2.3", "@types/nprogress": "^0.2.3",
"@types/sortablejs": "^1.15.8", "@types/sortablejs": "^1.15.8",
"@typescript-eslint/eslint-plugin": "^8.26.0", "@typescript-eslint/eslint-plugin": "^8.26.0",
@ -105,7 +105,7 @@
"sass": "^1.85.1", "sass": "^1.85.1",
"terser": "^5.39.0", "terser": "^5.39.0",
"typescript": "^5.8.2", "typescript": "^5.8.2",
"vite": "^6.2.0", "vite": "^6.2.1",
"vite-plugin-cdn-import": "^1.0.1", "vite-plugin-cdn-import": "^1.0.1",
"vite-plugin-compression2": "^1.3.3", "vite-plugin-compression2": "^1.3.3",
"vite-plugin-vue-setup-extend": "^0.4.0", "vite-plugin-vue-setup-extend": "^0.4.0",

View File

@ -76,6 +76,61 @@ export const SysOrgApiAxiosParamCreator = function (configuration?: Configuratio
options: localVarRequestOptions, options: localVarRequestOptions,
}; };
}, },
/**
*
* @summary 🔖
* @param {number} pid
* @param {number} level
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
apiSysOrgChildTreePidLevelGet: async (pid: number, level: number, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'pid' is not null or undefined
if (pid === null || pid === undefined) {
throw new RequiredError('pid','Required parameter pid was null or undefined when calling apiSysOrgChildTreePidLevelGet.');
}
// verify required parameter 'level' is not null or undefined
if (level === null || level === undefined) {
throw new RequiredError('level','Required parameter level was null or undefined when calling apiSysOrgChildTreePidLevelGet.');
}
const localVarPath = `/api/sysOrg/childTree/{pid}/{level}`
.replace(`{${"pid"}}`, encodeURIComponent(String(pid)))
.replace(`{${"level"}}`, encodeURIComponent(String(level)));
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, 'https://example.com');
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions :AxiosRequestConfig = { method: 'GET', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
// authentication Bearer required
// http bearer authentication required
if (configuration && configuration.accessToken) {
const accessToken = typeof configuration.accessToken === 'function'
? await configuration.accessToken()
: await configuration.accessToken;
localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
}
const query = new URLSearchParams(localVarUrlObj.search);
for (const key in localVarQueryParameter) {
query.set(key, localVarQueryParameter[key]);
}
for (const key in options.params) {
query.set(key, options.params[key]);
}
localVarUrlObj.search = (new URLSearchParams(query)).toString();
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
return {
url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
options: localVarRequestOptions,
};
},
/** /**
* *
* @summary 🔖 * @summary 🔖
@ -262,6 +317,21 @@ export const SysOrgApiFp = function(configuration?: Configuration) {
return axios.request(axiosRequestArgs); return axios.request(axiosRequestArgs);
}; };
}, },
/**
*
* @summary 🔖
* @param {number} pid
* @param {number} level
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async apiSysOrgChildTreePidLevelGet(pid: number, level: number, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminNETResultListSysOrg>>> {
const localVarAxiosArgs = await SysOrgApiAxiosParamCreator(configuration).apiSysOrgChildTreePidLevelGet(pid, level, options);
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
return axios.request(axiosRequestArgs);
};
},
/** /**
* *
* @summary 🔖 * @summary 🔖
@ -326,6 +396,17 @@ export const SysOrgApiFactory = function (configuration?: Configuration, basePat
async apiSysOrgAddPost(body?: AddOrgInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminNETResultInt64>> { async apiSysOrgAddPost(body?: AddOrgInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminNETResultInt64>> {
return SysOrgApiFp(configuration).apiSysOrgAddPost(body, options).then((request) => request(axios, basePath)); return SysOrgApiFp(configuration).apiSysOrgAddPost(body, options).then((request) => request(axios, basePath));
}, },
/**
*
* @summary 🔖
* @param {number} pid
* @param {number} level
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async apiSysOrgChildTreePidLevelGet(pid: number, level: number, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminNETResultListSysOrg>> {
return SysOrgApiFp(configuration).apiSysOrgChildTreePidLevelGet(pid, level, options).then((request) => request(axios, basePath));
},
/** /**
* *
* @summary 🔖 * @summary 🔖
@ -380,6 +461,18 @@ export class SysOrgApi extends BaseAPI {
public async apiSysOrgAddPost(body?: AddOrgInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminNETResultInt64>> { public async apiSysOrgAddPost(body?: AddOrgInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminNETResultInt64>> {
return SysOrgApiFp(this.configuration).apiSysOrgAddPost(body, options).then((request) => request(this.axios, this.basePath)); return SysOrgApiFp(this.configuration).apiSysOrgAddPost(body, options).then((request) => request(this.axios, this.basePath));
} }
/**
*
* @summary 🔖
* @param {number} pid
* @param {number} level
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof SysOrgApi
*/
public async apiSysOrgChildTreePidLevelGet(pid: number, level: number, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminNETResultListSysOrg>> {
return SysOrgApiFp(this.configuration).apiSysOrgChildTreePidLevelGet(pid, level, options).then((request) => request(this.axios, this.basePath));
}
/** /**
* *
* @summary 🔖 * @summary 🔖

View File

@ -62,6 +62,7 @@
<el-button icon="ele-OfficeBuilding" size="small" text type="primary" @click="openGrantData(row)" v-auth="'sysRole/grantDataScope'">{{ $t('message.list.authData') }}</el-button> <el-button icon="ele-OfficeBuilding" size="small" text type="primary" @click="openGrantData(row)" v-auth="'sysRole/grantDataScope'">{{ $t('message.list.authData') }}</el-button>
<el-button icon="ele-Grid" size="small" text type="primary" @click="openGrantTable(row)" v-auth="'sysRole/grantTable'">{{ $t('message.list.fieldBlacklist') }}</el-button> <el-button icon="ele-Grid" size="small" text type="primary" @click="openGrantTable(row)" v-auth="'sysRole/grantTable'">{{ $t('message.list.fieldBlacklist') }}</el-button>
<el-button icon="ele-Link" size="small" text type="primary" @click="openGrantApi(row)" v-auth="'sysRole/grantApi'">{{ $t('message.list.apiBlacklist') }}</el-button> <el-button icon="ele-Link" size="small" text type="primary" @click="openGrantApi(row)" v-auth="'sysRole/grantApi'">{{ $t('message.list.apiBlacklist') }}</el-button>
<el-button icon="ele-User" size="small" text type="primary" @click="openGrantUser(row)" v-auth="'sysRole/grantApi'"> 授权账号 </el-button>
</template> </template>
</vxe-grid> </vxe-grid>
</el-card> </el-card>
@ -71,6 +72,7 @@
<GrantTable ref="grantTableRef" /> <GrantTable ref="grantTableRef" />
<GrantData ref="grantDataRef" @handleQuery="handleQuery" /> <GrantData ref="grantDataRef" @handleQuery="handleQuery" />
<GrantApi ref="grantApiRef" /> <GrantApi ref="grantApiRef" />
<GrantUser v-model:visible="state.grantUserVisible" @change="closeGrantUser" />
</div> </div>
</template> </template>
@ -87,6 +89,7 @@ import GrantMenu from '/@/views/system/role/component/grantMenu.vue';
import GrantTable from '/@/views/system/role/component/grantTable.vue'; import GrantTable from '/@/views/system/role/component/grantTable.vue';
import GrantData from '/@/views/system/role/component/grantData.vue'; import GrantData from '/@/views/system/role/component/grantData.vue';
import GrantApi from '/@/views/system/role/component/grantApi.vue'; import GrantApi from '/@/views/system/role/component/grantApi.vue';
import GrantUser from '/@/components/selector/userSelectorDialog.vue';
import ModifyRecord from '/@/components/table/modifyRecord.vue'; import ModifyRecord from '/@/components/table/modifyRecord.vue';
import { getAPI } from '/@/utils/axios-utils'; import { getAPI } from '/@/utils/axios-utils';
@ -110,6 +113,8 @@ const state = reactive({
}, },
visible: false, visible: false,
title: '', title: '',
grantUserVisible: false, //
roleRow: {} as any, //
}); });
const i18n = useI18n(); const i18n = useI18n();
@ -131,7 +136,7 @@ const options = useVxeTable<PageRoleOutput>(
{ field: 'orderNo', title: i18n.t('message.list.orderNo'), width: 80, showOverflow: 'tooltip' }, { field: 'orderNo', title: i18n.t('message.list.orderNo'), width: 80, showOverflow: 'tooltip' },
{ field: 'status', title: i18n.t('message.list.status'), width: 80, showOverflow: 'tooltip', slots: { default: 'row_status' } }, { field: 'status', title: i18n.t('message.list.status'), width: 80, showOverflow: 'tooltip', slots: { default: 'row_status' } },
{ field: 'record', title: i18n.t('message.list.record'), width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } }, { field: 'record', title: i18n.t('message.list.record'), width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } },
{ field: 'buttons', title: i18n.t('message.list.operation'), fixed: 'right', width: 440, showOverflow: true, slots: { default: 'row_buttons' } }, { field: 'buttons', title: i18n.t('message.list.operation'), fixed: 'right', width: 520, showOverflow: true, slots: { default: 'row_buttons' } },
], ],
}, },
// vxeGrid()vxe-table // vxeGrid()vxe-table
@ -232,4 +237,17 @@ const openGrantData = (row: any) => {
const openGrantApi = (row: any) => { const openGrantApi = (row: any) => {
grantApiRef.value?.openDrawer(row); grantApiRef.value?.openDrawer(row);
}; };
//
const openGrantUser = (row: any) => {
state.roleRow = row;
state.grantUserVisible = true;
};
//
const closeGrantUser = (data: any) => {
var userIds = data.map((u: any) => u.id);
getAPI(SysRoleApi).apiSysRoleGrantUserPost({ id: state.roleRow.id, userIdList: userIds });
state.grantUserVisible = false;
};
</script> </script>