😎优化报表开发相关

This commit is contained in:
zuohuaijun 2025-08-03 20:04:20 +08:00
parent 5653b52703
commit 552bb47c42
12 changed files with 68 additions and 83 deletions

View File

@ -53,7 +53,7 @@
<PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="3.11.0" /> <PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="3.11.0" />
<PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="3.13.0" /> <PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="3.13.0" />
<PackageReference Include="SqlSugar.MongoDbCore" Version="5.1.4.238" /> <PackageReference Include="SqlSugar.MongoDbCore" Version="5.1.4.238" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.198" /> <PackageReference Include="SqlSugarCore" Version="5.1.4.199" />
<PackageReference Include="SSH.NET" Version="2025.0.0" /> <PackageReference Include="SSH.NET" Version="2025.0.0" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.6.7" /> <PackageReference Include="System.Linq.Dynamic.Core" Version="1.6.7" />
<PackageReference Include="System.Net.Http" Version="4.3.4" /> <PackageReference Include="System.Net.Http" Version="4.3.4" />

View File

@ -4,8 +4,6 @@
// //
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Newtonsoft.Json;
namespace Admin.NET.Core; namespace Admin.NET.Core;
/// <summary> /// <summary>
@ -17,16 +15,4 @@ public class ReportConfigOutput : SysReportConfig
/// 分组名称 /// 分组名称
/// </summary> /// </summary>
public string GroupName { get; set; } public string GroupName { get; set; }
}
/// <summary>
/// 报表配置解析Sql输出参数
/// </summary>
public class ReportConfigParseSqlOutput
{
/// <summary>
/// 报表字段名称集合
/// </summary>
[JsonConverter(typeof(CamelCaseValueConverter))]
public List<string> FieldNames { get; set; }
} }

View File

@ -40,6 +40,11 @@ public class SysReportField
/// </summary> /// </summary>
public string Title { get; set; } public string Title { get; set; }
/// <summary>
/// 数据类型
/// </summary>
public string DataType { get; set; }
/// <summary> /// <summary>
/// 是否合计 /// 是否合计
/// </summary> /// </summary>

View File

@ -144,15 +144,21 @@ public class SysReportConfigService : IDynamicApiController, ITransient
/// <param name="input">输入参数</param> /// <param name="input">输入参数</param>
[ApiDescriptionSettings(Name = "ParseSql"), HttpPost] [ApiDescriptionSettings(Name = "ParseSql"), HttpPost]
[DisplayName("解析报表配置Sql")] [DisplayName("解析报表配置Sql")]
public async Task<ReportConfigParseSqlOutput> ParseSql(ReportConfigParseSqlInput input) public async Task<List<SysReportField>> ParseSql(ReportConfigParseSqlInput input)
{ {
var dataTable = await InnerExecuteSqlScript(input.DataSource, input.SqlScript, input.ExecParams); var dataTable = await InnerExecuteSqlScript(input.DataSource, input.SqlScript, input.ExecParams);
var fieldNames = (from DataColumn column in dataTable.Columns select column.ColumnName).ToList();
return new ReportConfigParseSqlOutput var reportFieldList = new List<SysReportField>();
foreach (DataColumn field in dataTable.Columns)
{ {
FieldNames = fieldNames reportFieldList.Add(new SysReportField
}; {
FieldName = field.ColumnName,
DataType = field.DataType.ToString(),
Visible = !CodeGenHelper.IsCommonColumn(field.ColumnName)
});
}
return reportFieldList;
} }
/// <summary> /// <summary>

View File

