😎完善初始化种子数据流程(限定程序集和执行顺序)
This commit is contained in:
parent
03d438436c
commit
a72a4095e9
@ -10,9 +10,11 @@ public class DataInitItemOutput
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public int Count { get; set; }
|
||||
|
||||
public string AssemblyName { get; set; }
|
||||
|
||||
public int Order { get; set; }
|
||||
|
||||
public int Count { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
}
|
||||
@ -6,9 +6,25 @@
|
||||
|
||||
namespace Admin.NET.Core.Service;
|
||||
|
||||
public class InitTableSeedDataInput
|
||||
public class InitTableInput
|
||||
{
|
||||
public string ConfigId { get; set; }
|
||||
|
||||
public List<string> EntityNames { get; set; }
|
||||
}
|
||||
|
||||
public class InitSeedDataInput
|
||||
{
|
||||
public string ConfigId { get; set; }
|
||||
|
||||
public List<SeedType> SeedNames { get; set; }
|
||||
}
|
||||
|
||||
public class SeedType
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string AssemblyName { get; set; }
|
||||
|
||||
public int Order { get; set; }
|
||||
}
|
||||
@ -567,7 +567,15 @@ public class SysDatabaseService : IDynamicApiController, ITransient
|
||||
var seedData = ((IEnumerable)hasDataMethod?.Invoke(instance, null))?.Cast<object>().ToArray() ?? [];
|
||||
|
||||
var entityType = seedDataType.GetInterfaces().First().GetGenericArguments().First();
|
||||
outputList.Add(new DataInitItemOutput() { Name = seedDataType.Name, Count = seedData.Length, AssemblyName = seedDataType.Assembly.ManifestModule.Name, Description = entityType.GetCustomAttribute<SugarTable>().TableDescription + "种子数据" });
|
||||
var seedDataAtt = seedDataType.GetCustomAttribute<SeedDataAttribute>();
|
||||
outputList.Add(new DataInitItemOutput()
|
||||
{
|
||||
Name = seedDataType.Name,
|
||||
AssemblyName = seedDataType.Assembly.ManifestModule.Name,
|
||||
Order = seedDataAtt != null ? seedDataAtt.Order : 0,
|
||||
Count = seedData.Length,
|
||||
Description = entityType.GetCustomAttribute<SugarTable>().TableDescription + "种子数据"
|
||||
});
|
||||
}
|
||||
return outputList;
|
||||
}
|
||||
@ -577,7 +585,7 @@ public class SysDatabaseService : IDynamicApiController, ITransient
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
[DisplayName("初始化表结构")]
|
||||
public void InitTable(InitTableSeedDataInput input)
|
||||
public void InitTable(InitTableInput input)
|
||||
{
|
||||
if (!_userManager.SuperAdmin)
|
||||
throw Oops.Oh("只有超管才可以操作!");
|
||||
@ -591,13 +599,13 @@ public class SysDatabaseService : IDynamicApiController, ITransient
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
[DisplayName("初始化种子数据")]
|
||||
public void InitSeedData(InitTableSeedDataInput input)
|
||||
public void InitSeedData(InitSeedDataInput input)
|
||||
{
|
||||
if (!_userManager.SuperAdmin)
|
||||
throw Oops.Oh("只有超管才可以操作!");
|
||||
|
||||
var dbProvider = _db.AsTenant().GetConnectionScope(input.ConfigId);
|
||||
SqlSugarSetup.InitSeedData(dbProvider, false, input.EntityNames);
|
||||
SqlSugarSetup.InitSeedData(dbProvider, false, input.SeedNames);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -524,8 +524,8 @@ public static class SqlSugarSetup
|
||||
/// </summary>
|
||||
/// <param name="dbProvider"></param>
|
||||
/// <param name="enableIncreSeed"></param>
|
||||
/// <param name="entityNames"></param>
|
||||
public static void InitSeedData(SqlSugarScopeProvider dbProvider, bool enableIncreSeed, List<string> entityNames = null)
|
||||
/// <param name="seedTypes"></param>
|
||||
public static void InitSeedData(SqlSugarScopeProvider dbProvider, bool enableIncreSeed, List<SeedType> seedTypes = null)
|
||||
{
|
||||
var config = dbProvider.CurrentConnectionConfig;
|
||||
|
||||
@ -536,9 +536,19 @@ public static class SqlSugarSetup
|
||||
.WhereIF(enableIncreSeed, u => u.IsDefined(typeof(IncreSeedAttribute), false))
|
||||
.OrderBy(u => u.GetCustomAttributes(typeof(SeedDataAttribute), false).Length > 0 ? ((SeedDataAttribute)u.GetCustomAttributes(typeof(SeedDataAttribute), false)[0]).Order : 0).ToList();
|
||||
|
||||
// 过滤指定实体
|
||||
if (entityNames != null && entityNames.Count > 0)
|
||||
seedDataTypes = seedDataTypes.Where(u => entityNames.Contains(u.Name)).ToList();
|
||||
// 过滤指定程序集种子
|
||||
if (seedTypes != null && seedTypes.Count > 0)
|
||||
{
|
||||
seedTypes = seedTypes.OrderBy(u => u.Order).ToList();
|
||||
var tmpSeedTypes = new List<Type>();
|
||||
foreach (var seedType in seedTypes)
|
||||
{
|
||||
var tmpSeedType = seedDataTypes.FirstOrDefault(u => u.Name == seedType.Name && u.Assembly.ManifestModule.Name == seedType.AssemblyName);
|
||||
if (tmpSeedType != null) tmpSeedTypes.Add(tmpSeedType);
|
||||
}
|
||||
if (tmpSeedTypes.Count > 0)
|
||||
seedDataTypes = tmpSeedTypes;
|
||||
}
|
||||
|
||||
// 由于种子数据在应用层存在重写,必须保证应用层种子最后执行(多线程顺序会乱)
|
||||
int taskIndex = 0, size = seedDataTypes.Count;
|
||||
|
||||
@ -106,7 +106,7 @@
|
||||
"prettier": "^3.5.3",
|
||||
"rollup-plugin-visualizer": "^6.0.1",
|
||||
"sass": "^1.89.1",
|
||||
"terser": "^5.40.0",
|
||||
"terser": "^5.41.0",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.5",
|
||||
"vite-plugin-cdn-import": "^1.0.1",
|
||||
|
||||
@ -30,7 +30,8 @@ import { DbColumnInput } from '../models';
|
||||
import { DbTableInput } from '../models';
|
||||
import { DeleteDbColumnInput } from '../models';
|
||||
import { DeleteDbTableInput } from '../models';
|
||||
import { InitTableSeedDataInput } from '../models';
|
||||
import { InitSeedDataInput } from '../models';
|
||||
import { InitTableInput } from '../models';
|
||||
import { UpdateDbColumnInput } from '../models';
|
||||
import { UpdateDbTableInput } from '../models';
|
||||
/**
|
||||
@ -592,11 +593,11 @@ export const SysDatabaseApiAxiosParamCreator = function (configuration?: Configu
|
||||
/**
|
||||
*
|
||||
* @summary 初始化种子数据 🔖
|
||||
* @param {InitTableSeedDataInput} [body]
|
||||
* @param {InitSeedDataInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
apiSysDatabaseInitSeedDataPost: async (body?: InitTableSeedDataInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
apiSysDatabaseInitSeedDataPost: async (body?: InitSeedDataInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/api/sysDatabase/initSeedData`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, 'https://example.com');
|
||||
@ -640,11 +641,11 @@ export const SysDatabaseApiAxiosParamCreator = function (configuration?: Configu
|
||||
/**
|
||||
*
|
||||
* @summary 初始化表结构 🔖
|
||||
* @param {InitTableSeedDataInput} [body]
|
||||
* @param {InitTableInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
apiSysDatabaseInitTablePost: async (body?: InitTableSeedDataInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
apiSysDatabaseInitTablePost: async (body?: InitTableInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/api/sysDatabase/initTable`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, 'https://example.com');
|
||||
@ -1133,11 +1134,11 @@ export const SysDatabaseApiFp = function(configuration?: Configuration) {
|
||||
/**
|
||||
*
|
||||
* @summary 初始化种子数据 🔖
|
||||
* @param {InitTableSeedDataInput} [body]
|
||||
* @param {InitSeedDataInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiSysDatabaseInitSeedDataPost(body?: InitTableSeedDataInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<void>>> {
|
||||
async apiSysDatabaseInitSeedDataPost(body?: InitSeedDataInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<void>>> {
|
||||
const localVarAxiosArgs = await SysDatabaseApiAxiosParamCreator(configuration).apiSysDatabaseInitSeedDataPost(body, options);
|
||||
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
|
||||
@ -1147,11 +1148,11 @@ export const SysDatabaseApiFp = function(configuration?: Configuration) {
|
||||
/**
|
||||
*
|
||||
* @summary 初始化表结构 🔖
|
||||
* @param {InitTableSeedDataInput} [body]
|
||||
* @param {InitTableInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiSysDatabaseInitTablePost(body?: InitTableSeedDataInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<void>>> {
|
||||
async apiSysDatabaseInitTablePost(body?: InitTableInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<void>>> {
|
||||
const localVarAxiosArgs = await SysDatabaseApiAxiosParamCreator(configuration).apiSysDatabaseInitTablePost(body, options);
|
||||
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
|
||||
@ -1365,21 +1366,21 @@ export const SysDatabaseApiFactory = function (configuration?: Configuration, ba
|
||||
/**
|
||||
*
|
||||
* @summary 初始化种子数据 🔖
|
||||
* @param {InitTableSeedDataInput} [body]
|
||||
* @param {InitSeedDataInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiSysDatabaseInitSeedDataPost(body?: InitTableSeedDataInput, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
|
||||
async apiSysDatabaseInitSeedDataPost(body?: InitSeedDataInput, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
|
||||
return SysDatabaseApiFp(configuration).apiSysDatabaseInitSeedDataPost(body, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 初始化表结构 🔖
|
||||
* @param {InitTableSeedDataInput} [body]
|
||||
* @param {InitTableInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiSysDatabaseInitTablePost(body?: InitTableSeedDataInput, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
|
||||
async apiSysDatabaseInitTablePost(body?: InitTableInput, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
|
||||
return SysDatabaseApiFp(configuration).apiSysDatabaseInitTablePost(body, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
@ -1577,23 +1578,23 @@ export class SysDatabaseApi extends BaseAPI {
|
||||
/**
|
||||
*
|
||||
* @summary 初始化种子数据 🔖
|
||||
* @param {InitTableSeedDataInput} [body]
|
||||
* @param {InitSeedDataInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof SysDatabaseApi
|
||||
*/
|
||||
public async apiSysDatabaseInitSeedDataPost(body?: InitTableSeedDataInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
|
||||
public async apiSysDatabaseInitSeedDataPost(body?: InitSeedDataInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
|
||||
return SysDatabaseApiFp(this.configuration).apiSysDatabaseInitSeedDataPost(body, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @summary 初始化表结构 🔖
|
||||
* @param {InitTableSeedDataInput} [body]
|
||||
* @param {InitTableInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof SysDatabaseApi
|
||||
*/
|
||||
public async apiSysDatabaseInitTablePost(body?: InitTableSeedDataInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
|
||||
public async apiSysDatabaseInitTablePost(body?: InitTableInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
|
||||
return SysDatabaseApiFp(this.configuration).apiSysDatabaseInitTablePost(body, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
/**
|
||||
|
||||
@ -26,18 +26,24 @@ export interface DataInitItemOutput {
|
||||
*/
|
||||
name?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof DataInitItemOutput
|
||||
*/
|
||||
assemblyName?: string | null;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @memberof DataInitItemOutput
|
||||
*/
|
||||
order?: number;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @memberof DataInitItemOutput
|
||||
*/
|
||||
count?: number;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof DataInitItemOutput
|
||||
*/
|
||||
assemblyName?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof DataInitItemOutput
|
||||
|
||||
@ -259,7 +259,8 @@ export * from './icontainer';
|
||||
export * from './icustom-attribute-provider';
|
||||
export * from './idisposable';
|
||||
export * from './isite';
|
||||
export * from './init-table-seed-data-input';
|
||||
export * from './init-seed-data-input';
|
||||
export * from './init-table-input';
|
||||
export * from './int-ptr';
|
||||
export * from './invoice-info';
|
||||
export * from './invoice-key-info';
|
||||
@ -363,6 +364,7 @@ export * from './schedule-input';
|
||||
export * from './schema-serialization-mode';
|
||||
export * from './search';
|
||||
export * from './security-rule-set';
|
||||
export * from './seed-type';
|
||||
export * from './send-subscribe-message-input';
|
||||
export * from './serialization-format';
|
||||
export * from './set-nick-name-input';
|
||||
|
||||
35
Web/src/api-services/models/init-seed-data-input.ts
Normal file
35
Web/src/api-services/models/init-seed-data-input.ts
Normal file
@ -0,0 +1,35 @@
|
||||
/* 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 { SeedType } from './seed-type';
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @export
|
||||
* @interface InitSeedDataInput
|
||||
*/
|
||||
export interface InitSeedDataInput {
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof InitSeedDataInput
|
||||
*/
|
||||
configId?: string | null;
|
||||
|
||||
/**
|
||||
* @type {Array<SeedType>}
|
||||
* @memberof InitSeedDataInput
|
||||
*/
|
||||
seedNames?: Array<SeedType> | null;
|
||||
}
|
||||
@ -16,19 +16,19 @@
|
||||
*
|
||||
*
|
||||
* @export
|
||||
* @interface InitTableSeedDataInput
|
||||
* @interface InitTableInput
|
||||
*/
|
||||
export interface InitTableSeedDataInput {
|
||||
export interface InitTableInput {
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof InitTableSeedDataInput
|
||||
* @memberof InitTableInput
|
||||
*/
|
||||
configId?: string | null;
|
||||
|
||||
/**
|
||||
* @type {Array<string>}
|
||||
* @memberof InitTableSeedDataInput
|
||||
* @memberof InitTableInput
|
||||
*/
|
||||
entityNames?: Array<string> | null;
|
||||
}
|
||||
40
Web/src/api-services/models/seed-type.ts
Normal file
40
Web/src/api-services/models/seed-type.ts
Normal file
@ -0,0 +1,40 @@
|
||||
/* 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 SeedType
|
||||
*/
|
||||
export interface SeedType {
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof SeedType
|
||||
*/
|
||||
name?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof SeedType
|
||||
*/
|
||||
assemblyName?: string | null;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @memberof SeedType
|
||||
*/
|
||||
order?: number;
|
||||
}
|
||||
@ -133,7 +133,7 @@ export interface SysLogDiff {
|
||||
businessData?: string | null;
|
||||
|
||||
/**
|
||||
* 差异操作
|
||||
* 操作类型(增删改)
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof SysLogDiff
|
||||
|
||||
@ -137,6 +137,7 @@ const optionsSeed = useVxeTable(
|
||||
{ type: 'seq', title: '序号', width: 50, fixed: 'left' },
|
||||
{ field: 'name', title: '种子名称', showOverflow: 'tooltip', align: 'left' },
|
||||
{ field: 'description', title: '描述', showOverflow: 'tooltip', align: 'left' },
|
||||
{ field: 'order', title: '执行顺序', showOverflow: 'tooltip' },
|
||||
{ field: 'count', title: '种子个数', showOverflow: 'tooltip', slots: { default: 'row_count' } },
|
||||
{ field: 'assemblyName', title: '所属程序集', showOverflow: 'tooltip', align: 'left' },
|
||||
],
|
||||
@ -186,7 +187,11 @@ const handleInitSeedData = async () => {
|
||||
try {
|
||||
const params = {
|
||||
configId: state.configId,
|
||||
entityNames: state.seedSelectedRows.map((row) => row.name),
|
||||
seedNames: state.seedSelectedRows.map((row) => ({
|
||||
name: row.name,
|
||||
assemblyName: row.assemblyName,
|
||||
order: row.order,
|
||||
})),
|
||||
};
|
||||
await getAPI(SysDatabaseApi).apiSysDatabaseInitSeedDataPost(params);
|
||||
ElMessage.success('生成种子数据操作成功');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user