😎1、增加访问IP黑名单限流 2、代码整理 3、升级依赖

This commit is contained in:
zuohuaijun 2024-08-30 12:36:39 +08:00
parent 1d3c1d6512
commit 9685e789fb
25 changed files with 557 additions and 140 deletions

View File

@ -21,7 +21,7 @@
//
"ClientWhitelist": [],
"QuotaExceededResponse": {
"Content": "{{\"code\":429,\"type\":\"error\",\"message\":\"访问过于频繁,请稍后重试!\",\"result\":null,\"extras\":null}}",
"Content": "{{\"code\":429,\"type\":\"error\",\"message\":\"访问过于频繁,请稍后重试禁止违法行为否则110 👮\",\"result\":null,\"extras\":null}}",
"ContentType": "application/json",
"StatusCode": 429
},
@ -29,46 +29,42 @@
"HttpStatusCode": 429,
// API,*
"GeneralRules": [
// 110
// 11000
{
"Endpoint": "*",
"Period": "1s",
"Limit": 10
"Limit": 1000
},
// 1600
// 160000
{
"Endpoint": "*",
"Period": "1m",
"Limit": 600
},
// 13600
{
"Endpoint": "*",
"Period": "1h",
"Limit": 3600
},
// 186400
{
"Endpoint": "*",
"Period": "1d",
"Limit": 86400
"Limit": 60000
}
//// 13600000
//{
// "Endpoint": "*",
// "Period": "1h",
// "Limit": 3600000
//},
//// 186400000
//{
// "Endpoint": "*",
// "Period": "1d",
// "Limit": 86400000
//}
]
},
// IP
"IpRateLimitPolicies": {
"IpRules": [
{
"Ip": "XXX.XXX.XXX.XXX",
"Ip": "0.0.0.0", // IP"::1/10"
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 10
},
{
"Endpoint": "*",
"Period": "1m",
"Limit": 600
"Limit": 0 // 01
}
]
}
@ -90,29 +86,19 @@
{
"Endpoint": "*",
"Period": "1s",
"Limit": 10
},
{
"Endpoint": "*",
"Period": "1m",
"Limit": 600
"Limit": 2000
}
]
},
"ClientRateLimitPolicies": {
"ClientRules": [
{
"ClientId": "xxx-xxx",
"ClientId": "",
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 10
},
{
"Endpoint": "*",
"Period": "1m",
"Limit": 600
"Limit": 2000
}
]
}

View File

@ -21,7 +21,7 @@
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.5.5" />
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.5.5" />
<PackageReference Include="Furion.Pure" Version="4.9.5.5" />
<PackageReference Include="Hardware.Info" Version="100.1.0.1" />
<PackageReference Include="Hardware.Info" Version="100.1.1" />
<PackageReference Include="Hashids.net" Version="1.7.0" />
<PackageReference Include="IPTools.China" Version="1.6.0" />
<PackageReference Include="IPTools.International" Version="1.6.0" />
@ -40,7 +40,7 @@
<PackageReference Include="SqlSugarCore" Version="5.1.4.167" />
<PackageReference Include="SSH.NET" Version="2024.1.0" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.4.5" />
<PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1078" />
<PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1079" />
<PackageReference Include="UAParser" Version="3.1.47" />
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
</ItemGroup>

View File

@ -0,0 +1,26 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using AspNetCoreRateLimit;
using Microsoft.AspNetCore.Builder;
namespace Admin.NET.Core;
/// <summary>
/// 配置中间件扩展
/// </summary>
public static class UseApplicationBuilder
{
// 配置限流中间件策略
public static void UsePolicyRateLimit(this IApplicationBuilder app)
{
var ipPolicyStore = app.ApplicationServices.GetRequiredService<IIpPolicyStore>();
ipPolicyStore.SeedAsync().GetAwaiter().GetResult();
var clientPolicyStore = app.ApplicationServices.GetRequiredService<IClientPolicyStore>();
clientPolicyStore.SeedAsync().GetAwaiter().GetResult();
}
}

View File

