@shencom/api
Version:
shencom api group
305 lines (274 loc) • 9.55 kB
text/typescript
import type { SC } from '../typings/api';
import { OperateEnum } from './operate';
import type { Operate, OperateType, QueryLr } from './operate';
type QueryValue = string | number | null | undefined;
/**
* 创建单个查询条件表达式
*
* @export
* @param {QueryValue} val 查询的值
* @param {string} prop 后端字段
* @param {Operate} [operate] 筛选条件 (默认: OperateEnum.LIKE)
* @param {QueryLr} [lr] 逻辑关系(and/or)
*
* @example
* ```js
* ApiQueryItemConstruct('张三', 'name') // { value: '张三', prop: 'name', operate: 'LIKE' }
* ApiQueryItemConstruct(100, 'age', OperateEnum.EQ) // { value: 100, prop: 'age', operate: 'EQ' }
* ApiQueryItemConstruct('2022-01-01', 'createTime', OperateEnum.BTW) // { value: '2022-01-01', prop: 'createTime', operate: 'BTW' }
* ApiQueryItemConstruct(null, 'status') // null
* ApiQueryItemConstruct(undefined, 'status') // null
* ApiQueryItemConstruct('', 'status') // null
* ```
* @returns {SC.API.Query | null} 查询条件表达式,如果值为null、undefined或空字符串则返回null
*/
export function ApiQueryItemConstruct(
val: QueryValue,
prop: string,
operate?: Operate,
lr?: QueryLr,
): SC.API.Query | null {
// 如果值为null、undefined或空字符串,直接返回null
if (val === null || val === undefined || val === '') {
return null;
}
const _operate = operate || OperateEnum.LIKE;
return { value: val, prop, operate: _operate, lr };
}
const OperateTypeDefault: Record<OperateType, Operate> = {
number: OperateEnum.EQ,
string: OperateEnum.LIKE,
rangeDateTime: OperateEnum.BTW,
select: OperateEnum.IN,
date: OperateEnum.EQ,
};
/**
* 查询参数生成格式方法
*
* @export
* @param {string | number | null} val 查询的值
* @param {string} prop 后端字段
* @param {Query['operate']} [operateType] 筛选条件 (默认: string)
* @param {[val, prop, operateType?][]} params - 同 [val, prop, operateType]
*
* @example
* ```js
* ApiQueryHandler('1', 'active')
* ApiQueryHandler('2020-08-03', 'createdAt', OperateEnum.RANGE_DATE_TIME)
* ApiQueryHandler([[1, 'active'], ['2020-08-03', 'createdAt', OperateEnum.RANGE_DATE_TIME, LrEnum.AND]]);
* ```
* @deprecated 请使用 ApiQueryItemConstruct 代替
* @returns {SC.API.IndexQuery}
*/
export function ApiQueryHandler(
val: QueryValue,
prop: string,
operate?: OperateType | Operate,
lr?: QueryLr,
): SC.API.IndexQuery;
export function ApiQueryHandler(
params: [QueryValue, string, (OperateType | Operate)?, QueryLr?][],
): SC.API.IndexQuery;
export function ApiQueryHandler(val: any, prop?: any, operate?: any, lr?: any): SC.API.IndexQuery {
const exps: SC.API.IndexQuery[0]['exps'] = [];
if (Array.isArray(val)) {
for (let index = 0; index < val.length; index++) {
const [value, prop, operate, lr] = val[index];
const _lr = index === 0 ? undefined : lr;
const _operate = OperateTypeDefault[operate as OperateType] || operate;
const item = ApiQueryItemConstruct(value, prop, _operate, _lr);
if (item) {
exps.push(item);
}
}
} else {
const _operate = OperateTypeDefault[operate as OperateType] || operate;
const item = ApiQueryItemConstruct(val, prop, _operate, lr);
if (item) {
exps.push(item);
}
}
return [{ exps }];
}
/**
* 创建查询条件表达式数组
*
* @export
* @param {QueryValue} val 查询的值
* @param {string} prop 后端字段
* @param {Operate} [operate] 筛选条件 (默认: OperateEnum.LIKE)
* @param {QueryLr} [lr] 逻辑关系(and/or)
* @param {[QueryValue, string, Operate?, QueryLr?][]} params 同 [val, prop, operate, lr]
*
* @example
* ```js
* ApiQueryConstruct('张三', 'name')
* // 返回: [{ value: '张三', prop: 'name', operate: 'LIKE' }]
*
* ApiQueryConstruct([
* [100, 'age', OperateEnum.EQ],
* ['张三', 'name', OperateEnum.LIKE, LrEnum.AND]
* ])
* // 返回: [
* // { value: 100, prop: 'age', operate: 'EQ' },
* // { value: '张三', prop: 'name', operate: 'LIKE', lr: 'and' }
* // ]
* ```
* @returns {SC.API.Query[]} 查询条件表达式数组
*/
export function ApiQueryConstruct(
val: QueryValue,
prop: string,
operate?: Operate,
lr?: QueryLr,
): SC.API.Query[];
export function ApiQueryConstruct(
params: [QueryValue, string, Operate?, QueryLr?][],
): SC.API.Query[];
export function ApiQueryConstruct(val: any, prop?: any, operate?: any, lr?: any): SC.API.Query[] {
const queries: SC.API.Query[] = [];
if (Array.isArray(val)) {
for (let index = 0; index < val.length; index++) {
const [value, prop, operate, lr] = val[index];
const _lr = index === 0 ? undefined : lr;
const queryItem = ApiQueryItemConstruct(value, prop, operate, _lr);
// 只有当queryItem不为null时才添加到查询数组中
if (queryItem !== null) {
queries.push(queryItem);
}
}
} else {
const queryItem = ApiQueryItemConstruct(val, prop, operate, lr);
// 只有当queryItem不为null时才添加到查询数组中
if (queryItem !== null) {
queries.push(queryItem);
}
}
return queries;
}
/**
* 将查询条件转换为键值对格式
*
* @export
* @param {SC.API.Query} query 单个查询条件
* @param {SC.API.Query[]} queries 查询条件数组
*
* @example
* ```js
* ApiQueryDestructure({ value: '张三', prop: 'name', operate: 'LIKE' }) // { "name": "张三" }
* ApiQueryDestructure([
* { value: 100, prop: 'age', operate: 'EQ' },
* { value: '张三', prop: 'name', operate: 'LIKE', lr: 'and' }
* ]) // { "age": 100, "name": "张三" }
* ```
* @returns {Record<string, any>} 键值对格式的查询条件
*/
export function ApiQueryDestructure(query: SC.API.Query): Record<string, any>;
export function ApiQueryDestructure(queries: SC.API.Query[]): Record<string, any>;
export function ApiQueryDestructure(param: any): Record<string, any> {
const result: Record<string, any> = {};
if (Array.isArray(param)) {
param.forEach((item) => {
if (item && item.prop) {
result[item.prop] = item.value;
}
});
} else if (param && param.prop) {
result[param.prop] = param.value;
}
return result;
}
/**
* 向查询条件数组中插入查询条件
*
* @export
* @param {SC.API.Query[]} query 查询条件数组
* @param {SC.API.Query | SC.API.Query[]} insertQuery 要插入的查询条件
*
* @example
* ```js
* // 向查询条件中插入单个条件
* const query = [{ value: 100, prop: 'age', operate: 'EQ' }];
* const newQuery = { value: '张三', prop: 'name', operate: 'LIKE', lr: LrEnum.AND };
* ApiQueryInsert(query, newQuery)
* // 返回: [
* // { value: 100, prop: 'age', operate: 'EQ' },
* // { value: '张三', prop: 'name', operate: 'LIKE', lr: LrEnum.AND }
* // ]
*
* // 向查询条件中插入多个条件
* const query = [{ value: 100, prop: 'age', operate: 'EQ' }];
* const newQueries = [
* { value: '张三', prop: 'name', operate: 'LIKE', lr: LrEnum.AND },
* { value: 1, prop: 'gender', operate: 'EQ', lr: LrEnum.AND }
* ];
* ApiQueryInsert(query, newQueries)
* // 返回: [
* // { value: 100, prop: 'age', operate: 'EQ' },
* // { value: '张三', prop: 'name', operate: 'LIKE', lr: LrEnum.AND },
* // { value: 1, prop: 'gender', operate: 'EQ', lr: LrEnum.AND }
* // ]
* ```
*
* @returns {SC.API.Query[]} 插入后的查询条件数组
*/
export function ApiQueryInsert(
query: SC.API.Query[],
insertQuery: SC.API.Query | SC.API.Query[],
): SC.API.Query[] {
if (!Array.isArray(query) || query.length === 0) {
return Array.isArray(insertQuery) ? [...insertQuery] : [insertQuery];
}
if (Array.isArray(insertQuery)) {
return [...query, ...insertQuery];
} else {
return [...query, insertQuery];
}
}
/**
* 从查询条件数组中删除指定字段的查询条件
*
* @export
* @param {SC.API.Query[]} query 查询条件数组
* @param {string | string[]} deleteProps 要删除的字段名(单个字符串或字符串数组)
*
* @example
* ```js
* // 删除单个字段的查询条件
* const query = [
* { value: 100, prop: 'age', operate: 'EQ' },
* { value: '张三', prop: 'name', operate: 'LIKE', lr: LrEnum.AND }
* ];
* ApiQueryDelete(query, 'age')
* // 返回: [{ value: '张三', prop: 'name', operate: 'LIKE', lr: LrEnum.AND }]
*
* // 删除多个字段的查询条件
* const query = [
* { value: 100, prop: 'age', operate: 'EQ' },
* { value: '张三', prop: 'name', operate: 'LIKE', lr: LrEnum.AND },
* { value: 1, prop: 'gender', operate: 'EQ', lr: LrEnum.AND }
* ];
* ApiQueryDelete(query, ['age', 'gender'])
* // 返回: [{ value: '张三', prop: 'name', operate: 'LIKE', lr: LrEnum.AND }]
*
* // 当结果为空数组时返回null
* const query = [{ value: 100, prop: 'age', operate: 'EQ' }];
* ApiQueryDelete(query, 'age') // null
* ```
*
* @returns {SC.API.Query[] | null} 删除后的查询条件数组,如果为空则返回null
*/
export function ApiQueryDelete(
query: SC.API.Query[],
deleteProps: string | string[],
): SC.API.Query[] | null {
if (!Array.isArray(query) || query.length === 0) {
return query;
}
if (!deleteProps || (Array.isArray(deleteProps) && deleteProps.length === 0)) {
return query;
}
const targetDeleteProps = Array.isArray(deleteProps) ? deleteProps : [deleteProps];
const filteredQuery = query.filter((item) => !targetDeleteProps.includes(item.prop));
return filteredQuery.length === 0 ? null : filteredQuery;
}