mirror of
https://github.com/cool-team-official/cool-admin-midway-packages.git
synced 2025-12-14 07:12:49 +00:00
修复postgres单表排序
This commit is contained in:
parent
689d7b3f1e
commit
8f35e571fb
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@cool-midway/core",
|
"name": "@cool-midway/core",
|
||||||
"version": "7.1.14",
|
"version": "7.1.15",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"typings": "index.d.ts",
|
"typings": "index.d.ts",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@cool-midway/core",
|
"name": "@cool-midway/core",
|
||||||
"version": "7.1.14",
|
"version": "7.1.15",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"typings": "index.d.ts",
|
"typings": "index.d.ts",
|
||||||
|
|||||||
@ -68,18 +68,18 @@ export abstract class BasePgService {
|
|||||||
let rSql = false;
|
let rSql = false;
|
||||||
if (condition || (condition === 0 && condition !== "")) {
|
if (condition || (condition === 0 && condition !== "")) {
|
||||||
rSql = true;
|
rSql = true;
|
||||||
for(let i = 0; i < params.length; i++) {
|
for (let i = 0; i < params.length; i++) {
|
||||||
const param = params[i];
|
const param = params[i];
|
||||||
if (param instanceof Array) {
|
if (param instanceof Array) {
|
||||||
// 将这个? 替换成 $1,$2,$3
|
// 将这个? 替换成 $1,$2,$3
|
||||||
const replaceStr = [];
|
const replaceStr = [];
|
||||||
for(let j = 0; j < param.length; j++) {
|
for (let j = 0; j < param.length; j++) {
|
||||||
replaceStr.push('$' + (this.sqlParams.length + j + 1));
|
replaceStr.push("$" + (this.sqlParams.length + j + 1));
|
||||||
}
|
}
|
||||||
this.sqlParams = this.sqlParams.concat(...params);
|
this.sqlParams = this.sqlParams.concat(...params);
|
||||||
sql = sql.replace('?', replaceStr.join(','));
|
sql = sql.replace("?", replaceStr.join(","));
|
||||||
} else {
|
} else {
|
||||||
sql = sql.replace('?', '$' + (this.sqlParams.length + 1));
|
sql = sql.replace("?", "$" + (this.sqlParams.length + 1));
|
||||||
this.sqlParams.push(param);
|
this.sqlParams.push(param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,22 +130,22 @@ export abstract class BasePgService {
|
|||||||
}
|
}
|
||||||
let newParams = [];
|
let newParams = [];
|
||||||
// sql没处理过?的情况下
|
// sql没处理过?的情况下
|
||||||
if(sql.includes('?')){
|
if (sql.includes("?")) {
|
||||||
for (const item of params) {
|
for (const item of params) {
|
||||||
// 如果是数组,将这个? 替换成 $1,$2,$3
|
// 如果是数组,将这个? 替换成 $1,$2,$3
|
||||||
if (item instanceof Array) {
|
if (item instanceof Array) {
|
||||||
const replaceStr = [];
|
const replaceStr = [];
|
||||||
for(let i = 0; i < item.length; i++) {
|
for (let i = 0; i < item.length; i++) {
|
||||||
replaceStr.push('$' + (newParams.length + i + 1));
|
replaceStr.push("$" + (newParams.length + i + 1));
|
||||||
}
|
}
|
||||||
newParams.push(...item)
|
newParams.push(...item);
|
||||||
sql = sql.replace('?', replaceStr.join(','));
|
sql = sql.replace("?", replaceStr.join(","));
|
||||||
} else {
|
} else {
|
||||||
sql = sql.replace('?', '$' + (newParams.length + 1));
|
sql = sql.replace("?", "$" + (newParams.length + 1));
|
||||||
newParams.push(item);
|
newParams.push(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
newParams = params;
|
newParams = params;
|
||||||
}
|
}
|
||||||
this.sqlParams = [];
|
this.sqlParams = [];
|
||||||
@ -202,20 +202,20 @@ export abstract class BasePgService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 将mysql语句转换为postgres语句
|
* 将mysql语句转换为postgres语句
|
||||||
* @param sql
|
* @param sql
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
protected convertToPostgres(sql) {
|
protected convertToPostgres(sql) {
|
||||||
// 首先确保表名被正确引用
|
// 首先确保表名被正确引用
|
||||||
sql = sql.replace(/(?<!")(\b\w+\b)\.(?!\w+")/g, '"$1".');
|
sql = sql.replace(/(?<!")(\b\w+\b)\.(?!\w+")/g, '"$1".');
|
||||||
// 然后确保字段名被正确引用
|
// 然后确保字段名被正确引用
|
||||||
return sql.replace(/\.(\w+)(?!\w)/g, '."$1"');
|
return sql.replace(/\.(\w+)(?!\w)/g, '."$1"');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询sql中的参数个数
|
* 查询sql中的参数个数
|
||||||
* @param sql
|
* @param sql
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
protected countDollarSigns(sql) {
|
protected countDollarSigns(sql) {
|
||||||
const matches = sql.match(/\$\d+/g);
|
const matches = sql.match(/\$\d+/g);
|
||||||
@ -238,25 +238,25 @@ export abstract class BasePgService {
|
|||||||
isExport = false,
|
isExport = false,
|
||||||
maxExportLimit,
|
maxExportLimit,
|
||||||
} = query;
|
} = query;
|
||||||
sql = `SELECT * FROM (${sql}) a `
|
sql = `SELECT * FROM (${sql}) a `;
|
||||||
if (order && sort && autoSort) {
|
if (order && sort && autoSort) {
|
||||||
if (!(await this.paramSafetyCheck(order + sort))) {
|
if (!(await this.paramSafetyCheck(order + sort))) {
|
||||||
throw new CoolValidateException("非法传参~");
|
throw new CoolValidateException("非法传参~");
|
||||||
}
|
}
|
||||||
sql += `ORDER BY a."${order}" ${this.checkSort(sort)}`
|
sql += `ORDER BY a."${order}" ${this.checkSort(sort)}`;
|
||||||
}
|
}
|
||||||
let cutParams = 0;
|
let cutParams = 0;
|
||||||
let paramCount = this.countDollarSigns(sql);
|
let paramCount = this.countDollarSigns(sql);
|
||||||
if (isExport && maxExportLimit > 0) {
|
if (isExport && maxExportLimit > 0) {
|
||||||
this.sqlParams.push(parseInt(maxExportLimit));
|
this.sqlParams.push(parseInt(maxExportLimit));
|
||||||
cutParams = 1;
|
cutParams = 1;
|
||||||
sql += ` LIMIT $${paramCount+1}`;
|
sql += ` LIMIT $${paramCount + 1}`;
|
||||||
}
|
}
|
||||||
if (!isExport) {
|
if (!isExport) {
|
||||||
this.sqlParams.push(parseInt(size));
|
this.sqlParams.push(parseInt(size));
|
||||||
this.sqlParams.push((page - 1) * size);
|
this.sqlParams.push((page - 1) * size);
|
||||||
cutParams = 2;
|
cutParams = 2;
|
||||||
sql += ` LIMIT $${ paramCount + 1} OFFSET $${ paramCount+ 2 }`;
|
sql += ` LIMIT $${paramCount + 1} OFFSET $${paramCount + 2}`;
|
||||||
}
|
}
|
||||||
let params = [];
|
let params = [];
|
||||||
params = params.concat(this.sqlParams);
|
params = params.concat(this.sqlParams);
|
||||||
@ -351,33 +351,37 @@ export abstract class BasePgService {
|
|||||||
* 新增|修改
|
* 新增|修改
|
||||||
* @param param 数据
|
* @param param 数据
|
||||||
*/
|
*/
|
||||||
async addOrUpdate(param: any | any[], type: 'add' | 'update' = 'add') {
|
async addOrUpdate(param: any | any[], type: "add" | "update" = "add") {
|
||||||
if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY);
|
if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY);
|
||||||
delete param.createTime;
|
delete param.createTime;
|
||||||
// 判断是否是批量操作
|
// 判断是否是批量操作
|
||||||
if (param instanceof Array) {
|
if (param instanceof Array) {
|
||||||
param.forEach((item) => {
|
param.forEach((item) => {
|
||||||
item.updateTime = new Date();
|
item.updateTime = new Date();
|
||||||
item.createTime = new Date();
|
item.createTime = new Date();
|
||||||
});
|
});
|
||||||
await this.entity.save(param);
|
await this.entity.save(param);
|
||||||
} else{
|
} else {
|
||||||
const upsert = this._coolConfig.crud?.upsert || 'normal';
|
const upsert = this._coolConfig.crud?.upsert || "normal";
|
||||||
if (type == 'update') {
|
if (type == "update") {
|
||||||
if(upsert == 'save') {
|
if (upsert == "save") {
|
||||||
const info = await this.entity.findOneBy({id: param.id})
|
const info = await this.entity.findOneBy({ id: param.id });
|
||||||
param = {
|
param = {
|
||||||
...info,
|
...info,
|
||||||
...param
|
...param,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
param.updateTime = new Date();
|
param.updateTime = new Date();
|
||||||
upsert == 'normal'? await this.entity.update(param.id, param): await this.entity.save(param);
|
upsert == "normal"
|
||||||
|
? await this.entity.update(param.id, param)
|
||||||
|
: await this.entity.save(param);
|
||||||
}
|
}
|
||||||
if(type =='add'){
|
if (type == "add") {
|
||||||
param.createTime = new Date();
|
param.createTime = new Date();
|
||||||
param.updateTime = new Date();
|
param.updateTime = new Date();
|
||||||
upsert == 'normal'? await this.entity.insert(param): await this.entity.save(param);
|
upsert == "normal"
|
||||||
|
? await this.entity.insert(param)
|
||||||
|
: await this.entity.save(param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -473,10 +477,10 @@ export abstract class BasePgService {
|
|||||||
const keyWordLikeFields = option.keyWordLikeFields || [];
|
const keyWordLikeFields = option.keyWordLikeFields || [];
|
||||||
for (let i = 0; i < option.keyWordLikeFields?.length || 0; i++) {
|
for (let i = 0; i < option.keyWordLikeFields?.length || 0; i++) {
|
||||||
let column = keyWordLikeFields[i];
|
let column = keyWordLikeFields[i];
|
||||||
column = column.includes('.')? column: `a.${column}`;
|
column = column.includes(".") ? column : `a.${column}`;
|
||||||
const values = {};
|
const values = {};
|
||||||
values[`keyWord${i}`] = keyWord;
|
values[`keyWord${i}`] = keyWord;
|
||||||
qb.orWhere(`${column} like :keyWord${i}`,values);
|
qb.orWhere(`${column} like :keyWord${i}`, values);
|
||||||
this.sqlParams.push(keyWord);
|
this.sqlParams.push(keyWord);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -495,13 +499,13 @@ export abstract class BasePgService {
|
|||||||
const c = {};
|
const c = {};
|
||||||
let column;
|
let column;
|
||||||
// 如果key有包含.的情况下操作
|
// 如果key有包含.的情况下操作
|
||||||
if(typeof key === "string" && key.includes('.')){
|
if (typeof key === "string" && key.includes(".")) {
|
||||||
const keys = key.split('.');
|
const keys = key.split(".");
|
||||||
const lastKey = keys.pop();
|
const lastKey = keys.pop();
|
||||||
key = {requestParam: lastKey, column: key};
|
key = { requestParam: lastKey, column: key };
|
||||||
column = key
|
column = key;
|
||||||
}else{
|
} else {
|
||||||
column = `a.${key}`
|
column = `a.${key}`;
|
||||||
}
|
}
|
||||||
// 单表字段无别名的情况下操作
|
// 单表字段无别名的情况下操作
|
||||||
if (typeof key === "string") {
|
if (typeof key === "string") {
|
||||||
@ -556,9 +560,50 @@ export abstract class BasePgService {
|
|||||||
sqlArr.push("FROM");
|
sqlArr.push("FROM");
|
||||||
// 取sqls的最后一个
|
// 取sqls的最后一个
|
||||||
sqlArr.push(sqls[sqls.length - 1]);
|
sqlArr.push(sqls[sqls.length - 1]);
|
||||||
|
sqlArr.forEach((item, index) => {
|
||||||
|
if (item.includes("ORDER BY")) {
|
||||||
|
sqlArr[index] = this.replaceOrderByPrefix(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
return sqlArr.join(" ");
|
return sqlArr.join(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换sql中的表别名
|
||||||
|
* @param sql
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
replaceOrderByPrefix(sql) {
|
||||||
|
// 使用正则表达式匹配 ORDER BY 后面的部分
|
||||||
|
// 这里假设 ORDER BY 后面跟着的是由空格分隔的字段名,且字段名由双引号包围
|
||||||
|
const orderByRegex =
|
||||||
|
/ORDER BY\s+("[^"]+_[^"]+")(\s*(ASC|DESC)?\s*(,\s*"[^"]+_[^"]+")*)/gi;
|
||||||
|
|
||||||
|
// 定义替换函数
|
||||||
|
// @ts-ignore
|
||||||
|
function replaceMatch(match, p1, p2) {
|
||||||
|
// 将 p1 中的 "a_" 替换为 "a."
|
||||||
|
const replacedField = p1.replace(/a_([^"]+)/g, "a.$1");
|
||||||
|
// 如果有其他字段,递归调用替换函数
|
||||||
|
const replacedRest = p2.replace(/("[^"]+_)/g, (m, p) =>
|
||||||
|
p.replace("a_", "a.")
|
||||||
|
);
|
||||||
|
// 组合替换后的字段和其他部分
|
||||||
|
return `ORDER BY ${replacedField.replace(/"/g, "")}${replacedRest.replace(
|
||||||
|
/"/g,
|
||||||
|
""
|
||||||
|
)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用替换函数替换匹配到的内容
|
||||||
|
const replacedOrderBySql = sql.replace(orderByRegex, replaceMatch);
|
||||||
|
|
||||||
|
// 移除所有双引号
|
||||||
|
const sqlWithoutQuotes = replacedOrderBySql.replace(/"/g, "");
|
||||||
|
|
||||||
|
return sqlWithoutQuotes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 筛选的字段匹配
|
* 筛选的字段匹配
|
||||||
* @param select 筛选的字段
|
* @param select 筛选的字段
|
||||||
@ -567,30 +612,32 @@ export abstract class BasePgService {
|
|||||||
*/
|
*/
|
||||||
protected matchColumn(select: string[] = [], field: string) {
|
protected matchColumn(select: string[] = [], field: string) {
|
||||||
for (const column of select) {
|
for (const column of select) {
|
||||||
// 检查字段是否有别名,考虑 'AS' 关键字的不同大小写形式
|
// 检查字段是否有别名,考虑 'AS' 关键字的不同大小写形式
|
||||||
const aliasPattern = new RegExp(`\\b\\w+\\s+as\\s+${field}\\b`, 'i');
|
const aliasPattern = new RegExp(`\\b\\w+\\s+as\\s+${field}\\b`, "i");
|
||||||
const aliasMatch = column.match(aliasPattern);
|
const aliasMatch = column.match(aliasPattern);
|
||||||
if (aliasMatch) {
|
if (aliasMatch) {
|
||||||
// 提取别名前的字段和表名
|
// 提取别名前的字段和表名
|
||||||
const fieldPattern = new RegExp(`(\\w+)\\.(\\w+)\\s+as\\s+${field}`, 'i');
|
const fieldPattern = new RegExp(
|
||||||
const fieldMatch = column.match(fieldPattern);
|
`(\\w+)\\.(\\w+)\\s+as\\s+${field}`,
|
||||||
if (fieldMatch) {
|
"i"
|
||||||
// 返回匹配到的表名
|
);
|
||||||
return fieldMatch[1];
|
const fieldMatch = column.match(fieldPattern);
|
||||||
}
|
if (fieldMatch) {
|
||||||
}
|
// 返回匹配到的表名
|
||||||
|
return fieldMatch[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 检查字段是否直接在选择列表中
|
// 检查字段是否直接在选择列表中
|
||||||
const fieldPattern = new RegExp(`\\b(\\w+)\\.${field}\\b`, 'i');
|
const fieldPattern = new RegExp(`\\b(\\w+)\\.${field}\\b`, "i");
|
||||||
const fieldMatch = column.match(fieldPattern);
|
const fieldMatch = column.match(fieldPattern);
|
||||||
if (fieldMatch) {
|
if (fieldMatch) {
|
||||||
// 如果直接匹配到字段,返回字段所属的表名
|
// 如果直接匹配到字段,返回字段所属的表名
|
||||||
return fieldMatch[1];
|
return fieldMatch[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果没有匹配到任何特定的表或别名,返回默认的 'a' 表
|
// 如果没有匹配到任何特定的表或别名,返回默认的 'a' 表
|
||||||
return 'a';
|
return "a";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user