@ -4,14 +4,12 @@
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Microsoft.AspNetCore.Server.IISIntegration;
namespace Admin.NET.Core;
/// <summary>
/// 代码生成模板配置表种子数据
/// </summary>
public class SysCodeGenTemplateSeedData : ISqlSugarEntitySeedData<SysCodeGenTemplate>
public class SysCodeGenTemplateSeedData : ISqlSugarEntitySeedData<SysCodeGenTemplate>
{
/// <summary>
/// 种子数据

View File

@ -84,7 +84,6 @@ public class SysCodeGenService : IDynamicApiController, ITransient
/// <returns></returns>
private List<SysCodeGenTemplateRelation> GetCodeGenTemplateRelation(long codeGenId, List<long> templateIds)
{
List<SysCodeGenTemplateRelation> list = new List<SysCodeGenTemplateRelation>();
foreach (var item in templateIds)
{
@ -96,8 +95,6 @@ public class SysCodeGenService : IDynamicApiController, ITransient
return list;
}
/// <summary>
/// 更新代码生成 🔖
/// </summary>
@ -138,7 +135,7 @@ public class SysCodeGenService : IDynamicApiController, ITransient
inputs.ForEach(u =>
{
//_db.Deleteable<SysCodeGen>().In(u.Id).ExecuteCommand();
_db.DeleteNav<SysCodeGen>(t=>t.Id==u.Id)
_db.DeleteNav<SysCodeGen>(t => t.Id == u.Id)
.Include(t => t.CodeGenTemplateRelations)
.ExecuteCommand();

View File

@ -13,6 +13,7 @@ namespace Admin.NET.Core.Service;
public class SysCodeGenTemplateService : IDynamicApiController, ITransient
{
private readonly SqlSugarRepository<SysCodeGenTemplate> _codeGenTemplateRep;
public SysCodeGenTemplateService(SqlSugarRepository<SysCodeGenTemplate> codeGenTemplateRep)
{
_codeGenTemplateRep = codeGenTemplateRep;
@ -28,4 +29,4 @@ public class SysCodeGenTemplateService : IDynamicApiController, ITransient
{
return await _codeGenTemplateRep.AsQueryable().Select<SysCodeGenTemplate>().ToListAsync();
}
}
}

View File

@ -109,6 +109,7 @@ public class SysServerService : IDynamicApiController, ITransient
var giteeAuthenticationOptionsAssembly = typeof(AspNet.Security.OAuth.Gitee.GiteeAuthenticationOptions).Assembly.GetName();
var hashidsAssembly = typeof(HashidsNet.Hashids).Assembly.GetName();
var sftpClientAssembly = typeof(Renci.SshNet.SftpClient).Assembly.GetName();
var hardwareInfoAssembly = typeof(Hardware.Info.HardwareInfo).Assembly.GetName();
return new[]
{
@ -140,6 +141,7 @@ public class SysServerService : IDynamicApiController, ITransient
new { giteeAuthenticationOptionsAssembly.Name, giteeAuthenticationOptionsAssembly.Version },
new { hashidsAssembly.Name, hashidsAssembly.Version },
new { sftpClientAssembly.Name, sftpClientAssembly.Version },
new { hardwareInfoAssembly.Name, hardwareInfoAssembly.Version },
};
}
}

View File

@ -262,6 +262,7 @@ public class Startup : AppStartup
// 限流组件(在跨域之后)
app.UseIpRateLimiting();
app.UseClientRateLimiting();
app.UsePolicyRateLimit();
// 任务调度看板
app.UseScheduleUI(options =>

View File

@ -2,7 +2,7 @@
"name": "admin.net.pro",
"type": "module",
"version": "2.4.33",
"lastBuildTime": "2024.08.27",
"lastBuildTime": "2024.08.30",
"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",
"author": "zuohuaijun",
"license": "MIT",
@ -41,7 +41,7 @@
"js-table2excel": "^1.1.2",
"jsplumb": "^2.15.6",
"lodash-es": "^4.17.21",
"md-editor-v3": "^4.19.1",
"md-editor-v3": "^4.19.2",
"mitt": "^3.0.1",
"monaco-editor": "^0.51.0",
"mqtt": "^4.3.8",
@ -70,7 +70,7 @@
"vue-router": "^4.4.3",
"vue-signature-pad": "^3.0.2",
"vue3-tree-org": "^4.2.2",
"vxe-pc-ui": "^4.1.8",
"vxe-pc-ui": "^4.1.12",
"vxe-table": "^4.7.59",
"vxe-table-plugin-element": "^4.0.4",
"vxe-table-plugin-export-xlsx": "^4.0.5",
@ -86,7 +86,7 @@
"@types/sortablejs": "^1.15.8",
"@typescript-eslint/eslint-plugin": "^8.3.0",
"@typescript-eslint/parser": "^8.3.0",
"@vitejs/plugin-vue": "^5.1.2",
"@vitejs/plugin-vue": "^5.1.3",
"@vitejs/plugin-vue-jsx": "^4.0.1",
"@vue/compiler-sfc": "^3.4.38",
"code-inspector-plugin": "^0.16.0",

View File

@ -16,6 +16,7 @@ export * from './apis/sys-auth-api';
export * from './apis/sys-cache-api';
export * from './apis/sys-code-gen-api';
export * from './apis/sys-code-gen-config-api';
export * from './apis/sys-code-gen-template-api';
export * from './apis/sys-common-api';
export * from './apis/sys-config-api';
export * from './apis/sys-const-api';

View File

@ -0,0 +1,130 @@
/* 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 { AdminResultListSysCodeGenTemplate } from '../models';
/**
* SysCodeGenTemplateApi - axios parameter creator
* @export
*/
export const SysCodeGenTemplateApiAxiosParamCreator = function (configuration?: Configuration) {
return {
/**
*
* @summary
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
apiSysCodeGenTemplateListGet: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/sysCodeGenTemplate/list`;
// 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,
};
},
}
};
/**
* SysCodeGenTemplateApi - functional programming interface
* @export
*/
export const SysCodeGenTemplateApiFp = function(configuration?: Configuration) {
return {
/**
*
* @summary
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async apiSysCodeGenTemplateListGet(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultListSysCodeGenTemplate>>> {
const localVarAxiosArgs = await SysCodeGenTemplateApiAxiosParamCreator(configuration).apiSysCodeGenTemplateListGet(options);
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
return axios.request(axiosRequestArgs);
};
},
}
};
/**
* SysCodeGenTemplateApi - factory interface
* @export
*/
export const SysCodeGenTemplateApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {
return {
/**
*
* @summary
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async apiSysCodeGenTemplateListGet(options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultListSysCodeGenTemplate>> {
return SysCodeGenTemplateApiFp(configuration).apiSysCodeGenTemplateListGet(options).then((request) => request(axios, basePath));
},
};
};
/**
* SysCodeGenTemplateApi - object-oriented interface
* @export
* @class SysCodeGenTemplateApi
* @extends {BaseAPI}
*/
export class SysCodeGenTemplateApi extends BaseAPI {
/**
*
* @summary
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof SysCodeGenTemplateApi
*/
public async apiSysCodeGenTemplateListGet(options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultListSysCodeGenTemplate>> {
return SysCodeGenTemplateApiFp(this.configuration).apiSysCodeGenTemplateListGet(options).then((request) => request(this.axios, this.basePath));
}
}

View File

@ -241,4 +241,12 @@ export interface AddCodeGenInput {
* @memberof AddCodeGenInput
*/
isApiService?: boolean;
/**
* Id集合
*
* @type {Array<number>}
* @memberof AddCodeGenInput
*/
codeGenTemplateIds?: Array<number> | null;
}

View File

@ -0,0 +1,71 @@
/* 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 { SysCodeGenTemplate } from './sys-code-gen-template';
/**
*
*
* @export
* @interface AdminResultListSysCodeGenTemplate
*/
export interface AdminResultListSysCodeGenTemplate {
/**
*
*
* @type {number}
* @memberof AdminResultListSysCodeGenTemplate
*/
code?: number;
/**
* successwarningerror
*
* @type {string}
* @memberof AdminResultListSysCodeGenTemplate
*/
type?: string | null;
/**
*
*
* @type {string}
* @memberof AdminResultListSysCodeGenTemplate
*/
message?: string | null;
/**
*
*
* @type {Array<SysCodeGenTemplate>}
* @memberof AdminResultListSysCodeGenTemplate
*/
result?: Array<SysCodeGenTemplate> | null;
/**
*
*
* @type {any}
* @memberof AdminResultListSysCodeGenTemplate
*/
extras?: any | null;
/**
*
*
* @type {Date}
* @memberof AdminResultListSysCodeGenTemplate
*/
time?: Date;
}

View File

@ -0,0 +1,24 @@
/* 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.
*/
/**
* <br />&nbsp; Frontend = 1<br />&nbsp; Backend = 2<br />
* @export
* @enum {string}
*/
export enum CodeGenTypeEnum {
NUMBER_1 = 1,
NUMBER_2 = 2
}

View File

@ -48,6 +48,7 @@ export * from './admin-result-list-menu-output';
export * from './admin-result-list-pos-output';
export * from './admin-result-list-role-output';
export * from './admin-result-list-string';
export * from './admin-result-list-sys-code-gen-template';
export * from './admin-result-list-sys-config';
export * from './admin-result-list-sys-dict-data';
export * from './admin-result-list-sys-dict-type';
@ -124,6 +125,7 @@ export * from './card-type-enum';
export * from './change-pwd-input';
export * from './cluster-status';
export * from './code-gen-config';
export * from './code-gen-type-enum';
export * from './column-ouput';
export * from './column-relation';
export * from './compare-info';
@ -335,6 +337,8 @@ export * from './sync-input';
export * from './sync-sys-ldap-input';
export * from './sys-code-gen';
export * from './sys-code-gen-config';
export * from './sys-code-gen-template';
export * from './sys-code-gen-template-relation';
export * from './sys-config';
export * from './sys-dict-data';
export * from './sys-dict-type';

View File

@ -0,0 +1,46 @@
/* 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 SysCodeGenTemplateRelation
*/
export interface SysCodeGenTemplateRelation {
/**
* Id
*
* @type {number}
* @memberof SysCodeGenTemplateRelation
*/
id?: number;
/**
* Id
*
* @type {number}
* @memberof SysCodeGenTemplateRelation
*/
codeGenId: number;
/**
* Id
*
* @type {number}
* @memberof SysCodeGenTemplateRelation
*/
templateId: number;
}

View File

@ -0,0 +1,140 @@
/* 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 { CodeGenTypeEnum } from './code-gen-type-enum';
import { YesNoEnum } from './yes-no-enum';
/**
*
*
* @export
* @interface SysCodeGenTemplate
*/
export interface SysCodeGenTemplate {
/**
* Id
*
* @type {number}
* @memberof SysCodeGenTemplate
*/
id?: number;
/**
*
*
* @type {Date}
* @memberof SysCodeGenTemplate
*/
createTime?: Date;
/**
*
*
* @type {Date}
* @memberof SysCodeGenTemplate
*/
updateTime?: Date | null;
/**
* Id
*
* @type {number}
* @memberof SysCodeGenTemplate
*/
createUserId?: number | null;
/**
*
*
* @type {string}
* @memberof SysCodeGenTemplate
*/
createUserName?: string | null;
/**
* Id
*
* @type {number}
* @memberof SysCodeGenTemplate
*/
updateUserId?: number | null;
/**
*
*
* @type {string}
* @memberof SysCodeGenTemplate
*/
updateUserName?: string | null;
/**
*
*
* @type {boolean}
* @memberof SysCodeGenTemplate
*/
isDelete?: boolean;
/**
*
*
* @type {string}
* @memberof SysCodeGenTemplate
*/
name: string;
/**
* @type {CodeGenTypeEnum}
* @memberof SysCodeGenTemplate
*/
type?: CodeGenTypeEnum;
/**
* @type {YesNoEnum}
* @memberof SysCodeGenTemplate
*/
sysFlag?: YesNoEnum;
/**
*
*
* @type {boolean}
* @memberof SysCodeGenTemplate
*/
isDefault?: boolean | null;
/**
*
*
* @type {string}
* @memberof SysCodeGenTemplate
*/
outputFile: string;
/**
*
*
* @type {string}
* @memberof SysCodeGenTemplate
*/
describe: string;
/**
*
*
* @type {number}
* @memberof SysCodeGenTemplate
*/
orderNo?: number;
}

View File

@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { SysCodeGenTemplateRelation } from './sys-code-gen-template-relation';
/**
*
*
@ -219,4 +220,12 @@ export interface SysCodeGen {
* @memberof SysCodeGen
*/
isApiService?: boolean;
/**
*
*
* @type {Array<SysCodeGenTemplateRelation>}
* @memberof SysCodeGen
*/
codeGenTemplateRelations?: Array<SysCodeGenTemplateRelation> | null;
}

View File

@ -242,6 +242,14 @@ export interface UpdateCodeGenInput {
*/
isApiService?: boolean;
/**
* Id集合
*
* @type {Array<number>}
* @memberof UpdateCodeGenInput
*/
codeGenTemplateIds?: Array<number> | null;
/**
* Id
*
@ -249,12 +257,4 @@ export interface UpdateCodeGenInput {
* @memberof UpdateCodeGenInput
*/
id: number;
/**
*
*
* @type {any[]}
* @memberof UpdateCodeGenInput
*/
codeGenTemplateRelations:any[];
}

View File

@ -190,7 +190,7 @@ export function verifyNumberCnUppercase(val: any, unit = '仟佰拾亿仟佰拾
*/
export function verifyPhone(val: string) {
// false: 手机号码不正确
if (!/^((12[0-9])|(13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0|1,5-9]))\d{8}$/.test(val)) return false;
if (!/^1[3456789][0-9]{9}$/.test(val)) return false;
// true: 手机号码正确
else return true;
}

View File

@ -3,8 +3,7 @@
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="700px">
<template #header>
<div style="color: #fff">
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit />
</el-icon>
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
<span> {{ props.title }} </span>
</div>
</template>
@ -18,18 +17,14 @@
<el-row :gutter="10">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="库定位器" prop="configId">
<el-select v-model="state.ruleForm.configId" placeholder="库名" filterable
@change="dbChanged()" class="w100">
<el-option v-for="item in state.dbData" :key="item.configId"
:label="item.configId" :value="item.configId" />
<el-select v-model="state.ruleForm.configId" placeholder="库名" filterable @change="dbChanged()" class="w100">
<el-option v-for="item in state.dbData" :key="item.configId" :label="item.configId" :value="item.configId" />
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="库类型" prop="dbType"
:rules="[{ required: true, message: '描述不能为空', trigger: 'blur' }]">
<el-select v-model="state.ruleForm.dbType" placeholder="数据库类型" filterable clearable
disabled class="w100">
<el-form-item label="库类型" prop="dbType" :rules="[{ required: true, message: '描述不能为空', trigger: 'blur' }]">
<el-select v-model="state.ruleForm.dbType" placeholder="数据库类型" filterable clearable disabled class="w100">
<el-option label="MySql" :value="'0'" />
<el-option label="SqlServer" :value="'1'" />
<el-option label="Sqlite" :value="'2'" />
@ -60,28 +55,21 @@
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="库地址" prop="connectionString">
<el-input v-model="state.ruleForm.connectionString" disabled clearable
type="textarea" />
<el-input v-model="state.ruleForm.connectionString" disabled clearable type="textarea" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="生成表" prop="tableName"
:rules="[{ required: true, message: '生成表不能为空', trigger: 'blur' }]">
<el-form-item label="生成表" prop="tableName" :rules="[{ required: true, message: '生成表不能为空', trigger: 'blur' }]">
<template v-slot:label>
<div>
生成表
<el-tooltip raw-content
content="如果是在前端生成的实体/表(在生成表选择项里面找不到),请重启后台服务后再进行代码生成。" placement="top">
<el-icon size="16"
style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
<el-tooltip raw-content content="如果是在前端生成的实体/表(在生成表选择项里面找不到),请重启后台服务后再进行代码生成。" placement="top">
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
</el-tooltip>
</div>
</template>
<el-select v-model="state.ruleForm.tableName" @change="tableChanged"
value-key="value" filterable clearable class="w100">
<el-option v-for="item in state.tableData" :key="item.entityName"
:label="item.entityName + ' ( ' + item.tableName + ' ) [' + item.tableComment + ']'"
:value="item" />
<el-select v-model="state.ruleForm.tableName" @change="tableChanged" value-key="value" filterable clearable class="w100">
<el-option v-for="item in state.tableData" :key="item.entityName" :label="item.entityName + ' ( ' + item.tableName + ' ) [' + item.tableComment + ']'" :value="item" />
</el-select>
</el-form-item>
</el-col>
@ -100,16 +88,21 @@
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="菜单图标" prop="menuIcon">
<IconSelector v-model="state.ruleForm.menuIcon" :size="getGlobalComponentSize"
placeholder="菜单图标" type="all" />
<IconSelector v-model="state.ruleForm.menuIcon" :size="getGlobalComponentSize" placeholder="菜单图标" type="all" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="父级菜单" prop="menuPid">
<el-cascader :options="state.menuData"
<el-cascader
:options="state.menuData"
:props="{ checkStrictly: true, emitPath: false, value: 'id', label: 'title' }"
placeholder="请选择上级菜单" :disabled="!state.ruleForm.generateMenu" clearable
class="w100" v-model="state.ruleForm.menuPid" @change="menuChange">
placeholder="请选择上级菜单"
:disabled="!state.ruleForm.generateMenu"
clearable
class="w100"
v-model="state.ruleForm.menuPid"
@change="menuChange"
>
<template #default="{ node, data }">
<span>{{ data.title }}</span>
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
@ -118,13 +111,10 @@
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="命名空间" prop="nameSpace"
:rules="[{ required: true, message: '请选择命名空间', trigger: 'blur' }]">
<el-form-item label="命名空间" prop="nameSpace" :rules="[{ required: true, message: '请选择命名空间', trigger: 'blur' }]">
<!-- <el-input v-model="state.ruleForm.nameSpace" clearable placeholder="请输入" /> -->
<el-select v-model="state.ruleForm.nameSpace" filterable clearable class="w100"
placeholder="命名空间">
<el-option v-for="(item, index) in props.applicationNamespaces" :key="index"
:label="item" :value="item" />
<el-select v-model="state.ruleForm.nameSpace" filterable clearable class="w100" placeholder="命名空间">
<el-option v-for="(item, index) in props.applicationNamespaces" :key="index" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
@ -141,8 +131,7 @@
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="生成方式" prop="generateType">
<el-select v-model="state.ruleForm.generateType" filterable class="w100">
<el-option v-for="item in state.codeGenTypeList" :key="item.value"
:label="item.value" :value="item.code" />
<el-option v-for="item in state.codeGenTypeList" :key="item.value" :label="item.value" :value="item.code" />
</el-select>
</el-form-item>
</el-col>
@ -151,11 +140,8 @@
<template v-slot:label>
<div>
接口模式
<el-tooltip raw-content
content="API Service 模式是自动生成前端接口请求文件,推荐此模式。不使用则是指自定义前端接口请求。"
placement="top">
<el-icon size="16"
style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
<el-tooltip raw-content content="API Service 模式是自动生成前端接口请求文件,推荐此模式。不使用则是指自定义前端接口请求。" placement="top">
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
</el-tooltip>
</div>
</template>
@ -167,19 +153,15 @@
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="支持打印" prop="printType">
<el-select v-model="state.ruleForm.printType" filterable class="w100"
@change="printTypeChanged">
<el-option v-for="item in state.printTypeList" :key="item.value"
:label="item.value" :value="item.code" />
<el-select v-model="state.ruleForm.printType" filterable class="w100" @change="printTypeChanged">
<el-option v-for="item in state.printTypeList" :key="item.value" :label="item.value" :value="item.code" />
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20"
v-if="state.ruleForm.printType == 'custom'">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20" v-if="state.ruleForm.printType == 'custom'">
<el-form-item label="打印模版" prop="printName">
<el-select v-model="state.ruleForm.printName" filterable class="w100">
<el-option v-for="item in state.printList" :key="item.id" :label="item.name"
:value="item.name" />
<el-option v-for="item in state.printList" :key="item.id" :label="item.name" :value="item.name" />
</el-select>
</el-form-item>
</el-col>
@ -187,8 +169,7 @@
</el-form>
</el-tab-pane>
<el-tab-pane label="选择模板" name="template">
<el-table ref="templateTableRef" :data="templateTableData" @selection-change="handleSelectionChange"
style="width: 100%">
<el-table ref="templateTableRef" :data="templateTableData" @selection-change="handleSelectionChange" style="width: 100%">
<el-table-column type="selection" width="55" />
<el-table-column property="name" label="模板文件名" width="200" />
<el-table-column property="describe" label="描述" show-overflow-tooltip />
@ -208,14 +189,14 @@
<script lang="ts" setup name="sysEditCodeGen">
import { computed, onMounted, reactive, ref, nextTick } from 'vue';
import IconSelector from '/@/components/iconSelector/index.vue';
import { ElMessage } from "element-plus";
import { ElMessage } from 'element-plus';
import other from '/@/utils/other';
import { getAPI } from '/@/utils/axios-utils';
import { SysCodeGenApi, SysDictDataApi, SysMenuApi, SysPrintApi } from '/@/api-services/api';
import { UpdateCodeGenInput, AddCodeGenInput, SysMenu, SysPrint } from '/@/api-services/models';
import { listSysCodeGenTemplate } from "/@/api/system/sysCodeGenTemplate";
import { listSysCodeGenTemplate } from '/@/api/system/sysCodeGenTemplate';
const props = defineProps({
title: String,
@ -236,7 +217,7 @@ const state = reactive({
const activeTab = ref('codeGen');
const templateTableRef = ref();
const multipleSelection = ref([] as any)
const multipleSelection = ref([] as any);
const templateTableData = ref([] as any);
onMounted(async () => {
@ -289,14 +270,13 @@ const getSysCodeGenTemplateList = async () => {
multipleSelection.value = checkedRows;
});
};
//
const handleSelectionChange = (val: any[]) => {
multipleSelection.value = val;
// console.log(val);
}
};
// db
const dbChanged = async () => {
@ -358,11 +338,11 @@ const submit = () => {
if (multipleSelection.value.length == 0) {
ElMessage({
message: `请选择模板`,
type: "error",
type: 'error',
});
activeTab.value = 'template';
return;
};
}
let codeGenTemplateIds: any[] = [];
multipleSelection.value.forEach((item: any) => {
codeGenTemplateIds.push(item.id);

View File

@ -88,7 +88,7 @@
<el-input v-model="scope.row.orderNo" autocomplete="off" type="number" />
</template>
</el-table-column>
<el-table-column prop="orderNo" label="校验规则" width="120" show-overflow-tooltip>
<el-table-column prop="orderNo" label="校验规则" width="120" show-overflow-tooltip>
<template #default="scope">
<el-button type="primary" plain v-if="scope.row.columnKey === 'False' && !scope.row.whetherCommon" @click="openVerifyDialog(scope.row)">校验规则{{ scope.row.ruleCount }}</el-button>
<span v-else></span>

View File

@ -3,30 +3,26 @@
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="800px">
<template #header>
<div style="color: #fff">
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit />
</el-icon>
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
<span> 编辑规则 </span>
</div>
</template>
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
<el-row :gutter="35">
<el-form-item style="display: none !important;">
<el-form-item style="display: none !important">
<el-input v-model="state.ruleForm.id" />
</el-form-item>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="">
本字段的数据库类型是{{ state.column.dataType }}.Net类型是{{ state.column.netType }}
</el-form-item>
<el-form-item label=""> 本字段的数据库类型是{{ state.column.dataType }}.Net类型是{{ state.column.netType }} </el-form-item>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="验证类型" prop="type" :rules="rules.type">
<el-select v-model="state.ruleForm.type" placeholder="请选择类型" @change="handleTypeChange">
<el-option v-for="(item, index) in validTypeData" :key="index" :label="item.name"
:value="item.code" />
<el-option v-for="(item, index) in validTypeData" :key="index" :label="item.name" :value="item.code" />
</el-select>
</el-form-item>
</el-col>
<template v-if="state.ruleForm.type == 'length'&&(state.column.netType.includes('int')||state.column.netType.includes('long')||state.column.netType.includes('string'))">
<template v-if="state.ruleForm.type == 'length' && (state.column.netType.includes('int') || state.column.netType.includes('long') || state.column.netType.includes('string'))">
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="最小值" prop="min" :rules="rules.min">
<el-input-number v-model="state.ruleForm.min" :min="0" :max="100000" />
@ -38,7 +34,7 @@
</el-form-item>
</el-col>
</template>
<template v-if="state.ruleForm.type == 'length'&&(state.column.netType.includes('decimal')||state.column.netType.includes('float')||state.column.netType.includes('double'))">
<template v-if="state.ruleForm.type == 'length' && (state.column.netType.includes('decimal') || state.column.netType.includes('float') || state.column.netType.includes('double'))">
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="最小值" prop="min" :rules="rules.minDecimal">
<el-input-number v-model="state.ruleForm.min" :min="0" :max="100000" />
@ -50,25 +46,22 @@
</el-form-item>
</el-col>
</template>
<template v-if="state.ruleForm.type == 'length'&&state.column.netType.includes('DateTime')">
<template v-if="state.ruleForm.type == 'length' && state.column.netType.includes('DateTime')">
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="起始日期" prop="min" :rules="rules.minDate">
<el-date-picker v-model="state.ruleForm.min" type="date" format="YYYY-MM-DD"
value-format="YYYY-MM-DD" placeholder="请选择起始日期" />
<el-date-picker v-model="state.ruleForm.min" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" placeholder="请选择起始日期" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="结束日期" prop="max" :rules="rules.maxDate">
<el-date-picker v-model="state.ruleForm.max" type="date" format="YYYY-MM-DD"
value-format="YYYY-MM-DD" placeholder="请选择结束日期" />
<el-date-picker v-model="state.ruleForm.max" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" placeholder="请选择结束日期" />
</el-form-item>
</el-col>
</template>
<template v-if="state.ruleForm.type == 'pattern'">
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="提示信息" prop="message" :rules="rules.message">
<el-input v-model="state.ruleForm.message" placeholder="请输入提示信息" maxlength="128"
show-word-limit clearable />
<el-input v-model="state.ruleForm.message" placeholder="请输入提示信息" maxlength="128" show-word-limit clearable />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
@ -123,7 +116,7 @@ const rules = ref<FormRules>({
],
min: [
{
type:'integer',
type: 'integer',
required: true,
pattern: /[^\d]/g,
message: '请输入正确的数字',
@ -147,7 +140,7 @@ const rules = ref<FormRules>({
],
max: [
{
type:'integer',
type: 'integer',
required: true,
pattern: /[^\d]/g,
message: '请输入正确的数字',

View File

@ -47,7 +47,7 @@ const state = reactive({
title: '',
column: {} as any,
});
const column=ref();
const column = ref();
//
const openDialog = (row: any) => {

View File

@ -52,7 +52,7 @@
</vxe-grid>
</el-card>
<EditPos ref="editPosRef" :title="state.title" @handleSearch="handleQuery" />
<EditPos ref="editPosRef" :title="state.title" @handleQuery="handleQuery" />
</div>
</template>