mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-10-04 17:14:21 +00:00
fix(web): 修复代码格式和文件清理问题
清理无用文件和资源,调整代码格式统一双引号,修复部分组件路径引用问题 删除大量无用图片资源和组件文件,统一代码风格使用双引号,修复国际化文件路径引用,调整部分组件逻辑,优化项目结构
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* 将「表结构」表单状态编译为可执行的 CREATE TABLE SQL(MySQL / PostgreSQL)。
|
||||
*/
|
||||
|
||||
export type SqlDialect = 'mysql' | 'postgres';
|
||||
export type SqlDialect = "mysql" | "postgres";
|
||||
|
||||
export interface ColDef {
|
||||
name: string;
|
||||
@@ -30,7 +30,7 @@ export interface VisualBuildState {
|
||||
}
|
||||
|
||||
function qMysql(name: string): string {
|
||||
return `\`${name.replace(/`/g, '')}\``;
|
||||
return `\`${name.replace(/`/g, "")}\``;
|
||||
}
|
||||
|
||||
function buildMysqlTable(name: string, comment: string, columns: ColDef[]): string {
|
||||
@@ -39,28 +39,28 @@ function buildMysqlTable(name: string, comment: string, columns: ColDef[]): stri
|
||||
for (const c of columns) {
|
||||
let line = ` ${qMysql(c.name)} ${c.type}`;
|
||||
if (c.isPk && c.autoIncrement) {
|
||||
line += ' NOT NULL AUTO_INCREMENT';
|
||||
line += " NOT NULL AUTO_INCREMENT";
|
||||
} else if (c.isPk) {
|
||||
line += ' NOT NULL';
|
||||
line += " NOT NULL";
|
||||
} else if (!c.nullable) {
|
||||
line += ' NOT NULL';
|
||||
line += " NOT NULL";
|
||||
} else {
|
||||
line += ' DEFAULT NULL';
|
||||
line += " DEFAULT NULL";
|
||||
}
|
||||
if (c.comment) line += ` COMMENT '${c.comment.replace(/'/g, "''")}'`;
|
||||
lines.push(line);
|
||||
}
|
||||
const tail: string[] = [];
|
||||
if (pkCols.length) {
|
||||
tail.push(` PRIMARY KEY (${pkCols.join(', ')})`);
|
||||
tail.push(` PRIMARY KEY (${pkCols.join(", ")})`);
|
||||
}
|
||||
const uuidCol = columns.find((c) => c.name === 'uuid');
|
||||
const uuidCol = columns.find((c) => c.name === "uuid");
|
||||
if (uuidCol) {
|
||||
tail.push(` UNIQUE KEY ${qMysql(`uk_${name.replace(/`/g, '')}_uuid`)} (${qMysql('uuid')})`);
|
||||
tail.push(` UNIQUE KEY ${qMysql(`uk_${name.replace(/`/g, "")}_uuid`)} (${qMysql("uuid")})`);
|
||||
}
|
||||
const allLines = [...lines, ...tail];
|
||||
return (
|
||||
`CREATE TABLE ${qMysql(name)} (\n${allLines.join(',\n')}\n)` +
|
||||
`CREATE TABLE ${qMysql(name)} (\n${allLines.join(",\n")}\n)` +
|
||||
` ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='${comment.replace(/'/g, "''")}';`
|
||||
);
|
||||
}
|
||||
@@ -77,15 +77,15 @@ function buildPostgresTable(name: string, comment: string, columns: ColDef[]): s
|
||||
const pkCols = columns.filter((c) => c.isPk).map((c) => c.name);
|
||||
for (const c of columns) {
|
||||
let line = ` ${c.name} ${c.type}`;
|
||||
const isSerial = c.type.toUpperCase().includes('SERIAL');
|
||||
if (!isSerial && !c.nullable) line += ' NOT NULL';
|
||||
const isSerial = c.type.toUpperCase().includes("SERIAL");
|
||||
if (!isSerial && !c.nullable) line += " NOT NULL";
|
||||
lines.push(line);
|
||||
}
|
||||
const tail: string[] = [];
|
||||
if (pkCols.length) {
|
||||
tail.push(` PRIMARY KEY (${pkCols.join(', ')})`);
|
||||
tail.push(` PRIMARY KEY (${pkCols.join(", ")})`);
|
||||
}
|
||||
const body = [...lines, ...tail].join(',\n');
|
||||
const body = [...lines, ...tail].join(",\n");
|
||||
return (
|
||||
`CREATE TABLE ${name} (\n${body}\n);\n` +
|
||||
`COMMENT ON TABLE ${name} IS '${comment.replace(/'/g, "''")}';`
|
||||
@@ -96,7 +96,7 @@ function buildPostgresColumnComments(table: string, columns: ColDef[]): string {
|
||||
return columns
|
||||
.filter((c) => c.comment)
|
||||
.map((c) => `COMMENT ON COLUMN ${table}.${c.name} IS '${c.comment.replace(/'/g, "''")}';`)
|
||||
.join('\n');
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
function buildPostgresFk(subName: string, fkCol: string, mainName: string, refCol: string): string {
|
||||
@@ -109,11 +109,11 @@ function buildPostgresFk(subName: string, fkCol: string, mainName: string, refCo
|
||||
/** 由表结构状态生成完整 SQL(单表或主子表) */
|
||||
export function buildSqlFromVisual(state: VisualBuildState): string {
|
||||
const m = state.mainTableName.trim();
|
||||
if (!m) return '';
|
||||
if (!m) return "";
|
||||
|
||||
const parts: string[] = [];
|
||||
|
||||
if (state.dialect === 'mysql') {
|
||||
if (state.dialect === "mysql") {
|
||||
parts.push(buildMysqlTable(m, state.mainComment || m, state.mainColumns));
|
||||
if (state.subEnabled && state.subTableName.trim()) {
|
||||
const s = state.subTableName.trim();
|
||||
@@ -131,5 +131,5 @@ export function buildSqlFromVisual(state: VisualBuildState): string {
|
||||
}
|
||||
}
|
||||
|
||||
return parts.filter(Boolean).join('\n\n');
|
||||
return parts.filter(Boolean).join("\n\n");
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { buildSqlFromVisual } from './buildCreateTableSql';
|
||||
import { buildSqlFromVisual } from "./buildCreateTableSql";
|
||||
import {
|
||||
applySubColumns,
|
||||
visualPresetMasterSub,
|
||||
visualPresetSingle,
|
||||
} from './createTableVisualPresets';
|
||||
} from "./createTableVisualPresets";
|
||||
|
||||
/** 与「表结构」单表模板一致的 SQL(便于两种模式对齐) */
|
||||
export function getExampleFromPresetSingle(dialect: 'mysql' | 'postgres'): string {
|
||||
export function getExampleFromPresetSingle(dialect: "mysql" | "postgres"): string {
|
||||
return buildSqlFromVisual(visualPresetSingle(dialect));
|
||||
}
|
||||
|
||||
/** 与「表结构」主子表模板一致的 SQL */
|
||||
export function getExampleFromPresetMasterSub(dialect: 'mysql' | 'postgres'): string {
|
||||
export function getExampleFromPresetMasterSub(dialect: "mysql" | "postgres"): string {
|
||||
return buildSqlFromVisual(applySubColumns(visualPresetMasterSub(dialect)));
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ColDef, SqlDialect, VisualBuildState } from './buildCreateTableSql';
|
||||
import type { ColDef, SqlDialect, VisualBuildState } from "./buildCreateTableSql";
|
||||
|
||||
/** 与代码生成第三步「基本信息」联动时的输入(主表名、子表名、外键列名) */
|
||||
export interface GenTableCreateLink {
|
||||
@@ -11,143 +11,143 @@ export interface GenTableCreateLink {
|
||||
function mixinMysql(): ColDef[] {
|
||||
return [
|
||||
{
|
||||
name: 'status',
|
||||
type: 'varchar(10)',
|
||||
name: "status",
|
||||
type: "varchar(10)",
|
||||
nullable: false,
|
||||
isPk: false,
|
||||
comment: '是否启用(0:启用 1:禁用)',
|
||||
comment: "是否启用(0:启用 1:禁用)",
|
||||
},
|
||||
{ name: 'description', type: 'text', nullable: true, isPk: false, comment: '备注/描述' },
|
||||
{ name: "description", type: "text", nullable: true, isPk: false, comment: "备注/描述" },
|
||||
{
|
||||
name: 'created_time',
|
||||
type: 'datetime',
|
||||
name: "created_time",
|
||||
type: "datetime",
|
||||
nullable: false,
|
||||
isPk: false,
|
||||
comment: '创建时间',
|
||||
comment: "创建时间",
|
||||
},
|
||||
{
|
||||
name: 'updated_time',
|
||||
type: 'datetime',
|
||||
name: "updated_time",
|
||||
type: "datetime",
|
||||
nullable: false,
|
||||
isPk: false,
|
||||
comment: '更新时间',
|
||||
comment: "更新时间",
|
||||
},
|
||||
{ name: 'created_id', type: 'int', nullable: true, isPk: false, comment: '创建人ID' },
|
||||
{ name: 'updated_id', type: 'int', nullable: true, isPk: false, comment: '更新人ID' },
|
||||
{ name: "created_id", type: "int", nullable: true, isPk: false, comment: "创建人ID" },
|
||||
{ name: "updated_id", type: "int", nullable: true, isPk: false, comment: "更新人ID" },
|
||||
{
|
||||
name: 'is_deleted',
|
||||
type: 'tinyint(1)',
|
||||
name: "is_deleted",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
isPk: false,
|
||||
comment: '是否已删除(0:未删除 1:已删除)',
|
||||
comment: "是否已删除(0:未删除 1:已删除)",
|
||||
},
|
||||
{ name: 'deleted_time', type: 'datetime', nullable: true, isPk: false, comment: '删除时间' },
|
||||
{ name: 'deleted_id', type: 'int', nullable: true, isPk: false, comment: '删除人ID' },
|
||||
{ name: "deleted_time", type: "datetime", nullable: true, isPk: false, comment: "删除时间" },
|
||||
{ name: "deleted_id", type: "int", nullable: true, isPk: false, comment: "删除人ID" },
|
||||
];
|
||||
}
|
||||
|
||||
function mixinPostgres(): ColDef[] {
|
||||
return [
|
||||
{
|
||||
name: 'status',
|
||||
type: 'varchar(10)',
|
||||
name: "status",
|
||||
type: "varchar(10)",
|
||||
nullable: false,
|
||||
isPk: false,
|
||||
comment: '是否启用(0:启用 1:禁用)',
|
||||
comment: "是否启用(0:启用 1:禁用)",
|
||||
},
|
||||
{ name: 'description', type: 'text', nullable: true, isPk: false, comment: '备注/描述' },
|
||||
{ name: "description", type: "text", nullable: true, isPk: false, comment: "备注/描述" },
|
||||
{
|
||||
name: 'created_time',
|
||||
type: 'timestamp without time zone',
|
||||
name: "created_time",
|
||||
type: "timestamp without time zone",
|
||||
nullable: false,
|
||||
isPk: false,
|
||||
comment: '创建时间',
|
||||
comment: "创建时间",
|
||||
},
|
||||
{
|
||||
name: 'updated_time',
|
||||
type: 'timestamp without time zone',
|
||||
name: "updated_time",
|
||||
type: "timestamp without time zone",
|
||||
nullable: false,
|
||||
isPk: false,
|
||||
comment: '更新时间',
|
||||
comment: "更新时间",
|
||||
},
|
||||
{ name: 'created_id', type: 'integer', nullable: true, isPk: false, comment: '创建人ID' },
|
||||
{ name: 'updated_id', type: 'integer', nullable: true, isPk: false, comment: '更新人ID' },
|
||||
{ name: "created_id", type: "integer", nullable: true, isPk: false, comment: "创建人ID" },
|
||||
{ name: "updated_id", type: "integer", nullable: true, isPk: false, comment: "更新人ID" },
|
||||
{
|
||||
name: 'is_deleted',
|
||||
type: 'boolean',
|
||||
name: "is_deleted",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
isPk: false,
|
||||
comment: '是否已删除(0:未删除 1:已删除)',
|
||||
comment: "是否已删除(0:未删除 1:已删除)",
|
||||
},
|
||||
{
|
||||
name: 'deleted_time',
|
||||
type: 'timestamp without time zone',
|
||||
name: "deleted_time",
|
||||
type: "timestamp without time zone",
|
||||
nullable: true,
|
||||
isPk: false,
|
||||
comment: '删除时间',
|
||||
comment: "删除时间",
|
||||
},
|
||||
{ name: 'deleted_id', type: 'integer', nullable: true, isPk: false, comment: '删除人ID' },
|
||||
{ name: "deleted_id", type: "integer", nullable: true, isPk: false, comment: "删除人ID" },
|
||||
];
|
||||
}
|
||||
|
||||
function pkMysql(): ColDef[] {
|
||||
return [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'bigint',
|
||||
name: "id",
|
||||
type: "bigint",
|
||||
nullable: false,
|
||||
isPk: true,
|
||||
comment: '主键ID',
|
||||
comment: "主键ID",
|
||||
autoIncrement: true,
|
||||
},
|
||||
{
|
||||
name: 'uuid',
|
||||
type: 'varchar(64)',
|
||||
name: "uuid",
|
||||
type: "varchar(64)",
|
||||
nullable: false,
|
||||
isPk: false,
|
||||
comment: 'UUID全局唯一标识',
|
||||
comment: "UUID全局唯一标识",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function pkPostgres(): ColDef[] {
|
||||
return [
|
||||
{ name: 'id', type: 'SERIAL', nullable: false, isPk: true, comment: '主键ID' },
|
||||
{ name: "id", type: "SERIAL", nullable: false, isPk: true, comment: "主键ID" },
|
||||
{
|
||||
name: 'uuid',
|
||||
type: 'varchar(64)',
|
||||
name: "uuid",
|
||||
type: "varchar(64)",
|
||||
nullable: false,
|
||||
isPk: false,
|
||||
comment: 'UUID全局唯一标识',
|
||||
comment: "UUID全局唯一标识",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function buildSubColumns(dialect: SqlDialect, mainTableName: string, fkColumn: string): ColDef[] {
|
||||
const isMysql = dialect === 'mysql';
|
||||
const isMysql = dialect === "mysql";
|
||||
const mixin = isMysql ? mixinMysql() : mixinPostgres();
|
||||
const subPk = isMysql ? pkMysql() : pkPostgres();
|
||||
const fkColDef: ColDef = {
|
||||
name: fkColumn,
|
||||
type: 'bigint',
|
||||
type: "bigint",
|
||||
nullable: false,
|
||||
isPk: false,
|
||||
comment: `关联 ${mainTableName}.${'id'}`,
|
||||
comment: `关联 ${mainTableName}.${"id"}`,
|
||||
};
|
||||
const subBusiness: ColDef[] = [
|
||||
{
|
||||
name: 'line_name',
|
||||
type: 'varchar(128)',
|
||||
name: "line_name",
|
||||
type: "varchar(128)",
|
||||
nullable: true,
|
||||
isPk: false,
|
||||
comment: '明细名称',
|
||||
comment: "明细名称",
|
||||
},
|
||||
{
|
||||
name: 'qty',
|
||||
type: isMysql ? 'int' : 'integer',
|
||||
name: "qty",
|
||||
type: isMysql ? "int" : "integer",
|
||||
nullable: false,
|
||||
isPk: false,
|
||||
comment: '数量',
|
||||
comment: "数量",
|
||||
},
|
||||
];
|
||||
return [...subPk, fkColDef, ...subBusiness, ...mixin];
|
||||
@@ -165,50 +165,50 @@ export function applySubColumns(state: VisualBuildState): VisualBuildState {
|
||||
|
||||
/** 单表:带业务字段 name */
|
||||
export function visualPresetSingle(dialect: SqlDialect): VisualBuildState {
|
||||
const isMysql = dialect === 'mysql';
|
||||
const isMysql = dialect === "mysql";
|
||||
const mixin = isMysql ? mixinMysql() : mixinPostgres();
|
||||
const pk = isMysql ? pkMysql() : pkPostgres();
|
||||
const business: ColDef[] = [
|
||||
{ name: 'name', type: 'varchar(64)', nullable: true, isPk: false, comment: '名称' },
|
||||
{ name: "name", type: "varchar(64)", nullable: true, isPk: false, comment: "名称" },
|
||||
];
|
||||
return {
|
||||
dialect,
|
||||
mainTableName: 'gen_demo_single',
|
||||
mainComment: '代码生成-单表示例',
|
||||
mainTableName: "gen_demo_single",
|
||||
mainComment: "代码生成-单表示例",
|
||||
mainColumns: [...pk, ...business, ...mixin],
|
||||
subEnabled: false,
|
||||
subTableName: 'gen_demo_order_item',
|
||||
subComment: '子表示例',
|
||||
fkColumn: 'order_id',
|
||||
fkRefColumn: 'id',
|
||||
subTableName: "gen_demo_order_item",
|
||||
subComment: "子表示例",
|
||||
fkColumn: "order_id",
|
||||
fkRefColumn: "id",
|
||||
subColumns: [],
|
||||
};
|
||||
}
|
||||
|
||||
/** 主子表:主表订单头 + 子表明细,子表含外键列 */
|
||||
export function visualPresetMasterSub(dialect: SqlDialect): VisualBuildState {
|
||||
const isMysql = dialect === 'mysql';
|
||||
const isMysql = dialect === "mysql";
|
||||
const mixin = isMysql ? mixinMysql() : mixinPostgres();
|
||||
const pk = isMysql ? pkMysql() : pkPostgres();
|
||||
const mainBusiness: ColDef[] = [
|
||||
{
|
||||
name: 'order_title',
|
||||
type: 'varchar(128)',
|
||||
name: "order_title",
|
||||
type: "varchar(128)",
|
||||
nullable: true,
|
||||
isPk: false,
|
||||
comment: '订单标题',
|
||||
comment: "订单标题",
|
||||
},
|
||||
];
|
||||
return applySubColumns({
|
||||
dialect,
|
||||
mainTableName: 'gen_demo_order_master',
|
||||
mainComment: '代码生成-主表示例(订单头)',
|
||||
mainTableName: "gen_demo_order_master",
|
||||
mainComment: "代码生成-主表示例(订单头)",
|
||||
mainColumns: [...pk, ...mainBusiness, ...mixin],
|
||||
subEnabled: true,
|
||||
subTableName: 'gen_demo_order_item',
|
||||
subComment: '代码生成-子表示例(订单明细)',
|
||||
fkColumn: 'order_id',
|
||||
fkRefColumn: 'id',
|
||||
subTableName: "gen_demo_order_item",
|
||||
subComment: "代码生成-子表示例(订单明细)",
|
||||
fkColumn: "order_id",
|
||||
fkRefColumn: "id",
|
||||
subColumns: [],
|
||||
});
|
||||
}
|
||||
@@ -221,21 +221,21 @@ export function mergeGenTableLinkIntoVisual(
|
||||
link: GenTableCreateLink,
|
||||
dialect: SqlDialect
|
||||
): VisualBuildState {
|
||||
const main = (link.table_name || '').trim();
|
||||
const subSn = (link.sub_table_name || '').trim();
|
||||
const subFk = (link.sub_table_fk_name || '').trim();
|
||||
const main = (link.table_name || "").trim();
|
||||
const subSn = (link.sub_table_name || "").trim();
|
||||
const subFk = (link.sub_table_fk_name || "").trim();
|
||||
const hasSubPair = Boolean(subSn && subFk);
|
||||
const base: VisualBuildState = hasSubPair
|
||||
? visualPresetMasterSub(dialect)
|
||||
: visualPresetSingle(dialect);
|
||||
if (main) base.mainTableName = main;
|
||||
const mc = (link.table_comment || '').trim();
|
||||
const mc = (link.table_comment || "").trim();
|
||||
if (mc) base.mainComment = mc;
|
||||
if (hasSubPair) {
|
||||
base.subEnabled = true;
|
||||
base.subTableName = subSn;
|
||||
base.fkColumn = subFk;
|
||||
base.fkRefColumn = 'id';
|
||||
base.fkRefColumn = "id";
|
||||
} else {
|
||||
base.subEnabled = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user