Merge pull request '😎增加服务端列配置' (#369) from KaneLeung/Admin.NET.Pro:v2 into v2

Reviewed-on: https://code.adminnet.top/Admin.NET/Admin.NET.Pro/pulls/369
This commit is contained in:
zuohuaijun 2025-07-11 20:44:51 +08:00
commit b7eea750e2
14 changed files with 812 additions and 2 deletions

View File

@ -110,4 +110,9 @@ public class CacheConst
/// Excel临时文件缓存 /// Excel临时文件缓存
/// </summary> /// </summary>
public const string KeyExcelTemp = "sys_excel_temp:"; public const string KeyExcelTemp = "sys_excel_temp:";
/// <summary>
/// 列配置缓存
/// </summary>
public const string KeyColumnCustom = "sys_column_custom:";
} }

View File

@ -0,0 +1,49 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// Vxe表格列配置
/// </summary>
[SugarTable(null, "Vxe表格列配置")]
[SysTable]
[SugarIndex("i_{table}_u", nameof(UserId), OrderByType.Asc)]
[SugarIndex("i_{table}_g", nameof(GridId), OrderByType.Asc)]
public class SysColumnCustom : EntityTenantId
{
/// <summary>
/// 用户Id
/// </summary>
[SugarColumn(ColumnDescription = "用户Id")]
public long UserId { get; set; }
/// <summary>
/// 表格Id
/// </summary>
[MaxLength(128)]
[SugarColumn(ColumnDescription = "表格Id", Length = 128)]
public string GridId { get; set; }
/// <summary>
/// 冻结列状态数据
/// </summary>
[SugarColumn(ColumnDescription = "冻结列状态数据", IsNullable = true, ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? FixedData { get; set; }
/// <summary>
/// 列宽状态数据
/// </summary>
[SugarColumn(ColumnDescription = "列宽状态数据", IsNullable = true, ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? ResizableData { get; set; }
/// <summary>
/// 列顺序数据
/// </summary>
[SugarColumn(ColumnDescription = "列顺序数据", IsNullable = true, ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? SortData { get; set; }
/// <summary>
/// 显示/隐藏列状态数据
/// </summary>
[SugarColumn(ColumnDescription = "显示/隐藏列状态数据", IsNullable = true, ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? VisibleData { get; set; }
}

View File

@ -0,0 +1,63 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core.Service;
/// <summary>
/// 用户表格列配置基数输入参数
/// </summary>
public class BaseColumnCustomInput
{
/// <summary>
/// 表格Id
/// </summary>
[MaxLength(128)]
[Required(ErrorMessage = "表格Id不能为空")]
public virtual string GridId { get; set; }
}
/// <summary>
/// 获取用户表格列配置输入参数
/// </summary>
public class GetColumnCustomInput : BaseColumnCustomInput
{
}
/// <summary>
/// 保存用户表格列配置输入参数
/// </summary>
public class StoreColumnCustomInput
{
/// <summary>
/// 表格Id
/// </summary>
[MaxLength(128)]
[Required(ErrorMessage = "表格Id不能为空")]
public virtual string GridId { get; set; }
/// <summary>
/// 冻结列状态数据
/// </summary>
public virtual Dictionary<string, string>? FixedData { get; set; }
/// <summary>
/// 列宽状态数据
/// </summary>
public virtual Dictionary<string, int>? ResizableData { get; set; }
/// <summary>
/// 列顺序数据
/// </summary>
public virtual Dictionary<string, int>? SortData { get; set; }
/// <summary>
/// 显示/隐藏列状态数据
/// </summary>
public virtual Dictionary<string, bool>? VisibleData { get; set; }
}
/// <summary>
/// 重置用户表格列配置输入参数
/// </summary>
public class ResetColumnCustomInput : BaseColumnCustomInput
{
}

View File

@ -0,0 +1,37 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core.Service;
/// <summary>
/// 用户表格列配置输出参数
/// </summary>
public class ColumnCustomOutput
{
/// <summary>
/// 用户Id
/// </summary>
public virtual long UserId { get; set; }
/// <summary>
/// 表格Id
/// </summary>
public virtual string GridId { get; set; }
/// <summary>
/// 冻结列状态数据
/// </summary>
public virtual Dictionary<string, string>? FixedData { get; set; }
/// <summary>
/// 列宽状态数据
/// </summary>
public virtual Dictionary<string, int>? ResizableData { get; set; }
/// <summary>
/// 列顺序数据
/// </summary>
public virtual Dictionary<string, int>? SortData { get; set; }
/// <summary>
/// 显示/隐藏列状态数据
/// </summary>
public virtual Dictionary<string, bool>? VisibleData { get; set; }
}

View File

@ -0,0 +1,80 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core.Service;
/// <summary>
/// 表格列配置服务 🧩
/// </summary>
/// <param name="rep"></param>
/// <param name="um"></param>
/// <param name="cache"></param>
[ApiDescriptionSettings(Order = 440, Description = "代码生成模板配置")]
public class SysColumnCustomService(SqlSugarRepository<SysColumnCustom> rep, UserManager um, SysCacheService cache) : IDynamicApiController, ITransient
{
/// <summary>
/// 获取用户表格列配置信息
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[SuppressMonitor]
[DisplayName("获取用户表格列配置信息")]
public async Task<ColumnCustomOutput> GetDetail([FromQuery] GetColumnCustomInput input)
{
var key = $"{CacheConst.KeyColumnCustom}{um.UserId}:{input.GridId}";
var result = cache.Get<ColumnCustomOutput>(key);
if (result is null)
{
var temp = await rep.GetFirstAsync(e => e.UserId == um.UserId && e.GridId == input.GridId);
if (temp != null)
{
result = new ColumnCustomOutput
{
UserId = temp.UserId,
GridId = temp.GridId,
FixedData = string.IsNullOrEmpty(temp.FixedData) ? null : JSON.Deserialize<Dictionary<string, string>>(temp.FixedData),
ResizableData = string.IsNullOrEmpty(temp.ResizableData) ? null : JSON.Deserialize<Dictionary<string, int>>(temp.ResizableData),
SortData = string.IsNullOrEmpty(temp.SortData) ? null : JSON.Deserialize<Dictionary<string, int>>(temp.SortData),
VisibleData = string.IsNullOrEmpty(temp.VisibleData) ? null : JSON.Deserialize<Dictionary<string, bool>>(temp.VisibleData),
};
cache.Set(key, result, TimeSpan.FromDays(7));
}
}
return result;
}
/// <summary>
/// 保存用户表格列配置信息
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
[DisplayName("保存用户表格列配置信息")]
public async Task Store(StoreColumnCustomInput input)
{
var temp = await rep.GetFirstAsync(e => e.UserId == um.UserId && e.GridId == input.GridId);
if (temp is null) temp = new SysColumnCustom { UserId = um.UserId, GridId = input.GridId };
else cache.Remove($"{CacheConst.KeyColumnCustom}{um.UserId}:{input.GridId}"); //移除缓存
temp.FixedData = JSON.Serialize(input.FixedData);
temp.ResizableData = JSON.Serialize(input.ResizableData);
temp.SortData = JSON.Serialize(input.SortData);
temp.VisibleData = JSON.Serialize(input.VisibleData);
await rep.Context.Storageable(temp).ExecuteCommandAsync();
}
/// <summary>
/// 清除用户表格列配置信息
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
[DisplayName("清除用户表格列配置信息")]
public async Task Reset(ResetColumnCustomInput input)
{
await rep.AsDeleteable().Where(e => e.UserId == um.UserId && e.GridId == input.GridId).ExecuteCommandAsync();
cache.Remove($"{CacheConst.KeyColumnCustom}{um.UserId}:{input.GridId}"); //移除缓存
}
}

View File

@ -22,6 +22,7 @@ export * from './apis/sys-cache-api';
export * from './apis/sys-code-gen-api'; export * from './apis/sys-code-gen-api';
export * from './apis/sys-code-gen-config-api'; export * from './apis/sys-code-gen-config-api';
export * from './apis/sys-code-gen-template-api'; export * from './apis/sys-code-gen-template-api';
export * from './apis/sys-column-custom-api';
export * from './apis/sys-common-api'; export * from './apis/sys-common-api';
export * from './apis/sys-config-api'; export * from './apis/sys-config-api';
export * from './apis/sys-config-tenant-api'; export * from './apis/sys-config-tenant-api';

View File

@ -0,0 +1,310 @@
/* tslint:disable */
/* eslint-disable */
/**
* Admin.NET
* .NET <br/><u><b><font color='FF0000'> 👮</font></b></u>
*
* OpenAPI spec version: 1.0.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import globalAxios, { AxiosResponse, AxiosInstance, AxiosRequestConfig } from 'axios';
import { Configuration } from '../configuration';
// Some imports not used depending on template conditions
// @ts-ignore
import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from '../base';
import { AdminNETResultColumnCustomOutput } from '../models';
import { ResetColumnCustomInput } from '../models';
import { StoreColumnCustomInput } from '../models';
/**
* SysColumnCustomApi - axios parameter creator
* @export
*/
export const SysColumnCustomApiAxiosParamCreator = function (configuration?: Configuration) {
return {
/**
*
* @summary
* @param {string} gridId Id
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
apiSysColumnCustomDetailGet: async (gridId: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'gridId' is not null or undefined
if (gridId === null || gridId === undefined) {
throw new RequiredError('gridId','Required parameter gridId was null or undefined when calling apiSysColumnCustomDetailGet.');
}
const localVarPath = `/api/sysColumnCustom/detail`;
// 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;
}
if (gridId !== undefined) {
localVarQueryParameter['GridId'] = gridId;
}
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
* @param {ResetColumnCustomInput} [body]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
apiSysColumnCustomResetPost: async (body?: ResetColumnCustomInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/sysColumnCustom/reset`;
// 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: 'POST', ...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;
}
localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
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};
const needsSerialization = (typeof body !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
localVarRequestOptions.data = needsSerialization ? JSON.stringify(body !== undefined ? body : {}) : (body || "");
return {
url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
options: localVarRequestOptions,
};
},
/**
*
* @summary
* @param {StoreColumnCustomInput} [body]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
apiSysColumnCustomStorePost: async (body?: StoreColumnCustomInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/sysColumnCustom/store`;
// 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: 'POST', ...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;
}
localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
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};
const needsSerialization = (typeof body !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
localVarRequestOptions.data = needsSerialization ? JSON.stringify(body !== undefined ? body : {}) : (body || "");
return {
url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
options: localVarRequestOptions,
};
},
}
};
/**
* SysColumnCustomApi - functional programming interface
* @export
*/
export const SysColumnCustomApiFp = function(configuration?: Configuration) {
return {
/**
*
* @summary
* @param {string} gridId Id
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async apiSysColumnCustomDetailGet(gridId: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminNETResultColumnCustomOutput>>> {
const localVarAxiosArgs = await SysColumnCustomApiAxiosParamCreator(configuration).apiSysColumnCustomDetailGet(gridId, options);
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
return axios.request(axiosRequestArgs);
};
},
/**
*
* @summary
* @param {ResetColumnCustomInput} [body]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async apiSysColumnCustomResetPost(body?: ResetColumnCustomInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<void>>> {
const localVarAxiosArgs = await SysColumnCustomApiAxiosParamCreator(configuration).apiSysColumnCustomResetPost(body, options);
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
return axios.request(axiosRequestArgs);
};
},
/**
*
* @summary
* @param {StoreColumnCustomInput} [body]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async apiSysColumnCustomStorePost(body?: StoreColumnCustomInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<void>>> {
const localVarAxiosArgs = await SysColumnCustomApiAxiosParamCreator(configuration).apiSysColumnCustomStorePost(body, options);
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
return axios.request(axiosRequestArgs);
};
},
}
};
/**
* SysColumnCustomApi - factory interface
* @export
*/
export const SysColumnCustomApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {
return {
/**
*
* @summary
* @param {string} gridId Id
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async apiSysColumnCustomDetailGet(gridId: string, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminNETResultColumnCustomOutput>> {
return SysColumnCustomApiFp(configuration).apiSysColumnCustomDetailGet(gridId, options).then((request) => request(axios, basePath));
},
/**
*
* @summary
* @param {ResetColumnCustomInput} [body]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async apiSysColumnCustomResetPost(body?: ResetColumnCustomInput, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
return SysColumnCustomApiFp(configuration).apiSysColumnCustomResetPost(body, options).then((request) => request(axios, basePath));
},
/**
*
* @summary
* @param {StoreColumnCustomInput} [body]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async apiSysColumnCustomStorePost(body?: StoreColumnCustomInput, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
return SysColumnCustomApiFp(configuration).apiSysColumnCustomStorePost(body, options).then((request) => request(axios, basePath));
},
};
};
/**
* SysColumnCustomApi - object-oriented interface
* @export
* @class SysColumnCustomApi
* @extends {BaseAPI}
*/
export class SysColumnCustomApi extends BaseAPI {
/**
*
* @summary
* @param {string} gridId Id
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof SysColumnCustomApi
*/
public async apiSysColumnCustomDetailGet(gridId: string, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminNETResultColumnCustomOutput>> {
return SysColumnCustomApiFp(this.configuration).apiSysColumnCustomDetailGet(gridId, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @summary
* @param {ResetColumnCustomInput} [body]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof SysColumnCustomApi
*/
public async apiSysColumnCustomResetPost(body?: ResetColumnCustomInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
return SysColumnCustomApiFp(this.configuration).apiSysColumnCustomResetPost(body, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @summary
* @param {StoreColumnCustomInput} [body]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof SysColumnCustomApi
*/
public async apiSysColumnCustomStorePost(body?: StoreColumnCustomInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
return SysColumnCustomApiFp(this.configuration).apiSysColumnCustomStorePost(body, options).then((request) => request(this.axios, this.basePath));
}
}

View File

@ -0,0 +1,69 @@
/* tslint:disable */
/* eslint-disable */
/**
* Admin.NET
* .NET <br/><u><b><font color='FF0000'> 👮</font></b></u>
*
* OpenAPI spec version: 1.0.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { ColumnCustomOutput } from './column-custom-output';
/**
*
*
* @export
* @interface AdminNETResultColumnCustomOutput
*/
export interface AdminNETResultColumnCustomOutput {
/**
*
*
* @type {number}
* @memberof AdminNETResultColumnCustomOutput
*/
code?: number;
/**
* successwarningerror
*
* @type {string}
* @memberof AdminNETResultColumnCustomOutput
*/
type?: string | null;
/**
*
*
* @type {string}
* @memberof AdminNETResultColumnCustomOutput
*/
message?: string | null;
/**
* @type {ColumnCustomOutput}
* @memberof AdminNETResultColumnCustomOutput
*/
result?: ColumnCustomOutput;
/**
*
*
* @type {any}
* @memberof AdminNETResultColumnCustomOutput
*/
extras?: any | null;
/**
*
*
* @type {Date}
* @memberof AdminNETResultColumnCustomOutput
*/
time?: Date;
}

View File

@ -0,0 +1,70 @@
/* tslint:disable */
/* eslint-disable */
/**
* Admin.NET
* .NET <br/><u><b><font color='FF0000'> 👮</font></b></u>
*
* OpenAPI spec version: 1.0.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
*
*
* @export
* @interface ColumnCustomOutput
*/
export interface ColumnCustomOutput {
/**
* Id
*
* @type {number}
* @memberof ColumnCustomOutput
*/
userId?: number;
/**
* Id
*
* @type {string}
* @memberof ColumnCustomOutput
*/
gridId?: string | null;
/**
*
*
* @type {{ [key: string]: string; }}
* @memberof ColumnCustomOutput
*/
fixedData?: { [key: string]: string; } | null;
/**
*
*
* @type {{ [key: string]: number; }}
* @memberof ColumnCustomOutput
*/
resizableData?: { [key: string]: number; } | null;
/**
*
*
* @type {{ [key: string]: number; }}
* @memberof ColumnCustomOutput
*/
sortData?: { [key: string]: number; } | null;
/**
* /
*
* @type {{ [key: string]: boolean; }}
* @memberof ColumnCustomOutput
*/
visibleData?: { [key: string]: boolean; } | null;
}

View File

@ -27,6 +27,7 @@ export * from './address-family';
export * from './admin-netresult-boolean'; export * from './admin-netresult-boolean';
export * from './admin-netresult-captcha-output'; export * from './admin-netresult-captcha-output';
export * from './admin-netresult-chat-output'; export * from './admin-netresult-chat-output';
export * from './admin-netresult-column-custom-output';
export * from './admin-netresult-create-pay-transaction-native-output'; export * from './admin-netresult-create-pay-transaction-native-output';
export * from './admin-netresult-create-pay-transaction-output'; export * from './admin-netresult-create-pay-transaction-output';
export * from './admin-netresult-data-set'; export * from './admin-netresult-data-set';
@ -181,6 +182,7 @@ export * from './chat-output';
export * from './cluster-status'; export * from './cluster-status';
export * from './code-gen-config'; export * from './code-gen-config';
export * from './code-gen-type-enum'; export * from './code-gen-type-enum';
export * from './column-custom-output';
export * from './column-ouput'; export * from './column-ouput';
export * from './column-relation'; export * from './column-relation';
export * from './compare-info'; export * from './compare-info';
@ -392,6 +394,7 @@ export * from './report-config-output';
export * from './report-config-parse-sql-input'; export * from './report-config-parse-sql-input';
export * from './report-config-parse-sql-output'; export * from './report-config-parse-sql-output';
export * from './report-data-source-output'; export * from './report-data-source-output';
export * from './reset-column-custom-input';
export * from './reset-pwd-user-input'; export * from './reset-pwd-user-input';
export * from './role-api-input'; export * from './role-api-input';
export * from './role-input'; export * from './role-input';
@ -450,6 +453,7 @@ export * from './sql-sugar-paged-list-tenant-output';
export * from './sql-sugar-paged-list-user-output'; export * from './sql-sugar-paged-list-user-output';
export * from './stat-log-output'; export * from './stat-log-output';
export * from './status-enum'; export * from './status-enum';
export * from './store-column-custom-input';
export * from './stress-test-harness-result'; export * from './stress-test-harness-result';
export * from './stress-test-input'; export * from './stress-test-input';
export * from './struct-layout-attribute'; export * from './struct-layout-attribute';

View File

@ -0,0 +1,30 @@
/* tslint:disable */
/* eslint-disable */
/**
* Admin.NET
* .NET <br/><u><b><font color='FF0000'> 👮</font></b></u>
*
* OpenAPI spec version: 1.0.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
*
*
* @export
* @interface ResetColumnCustomInput
*/
export interface ResetColumnCustomInput {
/**
* Id
*
* @type {string}
* @memberof ResetColumnCustomInput
*/
gridId: string;
}

View File

@ -0,0 +1,62 @@
/* tslint:disable */
/* eslint-disable */
/**
* Admin.NET
* .NET <br/><u><b><font color='FF0000'> 👮</font></b></u>
*
* OpenAPI spec version: 1.0.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
*
*
* @export
* @interface StoreColumnCustomInput
*/
export interface StoreColumnCustomInput {
/**
* Id
*
* @type {string}
* @memberof StoreColumnCustomInput
*/
gridId: string;
/**
*
*
* @type {{ [key: string]: string; }}
* @memberof StoreColumnCustomInput
*/
fixedData?: { [key: string]: string; } | null;
/**
*
*
* @type {{ [key: string]: number; }}
* @memberof StoreColumnCustomInput
*/
resizableData?: { [key: string]: number; } | null;
/**
*
*
* @type {{ [key: string]: number; }}
* @memberof StoreColumnCustomInput
*/
sortData?: { [key: string]: number; } | null;
/**
* /
*
* @type {{ [key: string]: boolean; }}
* @memberof StoreColumnCustomInput
*/
visibleData?: { [key: string]: boolean; } | null;
}

View File

@ -4,6 +4,8 @@ import { useThemeConfig } from '/@/stores/themeConfig';
import { merge } from 'lodash-es'; import { merge } from 'lodash-es';
import { VxeGridProps, VxeGridPropTypes, VxeComponentSizeType } from 'vxe-table'; import { VxeGridProps, VxeGridPropTypes, VxeComponentSizeType } from 'vxe-table';
import { VxeTablePropTypes } from 'vxe-pc-ui/types/components/table'; import { VxeTablePropTypes } from 'vxe-pc-ui/types/components/table';
import { getAPI } from '/@/utils/axios-utils';
import { SysColumnCustomApi } from '/@/api-services';
// 根据主题配置获取组件大小 // 根据主题配置获取组件大小
const vxeSize: VxeComponentSizeType = useThemeConfig().themeConfig.globalComponentSize == 'small' ? 'mini' : useThemeConfig().themeConfig.globalComponentSize == 'default' ? 'small' : 'medium'; const vxeSize: VxeComponentSizeType = useThemeConfig().themeConfig.globalComponentSize == 'small' ? 'mini' : useThemeConfig().themeConfig.globalComponentSize == 'default' ? 'small' : 'medium';
@ -15,6 +17,7 @@ const vxeSize: VxeComponentSizeType = useThemeConfig().themeConfig.globalCompone
* @param {Boolean} showFooter ; * @param {Boolean} showFooter ;
* @param {any} footerData ; * @param {any} footerData ;
* @param {VxeTablePropTypes.FooterMethod<any>} footerMethod ; * @param {VxeTablePropTypes.FooterMethod<any>} footerMethod ;
* @param {Boolean} remoteCustom 使;
*/ */
interface iVxeOption { interface iVxeOption {
id?: string; id?: string;
@ -25,6 +28,7 @@ interface iVxeOption {
showFooter?: boolean; showFooter?: boolean;
footerData?: VxeTablePropTypes.FooterData; footerData?: VxeTablePropTypes.FooterData;
footerMethod?: VxeTablePropTypes.FooterMethod<D>; footerMethod?: VxeTablePropTypes.FooterMethod<D>;
remoteCustom?: boolean;
} }
/** /**
@ -35,7 +39,7 @@ interface iVxeOption {
*/ */
export const useVxeTable = <T>(opt: iVxeOption, extras?: VxeGridProps<T>) => { export const useVxeTable = <T>(opt: iVxeOption, extras?: VxeGridProps<T>) => {
// 创建tableId,表格id固定才可以记录调整列宽再次刷新仍有效。 // 创建tableId,表格id固定才可以记录调整列宽再次刷新仍有效。
opt.id = opt.id ? opt.id : String(new Date().getTime()); opt.id = opt.id ? opt.id : opt.name;
const options = reactive<VxeGridProps>({ const options = reactive<VxeGridProps>({
id: opt.id, id: opt.id,
height: 'auto', height: 'auto',
@ -88,6 +92,8 @@ export const useVxeTable = <T>(opt: iVxeOption, extras?: VxeGridProps<T>) => {
// 是否启用 localStorage 本地保存,会将列操作状态保留在本地(需要有 id // 是否启用 localStorage 本地保存,会将列操作状态保留在本地(需要有 id
visible: true, // 启用显示/隐藏列状态 visible: true, // 启用显示/隐藏列状态
resizable: true, // 启用列宽状态 resizable: true, // 启用列宽状态
sort: true, // 启用列顺序缓存
fixed: true, // 启用冻结列状态缓存
}, },
}, },
}); });
@ -112,5 +118,29 @@ export const useVxeTable = <T>(opt: iVxeOption, extras?: VxeGridProps<T>) => {
} else { } else {
options.sortConfig = { remote: true }; options.sortConfig = { remote: true };
} }
if (opt.remoteCustom) {
// 重写默认的恢复自定义配置逻辑
options.customConfig.restoreStore = async ({ id, storeData }) => {
const { data } = await getAPI(SysColumnCustomApi).apiSysColumnCustomDetailGet(id);
if (data.result?.fixedData) storeData.fixedData = data.result.fixedData;
if (data.result?.resizableData) storeData.resizableData = data.result.resizableData;
if (data.result?.sortData) storeData.sortData = data.result.sortData;
if (data.result?.visibleData) storeData.visibleData = data.result.visibleData;
return storeData;
};
// 重写默认的保存方法
options.customConfig.updateStore = async ({ id, type, storeData }) => {
if (type === 'reset') await getAPI(SysColumnCustomApi).apiSysColumnCustomResetPost({ gridId: id });
else {
await getAPI(SysColumnCustomApi).apiSysColumnCustomStorePost({
gridId: id,
fixedData: storeData?.fixedData,
resizableData: storeData?.resizableData,
sortData: storeData?.sortData,
visibleData: storeData?.visibleData,
});
}
};
}
return extras ? merge(options, extras) : options; return extras ? merge(options, extras) : options;
}; };

View File

@ -60,7 +60,7 @@
<script setup lang="ts" name="sysReportGroup"> <script setup lang="ts" name="sysReportGroup">
import { onMounted, reactive, ref, watch } from 'vue'; import { onMounted, reactive, ref, watch } from 'vue';
import { ElMessage, ElMessageBox, ElTree } from 'element-plus'; import { ElMessage, ElMessageBox, ElTree } from 'element-plus';
import { Search, Delete, RefreshRight, MoreFilled } from '@element-plus/icons-vue'; import { Search, MoreFilled } from '@element-plus/icons-vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import EditReportGroup from './editReportGroup.vue'; import EditReportGroup from './editReportGroup.vue';