mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-02 03:58:07 +08:00
Merge pull request #6279 from hsm-lv/feat-formula
feat:增加判断日期范围的表达式BETWEENRANGE&&优化STARTOF和ENDOF
This commit is contained in:
commit
e5b9f24dfc
@ -508,6 +508,11 @@ test('evalute:array:func', () => {
|
||||
expect(evaluate('${GET(obj1, "p2")}', data)).toBe('age');
|
||||
expect(evaluate('${GET(obj1, "p4.1.p42")}', data)).toBe('amis');
|
||||
expect(evaluate('${GET(obj1, "p4[1].p42")}', data)).toBe('amis');
|
||||
|
||||
expect(evaluate('${ENCODEJSON(obj1)}', data)).toBe(JSON.stringify(data.obj1));
|
||||
expect(
|
||||
evaluate('${DECODEJSON("{\\"name\\":\\"amis\\"}")}', data)
|
||||
).toMatchObject(JSON.parse('{"name":"amis"}'));
|
||||
});
|
||||
|
||||
test('evalute:ISTYPE', () => {
|
||||
|
@ -272,6 +272,80 @@ test('formula:date', () => {
|
||||
moment('2023-02-27').isoWeekday()
|
||||
);
|
||||
expect(evalFormual('WEEK("2023-03-05")')).toBe(moment('2023-03-05').week());
|
||||
expect(
|
||||
evalFormual(
|
||||
'BETWEENRANGE("2023-03-08", ["2023-03-01", "2024-04-07"], "year")'
|
||||
)
|
||||
).toBe(
|
||||
moment('2023-03-08').isBetween('2023-03-01', '2024-04-07', 'year', '[]')
|
||||
);
|
||||
expect(
|
||||
evalFormual(
|
||||
'BETWEENRANGE("2022-03-08", ["2023-03-01", "2024-04-07"], "year")'
|
||||
)
|
||||
).toBe(
|
||||
moment('2022-03-08').isBetween('2023-03-01', '2024-04-07', 'year', '[]')
|
||||
);
|
||||
expect(
|
||||
evalFormual(
|
||||
'BETWEENRANGE("2023-03-08", ["2023-03-01", "2023-04-07"], "month")'
|
||||
)
|
||||
).toBe(
|
||||
moment('2023-03-08').isBetween('2023-03-01', '2023-04-07', 'month', '[]')
|
||||
);
|
||||
expect(
|
||||
evalFormual(
|
||||
'BETWEENRANGE("2023-05-08", ["2023-03-01", "2023-04-07", "month"])'
|
||||
)
|
||||
).toBe(
|
||||
moment('2023-05-08').isBetween('2023-03-01', '2023-04-07', 'month', '[]')
|
||||
);
|
||||
expect(
|
||||
evalFormual('BETWEENRANGE("2023-03-06", ["2023-03-01", "2023-05-07"])')
|
||||
).toBe(
|
||||
moment('2023-03-06').isBetween('2023-03-01', '2023-05-07', 'day', '[]')
|
||||
);
|
||||
expect(
|
||||
evalFormual('BETWEENRANGE("2023-05-08", ["2023-03-01", "2023-05-07"])')
|
||||
).toBe(
|
||||
moment('2023-05-08').isBetween('2023-03-01', '2023-05-07', 'day', '[]')
|
||||
);
|
||||
expect(
|
||||
evalFormual(
|
||||
'BETWEENRANGE("2023-05-07", ["2023-03-01", "2023-05-07"], "day", "()")'
|
||||
)
|
||||
).toBe(
|
||||
moment('2023-05-07').isBetween('2023-03-01', '2023-05-07', 'day', '()')
|
||||
);
|
||||
expect(
|
||||
evalFormual(
|
||||
'CONCATENATE(STARTOF("2023-02-28", "day"), "," ,ENDOF("2023-02-28", "day"))'
|
||||
)
|
||||
).toBe(
|
||||
`${moment('2023-02-28').startOf('day').toDate()},${moment('2023-02-28')
|
||||
.endOf('day')
|
||||
.toDate()}`
|
||||
);
|
||||
expect(
|
||||
evalFormual(
|
||||
'CONCATENATE(STARTOF("2023-02-28", "day", "YYYY-MM-DD HH:mm:ss"), ",", ENDOF("2023-02-28", "day", "YYYY-MM-DD HH:mm:ss"))'
|
||||
)
|
||||
).toBe(
|
||||
`${moment('2023-02-28')
|
||||
.startOf('day')
|
||||
.format('YYYY-MM-DD HH:mm:ss')},${moment('2023-02-28')
|
||||
.endOf('day')
|
||||
.format('YYYY-MM-DD HH:mm:ss')}`
|
||||
);
|
||||
expect(
|
||||
evalFormual(
|
||||
'CONCATENATE(STARTOF("2023-02-28", "day", "X"), "," ,ENDOF("2023-02-28", "day", "X"))'
|
||||
)
|
||||
).toBe(
|
||||
`${moment('2023-02-28').startOf('day').format('X')},${moment('2023-02-28')
|
||||
.endOf('day')
|
||||
.format('X')}`
|
||||
);
|
||||
});
|
||||
|
||||
test('formula:last', () => {
|
||||
|
@ -617,7 +617,7 @@
|
||||
用法:`WEEKDAY(date)`
|
||||
|
||||
* `date:any` 日期
|
||||
* `type:number` 星期定义类型 1表示0至6代表星期一到星期日,2表示1至7代表星期一到星期天
|
||||
* `type:number` 星期定义类型,默认为1,1表示0至6代表星期一到星期日,2表示1至7代表星期一到星期日
|
||||
|
||||
返回:`number` 星期几的数字标识
|
||||
|
||||
@ -632,6 +632,7 @@ WEEKDAY('2023-02-27') 得到 1
|
||||
用法:`WEEK(date)`
|
||||
|
||||
* `date:any` 日期
|
||||
* `isISO:boolean` 是否ISO星期
|
||||
|
||||
返回:`number` 星期几的数字标识
|
||||
|
||||
@ -687,6 +688,7 @@ DATERANGESPLIT('1676563200, 1676735999', 'end' , 'YYYY.MM.DD hh:mm:ss') 得到 '
|
||||
|
||||
* `date:date` 日期对象
|
||||
* `unit:string` 比如可以传入 'day'、'month'、'year' 或者 `week` 等等
|
||||
* `format:string` 日期格式,可选
|
||||
|
||||
返回:`date` 新的日期对象
|
||||
|
||||
@ -698,6 +700,7 @@ DATERANGESPLIT('1676563200, 1676735999', 'end' , 'YYYY.MM.DD hh:mm:ss') 得到 '
|
||||
|
||||
* `date:date` 日期对象
|
||||
* `unit:string` 比如可以传入 'day'、'month'、'year' 或者 `week` 等等
|
||||
* `format:string` 日期格式,可选
|
||||
|
||||
返回:`date` 新的日期对象
|
||||
|
||||
@ -862,6 +865,21 @@ DATEMODIFY(A, -2, 'month')
|
||||
|
||||
判断两个日期,是否第一个日期在第二个日期的后面
|
||||
|
||||
### BETWEENRANGE
|
||||
|
||||
用法:`BETWEENRANGE(date, [start, end])`
|
||||
|
||||
* `date:any` 第一个日期
|
||||
* `daterange:Array<any>` 日期范围
|
||||
* `unit:string` 单位,默认是 'day', 即之比较到天
|
||||
* `inclusivity:string` 包容性规则,默认为'[]'。[ 表示包含、( 表示排除,如果使用包容性参数,则必须传入两个指示符,如'()'表示左右范围都排除
|
||||
|
||||
返回:`boolean` 判断结果
|
||||
|
||||
判断日期是否在指定范围内
|
||||
|
||||
示例:BETWEENRANGE('2021/12/6', ['2021/12/5','2021/12/7'])
|
||||
|
||||
### ISSAMEORBEFORE
|
||||
|
||||
用法:`ISSAMEORBEFORE(a, b)`
|
||||
@ -1058,6 +1076,20 @@ CONCAT(['a', 'b', 'c'], ['1'], ['3']) 得到 ['a', 'b', 'c', '1', '3']
|
||||
|
||||
UNIQ([{a: '1'}, {b: '2'}, {a: '1'}], 'id')
|
||||
|
||||
### ENCODEJSON
|
||||
|
||||
用法:`ENCODEJSON({name: 'amis'})`
|
||||
|
||||
* `obj:object` 数组
|
||||
|
||||
返回:`string` 结果
|
||||
|
||||
将JS对象转换成JSON字符串
|
||||
|
||||
示例:
|
||||
|
||||
ENCODEJSON({name: 'amis'}) 得到 '{"name":"amis"}'
|
||||
|
||||
## 其他
|
||||
|
||||
### GET
|
||||
@ -1086,7 +1118,23 @@ GET({arr: [{name: 'amis', age: 18}]}, 'arr.1.name', 'not-found') 得到 'not-fou
|
||||
|
||||
* `判断对象:string` null
|
||||
|
||||
返回:`boolean` 结果结果
|
||||
返回:`boolean` 结果
|
||||
|
||||
判断是否为类型支持:string, number, array, date, plain-object。
|
||||
|
||||
## 编码
|
||||
|
||||
### DECODEJSON
|
||||
|
||||
用法:`DECODEJSON('{\"name\": "amis"}')`
|
||||
|
||||
* `str:string` 字符串
|
||||
|
||||
返回:`object` 结果
|
||||
|
||||
解析JSON编码数据,返回JS对象
|
||||
|
||||
示例:
|
||||
|
||||
DECODEJSON('{\"name\": "amis"}') 得到 {name: 'amis'}
|
||||
|
||||
|
@ -1042,7 +1042,7 @@ export const doc: {
|
||||
{
|
||||
type: "number",
|
||||
name: "type",
|
||||
description: "星期定义类型 1表示0至6代表星期一到星期日,2表示1至7代表星期一到星期天"
|
||||
description: "星期定义类型,默认为1,1表示0至6代表星期一到星期日,2表示1至7代表星期一到星期日"
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
@ -1060,6 +1060,11 @@ export const doc: {
|
||||
type: "any",
|
||||
name: "date",
|
||||
description: "日期"
|
||||
},
|
||||
{
|
||||
type: "boolean",
|
||||
name: "isISO",
|
||||
description: "是否ISO星期"
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
@ -1136,6 +1141,11 @@ export const doc: {
|
||||
type: "string",
|
||||
name: "unit",
|
||||
description: "比如可以传入 'day'、'month'、'year' 或者 `week` 等等"
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "format",
|
||||
description: "日期格式,可选"
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
@ -1158,6 +1168,11 @@ export const doc: {
|
||||
type: "string",
|
||||
name: "unit",
|
||||
description: "比如可以传入 'day'、'month'、'year' 或者 `week` 等等"
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "format",
|
||||
description: "日期格式,可选"
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
@ -1459,6 +1474,38 @@ export const doc: {
|
||||
},
|
||||
namespace: "日期函数"
|
||||
},
|
||||
{
|
||||
name: "BETWEENRANGE",
|
||||
description: "判断日期是否在指定范围内\n\n示例:BETWEENRANGE('2021/12/6', ['2021/12/5','2021/12/7'])",
|
||||
example: "BETWEENRANGE(date, [start, end])",
|
||||
params: [
|
||||
{
|
||||
type: "any",
|
||||
name: "date",
|
||||
description: "第一个日期"
|
||||
},
|
||||
{
|
||||
type: "Array<any>",
|
||||
name: "daterange",
|
||||
description: "日期范围"
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "unit",
|
||||
description: "单位,默认是 'day', 即之比较到天"
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "inclusivity",
|
||||
description: "包容性规则,默认为'[]'。[ 表示包含、( 表示排除,如果使用包容性参数,则必须传入两个指示符,如'()'表示左右范围都排除"
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: "boolean",
|
||||
description: "判断结果"
|
||||
},
|
||||
namespace: "日期函数"
|
||||
},
|
||||
{
|
||||
name: "ISSAMEORBEFORE",
|
||||
description: "判断两个日期,是否第一个日期在第二个日期的前面或者相等",
|
||||
@ -1789,6 +1836,40 @@ export const doc: {
|
||||
},
|
||||
namespace: "数组"
|
||||
},
|
||||
{
|
||||
name: "ENCODEJSON",
|
||||
description: "将JS对象转换成JSON字符串\n\n示例:\n\nENCODEJSON({name: 'amis'}) 得到 '{\"name\":\"amis\"}'",
|
||||
example: "ENCODEJSON({name: 'amis'})",
|
||||
params: [
|
||||
{
|
||||
type: "object",
|
||||
name: "obj",
|
||||
description: "数组"
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: "string",
|
||||
description: "结果"
|
||||
},
|
||||
namespace: "数组"
|
||||
},
|
||||
{
|
||||
name: "DECODEJSON",
|
||||
description: "解析JSON编码数据,返回JS对象\n\n示例:\n\nDECODEJSON('{\\\"name\\\": \"amis\"}') 得到 {name: 'amis'}",
|
||||
example: "DECODEJSON('{\\\"name\\\": \"amis\"}')",
|
||||
params: [
|
||||
{
|
||||
type: "string",
|
||||
name: "str",
|
||||
description: "字符串"
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: "object",
|
||||
description: "结果"
|
||||
},
|
||||
namespace: "编码"
|
||||
},
|
||||
{
|
||||
name: "ISTYPE",
|
||||
description: "判断是否为类型支持:string, number, array, date, plain-object。",
|
||||
@ -1802,7 +1883,7 @@ export const doc: {
|
||||
],
|
||||
returns: {
|
||||
type: "boolean",
|
||||
description: "结果结果"
|
||||
description: "结果"
|
||||
},
|
||||
namespace: "其他"
|
||||
}
|
||||
|
@ -1529,11 +1529,13 @@ export class Evaluator {
|
||||
* @example WEEK(date)
|
||||
* @namespace 日期函数
|
||||
* @param {any} date 日期
|
||||
* @param {boolean} isISO 是否ISO星期
|
||||
*
|
||||
* @returns {number} 星期几的数字标识
|
||||
*/
|
||||
fnWEEK(date: Date | string | number) {
|
||||
return moment(this.normalizeDate(date)).week();
|
||||
fnWEEK(date: Date | string | number, isISO = false) {
|
||||
const md = moment(this.normalizeDate(date));
|
||||
return isISO ? md.isoWeek() : md.week();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1618,12 +1620,12 @@ export class Evaluator {
|
||||
* @example STARTOF(date[unit = "day"])
|
||||
* @param {date} date 日期对象
|
||||
* @param {string} unit 比如可以传入 'day'、'month'、'year' 或者 `week` 等等
|
||||
* @param {string} format 日期格式,可选
|
||||
* @returns {date} 新的日期对象
|
||||
*/
|
||||
fnSTARTOF(date: Date, unit?: any) {
|
||||
return moment(this.normalizeDate(date))
|
||||
.startOf(unit || 'day')
|
||||
.toDate();
|
||||
fnSTARTOF(date: Date, unit?: any, format?: string) {
|
||||
const md = moment(this.normalizeDate(date)).startOf(unit || 'day');
|
||||
return format ? md.format(format) : md.toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1632,12 +1634,12 @@ export class Evaluator {
|
||||
* @example ENDOF(date[unit = "day"])
|
||||
* @param {date} date 日期对象
|
||||
* @param {string} unit 比如可以传入 'day'、'month'、'year' 或者 `week` 等等
|
||||
* @param {string} format 日期格式,可选
|
||||
* @returns {date} 新的日期对象
|
||||
*/
|
||||
fnENDOF(date: Date, unit?: any) {
|
||||
return moment(this.normalizeDate(date))
|
||||
.endOf(unit || 'day')
|
||||
.toDate();
|
||||
fnENDOF(date: Date, unit?: any, format?: string) {
|
||||
const md = moment(this.normalizeDate(date)).endOf(unit || 'day');
|
||||
return format ? md.format(format) : md.toDate();
|
||||
}
|
||||
|
||||
normalizeDate(raw: any): Date {
|
||||
@ -1662,6 +1664,12 @@ export class Evaluator {
|
||||
return raw;
|
||||
}
|
||||
|
||||
normalizeDateRange(raw: string | Date[]): Date[] {
|
||||
return (Array.isArray(raw) ? raw : raw.split(',')).map((item: any) =>
|
||||
this.normalizeDate(String(item).trim())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回日期的年份
|
||||
* @namespace 日期函数
|
||||
@ -1859,6 +1867,34 @@ export class Evaluator {
|
||||
return moment(a).isAfter(moment(b), unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断日期是否在指定范围内
|
||||
*
|
||||
* 示例:BETWEENRANGE('2021/12/6', ['2021/12/5','2021/12/7'])
|
||||
*
|
||||
* @param {any} date 第一个日期
|
||||
* @param {any[]} daterange 日期范围
|
||||
* @param {string} unit 单位,默认是 'day', 即之比较到天
|
||||
* @param {string} inclusivity 包容性规则,默认为'[]'。[ 表示包含、( 表示排除,如果使用包容性参数,则必须传入两个指示符,如'()'表示左右范围都排除
|
||||
* @namespace 日期函数
|
||||
* @example BETWEENRANGE(date, [start, end])
|
||||
* @returns {boolean} 判断结果
|
||||
*/
|
||||
fnBETWEENRANGE(
|
||||
date: Date,
|
||||
daterange: Date[],
|
||||
unit: any = 'day',
|
||||
inclusivity: '[]' | '()' | '(]' | '[)' = '[]'
|
||||
) {
|
||||
const range = this.normalizeDateRange(daterange);
|
||||
return moment(this.normalizeDate(date)).isBetween(
|
||||
range[0],
|
||||
range[1],
|
||||
unit,
|
||||
inclusivity
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断两个日期,是否第一个日期在第二个日期的前面或者相等
|
||||
*
|
||||
@ -2162,13 +2198,45 @@ export class Evaluator {
|
||||
return field ? uniqBy(arr, field) : uniqWith(arr, isEqual);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将JS对象转换成JSON字符串
|
||||
*
|
||||
* 示例:
|
||||
*
|
||||
* ENCODEJSON({name: 'amis'}) 得到 '{"name":"amis"}'
|
||||
*
|
||||
* @param {object} obj 数组
|
||||
* @namespace 数组
|
||||
* @example ENCODEJSON({name: 'amis'})
|
||||
* @returns {string} 结果
|
||||
*/
|
||||
fnENCODEJSON(obj: object): string {
|
||||
return JSON.stringify(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析JSON编码数据,返回JS对象
|
||||
*
|
||||
* 示例:
|
||||
*
|
||||
* DECODEJSON('{\"name\": "amis"}') 得到 {name: 'amis'}
|
||||
*
|
||||
* @param {string} str 字符串
|
||||
* @namespace 编码
|
||||
* @example DECODEJSON('{\"name\": "amis"}')
|
||||
* @returns {object} 结果
|
||||
*/
|
||||
fnDECODEJSON(str: string): object {
|
||||
return JSON.parse(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为类型支持:string, number, array, date, plain-object。
|
||||
*
|
||||
* @param {string} 判断对象
|
||||
* @namespace 其他
|
||||
* @example ISTYPE([{a: '1'}, {b: '2'}, {a: '1'}], 'array')
|
||||
* @returns {boolean} 结果结果
|
||||
* @returns {boolean} 结果
|
||||
*/
|
||||
fnISTYPE(
|
||||
target: any,
|
||||
|
Loading…
Reference in New Issue
Block a user