优化eps

This commit is contained in:
COOL 2025-01-21 19:54:31 +08:00
parent e4b9e8a685
commit 3925e4fedb
10 changed files with 239 additions and 2 deletions

View File

@ -67,6 +67,8 @@ export interface QueryOp {
where?: Function;
// 查询字段
select?: string[];
// 字段模糊查询
fieldLike?: string[] | FieldEq[] | (string | FieldEq)[];
// 字段相等
fieldEq?: string[] | FieldEq[] | (string | FieldEq)[];
// 添加排序条件

View File

@ -15,6 +15,7 @@ import {
import { TypeORMDataSourceManager } from '@midwayjs/typeorm';
import { CoolUrlTagData } from '../tag/data';
import { TagTypes } from '../decorator/tag';
import { CurdOption, QueryOp } from '../decorator/controller';
/**
*
@ -54,6 +55,7 @@ export class CoolEps {
const appArr = [];
for (const controller of controllers) {
const { prefix, module, curdOption, routerOptions } = controller;
const pageQueryOp = await this.getPageOp(curdOption);
const name = curdOption?.entity?.name;
(_.startsWith(prefix, '/admin/') ? adminArr : appArr).push({
module,
@ -66,6 +68,29 @@ export class CoolEps {
api: routers[prefix],
name,
columns: entitys[name] || [],
pageQueryOp: {
keyWordLikeFields:
pageQueryOp?.keyWordLikeFields?.map(field =>
field.includes('.') ? field : `a.${field}`
) || [],
fieldEq:
pageQueryOp?.fieldEq?.map(field =>
typeof field === 'string'
? field.includes('.')
? field
: `a.${field}`
: field
) || [],
fieldLike:
pageQueryOp?.fieldLike?.map(field =>
typeof field === 'string'
? field.includes('.')
? field
: `a.${field}`
: field
) || [],
},
pageColumns: await this.pageColumns(entitys, curdOption),
prefix,
});
}
@ -73,6 +98,111 @@ export class CoolEps {
this.app = _.groupBy(appArr, 'module');
}
/**
*
* @param curdOption
* @returns
*/
async getPageOp(curdOption: CurdOption) {
let pageQueryOp: QueryOp | Function = curdOption?.pageQueryOp;
if (typeof pageQueryOp === 'function') {
pageQueryOp = await pageQueryOp();
}
return pageQueryOp as QueryOp;
}
/**
*
* @param entitys
* @param entityColumns
* @param curdOption
*/
async pageColumns(entitys: Record<string, any[]>, curdOption: CurdOption) {
const pageQueryOp = await this.getPageOp(curdOption);
// 检查 pageQueryOp 是否为对象且具有 select 属性
if (
pageQueryOp &&
typeof pageQueryOp === 'object' &&
'select' in pageQueryOp &&
curdOption?.entity?.name
) {
const select = pageQueryOp.select;
const join = pageQueryOp.join || [];
// 所有的关联entitys
const joinEntitys: {
name: string;
alias: string;
}[] = [{ name: curdOption.entity.name, alias: 'a' }];
if (join.length > 0) {
joinEntitys.push(
...join.map(item => {
return { name: item.entity.name, alias: item.alias };
})
);
}
// 处理 select
const result = [];
for (const selectItem of select) {
// 处理 'a.*' 这种情况
if (selectItem.endsWith('.*')) {
const alias = selectItem.split('.')[0];
const entity = joinEntitys.find(e => e.alias === alias);
if (entity) {
const entityColumns = entitys[entity.name] || [];
result.push(
...entityColumns.map(e => {
return {
...e,
source: `${alias}.${e.propertyName}`,
};
})
);
}
continue;
}
// 处理单个字段,如 'b.name' 或 'b.name as userName'
const asRegex = /\s+as\s+/i;
const [field, asName] = selectItem.split(asRegex).map(s => s.trim());
const [alias, fieldName] = field.split('.');
const entity = joinEntitys.find(e => e.alias === alias);
if (entity) {
const entityColumns = entitys[entity.name] || [];
const column = entityColumns.find(
col => col.propertyName === fieldName
);
if (column) {
result.push({
...column,
propertyName: asName || column.propertyName,
source: `${alias}.${column.propertyName}`,
});
}
}
}
// 将 createTime 和 updateTime 移到末尾
const finalResult = [...result];
const timeFields = ['createTime', 'updateTime'];
const timeColumns = [];
// 先找出并删除所有时间字段
for (let i = finalResult.length - 1; i >= 0; i--) {
if (timeFields.includes(finalResult[i].propertyName)) {
timeColumns.unshift(finalResult.splice(i, 1)[0]);
}
}
// 将时间字段添加到末尾
finalResult.push(...timeColumns);
return finalResult;
}
return [];
}
/**
*
* @param module
@ -150,13 +280,19 @@ export class CoolEps {
length: e.length,
comment: e.comment,
nullable: e.isNullable,
defaultValue: e.default,
dict: e['dict'],
source: `a.${e.propertyName}`,
};
}),
o => {
if (['createTime', 'updateTime'].includes(o.propertyName)) {
commColums.push(o);
}
return o && !['createTime', 'updateTime'].includes(o.propertyName);
return (
o &&
!['createTime', 'updateTime', 'tenantId'].includes(o.propertyName)
);
}
).concat(commColums);
result[entityMetadata.name] = columns;

View File

@ -470,6 +470,33 @@ export abstract class BaseMysqlService {
}
}
}
// 字段模糊查询
if (!_.isEmpty(option.fieldLike)) {
for (let key of option.fieldLike) {
// 如果key有包含.的情况下操作
if (typeof key === 'string' && key.includes('.')) {
const keys = key.split('.');
const lastKey = keys.pop();
key = { requestParam: lastKey, column: key };
}
// 单表字段无别名的情况下操作
if (typeof key === 'string') {
if (query[key] || query[key] === 0) {
find.andWhere(`${key} like :${key}`, {
[key]: `%${query[key]}%`,
});
this.sqlParams.push(`%${query[key]}%`);
}
} else {
if (query[key.requestParam] || query[key.requestParam] === 0) {
find.andWhere(`${key.column} like :${key.column}`, {
[key.column]: `%${query[key.requestParam]}%`,
});
this.sqlParams.push(`%${query[key.requestParam]}%`);
}
}
}
}
} else {
sqlArr.push(selects.join(','));
}

View File

@ -532,6 +532,40 @@ export abstract class BasePgService {
}
}
}
// 字段模糊查询
if (!_.isEmpty(option.fieldLike)) {
for (let key of option.fieldLike) {
const c = {};
let column;
// 如果key有包含.的情况下操作
if (typeof key === 'string' && key.includes('.')) {
const keys = key.split('.');
const lastKey = keys.pop();
key = { requestParam: lastKey, column: key };
column = key;
} else {
column = `a.${key}`;
}
// 单表字段无别名的情况下操作
if (typeof key === 'string') {
if (query[key] || query[key] == 0) {
c[key] = query[key];
find.andWhere(`${column} like :${key}`, {
[key]: `%${query[key]}%`,
});
this.sqlParams.push(`%${query[key]}%`);
}
} else {
if (query[key.requestParam] || query[key.requestParam] == 0) {
c[key.column] = query[key.requestParam];
find.andWhere(`${key.column} like :${key.column}`, {
[key.column]: `%${query[key.requestParam]}%`,
});
this.sqlParams.push(`%${query[key.requestParam]}%`);
}
}
}
}
} else {
sqlArr.push(selects.join(','));
}

View File

@ -523,7 +523,33 @@ export abstract class BaseSqliteService {
} else {
find.andWhere(`${key.column} ${eq} :${key.column}`, c);
}
// this.sqlParams.push(query[key.requestParam]);
}
}
}
}
// 字段模糊查询
if (!_.isEmpty(option.fieldLike)) {
for (let key of option.fieldLike) {
// 如果key有包含.的情况下操作
if (typeof key === 'string' && key.includes('.')) {
const keys = key.split('.');
const lastKey = keys.pop();
key = { requestParam: lastKey, column: key };
}
// 单表字段无别名的情况下操作
if (typeof key === 'string') {
if (query[key] || query[key] == 0) {
find.andWhere(`${key} like :${key}`, {
[key]: `%${query[key]}%`,
});
this.sqlParams.push(`%${query[key]}%`);
}
} else {
if (query[key.requestParam] || query[key.requestParam] == 0) {
find.andWhere(`${key.column} like :${key.column}`, {
[key.column]: `%${query[key.requestParam]}%`,
});
this.sqlParams.push(`%${query[key.requestParam]}%`);
}
}
}

View File

@ -35,6 +35,7 @@ function Column(typeOrOptions, options) {
if (options.type === "hstore" && !options.hstoreType)
options.hstoreType =
reflectMetadataType === Object ? "object" : "string";
if (typeof typeOrOptions === "function") {
// register an embedded
(0, globals_1.getMetadataArgsStorage)().embeddeds.push({
@ -61,6 +62,7 @@ function Column(typeOrOptions, options) {
propertyName: propertyName,
mode: "regular",
options: options,
dict: options.dict,
});
if (options.generated) {
(0, globals_1.getMetadataArgsStorage)().generations.push({

View File

@ -9,6 +9,10 @@ export interface ColumnOptions extends ColumnCommonOptions {
* Column type. Must be one of the value from the ColumnTypes class.
*/
type?: ColumnType;
/**
* cool dict key
*/
dict?: string | string[];
/**
* Column name in the database.
*/

View File

@ -11,6 +11,10 @@ import { ValueTransformer } from "../decorator/options/ValueTransformer";
*/
export declare class ColumnMetadata {
readonly "@instanceof": symbol;
/**
* cool
*/
dict?: string | string[];
/**
* Target class where column decorator is used.
* This may not be always equal to entity metadata (for example embeds or inheritance cases).

View File

@ -14,6 +14,7 @@ class ColumnMetadata {
// ---------------------------------------------------------------------
constructor(options) {
this["@instanceof"] = Symbol.for("ColumnMetadata");
this.dict = options.args.options.dict;
/**
* Type's length in the database.
*/

View File

@ -10,6 +10,7 @@ const UpdateValuesMissingError_1 = require("../error/UpdateValuesMissingError");
const error_1 = require("../error");
const EntityPropertyNotFoundError_1 = require("../error/EntityPropertyNotFoundError");
const DriverUtils_1 = require("../driver/DriverUtils");
const Broadcaster_1 = require("../subscriber/Broadcaster");
/**
* Allows to build complex sql queries in a fashion way and execute those queries.
*/