@ -26,7 +26,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" /> <PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.14.0" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.14.0" />
<PackageReference Include="Rezero.Api" Version="1.8.24" /> <PackageReference Include="Rezero.Api" Version="1.8.25" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -20,7 +20,7 @@ import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } fr
import { AddReportConfigInput } from '../models'; import { AddReportConfigInput } from '../models';
import { AdminNETResultFileStreamResult } from '../models'; import { AdminNETResultFileStreamResult } from '../models';
import { AdminNETResultListDictionaryStringObject } from '../models'; import { AdminNETResultListDictionaryStringObject } from '../models';
import { AdminNETResultReportConfigParseSqlOutput } from '../models'; import { AdminNETResultListSysReportField } from '../models';
import { AdminNETResultSqlSugarPagedListReportConfigOutput } from '../models'; import { AdminNETResultSqlSugarPagedListReportConfigOutput } from '../models';
import { AdminNETResultSysReportLayoutConfig } from '../models'; import { AdminNETResultSysReportLayoutConfig } from '../models';
import { BaseIdInput } from '../models'; import { BaseIdInput } from '../models';
@ -584,7 +584,7 @@ export const SysReportConfigApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async apiSysReportConfigParseSqlPost(body?: ReportConfigParseSqlInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminNETResultReportConfigParseSqlOutput>>> { async apiSysReportConfigParseSqlPost(body?: ReportConfigParseSqlInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminNETResultListSysReportField>>> {
const localVarAxiosArgs = await SysReportConfigApiAxiosParamCreator(configuration).apiSysReportConfigParseSqlPost(body, options); const localVarAxiosArgs = await SysReportConfigApiAxiosParamCreator(configuration).apiSysReportConfigParseSqlPost(body, options);
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url}; const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
@ -691,7 +691,7 @@ export const SysReportConfigApiFactory = function (configuration?: Configuration
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async apiSysReportConfigParseSqlPost(body?: ReportConfigParseSqlInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminNETResultReportConfigParseSqlOutput>> { async apiSysReportConfigParseSqlPost(body?: ReportConfigParseSqlInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminNETResultListSysReportField>> {
return SysReportConfigApiFp(configuration).apiSysReportConfigParseSqlPost(body, options).then((request) => request(axios, basePath)); return SysReportConfigApiFp(configuration).apiSysReportConfigParseSqlPost(body, options).then((request) => request(axios, basePath));
}, },
/** /**
@ -799,7 +799,7 @@ export class SysReportConfigApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof SysReportConfigApi * @memberof SysReportConfigApi
*/ */
public async apiSysReportConfigParseSqlPost(body?: ReportConfigParseSqlInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminNETResultReportConfigParseSqlOutput>> { public async apiSysReportConfigParseSqlPost(body?: ReportConfigParseSqlInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminNETResultListSysReportField>> {
return SysReportConfigApiFp(this.configuration).apiSysReportConfigParseSqlPost(body, options).then((request) => request(this.axios, this.basePath)); return SysReportConfigApiFp(this.configuration).apiSysReportConfigParseSqlPost(body, options).then((request) => request(this.axios, this.basePath));
} }
/** /**

View File

@ -12,20 +12,20 @@
* Do not edit the class manually. * Do not edit the class manually.
*/ */
import { ReportConfigParseSqlOutput } from './report-config-parse-sql-output'; import { SysReportField } from './sys-report-field';
/** /**
* *
* *
* @export * @export
* @interface AdminNETResultReportConfigParseSqlOutput * @interface AdminNETResultListSysReportField
*/ */
export interface AdminNETResultReportConfigParseSqlOutput { export interface AdminNETResultListSysReportField {
/** /**
* *
* *
* @type {number} * @type {number}
* @memberof AdminNETResultReportConfigParseSqlOutput * @memberof AdminNETResultListSysReportField
*/ */
code?: number; code?: number;
@ -33,7 +33,7 @@ export interface AdminNETResultReportConfigParseSqlOutput {
* successwarningerror * successwarningerror
* *
* @type {string} * @type {string}
* @memberof AdminNETResultReportConfigParseSqlOutput * @memberof AdminNETResultListSysReportField
*/ */
type?: string | null; type?: string | null;
@ -41,21 +41,23 @@ export interface AdminNETResultReportConfigParseSqlOutput {
* *
* *
* @type {string} * @type {string}
* @memberof AdminNETResultReportConfigParseSqlOutput * @memberof AdminNETResultListSysReportField
*/ */
message?: string | null; message?: string | null;
/** /**
* @type {ReportConfigParseSqlOutput} *
* @memberof AdminNETResultReportConfigParseSqlOutput *
* @type {Array<SysReportField>}
* @memberof AdminNETResultListSysReportField
*/ */
result?: ReportConfigParseSqlOutput; result?: Array<SysReportField> | null;
/** /**
* *
* *
* @type {any} * @type {any}
* @memberof AdminNETResultReportConfigParseSqlOutput * @memberof AdminNETResultListSysReportField
*/ */
extras?: any | null; extras?: any | null;
@ -63,7 +65,7 @@ export interface AdminNETResultReportConfigParseSqlOutput {
* *
* *
* @type {Date} * @type {Date}
* @memberof AdminNETResultReportConfigParseSqlOutput * @memberof AdminNETResultListSysReportField
*/ */
time?: Date; time?: Date;
} }

View File

@ -82,6 +82,7 @@ export * from './admin-netresult-list-sys-menu';
export * from './admin-netresult-list-sys-notice'; export * from './admin-netresult-list-sys-notice';
export * from './admin-netresult-list-sys-org'; export * from './admin-netresult-list-sys-org';
export * from './admin-netresult-list-sys-region'; export * from './admin-netresult-list-sys-region';
export * from './admin-netresult-list-sys-report-field';
export * from './admin-netresult-list-sys-report-group'; export * from './admin-netresult-list-sys-report-group';
export * from './admin-netresult-list-sys-schedule'; export * from './admin-netresult-list-sys-schedule';
export * from './admin-netresult-list-sys-user'; export * from './admin-netresult-list-sys-user';
@ -95,7 +96,6 @@ export * from './admin-netresult-login-user-output';
export * from './admin-netresult-model-list-output'; export * from './admin-netresult-model-list-output';
export * from './admin-netresult-notice-output'; export * from './admin-netresult-notice-output';
export * from './admin-netresult-object'; export * from './admin-netresult-object';
export * from './admin-netresult-report-config-parse-sql-output';
export * from './admin-netresult-sm-key-pair-output'; export * from './admin-netresult-sm-key-pair-output';
export * from './admin-netresult-sql-sugar-paged-list-chat-list-output'; export * from './admin-netresult-sql-sugar-paged-list-chat-list-output';
export * from './admin-netresult-sql-sugar-paged-list-job-detail-output'; export * from './admin-netresult-sql-sugar-paged-list-job-detail-output';
@ -393,7 +393,6 @@ export * from './report-config-ds-type-enum';
export * from './report-config-execute-sql-script-input'; export * from './report-config-execute-sql-script-input';
export * from './report-config-output'; 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-data-source-output'; export * from './report-data-source-output';
export * from './reset-column-custom-input'; export * from './reset-column-custom-input';
export * from './reset-pwd-user-input'; export * from './reset-pwd-user-input';

View File

@ -1,30 +0,0 @@
/* 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.
*/
/**
* Sql输出参数
*
* @export
* @interface ReportConfigParseSqlOutput
*/
export interface ReportConfigParseSqlOutput {
/**
*
*
* @type {Array<string>}
* @memberof ReportConfigParseSqlOutput
*/
fieldNames?: Array<string> | null;
}

View File

@ -36,6 +36,14 @@ export interface SysReportField {
*/ */
title?: string | null; title?: string | null;
/**
*
*
* @type {string}
* @memberof SysReportField
*/
dataType?: string | null;
/** /**
* *
* *

View File

@ -42,7 +42,7 @@
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20" :style="[state.ruleForm.dsType === ReportConfigDsTypeEnum.NUMBER_0 ? '' : 'display:none;']"> <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20" :style="[state.ruleForm.dsType === ReportConfigDsTypeEnum.NUMBER_0 ? '' : 'display:none;']">
<el-form-item :label="$t('脚本语句')" prop="sqlScript"> <el-form-item :label="$t('脚本语句')" prop="sqlScript">
<div ref="sqlScriptMonacoEditorRef" style="width: 100%; height: 300px; border: 1px solid var(--el-border-color)"></div> <div ref="sqlScriptMonacoEditorRef" style="width: 100%; height: 300px; border: 1px solid var(--el-border-color)"></div>
<el-button ref="parseSqlButtonRef" type="success" plain style="margin-top: 8px" @click="parseSqlClick">{{ $t('解析Sql') }}</el-button> <el-button ref="parseSqlButtonRef" type="primary" icon="ele-Position" plain style="margin-top: 8px" @click="parseSqlClick">{{ $t('解析Sql') }}</el-button>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8" class="mb20" v-if="state.ruleForm.dsType === ReportConfigDsTypeEnum.NUMBER_1"> <el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8" class="mb20" v-if="state.ruleForm.dsType === ReportConfigDsTypeEnum.NUMBER_1">
@ -77,10 +77,10 @@
</template> </template>
<template #toolbar_tools> </template> <template #toolbar_tools> </template>
<template #row_isSummary="{ row }"> <template #row_isSummary="{ row }">
{{ row.isSummary ? '√' : '' }} <el-switch v-model="row.isSummary" :active-value="true" :inactive-value="false" size="small" />
</template> </template>
<template #row_visible="{ row }"> <template #row_visible="{ row }">
{{ row.visible ? '√' : '' }} <el-switch v-model="row.visible" :active-value="true" :inactive-value="false" size="small" />
</template> </template>
</vxe-grid> </vxe-grid>
</el-tab-pane> </el-tab-pane>
@ -274,8 +274,9 @@ const fieldConfig = reactive({
{ type: 'checkbox', width: 60, fixed: 'left' }, { type: 'checkbox', width: 60, fixed: 'left' },
{ field: 'fieldName', title: t('字段名'), editRender: { name: 'ElInput', props: { size: 'small' } }, dragSort: true }, { field: 'fieldName', title: t('字段名'), editRender: { name: 'ElInput', props: { size: 'small' } }, dragSort: true },
{ field: 'title', title: t('字段标题'), editRender: { name: 'ElInput', props: { size: 'small' } } }, { field: 'title', title: t('字段标题'), editRender: { name: 'ElInput', props: { size: 'small' } } },
{ field: 'isSummary', title: t('是否合计'), editRender: { name: 'ElSwitch', props: { size: 'small' } }, slots: { default: 'row_isSummary' } }, { field: 'dataType', title: t('数据类型') },
{ field: 'visible', title: t('是否显示'), editRender: { name: 'ElSwitch', props: { size: 'small' } }, slots: { default: 'row_visible' } }, { field: 'isSummary', title: t('是否合计'), slots: { default: 'row_isSummary' } },
{ field: 'visible', title: t('是否显示'), slots: { default: 'row_visible' } },
{ field: 'groupTitle', title: t('分组标题'), editRender: { name: 'ElInput', props: { size: 'small' } } }, { field: 'groupTitle', title: t('分组标题'), editRender: { name: 'ElInput', props: { size: 'small' } } },
{ field: 'width', title: t('列宽'), editRender: { name: 'ElInputNumber', props: { size: 'small', min: 0, controlsPosition: 'right' } } }, { field: 'width', title: t('列宽'), editRender: { name: 'ElInputNumber', props: { size: 'small', min: 0, controlsPosition: 'right' } } },
], ],
@ -498,12 +499,13 @@ const parseSqlClick = () => {
ElMessage.success('解析成功'); ElMessage.success('解析成功');
const fieldList = vFieldGrid.value!.getFullData(); const fieldList = vFieldGrid.value!.getFullData();
const fieldNames = res.data.result?.fieldNames ?? []; const reportFieldList = res.data.result ?? [];
console.log(reportFieldList);
fieldNames.forEach((fieldName: string) => { reportFieldList.forEach((reportField: SysReportField) => {
if (fieldList.some((field) => field.fieldName === fieldName)) return; if (fieldList.some((field) => field.fieldName === reportField.fieldName)) return;
const field: SysReportField = { fieldName: fieldName, isSummary: false, visible: true, width: 0 }; const field: SysReportField = { fieldName: reportField.fieldName, title: reportField.title, dataType: reportField.dataType, isSummary: false, visible: reportField.visible, width: 0 };
vFieldGrid.value!.insertAt(field, -1); vFieldGrid.value!.insertAt(field, -1);
}); });
}); });

View File

@ -8,6 +8,9 @@
<vxe-grid ref="xGrid" v-bind="options" :loading="state.isLoading"> <vxe-grid ref="xGrid" v-bind="options" :loading="state.isLoading">
<!-- <template #top> <!-- <template #top>
</template> --> </template> -->
<template #row_record="{ row }">
<ModifyRecord :data="row" />
</template>
<template #toolbar_buttons> <template #toolbar_buttons>
<el-button type="primary" icon="ele-FolderOpened" @click="handleExport"> {{ $t('导出') }} </el-button> <el-button type="primary" icon="ele-FolderOpened" @click="handleExport"> {{ $t('导出') }} </el-button>
</template> </template>
@ -25,12 +28,13 @@ import { useVxeTable } from '/@/hooks/useVxeTableOptionsHook';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import TableSearch from '/@/components/table/search.vue'; import TableSearch from '/@/components/table/search.vue';
// import { downloadByData, getFileName } from '/@/utils/download'; import { downloadByData, getFileName } from '/@/utils/download';
import ModifyRecord from '/@/components/table/modifyRecord.vue';
import { getAPI } from '/@/utils/axios-utils'; import { getAPI } from '/@/utils/axios-utils';
import { SysReportConfigApi } from '/@/api-services/api'; import { SysReportConfigApi } from '/@/api-services/api';
import { SysReportField, SysReportLayoutConfig, SysReportParam } from '/@/api-services/models'; import { SysReportField, SysReportLayoutConfig, SysReportParam } from '/@/api-services/models';
import { downloadByData, getFileName } from '/@/utils/download';
const { t } = useI18n(); const { t } = useI18n();
@ -97,6 +101,9 @@ onBeforeMount(() => {
groupColumn.children!.push(column); groupColumn.children!.push(column);
}); });
//
newColumn.push({ field: 'record', title: t('message.list.record'), width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } });
options.columns!.push(...newColumn); options.columns!.push(...newColumn);
} }
@ -135,9 +142,9 @@ const options = useVxeTable<any>(
{ {
// //
proxyConfig: { autoLoad: true, ajax: { query: ({ page, sort }) => handleQueryApi(page, sort) } }, proxyConfig: { autoLoad: true, ajax: { query: ({ page, sort }) => handleQueryApi(page, sort) } },
columnConfig: { // columnConfig: {
width: 100, // // width: 100, //
}, // },
pagerConfig: { enabled: false }, pagerConfig: { enabled: false },
showFooter: false, showFooter: false,
footerMethod: footerMethod, footerMethod: footerMethod,
@ -194,7 +201,7 @@ const convertSysReportFieldToVxeColumn = (column: SysReportField): VxeTableDefin
return { return {
field: column.fieldName, field: column.fieldName,
title: column.title ?? column.fieldName, title: column.title ?? column.fieldName,
width: column.width ? column.width : undefined, width: column.width && column.width > 0 ? column.width : undefined,
visible: column.visible, visible: column.visible,
} as VxeTableDefines.ColumnOptions; } as VxeTableDefines.ColumnOptions;
}; };