|
|
@@ -7,820 +7,895 @@
|
|
|
* 版权:广州流辰信息技术有限公司
|
|
|
* </pre>
|
|
|
*/
|
|
|
-import _ from 'lodash'
|
|
|
-import Utils from '@/utils/util'
|
|
|
-import fecha from '@/utils/fecha'
|
|
|
-import { numberCurrency, numberThousands, num2Str, evalExpression } from './number'
|
|
|
-import pinyin4js from 'pinyin4js'
|
|
|
-import { getSystemTimestamp } from '@/api/platform/form/common'
|
|
|
+import _ from "lodash";
|
|
|
+import Utils from "@/utils/util";
|
|
|
+import fecha from "@/utils/fecha";
|
|
|
+import {
|
|
|
+ numberCurrency,
|
|
|
+ numberThousands,
|
|
|
+ num2Str,
|
|
|
+ evalExpression,
|
|
|
+} from "./number";
|
|
|
+import pinyin4js from "pinyin4js";
|
|
|
+import { getSystemTimestamp } from "@/api/platform/form/common";
|
|
|
|
|
|
// 当前窗口
|
|
|
-const wd = window
|
|
|
+const wd = window;
|
|
|
|
|
|
const FormulaUtil = {
|
|
|
- // ===============逻辑函数===================================
|
|
|
- /**
|
|
|
- * 并且
|
|
|
- */
|
|
|
- AND: function() {
|
|
|
- const args = Utils.flatten(arguments)
|
|
|
- for (let i = 0, c = args.length; i < c; i++) {
|
|
|
- if (!args[i]) return false
|
|
|
- }
|
|
|
- return true
|
|
|
- },
|
|
|
- /**
|
|
|
- * 或者
|
|
|
- */
|
|
|
- OR: function() {
|
|
|
- const args = Utils.flatten(arguments)
|
|
|
- for (let i = 0, c = args.length; i < c; i++) {
|
|
|
- if (args[i]) return true
|
|
|
- }
|
|
|
- return false
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回逻辑值false
|
|
|
- */
|
|
|
- FALSE: function() {
|
|
|
- return false
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回逻辑值true
|
|
|
- */
|
|
|
- TRUE: function() {
|
|
|
- return true
|
|
|
- },
|
|
|
- /**
|
|
|
- * IF(判断条件,结果为true的返回值, 结果为false的返回值)
|
|
|
- * 判断一个条件能否满足;如果满足返回一个值,如果不满足则返回另外一个值。
|
|
|
- */
|
|
|
- IF: function(a, b, c) {
|
|
|
- return a ? b : c
|
|
|
- },
|
|
|
- /**
|
|
|
- * IFS 函数检查是否满足一个或多个条件,且返回符合第一个 TRUE 条件的值。 IFS 可以取代多个嵌套 IF 语句,并且有多个条件时更方便阅读。
|
|
|
- * IFS( logical_1, value_if_true_1, logical_2, value_if_true_2, … ,logical_n, value_if_true_n)
|
|
|
- *
|
|
|
- */
|
|
|
- IFS: function() {
|
|
|
- let res = null
|
|
|
- for (let i = 0; i < arguments.length; i += 2) {
|
|
|
- if (arguments[i]) {
|
|
|
- const v = arguments[i + 1]
|
|
|
- res = Utils.isEmpty(v) ? null : v
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- return res
|
|
|
- },
|
|
|
- /**
|
|
|
- * 对参数逻辑值求反
|
|
|
- */
|
|
|
- NOT: function(a) {
|
|
|
- return !a
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回所有参数的异或值.
|
|
|
- * 异或的含义是:
|
|
|
- * 两个值相同,返回0,
|
|
|
- * 两个值不同,返回1。
|
|
|
- */
|
|
|
- XOR: function() {
|
|
|
- const args = Utils.flatten(arguments)
|
|
|
- let a = 0
|
|
|
- for (let i = 0, d = args.length; i < d; i++) {
|
|
|
- args[i] && a++
|
|
|
- }
|
|
|
- return !!(1 & Math.floor(Math.abs(a)))
|
|
|
- },
|
|
|
- // ===============文本函数===================================
|
|
|
- /**
|
|
|
- * 将多个文本字符串合并成一个文本字符串。
|
|
|
- * 示例:CONCATENATE(A,B,C),即返回值为ABC
|
|
|
- */
|
|
|
- CONCATENATE: function() {
|
|
|
- const args = Utils.flatten(arguments)
|
|
|
- return args.join('')
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回计算机字符集的数字代码所对应的字符。
|
|
|
- * 示例:(10),即返回值为换行字符。
|
|
|
- *
|
|
|
- */
|
|
|
- CHAR: function(number) {
|
|
|
- return number === 10 || number === 34 || number === 39 || number === 92 ? String.fromCharCode(number) : ''
|
|
|
- },
|
|
|
- /**
|
|
|
- * 比较两个字符串是否完全相同(区分大小写)。完全相同则返回true,否则返回false
|
|
|
- */
|
|
|
- EXACT: function(a, b) {
|
|
|
- return a === b
|
|
|
- },
|
|
|
- /**
|
|
|
- * 从一个文本字符串的第一个字符开始返回指定个数的字符。
|
|
|
- */
|
|
|
- LEFT: function(a, b) {
|
|
|
- b = Utils.isEmpty(b) ? 1 : b
|
|
|
- a = a + ''
|
|
|
- return a ? a.substring(0, b) : ''
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回文本字符串中的字符个数。
|
|
|
- */
|
|
|
- LEN: function(a) {
|
|
|
- a = a + ''
|
|
|
- return _.isString(a) ? a ? a.length : 0 : a && a.length ? a.length : 0
|
|
|
- },
|
|
|
- /**
|
|
|
- * 将一个文本字符串中的所有大写字母转换为小写字母。
|
|
|
- */
|
|
|
- LOWER: function(a) {
|
|
|
- return _.isString(a) ? a ? a.toLowerCase() : a : ''
|
|
|
- },
|
|
|
- /**
|
|
|
- * 根据指定的字符数,将部分文本字符串替换为不同的文本字符串。
|
|
|
- */
|
|
|
- REPLACE: function(oldText, startNum, numChars, newText) {
|
|
|
- oldText = oldText || ''
|
|
|
- newText = newText || ''
|
|
|
- if (_.isNumber(startNum) && _.isNumber(numChars)) {
|
|
|
- oldText = oldText.substr(0, startNum - 1) + newText + oldText.substr(startNum - 1 + numChars)
|
|
|
- }
|
|
|
- return oldText
|
|
|
- },
|
|
|
- /**
|
|
|
- * 将文本重复一定次数。
|
|
|
- */
|
|
|
- REPT: function(a, b) {
|
|
|
- b = b || 0
|
|
|
- return new Array(b + 1).join(a)
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回文本值中最右边的字符。
|
|
|
- * text: 必需。包含要提取字符的文本字符串。
|
|
|
- * num_chars: 可选。指定希望提取的字符数。
|
|
|
- */
|
|
|
- RIGHT: function(a, b) {
|
|
|
- b = undefined === b ? 1 : b
|
|
|
- return a ? a.substring(a.length - b) : ''
|
|
|
- },
|
|
|
- /**
|
|
|
- * 在第二个文本字符串中查找第一个文本字符串,并返回第一个文本字符串的起始位置的编号,该编号从第二个文本字符串的第一个字符算起。返回0则表示未查找到。
|
|
|
- * find_text: 必需。要查找的文本。
|
|
|
- * within_text: 必需。要在其中搜索find_text参数的值的文本。
|
|
|
- * start_num: 可选。within_text参数中从之开始搜索的字符编号。
|
|
|
- */
|
|
|
- SEARCH: function(a, b, c) {
|
|
|
- if (_.isString(a) && _.isString(b)) {
|
|
|
- c = _.isNull(c) ? 0 : c
|
|
|
- return b.toLowerCase().indexOf(a.toLowerCase(), c - 1) + 1
|
|
|
- } else {
|
|
|
- return 0
|
|
|
- }
|
|
|
- },
|
|
|
- /**
|
|
|
- * 字符串拆分
|
|
|
- */
|
|
|
- SPLIT: function(a, b) {
|
|
|
- if (Utils.isEmpty(a)) {
|
|
|
- return []
|
|
|
- }
|
|
|
- if (!_.isString(a)) {
|
|
|
- a = a + ''
|
|
|
- }
|
|
|
- return _.isString(a) ? a.split(b) : []
|
|
|
- },
|
|
|
- /**
|
|
|
- * 删除字符串首尾的空格,但是会保留字符串内部作为词与词之间分隔的空格。
|
|
|
- */
|
|
|
- TRIM: function(a) {
|
|
|
- if (Utils.isEmpty(a)) {
|
|
|
- return ''
|
|
|
- }
|
|
|
- if (!_.isString(a)) {
|
|
|
- a = a + ''
|
|
|
- }
|
|
|
- return _.isString(a) ? _.trim(a) : ''
|
|
|
- },
|
|
|
- /**
|
|
|
- * 将一个文本字符串中的所有小写字母转换为大写字母。
|
|
|
- */
|
|
|
- UPPER: function(a) {
|
|
|
- return _.isString(a) ? a.toUpperCase() : ''
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回文本字符串中从指定位置开始的特定数目的字符,该数目由用户指定。
|
|
|
- * text: 必需。 包含要提取字符的文本字符串。
|
|
|
- * start_num: 必需。 文本中要提取的第一个字符的位置。 文本中第一个字符的start_num为 1,以此类推。
|
|
|
- * num_chars: 必需。 指定希望从文本中返回字符的个数。
|
|
|
- */
|
|
|
- MID: function(text, startNum, numChars) {
|
|
|
- text = text || ''
|
|
|
- return _.isNumber(startNum) && _.isNumber(numChars) ? text.substr(startNum - 1, numChars) : text
|
|
|
- },
|
|
|
- // =============== 数学函数===================================
|
|
|
- /**
|
|
|
- * 返回参数的平均值(算术平均值)。
|
|
|
- */
|
|
|
- AVERAGE: function() {
|
|
|
- const a = Utils.flatten(arguments, function(a) {
|
|
|
- return _.isNumber(a)
|
|
|
- })
|
|
|
- let c = 0
|
|
|
- let d = 0
|
|
|
- for (let b = a.length, e = 0; e < b; e++) {
|
|
|
- c += a[e]
|
|
|
- d += 1
|
|
|
- }
|
|
|
- if (d === 0) return
|
|
|
- return c / d
|
|
|
- },
|
|
|
- /**
|
|
|
- * 统计参数个数。
|
|
|
- */
|
|
|
- COUNT: function() {
|
|
|
- return Utils.flatten(arguments).length
|
|
|
- },
|
|
|
- /**
|
|
|
- * 统计满足条件的参数个数。
|
|
|
- * 例如:
|
|
|
- * COUNTIF([1,2,3,4], “>2”),结果为2
|
|
|
- * COUNTIF([1,2,3,4], “!=2”),结果为3
|
|
|
- * COUNTIF([1,2,3,4], “>=1”),结果为4
|
|
|
- * COUNTIF([“a”, “b”, “c”], “d”),结果为0
|
|
|
- */
|
|
|
- COUNTIF: function() {
|
|
|
- const len = arguments.length
|
|
|
- let criteria = arguments[len - 1];
|
|
|
- /[<>=!]/.test(criteria) || (criteria = '=="' + criteria + '"')
|
|
|
- const args = Utils.flatten(Array.prototype.slice.call(arguments, 0, len - 1))
|
|
|
- let matches = 0
|
|
|
- for (let i = 0; i < args.length; i++) {
|
|
|
- if (typeof args[i] !== 'string') {
|
|
|
- if (wd.eval(args[i] + criteria)) {
|
|
|
- matches++
|
|
|
+ // ===============逻辑函数===================================
|
|
|
+ /**
|
|
|
+ * 并且
|
|
|
+ */
|
|
|
+ AND: function () {
|
|
|
+ const args = Utils.flatten(arguments);
|
|
|
+ for (let i = 0, c = args.length; i < c; i++) {
|
|
|
+ if (!args[i]) return false;
|
|
|
}
|
|
|
- } else {
|
|
|
- if (wd.eval('"' + args[i] + '"' + criteria)) {
|
|
|
- matches++
|
|
|
+ return true;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 或者
|
|
|
+ */
|
|
|
+ OR: function () {
|
|
|
+ const args = Utils.flatten(arguments);
|
|
|
+ for (let i = 0, c = args.length; i < c; i++) {
|
|
|
+ if (args[i]) return true;
|
|
|
}
|
|
|
- }
|
|
|
- }
|
|
|
- return matches
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回一组值中的最大值。
|
|
|
- */
|
|
|
- MAX: function() {
|
|
|
- const a = Utils.flatten(arguments, function(a) {
|
|
|
- return _.isNumber(a)
|
|
|
- })
|
|
|
- return a.length === 0 ? 0 : Math.max.apply(Math, a)
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回一组值中的最小值。
|
|
|
- */
|
|
|
- MIN: function() {
|
|
|
- const a = Utils.flatten(arguments, function(a) {
|
|
|
- return _.isNumber(a)
|
|
|
- })
|
|
|
- return a.length === 0 ? 0 : Math.min.apply(Math, a)
|
|
|
- },
|
|
|
- /**
|
|
|
- *返回数据集中第k个最大值。
|
|
|
- *Array: 必需。 需要确定第k个最大值的数组或数据区域。
|
|
|
- *k: 必需。 返回值在数组中的位置(从大到小排)
|
|
|
- */
|
|
|
- LARGE: function(a, b) {
|
|
|
- a = Utils.flatten(a, function(a) {
|
|
|
- return _.isNumber(a)
|
|
|
- })
|
|
|
- return a.sort(function(a, b) {
|
|
|
- return b - a
|
|
|
- })[b - 1]
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回数据集中第k个最小值。
|
|
|
- * Array: 必需。 需要确定第k个最小值的数组或数据区域。
|
|
|
- *k: 必需。 返回值在数组中的位置(从小到大排)。 用法同LARGE函数。
|
|
|
- */
|
|
|
- SMALL: function(a, b) {
|
|
|
- a = Utils.flatten(a, function(a) {
|
|
|
- return _.isNumber(a)
|
|
|
- })
|
|
|
- return a.sort(function(a, b) {
|
|
|
- return a - b
|
|
|
- })[b - 1]
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回数字的绝对值。
|
|
|
- */
|
|
|
- ABS: function(a) {
|
|
|
- return _.isNumber(a) ? Math.abs(a) : 0
|
|
|
- },
|
|
|
- /**
|
|
|
- * 将数字四舍五入到指定的位数。
|
|
|
- * number: 必需。 要四舍五入的数字。
|
|
|
- * num_digits: 必需。 要进行四舍五入运算的位数。
|
|
|
- */
|
|
|
- ROUND: function(a, b) {
|
|
|
- return Math.round(a * Math.pow(10, b)) / Math.pow(10, b)
|
|
|
- },
|
|
|
- /**
|
|
|
- *返回回将参数 number 向上舍入(沿绝对值增大的方向)为最接近的指定基数的倍数。
|
|
|
- *number: 必需。 要舍入的值。
|
|
|
- *significance: 必需。 要舍入到的倍数。
|
|
|
- */
|
|
|
- CEILING: function(a, b) {
|
|
|
- if (b === 0) {
|
|
|
- return 0
|
|
|
- }
|
|
|
- return _.ceil(a, b)
|
|
|
- },
|
|
|
- /**
|
|
|
- * 将参数number向下舍入(沿绝对值减小的方向)为最接近的significance的倍数。
|
|
|
- * number: 必需。 要舍入的数值。
|
|
|
- * significance: 必需。 要舍入到的倍数。
|
|
|
- */
|
|
|
- FLOOR: function(a, b) {
|
|
|
- if (b === 0) {
|
|
|
- return 0
|
|
|
- }
|
|
|
- return _.floor(a, b)
|
|
|
- },
|
|
|
- /**
|
|
|
- * 将数字向下舍入到最接近的整数。
|
|
|
- */
|
|
|
- INT: function(a) {
|
|
|
- return _.isNumber(a) ? Math.floor(a) : 0
|
|
|
- },
|
|
|
- /**
|
|
|
- * 根据指定底数返回数字的对数。
|
|
|
- * number: 必需。 想要计算其对数的正实数。
|
|
|
- * base: 可选。 对数的底数。 如果省略 base,则假定其值为 10。
|
|
|
- */
|
|
|
- LOG: function(a, b) {
|
|
|
- b = undefined === b ? 10 : b
|
|
|
- return _.isNumber(b) ? Math.log(a) / Math.log(b) : 0
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回两数相除的余数。 结果的符号与除数相同。
|
|
|
- * number: 必需。 要计算余数的被除数。
|
|
|
- * divisor: 必需。 除数。
|
|
|
- *
|
|
|
- */
|
|
|
- MOD: function(a, b) {
|
|
|
- if (b === 0) {
|
|
|
- return 0
|
|
|
- }
|
|
|
- const c = Math.abs(a % b)
|
|
|
- return b > 0 ? c : -c
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回数字乘幂的结果。
|
|
|
- * number: 必需。 基数。 可为任意实数。
|
|
|
- * power: 必需。 基数乘幂运算的指数。
|
|
|
- */
|
|
|
- POWER: function(a, b) {
|
|
|
- const c = Math.pow(a, b)
|
|
|
- return isNaN(c) ? 0 : c
|
|
|
- },
|
|
|
- /**
|
|
|
- * 函数使所有以参数形式给出的数字相乘并返回乘积。
|
|
|
- */
|
|
|
- PRODUCT: function() {
|
|
|
- const args = Utils.flatten(arguments, function(a) {
|
|
|
- return _.isNumber(a)
|
|
|
- })
|
|
|
- let b = 1
|
|
|
- for (let i = 0; i < args.length; i++) {
|
|
|
- b = evalExpression('*', b, args[i])
|
|
|
- }
|
|
|
- return b
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回正的平方根。
|
|
|
- */
|
|
|
- SQRT: function(a) {
|
|
|
- return a < 0 ? 0 : Math.sqrt(a)
|
|
|
- },
|
|
|
- /**
|
|
|
- * 函数使所有以参数形式给出的数字相加并返回和。
|
|
|
- */
|
|
|
- SUM: function() {
|
|
|
- const args = Utils.flatten(arguments, function(a) {
|
|
|
- return _.isNumber(a)
|
|
|
- })
|
|
|
- let v = 0
|
|
|
- for (let i = 0, d = args.length; i < d; ++i) {
|
|
|
- v = evalExpression('+', v, Number(args[i]))
|
|
|
- }
|
|
|
- return v
|
|
|
- },
|
|
|
- /**
|
|
|
- * 在给定的数组中,将数组间对应的元素相乘,并返回乘积之和。
|
|
|
- *
|
|
|
- * array: 可选。多个数字数组。
|
|
|
- * 主要可用于计算加权和。例如:SUMPRODUCT([1,2,3],[0.1,0.2,0.3]),相当于 1×0.1 + 2×0.2 + 3×0.3=1.4
|
|
|
- */
|
|
|
- SUMPRODUCT: function() {
|
|
|
- for (var a = 0, b = [], c = -1, d = 0; d < arguments.length; d++) {
|
|
|
- if (arguments[d] instanceof Array) {
|
|
|
- c = c < 0 ? arguments[d].length : Math.min(arguments[d].length, c)
|
|
|
- b.push(arguments[d])
|
|
|
- }
|
|
|
- }
|
|
|
- for (let e, f, g, h = 0; h < c; h++) {
|
|
|
- for (e = 1, f = 0; f < b.length; f++) {
|
|
|
- g = parseFloat(b[f][h])
|
|
|
- isNaN(g) && (g = 0)
|
|
|
- e = evalExpression('*', e, g)
|
|
|
- }
|
|
|
- a = evalExpression('+', a, e)
|
|
|
- }
|
|
|
- return a
|
|
|
- },
|
|
|
- /**
|
|
|
- * 将数字舍入到指定的小数位数,以十进制数格式对该数进行格式设置,并以文本形式返回结果。
|
|
|
- * number: 必需。 要进行舍入并转换为文本的数字。
|
|
|
- * decimals: 可选。 小数点右边的位数。
|
|
|
- */
|
|
|
- FIXED: function(a, b) {
|
|
|
- b = undefined === b ? 0 : b
|
|
|
- return _.isNumber(b) && b >= 0 ? Number(a).toFixed(b) : ''
|
|
|
- },
|
|
|
-
|
|
|
- RAND: function(a = 6) {
|
|
|
- return _.round(Math.random(), a)
|
|
|
- },
|
|
|
- /**
|
|
|
- *
|
|
|
- * 返回大于等于lower 且小于 upper 的均匀分布随机实数。每一次触发计算都会变化。
|
|
|
- * _.random(0, 5);
|
|
|
- * // => an integer between 0 and 5
|
|
|
- * _.random(5);
|
|
|
- * // => also an integer between 0 and 5
|
|
|
- * _.random(5, true);
|
|
|
- * // => a floating-point number between 0 and 5
|
|
|
- * _.random(1.2, 5.2);
|
|
|
- * // => a floating-point number between 1.2 and 5.2
|
|
|
- */
|
|
|
- RANDOM: function(lower, upper, floating) {
|
|
|
- return _.random(lower, upper, floating)
|
|
|
- },
|
|
|
- /**
|
|
|
- * 用于任意精度的十进制算术运算。
|
|
|
- * @param {*} symbol 符号
|
|
|
- * @param {*} a
|
|
|
- * @param {*} b
|
|
|
- */
|
|
|
- BIG(symbol, a, b) {
|
|
|
- return evalExpression(symbol, a, b)
|
|
|
- },
|
|
|
- // =============== 日期函数===================================
|
|
|
- /**
|
|
|
- * 最小日期
|
|
|
- */
|
|
|
- MINDATE: function() {
|
|
|
- const a = FormulaUtil.DATEFLATTEN(arguments)
|
|
|
- let min = a[0]
|
|
|
- for (let i = 1; i < a.length; i++) {
|
|
|
- if (a[i] < min) {
|
|
|
- min = a[i]
|
|
|
- }
|
|
|
- }
|
|
|
- const format = FormulaUtil.DATEFORMAT(min)
|
|
|
- return fecha.format(min, format)
|
|
|
- },
|
|
|
- /**
|
|
|
- * 最大日期
|
|
|
- */
|
|
|
- MAXDATE: function() {
|
|
|
- const a = FormulaUtil.DATEFLATTEN(arguments)
|
|
|
- let max = a[0]
|
|
|
- for (let i = 1; i < a.length; i++) {
|
|
|
- if (a[i] > max) {
|
|
|
- max = a[i]
|
|
|
- }
|
|
|
- }
|
|
|
- const format = FormulaUtil.DATEFORMAT(max)
|
|
|
- return fecha.format(max, format)
|
|
|
- },
|
|
|
- /**
|
|
|
- *1、 将时间戳转换为日期对象。 * timestamp: 必需。时间戳。
|
|
|
- *
|
|
|
- * DATE(year,month,day)
|
|
|
- * DATE(year,month,day,hour,minute,second)
|
|
|
- *
|
|
|
- *2、将年月日时分秒转换为日期对象。
|
|
|
- * year: 必需。年份。
|
|
|
- * month: 必需。月份。
|
|
|
- * day: 必需。天数。
|
|
|
- * hour: 必需。小时。
|
|
|
- * minute: 必需。分钟。
|
|
|
- * second: 必需。秒。
|
|
|
- * 例如,2015年11月1日的日期对象可以用如下表示:
|
|
|
- * DATE(2015,11,1)
|
|
|
- * DATE(1446307200000)
|
|
|
- * DATE(2015,11,1,0,0,0)
|
|
|
- * 这三个都表示“Sun Nov 01 2015 00:00:00 GMT+0800 (中国标准时间)”
|
|
|
- *
|
|
|
- */
|
|
|
- DATE: function() {
|
|
|
- if (Utils.isEmpty(arguments[0])) {
|
|
|
- return null
|
|
|
- }
|
|
|
- let v
|
|
|
- if (arguments.length === 6) {
|
|
|
- v = new Date(parseInt(arguments[0], 10), parseInt(arguments[1], 10) - 1, parseInt(arguments[2], 10), parseInt(arguments[3], 10), parseInt(arguments[4], 10), parseInt(arguments[5], 10))
|
|
|
- } else if (arguments.length === 3) {
|
|
|
- v = new Date(parseInt(arguments[0], 10), parseInt(arguments[1], 10) - 1, parseInt(arguments[2], 10))
|
|
|
- } else {
|
|
|
- // 移动端兼容问题
|
|
|
- v = new Date(arguments[0].replace(/-/g, '/'))
|
|
|
- }
|
|
|
- return v
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回特定时间的十进制数字。时间值为日期值的一部分,并用十进制数表示(例如 12:00 PM 可表示为 0.5,因为此时是一天的一半)。
|
|
|
- * hour: 必需。 0(零)到 32767 之间的数字,代表小时。 任何大于 23 的值都会除以 24,余数将作为小时值。 例如,TIME(27,0,0) = TIME(3,0,0) = .125
|
|
|
- * minute: 必需。 0 到 32767 之间的数字,代表分钟。 任何大于 59 的值将转换为小时和分钟。 例如,TIME(0,750,0) = TIME(12,30,0) = .520833
|
|
|
- * second: 必需。 0 到 32767 之间的数字,代表秒。 任何大于 59 的值将转换为小时、分钟和秒。 例如,TIME(0,0,2000) = TIME(0,33,20) = .023148
|
|
|
- *
|
|
|
- */
|
|
|
- TIME: function(a, b, c) {
|
|
|
- return (3600 * a + 60 * b + c) / 86400
|
|
|
- },
|
|
|
- /**
|
|
|
- * 将日期对象(或日期字符串)转换成时间戳。
|
|
|
- */
|
|
|
- TIMESTAMP: function(a) {
|
|
|
- if (Utils.isEmpty(a)) return 0
|
|
|
- if (_.isString(a)) return FormulaUtil.TIMESTAMP(FormulaUtil.DATE(a))
|
|
|
- return _.isDate(a) ? a.getTime() : 0
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回今天。
|
|
|
- */
|
|
|
- TODAY: function() {
|
|
|
- return new Date()
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回当前时间。与TODAY函数相同。
|
|
|
- */
|
|
|
- NOW: function() {
|
|
|
- return new Date()
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回当前服务器时间。
|
|
|
- * 即使客户端的时间被人为调整了,SYSTIME函数不受影响,获取的仍然是服务器时间。例如签到、打卡等场景下,可避免调整时间作弊的情况。
|
|
|
- */
|
|
|
- SYSTIME: function() {
|
|
|
- getSystemTimestamp().then(response => {
|
|
|
- return response.data
|
|
|
- }).catch(error => {
|
|
|
- console.error(error)
|
|
|
- })
|
|
|
- },
|
|
|
- /**
|
|
|
- *返回某日期的年。
|
|
|
- */
|
|
|
- YEAR: function(a) {
|
|
|
- return a.getFullYear()
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回某日期的天数。 天数是介于 1 到 31 之间的整数。
|
|
|
- */
|
|
|
- DAY: function(a) {
|
|
|
- return a.getDate()
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回某日期的月份。 月份是介于 1 到 12 之间的整数。
|
|
|
- */
|
|
|
- MONTH: function(a) {
|
|
|
- return a.getMonth() + 1
|
|
|
- },
|
|
|
+ return false;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回逻辑值false
|
|
|
+ */
|
|
|
+ FALSE: function () {
|
|
|
+ return false;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回逻辑值true
|
|
|
+ */
|
|
|
+ TRUE: function () {
|
|
|
+ return true;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * IF(判断条件,结果为true的返回值, 结果为false的返回值)
|
|
|
+ * 判断一个条件能否满足;如果满足返回一个值,如果不满足则返回另外一个值。
|
|
|
+ */
|
|
|
+ IF: function (a, b, c) {
|
|
|
+ return a ? b : c;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * IFS 函数检查是否满足一个或多个条件,且返回符合第一个 TRUE 条件的值。 IFS 可以取代多个嵌套 IF 语句,并且有多个条件时更方便阅读。
|
|
|
+ * IFS( logical_1, value_if_true_1, logical_2, value_if_true_2, … ,logical_n, value_if_true_n)
|
|
|
+ *
|
|
|
+ */
|
|
|
+ IFS: function () {
|
|
|
+ let res = null;
|
|
|
+ for (let i = 0; i < arguments.length; i += 2) {
|
|
|
+ if (arguments[i]) {
|
|
|
+ const v = arguments[i + 1];
|
|
|
+ res = Utils.isEmpty(v) ? null : v;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 对参数逻辑值求反
|
|
|
+ */
|
|
|
+ NOT: function (a) {
|
|
|
+ return !a;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回所有参数的异或值.
|
|
|
+ * 异或的含义是:
|
|
|
+ * 两个值相同,返回0,
|
|
|
+ * 两个值不同,返回1。
|
|
|
+ */
|
|
|
+ XOR: function () {
|
|
|
+ const args = Utils.flatten(arguments);
|
|
|
+ let a = 0;
|
|
|
+ for (let i = 0, d = args.length; i < d; i++) {
|
|
|
+ args[i] && a++;
|
|
|
+ }
|
|
|
+ return !!(1 & Math.floor(Math.abs(a)));
|
|
|
+ },
|
|
|
+ // ===============文本函数===================================
|
|
|
+ /**
|
|
|
+ * 将多个文本字符串合并成一个文本字符串。
|
|
|
+ * 示例:CONCATENATE(A,B,C),即返回值为ABC
|
|
|
+ */
|
|
|
+ CONCATENATE: function () {
|
|
|
+ const args = Utils.flatten(arguments);
|
|
|
+ return args.join("");
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回计算机字符集的数字代码所对应的字符。
|
|
|
+ * 示例:(10),即返回值为换行字符。
|
|
|
+ *
|
|
|
+ */
|
|
|
+ CHAR: function (number) {
|
|
|
+ return number === 10 || number === 34 || number === 39 || number === 92
|
|
|
+ ? String.fromCharCode(number)
|
|
|
+ : "";
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 比较两个字符串是否完全相同(区分大小写)。完全相同则返回true,否则返回false
|
|
|
+ */
|
|
|
+ EXACT: function (a, b) {
|
|
|
+ return a === b;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 从一个文本字符串的第一个字符开始返回指定个数的字符。
|
|
|
+ */
|
|
|
+ LEFT: function (a, b) {
|
|
|
+ b = Utils.isEmpty(b) ? 1 : b;
|
|
|
+ a = a + "";
|
|
|
+ return a ? a.substring(0, b) : "";
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回文本字符串中的字符个数。
|
|
|
+ */
|
|
|
+ LEN: function (a) {
|
|
|
+ a = a + "";
|
|
|
+ return _.isString(a)
|
|
|
+ ? a
|
|
|
+ ? a.length
|
|
|
+ : 0
|
|
|
+ : a && a.length
|
|
|
+ ? a.length
|
|
|
+ : 0;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 将一个文本字符串中的所有大写字母转换为小写字母。
|
|
|
+ */
|
|
|
+ LOWER: function (a) {
|
|
|
+ return _.isString(a) ? (a ? a.toLowerCase() : a) : "";
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 根据指定的字符数,将部分文本字符串替换为不同的文本字符串。
|
|
|
+ */
|
|
|
+ REPLACE: function (oldText, startNum, numChars, newText) {
|
|
|
+ oldText = oldText || "";
|
|
|
+ newText = newText || "";
|
|
|
+ if (_.isNumber(startNum) && _.isNumber(numChars)) {
|
|
|
+ oldText =
|
|
|
+ oldText.substr(0, startNum - 1) +
|
|
|
+ newText +
|
|
|
+ oldText.substr(startNum - 1 + numChars);
|
|
|
+ }
|
|
|
+ return oldText;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 将文本重复一定次数。
|
|
|
+ */
|
|
|
+ REPT: function (a, b) {
|
|
|
+ b = b || 0;
|
|
|
+ return new Array(b + 1).join(a);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回文本值中最右边的字符。
|
|
|
+ * text: 必需。包含要提取字符的文本字符串。
|
|
|
+ * num_chars: 可选。指定希望提取的字符数。
|
|
|
+ */
|
|
|
+ RIGHT: function (a, b) {
|
|
|
+ b = undefined === b ? 1 : b;
|
|
|
+ return a ? a.substring(a.length - b) : "";
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 在第二个文本字符串中查找第一个文本字符串,并返回第一个文本字符串的起始位置的编号,该编号从第二个文本字符串的第一个字符算起。返回0则表示未查找到。
|
|
|
+ * find_text: 必需。要查找的文本。
|
|
|
+ * within_text: 必需。要在其中搜索find_text参数的值的文本。
|
|
|
+ * start_num: 可选。within_text参数中从之开始搜索的字符编号。
|
|
|
+ */
|
|
|
+ SEARCH: function (a, b, c) {
|
|
|
+ if (_.isString(a) && _.isString(b)) {
|
|
|
+ c = _.isNull(c) ? 0 : c;
|
|
|
+ return b.toLowerCase().indexOf(a.toLowerCase(), c - 1) + 1;
|
|
|
+ } else {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 字符串拆分
|
|
|
+ */
|
|
|
+ SPLIT: function (a, b) {
|
|
|
+ if (Utils.isEmpty(a)) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ if (!_.isString(a)) {
|
|
|
+ a = a + "";
|
|
|
+ }
|
|
|
+ return _.isString(a) ? a.split(b) : [];
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 删除字符串首尾的空格,但是会保留字符串内部作为词与词之间分隔的空格。
|
|
|
+ */
|
|
|
+ TRIM: function (a) {
|
|
|
+ if (Utils.isEmpty(a)) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ if (!_.isString(a)) {
|
|
|
+ a = a + "";
|
|
|
+ }
|
|
|
+ return _.isString(a) ? _.trim(a) : "";
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 将一个文本字符串中的所有小写字母转换为大写字母。
|
|
|
+ */
|
|
|
+ UPPER: function (a) {
|
|
|
+ return _.isString(a) ? a.toUpperCase() : "";
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回文本字符串中从指定位置开始的特定数目的字符,该数目由用户指定。
|
|
|
+ * text: 必需。 包含要提取字符的文本字符串。
|
|
|
+ * start_num: 必需。 文本中要提取的第一个字符的位置。 文本中第一个字符的start_num为 1,以此类推。
|
|
|
+ * num_chars: 必需。 指定希望从文本中返回字符的个数。
|
|
|
+ */
|
|
|
+ MID: function (text, startNum, numChars) {
|
|
|
+ text = text || "";
|
|
|
+ return _.isNumber(startNum) && _.isNumber(numChars)
|
|
|
+ ? text.substr(startNum - 1, numChars)
|
|
|
+ : text;
|
|
|
+ },
|
|
|
+ // =============== 数学函数===================================
|
|
|
+ /**
|
|
|
+ * 返回参数的平均值(算术平均值)。
|
|
|
+ */
|
|
|
+ AVERAGE: function () {
|
|
|
+ const a = Utils.flatten(arguments, function (a) {
|
|
|
+ return _.isNumber(a);
|
|
|
+ });
|
|
|
+ let c = 0;
|
|
|
+ let d = 0;
|
|
|
+ for (let b = a.length, e = 0; e < b; e++) {
|
|
|
+ c += a[e];
|
|
|
+ d += 1;
|
|
|
+ }
|
|
|
+ if (d === 0) return;
|
|
|
+ return c / d;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 统计参数个数。
|
|
|
+ */
|
|
|
+ COUNT: function () {
|
|
|
+ return Utils.flatten(arguments).length;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 统计满足条件的参数个数。
|
|
|
+ * 例如:
|
|
|
+ * COUNTIF([1,2,3,4], “>2”),结果为2
|
|
|
+ * COUNTIF([1,2,3,4], “!=2”),结果为3
|
|
|
+ * COUNTIF([1,2,3,4], “>=1”),结果为4
|
|
|
+ * COUNTIF([“a”, “b”, “c”], “d”),结果为0
|
|
|
+ */
|
|
|
+ COUNTIF: function () {
|
|
|
+ const len = arguments.length;
|
|
|
+ let criteria = arguments[len - 1];
|
|
|
+ /[<>=!]/.test(criteria) || (criteria = '=="' + criteria + '"');
|
|
|
+ const args = Utils.flatten(
|
|
|
+ Array.prototype.slice.call(arguments, 0, len - 1)
|
|
|
+ );
|
|
|
+ let matches = 0;
|
|
|
+ for (let i = 0; i < args.length; i++) {
|
|
|
+ if (typeof args[i] !== "string") {
|
|
|
+ if (wd.eval(args[i] + criteria)) {
|
|
|
+ matches++;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (wd.eval('"' + args[i] + '"' + criteria)) {
|
|
|
+ matches++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return matches;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回一组值中的最大值。
|
|
|
+ */
|
|
|
+ MAX: function () {
|
|
|
+ const a = Utils.flatten(arguments, function (a) {
|
|
|
+ return _.isNumber(a);
|
|
|
+ });
|
|
|
+ return a.length === 0 ? 0 : Math.max.apply(Math, a);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回一组值中的最小值。
|
|
|
+ */
|
|
|
+ MIN: function () {
|
|
|
+ const a = Utils.flatten(arguments, function (a) {
|
|
|
+ return _.isNumber(a);
|
|
|
+ });
|
|
|
+ return a.length === 0 ? 0 : Math.min.apply(Math, a);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ *返回数据集中第k个最大值。
|
|
|
+ *Array: 必需。 需要确定第k个最大值的数组或数据区域。
|
|
|
+ *k: 必需。 返回值在数组中的位置(从大到小排)
|
|
|
+ */
|
|
|
+ LARGE: function (a, b) {
|
|
|
+ a = Utils.flatten(a, function (a) {
|
|
|
+ return _.isNumber(a);
|
|
|
+ });
|
|
|
+ return a.sort(function (a, b) {
|
|
|
+ return b - a;
|
|
|
+ })[b - 1];
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回数据集中第k个最小值。
|
|
|
+ * Array: 必需。 需要确定第k个最小值的数组或数据区域。
|
|
|
+ *k: 必需。 返回值在数组中的位置(从小到大排)。 用法同LARGE函数。
|
|
|
+ */
|
|
|
+ SMALL: function (a, b) {
|
|
|
+ a = Utils.flatten(a, function (a) {
|
|
|
+ return _.isNumber(a);
|
|
|
+ });
|
|
|
+ return a.sort(function (a, b) {
|
|
|
+ return a - b;
|
|
|
+ })[b - 1];
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回数字的绝对值。
|
|
|
+ */
|
|
|
+ ABS: function (a) {
|
|
|
+ return _.isNumber(a) ? Math.abs(a) : 0;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 将数字四舍五入到指定的位数。
|
|
|
+ * number: 必需。 要四舍五入的数字。
|
|
|
+ * num_digits: 必需。 要进行四舍五入运算的位数。
|
|
|
+ */
|
|
|
+ ROUND: function (a, b) {
|
|
|
+ return Math.round(a * Math.pow(10, b)) / Math.pow(10, b);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ *返回回将参数 number 向上舍入(沿绝对值增大的方向)为最接近的指定基数的倍数。
|
|
|
+ *number: 必需。 要舍入的值。
|
|
|
+ *significance: 必需。 要舍入到的倍数。
|
|
|
+ */
|
|
|
+ CEILING: function (a, b) {
|
|
|
+ if (b === 0) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return _.ceil(a, b);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 将参数number向下舍入(沿绝对值减小的方向)为最接近的significance的倍数。
|
|
|
+ * number: 必需。 要舍入的数值。
|
|
|
+ * significance: 必需。 要舍入到的倍数。
|
|
|
+ */
|
|
|
+ FLOOR: function (a, b) {
|
|
|
+ if (b === 0) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return _.floor(a, b);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 将数字向下舍入到最接近的整数。
|
|
|
+ */
|
|
|
+ INT: function (a) {
|
|
|
+ return _.isNumber(a) ? Math.floor(a) : 0;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 根据指定底数返回数字的对数。
|
|
|
+ * number: 必需。 想要计算其对数的正实数。
|
|
|
+ * base: 可选。 对数的底数。 如果省略 base,则假定其值为 10。
|
|
|
+ */
|
|
|
+ LOG: function (a, b) {
|
|
|
+ b = undefined === b ? 10 : b;
|
|
|
+ return _.isNumber(b) ? Math.log(a) / Math.log(b) : 0;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回两数相除的余数。 结果的符号与除数相同。
|
|
|
+ * number: 必需。 要计算余数的被除数。
|
|
|
+ * divisor: 必需。 除数。
|
|
|
+ *
|
|
|
+ */
|
|
|
+ MOD: function (a, b) {
|
|
|
+ if (b === 0) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ const c = Math.abs(a % b);
|
|
|
+ return b > 0 ? c : -c;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回数字乘幂的结果。
|
|
|
+ * number: 必需。 基数。 可为任意实数。
|
|
|
+ * power: 必需。 基数乘幂运算的指数。
|
|
|
+ */
|
|
|
+ POWER: function (a, b) {
|
|
|
+ const c = Math.pow(a, b);
|
|
|
+ return isNaN(c) ? 0 : c;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 函数使所有以参数形式给出的数字相乘并返回乘积。
|
|
|
+ */
|
|
|
+ PRODUCT: function () {
|
|
|
+ const args = Utils.flatten(arguments, function (a) {
|
|
|
+ return _.isNumber(a);
|
|
|
+ });
|
|
|
+ let b = 1;
|
|
|
+ for (let i = 0; i < args.length; i++) {
|
|
|
+ b = evalExpression("*", b, args[i]);
|
|
|
+ }
|
|
|
+ return b;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回正的平方根。
|
|
|
+ */
|
|
|
+ SQRT: function (a) {
|
|
|
+ return a < 0 ? 0 : Math.sqrt(a);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 函数使所有以参数形式给出的数字相加并返回和。
|
|
|
+ */
|
|
|
+ SUM: function () {
|
|
|
+ const args = Utils.flatten(arguments, function (a) {
|
|
|
+ return _.isNumber(a);
|
|
|
+ });
|
|
|
+ let v = 0;
|
|
|
+ for (let i = 0, d = args.length; i < d; ++i) {
|
|
|
+ v = evalExpression("+", v, Number(args[i]));
|
|
|
+ }
|
|
|
+ return v;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 在给定的数组中,将数组间对应的元素相乘,并返回乘积之和。
|
|
|
+ *
|
|
|
+ * array: 可选。多个数字数组。
|
|
|
+ * 主要可用于计算加权和。例如:SUMPRODUCT([1,2,3],[0.1,0.2,0.3]),相当于 1×0.1 + 2×0.2 + 3×0.3=1.4
|
|
|
+ */
|
|
|
+ SUMPRODUCT: function () {
|
|
|
+ for (var a = 0, b = [], c = -1, d = 0; d < arguments.length; d++) {
|
|
|
+ if (arguments[d] instanceof Array) {
|
|
|
+ c =
|
|
|
+ c < 0
|
|
|
+ ? arguments[d].length
|
|
|
+ : Math.min(arguments[d].length, c);
|
|
|
+ b.push(arguments[d]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (let e, f, g, h = 0; h < c; h++) {
|
|
|
+ for (e = 1, f = 0; f < b.length; f++) {
|
|
|
+ g = parseFloat(b[f][h]);
|
|
|
+ isNaN(g) && (g = 0);
|
|
|
+ e = evalExpression("*", e, g);
|
|
|
+ }
|
|
|
+ a = evalExpression("+", a, e);
|
|
|
+ }
|
|
|
+ return a;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 将数字舍入到指定的小数位数,以十进制数格式对该数进行格式设置,并以文本形式返回结果。
|
|
|
+ * number: 必需。 要进行舍入并转换为文本的数字。
|
|
|
+ * decimals: 可选。 小数点右边的位数。
|
|
|
+ */
|
|
|
+ FIXED: function (a, b) {
|
|
|
+ b = undefined === b ? 0 : b;
|
|
|
+ return _.isNumber(b) && b >= 0 ? Number(a).toFixed(b) : "";
|
|
|
+ },
|
|
|
|
|
|
- /**
|
|
|
- * 返回某日期的小时数。
|
|
|
- */
|
|
|
- HOUR: function(a) {
|
|
|
- return a.getHours()
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回某日期的分钟数。
|
|
|
- */
|
|
|
- MINUTE: function(a) {
|
|
|
- return a.getMinutes()
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回某日期的秒数。
|
|
|
- */
|
|
|
- SECOND: function(a) {
|
|
|
- return a.getSeconds()
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回两个日期之间的天数。
|
|
|
- * end_timestamp: 必需。结束日期。
|
|
|
- * start_timestamp: 必需。起始日期。
|
|
|
- */
|
|
|
- DAYS: function(a, b) {
|
|
|
- if (Utils.isEmpty(a) || Utils.isEmpty(b)) return 0
|
|
|
- const c = new Date(a.getFullYear(), a.getMonth(), a.getDate())
|
|
|
- const d = new Date(b.getFullYear(), b.getMonth(), b.getDate())
|
|
|
- return (c - d) / 864e5
|
|
|
- },
|
|
|
- /**
|
|
|
- * 按照一年 360 天的算法(每个月以 30 天计,一年共计 12 个月),DAYS360 函数返回两个日期间相差的天数,这在一些会计计算中将会用到。 如果财会系统是基于一年 12 个月,每月 30 天,可使用此函数帮助计算支付款项。
|
|
|
- * end_timestamp: 必需。结束日期。
|
|
|
- * start_timestamp: 必需。起始日期。
|
|
|
- * method: 可选。用于指定在计算中是采用美国方法还是欧洲方法。不填或false表示是美国方法,true表示是欧洲方法。
|
|
|
- *
|
|
|
- */
|
|
|
- DAYS360: function(a, b, c) {
|
|
|
- let d, e
|
|
|
- const f = b.getMonth()
|
|
|
- let g = a.getMonth()
|
|
|
- if (c) {
|
|
|
- d = b.getDate() === 31 ? 30 : b.getDate()
|
|
|
- e = a.getDate() === 31 ? 30 : a.getDate()
|
|
|
- } else {
|
|
|
- const h = new Date(b.getFullYear(), f + 1, 0).getDate()
|
|
|
- const i = new Date(a.getFullYear(), g + 1, 0).getDate()
|
|
|
- d = b.getDate() === h ? 30 : b.getDate()
|
|
|
- if (a.getDate() === i) {
|
|
|
- if (d < 30) {
|
|
|
- g++
|
|
|
- e = 1
|
|
|
+ RAND: function (a = 6) {
|
|
|
+ return _.round(Math.random(), a);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * 返回大于等于lower 且小于 upper 的均匀分布随机实数。每一次触发计算都会变化。
|
|
|
+ * _.random(0, 5);
|
|
|
+ * // => an integer between 0 and 5
|
|
|
+ * _.random(5);
|
|
|
+ * // => also an integer between 0 and 5
|
|
|
+ * _.random(5, true);
|
|
|
+ * // => a floating-point number between 0 and 5
|
|
|
+ * _.random(1.2, 5.2);
|
|
|
+ * // => a floating-point number between 1.2 and 5.2
|
|
|
+ */
|
|
|
+ RANDOM: function (lower, upper, floating) {
|
|
|
+ return _.random(lower, upper, floating);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 用于任意精度的十进制算术运算。
|
|
|
+ * @param {*} symbol 符号
|
|
|
+ * @param {*} a
|
|
|
+ * @param {*} b
|
|
|
+ */
|
|
|
+ BIG(symbol, a, b) {
|
|
|
+ return evalExpression(symbol, a, b);
|
|
|
+ },
|
|
|
+ // =============== 日期函数===================================
|
|
|
+ /**
|
|
|
+ * 最小日期
|
|
|
+ */
|
|
|
+ MINDATE: function () {
|
|
|
+ const a = FormulaUtil.DATEFLATTEN(arguments);
|
|
|
+ let min = a[0];
|
|
|
+ for (let i = 1; i < a.length; i++) {
|
|
|
+ if (a[i] < min) {
|
|
|
+ min = a[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const format = FormulaUtil.DATEFORMAT(min);
|
|
|
+ return fecha.format(min, format);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 最大日期
|
|
|
+ */
|
|
|
+ MAXDATE: function () {
|
|
|
+ const a = FormulaUtil.DATEFLATTEN(arguments);
|
|
|
+ let max = a[0];
|
|
|
+ for (let i = 1; i < a.length; i++) {
|
|
|
+ if (a[i] > max) {
|
|
|
+ max = a[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const format = FormulaUtil.DATEFORMAT(max);
|
|
|
+ return fecha.format(max, format);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ *1、 将时间戳转换为日期对象。 * timestamp: 必需。时间戳。
|
|
|
+ *
|
|
|
+ * DATE(year,month,day)
|
|
|
+ * DATE(year,month,day,hour,minute,second)
|
|
|
+ *
|
|
|
+ *2、将年月日时分秒转换为日期对象。
|
|
|
+ * year: 必需。年份。
|
|
|
+ * month: 必需。月份。
|
|
|
+ * day: 必需。天数。
|
|
|
+ * hour: 必需。小时。
|
|
|
+ * minute: 必需。分钟。
|
|
|
+ * second: 必需。秒。
|
|
|
+ * 例如,2015年11月1日的日期对象可以用如下表示:
|
|
|
+ * DATE(2015,11,1)
|
|
|
+ * DATE(1446307200000)
|
|
|
+ * DATE(2015,11,1,0,0,0)
|
|
|
+ * 这三个都表示“Sun Nov 01 2015 00:00:00 GMT+0800 (中国标准时间)”
|
|
|
+ *
|
|
|
+ */
|
|
|
+ DATE: function () {
|
|
|
+ if (Utils.isEmpty(arguments[0])) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ let v;
|
|
|
+ if (arguments.length === 6) {
|
|
|
+ v = new Date(
|
|
|
+ parseInt(arguments[0], 10),
|
|
|
+ parseInt(arguments[1], 10) - 1,
|
|
|
+ parseInt(arguments[2], 10),
|
|
|
+ parseInt(arguments[3], 10),
|
|
|
+ parseInt(arguments[4], 10),
|
|
|
+ parseInt(arguments[5], 10)
|
|
|
+ );
|
|
|
+ } else if (arguments.length === 3) {
|
|
|
+ v = new Date(
|
|
|
+ parseInt(arguments[0], 10),
|
|
|
+ parseInt(arguments[1], 10) - 1,
|
|
|
+ parseInt(arguments[2], 10)
|
|
|
+ );
|
|
|
} else {
|
|
|
- e = 30
|
|
|
+ // 移动端兼容问题
|
|
|
+ v = new Date(arguments[0].replace(/-/g, "/"));
|
|
|
}
|
|
|
- } else {
|
|
|
- e = a.getDate()
|
|
|
- }
|
|
|
- }
|
|
|
- return 360 * (a.getFullYear() - b.getFullYear()) + 30 * (g - f) + (e - d)
|
|
|
- },
|
|
|
- /**
|
|
|
- * 将指定日期加/减指定天数。
|
|
|
- * timestamp: 必需。初始日期。
|
|
|
- * deltadays: 必需。需要加减的天数。正数为增加,负数为减少。
|
|
|
- *
|
|
|
- */
|
|
|
- DATEDELTA: function(a, b) {
|
|
|
- if (Utils.isEmpty(a)) return ''
|
|
|
- if (!(a instanceof Date)) return ''
|
|
|
- if (!_.isNumber(b)) (b = 0)
|
|
|
+ return v;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回特定时间的十进制数字。时间值为日期值的一部分,并用十进制数表示(例如 12:00 PM 可表示为 0.5,因为此时是一天的一半)。
|
|
|
+ * hour: 必需。 0(零)到 32767 之间的数字,代表小时。 任何大于 23 的值都会除以 24,余数将作为小时值。 例如,TIME(27,0,0) = TIME(3,0,0) = .125
|
|
|
+ * minute: 必需。 0 到 32767 之间的数字,代表分钟。 任何大于 59 的值将转换为小时和分钟。 例如,TIME(0,750,0) = TIME(12,30,0) = .520833
|
|
|
+ * second: 必需。 0 到 32767 之间的数字,代表秒。 任何大于 59 的值将转换为小时、分钟和秒。 例如,TIME(0,0,2000) = TIME(0,33,20) = .023148
|
|
|
+ *
|
|
|
+ */
|
|
|
+ TIME: function (a, b, c) {
|
|
|
+ return (3600 * a + 60 * b + c) / 86400;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 将日期对象(或日期字符串)转换成时间戳。
|
|
|
+ */
|
|
|
+ TIMESTAMP: function (a) {
|
|
|
+ if (Utils.isEmpty(a)) return 0;
|
|
|
+ if (_.isString(a)) return FormulaUtil.TIMESTAMP(FormulaUtil.DATE(a));
|
|
|
+ return _.isDate(a) ? a.getTime() : 0;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回今天。
|
|
|
+ */
|
|
|
+ TODAY: function () {
|
|
|
+ return new Date();
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回当前时间。与TODAY函数相同。
|
|
|
+ */
|
|
|
+ NOW: function () {
|
|
|
+ return new Date();
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回当前服务器时间。
|
|
|
+ * 即使客户端的时间被人为调整了,SYSTIME函数不受影响,获取的仍然是服务器时间。例如签到、打卡等场景下,可避免调整时间作弊的情况。
|
|
|
+ */
|
|
|
+ SYSTIME: function () {
|
|
|
+ getSystemTimestamp()
|
|
|
+ .then((response) => {
|
|
|
+ return response.data;
|
|
|
+ })
|
|
|
+ .catch((error) => {
|
|
|
+ console.error(error);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ *返回某日期的年。
|
|
|
+ */
|
|
|
+ YEAR: function (a) {
|
|
|
+ return a.getFullYear();
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回某日期的天数。 天数是介于 1 到 31 之间的整数。
|
|
|
+ */
|
|
|
+ DAY: function (a) {
|
|
|
+ return a.getDate();
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回某日期的月份。 月份是介于 1 到 12 之间的整数。
|
|
|
+ */
|
|
|
+ MONTH: function (a) {
|
|
|
+ return a.getMonth() + 1;
|
|
|
+ },
|
|
|
|
|
|
- return new Date(a.getTime() + 864e5 * b)
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回给定日期在全年中的ISO周数。
|
|
|
- * timestamp: 必需。日期是Excel用于日期和时间计算的日期-时间代码。
|
|
|
- */
|
|
|
- ISOWEEKNUM: function(a) {
|
|
|
- a.setHours(0, 0, 0)
|
|
|
- a.setDate(a.getDate() + 4 - (a.getDay() || 7))
|
|
|
- const b = new Date(a.getFullYear(), 0, 1)
|
|
|
- return Math.ceil(((a - b) / 864e5 + 1) / 7)
|
|
|
- },
|
|
|
- /**
|
|
|
- * 返回特定日期的周数。例如,包含1月1日的周为该年的第1周,其编号为第1周。
|
|
|
- * timestamp: 必需。指定日期。代表一周中的日期。应使用DATE函数输入日期,或者将日期作为其他公式或函数的结果输入
|
|
|
- * return_type: 可选。一数字,确定星期从哪一天开始。默认值为1。
|
|
|
- */
|
|
|
- WEEKNUM: function(a, b) {
|
|
|
- undefined === b && (b = 1)
|
|
|
- if (b === 21) {
|
|
|
- return FormulaUtil.ISOWEEKNUM(a)
|
|
|
- }
|
|
|
- const c = [undefined, 0, 1, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, 1, 2, 3, 4, 5, 6, 0]
|
|
|
+ /**
|
|
|
+ * 返回某日期的小时数。
|
|
|
+ */
|
|
|
+ HOUR: function (a) {
|
|
|
+ return a.getHours();
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回某日期的分钟数。
|
|
|
+ */
|
|
|
+ MINUTE: function (a) {
|
|
|
+ return a.getMinutes();
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回某日期的秒数。
|
|
|
+ */
|
|
|
+ SECOND: function (a) {
|
|
|
+ return a.getSeconds();
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回两个日期之间的天数。
|
|
|
+ * end_timestamp: 必需。结束日期。
|
|
|
+ * start_timestamp: 必需。起始日期。
|
|
|
+ */
|
|
|
+ DAYS: function (a, b) {
|
|
|
+ if (Utils.isEmpty(a) || Utils.isEmpty(b)) return 0;
|
|
|
+ const c = new Date(a.getFullYear(), a.getMonth(), a.getDate());
|
|
|
+ const d = new Date(b.getFullYear(), b.getMonth(), b.getDate());
|
|
|
+ return (c - d) / 864e5;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 按照一年 360 天的算法(每个月以 30 天计,一年共计 12 个月),DAYS360 函数返回两个日期间相差的天数,这在一些会计计算中将会用到。 如果财会系统是基于一年 12 个月,每月 30 天,可使用此函数帮助计算支付款项。
|
|
|
+ * end_timestamp: 必需。结束日期。
|
|
|
+ * start_timestamp: 必需。起始日期。
|
|
|
+ * method: 可选。用于指定在计算中是采用美国方法还是欧洲方法。不填或false表示是美国方法,true表示是欧洲方法。
|
|
|
+ *
|
|
|
+ */
|
|
|
+ DAYS360: function (a, b, c) {
|
|
|
+ let d, e;
|
|
|
+ const f = b.getMonth();
|
|
|
+ let g = a.getMonth();
|
|
|
+ if (c) {
|
|
|
+ d = b.getDate() === 31 ? 30 : b.getDate();
|
|
|
+ e = a.getDate() === 31 ? 30 : a.getDate();
|
|
|
+ } else {
|
|
|
+ const h = new Date(b.getFullYear(), f + 1, 0).getDate();
|
|
|
+ const i = new Date(a.getFullYear(), g + 1, 0).getDate();
|
|
|
+ d = b.getDate() === h ? 30 : b.getDate();
|
|
|
+ if (a.getDate() === i) {
|
|
|
+ if (d < 30) {
|
|
|
+ g++;
|
|
|
+ e = 1;
|
|
|
+ } else {
|
|
|
+ e = 30;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ e = a.getDate();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return (
|
|
|
+ 360 * (a.getFullYear() - b.getFullYear()) + 30 * (g - f) + (e - d)
|
|
|
+ );
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 将指定日期加/减指定天数。
|
|
|
+ * timestamp: 必需。初始日期。
|
|
|
+ * deltadays: 必需。需要加减的天数。正数为增加,负数为减少。
|
|
|
+ *
|
|
|
+ */
|
|
|
+ DATEDELTA: function (a, b) {
|
|
|
+ if (Utils.isEmpty(a)) return "";
|
|
|
+ if (!_.isNumber(b)) b = 0;
|
|
|
+ if (!(a instanceof Date)) {
|
|
|
+ // 兼容字符串格式的日期数据 例如 2024-10-09
|
|
|
+ const dateRegex =
|
|
|
+ /^(\d{4})[-/](0[1-9]|1[0-2])[-/](0[1-9]|[12]\d|3[01])$/;
|
|
|
+ if (!dateRegex.test(a)) return "";
|
|
|
+ const date = new Date(a);
|
|
|
+ date.setDate(date.getDate() + b);
|
|
|
+ const year = date.getFullYear();
|
|
|
+ const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份从 0 开始,所以要加 1
|
|
|
+ const day = String(date.getDate()).padStart(2, "0");
|
|
|
+ return `${year}-${month}-${day}`;
|
|
|
+ }
|
|
|
+ return new Date(a.getTime() + 864e5 * b);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回给定日期在全年中的ISO周数。
|
|
|
+ * timestamp: 必需。日期是Excel用于日期和时间计算的日期-时间代码。
|
|
|
+ */
|
|
|
+ ISOWEEKNUM: function (a) {
|
|
|
+ a.setHours(0, 0, 0);
|
|
|
+ a.setDate(a.getDate() + 4 - (a.getDay() || 7));
|
|
|
+ const b = new Date(a.getFullYear(), 0, 1);
|
|
|
+ return Math.ceil(((a - b) / 864e5 + 1) / 7);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 返回特定日期的周数。例如,包含1月1日的周为该年的第1周,其编号为第1周。
|
|
|
+ * timestamp: 必需。指定日期。代表一周中的日期。应使用DATE函数输入日期,或者将日期作为其他公式或函数的结果输入
|
|
|
+ * return_type: 可选。一数字,确定星期从哪一天开始。默认值为1。
|
|
|
+ */
|
|
|
+ WEEKNUM: function (a, b) {
|
|
|
+ undefined === b && (b = 1);
|
|
|
+ if (b === 21) {
|
|
|
+ return FormulaUtil.ISOWEEKNUM(a);
|
|
|
+ }
|
|
|
+ const c = [
|
|
|
+ undefined,
|
|
|
+ 0,
|
|
|
+ 1,
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ 1,
|
|
|
+ 2,
|
|
|
+ 3,
|
|
|
+ 4,
|
|
|
+ 5,
|
|
|
+ 6,
|
|
|
+ 0,
|
|
|
+ ];
|
|
|
|
|
|
- const d = c[b]
|
|
|
- let e = new Date(a.getFullYear(), 0, 1)
|
|
|
- const f = e.getDay() < d ? 1 : 0
|
|
|
- e -= 24 * Math.abs(e.getDay() - d) * 60 * 60 * 1e3
|
|
|
- return Math.floor((a - e) / 864e5 / 7 + 1) + f
|
|
|
- },
|
|
|
- /**
|
|
|
- * 将日期对象转换为指定格式日期字符串
|
|
|
- */
|
|
|
- FORMAT: function(date, format) {
|
|
|
- return fecha.format(date, format)
|
|
|
- },
|
|
|
- /**
|
|
|
- * 将按指定格式日期字符串转换为日期对象
|
|
|
- */
|
|
|
- PARSE: function(dateStr, format) {
|
|
|
- return fecha.parse(dateStr, format)
|
|
|
- },
|
|
|
- // ===================高级函数===========================
|
|
|
- /**
|
|
|
- *
|
|
|
- * 将数字转换成特定格式的文本。
|
|
|
- * 其中text_format的含义如下:
|
|
|
- * #:数字占位符。只显有意义的数据而不显示无意义的数据。小数点后数字如大于”#”的数量,则按”#”的位数四舍五入。小数点后数字如小于”#”的数量,则显示实际值。例:在文本框中输入:###.##,23.1显示为23.1,23.1578显示为23.16。
|
|
|
- * 0:数字占位补位符。如果小数点前的数据的长度大于占位符,则显示实际数据,如果小于占位符的数量,则用0补足。小数点后的数据的长度大于占位符,则按“0”的位数四舍五入。小数点后数字如小于”0”的数量,则用“0”补足。例:在文本框中输入:000.00,23.1显示为023.10,23.1578显示为023.16。
|
|
|
- * ,:千位分隔符。可插入“#”或“0”中使用,数字中插入千位分隔符。合法使用形式:1.需要在小数点前使用。2.需要在“#”或“0”之间。
|
|
|
- * %:百分比。放在数字占位符或补位符之后。数据以百分比形式显示。例:代码:#%,23.1显示为2310%。
|
|
|
- * [Num0]显示原始数据。
|
|
|
- * [Num1]将数字转为中文小写。123显示为一百二十三
|
|
|
- * [Num2]将数字转为中文大写。123显示为壹佰贰拾叁
|
|
|
- * 直接在[Num0]或#或0的之前加字符即是前缀,支持中文字符,英文大小写,¥,$,及空格。
|
|
|
- */
|
|
|
- TEXT: function(a, b) {
|
|
|
- return _.isNull(a) ? '' : _.isDate(a) && Utils.isNotEmpty(b) ? fecha.format(a, b) : num2Str(a, b)
|
|
|
- },
|
|
|
- /**
|
|
|
- * 将文本转化为数字。
|
|
|
- */
|
|
|
- VALUE: function(a) {
|
|
|
- return Utils.isEmpty(a) ? 0 : isNaN(a) ? 0 : parseFloat(a)
|
|
|
- },
|
|
|
- /**
|
|
|
- * 把数组变成统一深度
|
|
|
- */
|
|
|
- FLATTEN: function(input, shallow, strict, startIndex) {
|
|
|
- return Utils.flatten(input, shallow, strict, startIndex)
|
|
|
- },
|
|
|
- /**
|
|
|
- * 随机码生成器。可适用于随机流水号的使用场景等。
|
|
|
- * 但要注意UUID()保证输出的32位字符串不会重复,不能保证从这32位字符串中截取的一部分也不重复,因此有需要不重复的用户,要勾选“不可重复”。
|
|
|
- */
|
|
|
- UUID: function() {
|
|
|
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
|
- const r = Math.random() * 16 | 0
|
|
|
- const v = c === 'x' ? r : (r & 0x3 | 0x8)
|
|
|
- return v.toString(16)
|
|
|
- })
|
|
|
- },
|
|
|
- /**
|
|
|
- * 是否为空
|
|
|
- */
|
|
|
- ISEMPTY: function(obj) {
|
|
|
- return Utils.isEmpty(obj)
|
|
|
- },
|
|
|
- /**
|
|
|
- * 人民币
|
|
|
- */
|
|
|
- CURRENCY: function(value) {
|
|
|
- return numberCurrency(value)
|
|
|
- },
|
|
|
- /**
|
|
|
- * 千分位
|
|
|
- */
|
|
|
- THOUSANDS: function(num, decimalPlaces, dsep, tsep) {
|
|
|
- return numberThousands(num, decimalPlaces, dsep, tsep)
|
|
|
- },
|
|
|
- DATEFLATTEN: function() {
|
|
|
- const a = Utils.flatten(arguments, function(a) {
|
|
|
- if (Utils.isEmpty(a)) {
|
|
|
- return 0
|
|
|
- }
|
|
|
- return a
|
|
|
- })
|
|
|
- return a
|
|
|
- },
|
|
|
- /**
|
|
|
- * 日期默认格式化
|
|
|
- * @param {*} date
|
|
|
- */
|
|
|
- DATEFORMAT: function(date) {
|
|
|
- let format
|
|
|
- if (date.indexOf(' ') !== -1) {
|
|
|
- format = 'yyyy-MM-dd HH:mm:ss'
|
|
|
- } else if (date.indexOf('-') !== -1) {
|
|
|
- format = 'yyyy-MM-dd'
|
|
|
- } else {
|
|
|
- format = 'HH:mm:ss'
|
|
|
- }
|
|
|
- return format
|
|
|
- },
|
|
|
- _: function() {
|
|
|
- return _
|
|
|
- },
|
|
|
- /**
|
|
|
- * 转换拼音
|
|
|
- * @param {*} value
|
|
|
- * @param {*} separator 字符间的分隔符
|
|
|
- * @param {*} format
|
|
|
- * WITH_TONE_MARK: "WITH_TONE_MARK", //带声调
|
|
|
- * WITHOUT_TONE: "WITHOUT_TONE", //不带声调
|
|
|
- * WITH_TONE_NUMBER: "WITH_TONE_NUMBER", //数字代表声调
|
|
|
- * FIRST_LETTER: "FIRST_LETTER" //首字母风格 【默认】
|
|
|
- */
|
|
|
- PINYIN(value, separator, format) {
|
|
|
- if (Utils.isEmpty(value)) {
|
|
|
- return ''
|
|
|
- }
|
|
|
- if (!separator) {
|
|
|
- separator = ''
|
|
|
- }
|
|
|
- if (!format) {
|
|
|
- format = pinyin4js.FIRST_LETTER
|
|
|
- }
|
|
|
- return pinyin4js.convertToPinyinString(value, separator, format)
|
|
|
- }
|
|
|
-}
|
|
|
-export default FormulaUtil
|
|
|
+ const d = c[b];
|
|
|
+ let e = new Date(a.getFullYear(), 0, 1);
|
|
|
+ const f = e.getDay() < d ? 1 : 0;
|
|
|
+ e -= 24 * Math.abs(e.getDay() - d) * 60 * 60 * 1e3;
|
|
|
+ return Math.floor((a - e) / 864e5 / 7 + 1) + f;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 将日期对象转换为指定格式日期字符串
|
|
|
+ */
|
|
|
+ FORMAT: function (date, format) {
|
|
|
+ return fecha.format(date, format);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 将按指定格式日期字符串转换为日期对象
|
|
|
+ */
|
|
|
+ PARSE: function (dateStr, format) {
|
|
|
+ return fecha.parse(dateStr, format);
|
|
|
+ },
|
|
|
+ // ===================高级函数===========================
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * 将数字转换成特定格式的文本。
|
|
|
+ * 其中text_format的含义如下:
|
|
|
+ * #:数字占位符。只显有意义的数据而不显示无意义的数据。小数点后数字如大于”#”的数量,则按”#”的位数四舍五入。小数点后数字如小于”#”的数量,则显示实际值。例:在文本框中输入:###.##,23.1显示为23.1,23.1578显示为23.16。
|
|
|
+ * 0:数字占位补位符。如果小数点前的数据的长度大于占位符,则显示实际数据,如果小于占位符的数量,则用0补足。小数点后的数据的长度大于占位符,则按“0”的位数四舍五入。小数点后数字如小于”0”的数量,则用“0”补足。例:在文本框中输入:000.00,23.1显示为023.10,23.1578显示为023.16。
|
|
|
+ * ,:千位分隔符。可插入“#”或“0”中使用,数字中插入千位分隔符。合法使用形式:1.需要在小数点前使用。2.需要在“#”或“0”之间。
|
|
|
+ * %:百分比。放在数字占位符或补位符之后。数据以百分比形式显示。例:代码:#%,23.1显示为2310%。
|
|
|
+ * [Num0]显示原始数据。
|
|
|
+ * [Num1]将数字转为中文小写。123显示为一百二十三
|
|
|
+ * [Num2]将数字转为中文大写。123显示为壹佰贰拾叁
|
|
|
+ * 直接在[Num0]或#或0的之前加字符即是前缀,支持中文字符,英文大小写,¥,$,及空格。
|
|
|
+ */
|
|
|
+ TEXT: function (a, b) {
|
|
|
+ return _.isNull(a)
|
|
|
+ ? ""
|
|
|
+ : _.isDate(a) && Utils.isNotEmpty(b)
|
|
|
+ ? fecha.format(a, b)
|
|
|
+ : num2Str(a, b);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 将文本转化为数字。
|
|
|
+ */
|
|
|
+ VALUE: function (a) {
|
|
|
+ return Utils.isEmpty(a) ? 0 : isNaN(a) ? 0 : parseFloat(a);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 把数组变成统一深度
|
|
|
+ */
|
|
|
+ FLATTEN: function (input, shallow, strict, startIndex) {
|
|
|
+ return Utils.flatten(input, shallow, strict, startIndex);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 随机码生成器。可适用于随机流水号的使用场景等。
|
|
|
+ * 但要注意UUID()保证输出的32位字符串不会重复,不能保证从这32位字符串中截取的一部分也不重复,因此有需要不重复的用户,要勾选“不可重复”。
|
|
|
+ */
|
|
|
+ UUID: function () {
|
|
|
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
|
|
|
+ /[xy]/g,
|
|
|
+ function (c) {
|
|
|
+ const r = (Math.random() * 16) | 0;
|
|
|
+ const v = c === "x" ? r : (r & 0x3) | 0x8;
|
|
|
+ return v.toString(16);
|
|
|
+ }
|
|
|
+ );
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 是否为空
|
|
|
+ */
|
|
|
+ ISEMPTY: function (obj) {
|
|
|
+ return Utils.isEmpty(obj);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 人民币
|
|
|
+ */
|
|
|
+ CURRENCY: function (value) {
|
|
|
+ return numberCurrency(value);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 千分位
|
|
|
+ */
|
|
|
+ THOUSANDS: function (num, decimalPlaces, dsep, tsep) {
|
|
|
+ return numberThousands(num, decimalPlaces, dsep, tsep);
|
|
|
+ },
|
|
|
+ DATEFLATTEN: function () {
|
|
|
+ const a = Utils.flatten(arguments, function (a) {
|
|
|
+ if (Utils.isEmpty(a)) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return a;
|
|
|
+ });
|
|
|
+ return a;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 日期默认格式化
|
|
|
+ * @param {*} date
|
|
|
+ */
|
|
|
+ DATEFORMAT: function (date) {
|
|
|
+ let format;
|
|
|
+ if (date.indexOf(" ") !== -1) {
|
|
|
+ format = "yyyy-MM-dd HH:mm:ss";
|
|
|
+ } else if (date.indexOf("-") !== -1) {
|
|
|
+ format = "yyyy-MM-dd";
|
|
|
+ } else {
|
|
|
+ format = "HH:mm:ss";
|
|
|
+ }
|
|
|
+ return format;
|
|
|
+ },
|
|
|
+ _: function () {
|
|
|
+ return _;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 转换拼音
|
|
|
+ * @param {*} value
|
|
|
+ * @param {*} separator 字符间的分隔符
|
|
|
+ * @param {*} format
|
|
|
+ * WITH_TONE_MARK: "WITH_TONE_MARK", //带声调
|
|
|
+ * WITHOUT_TONE: "WITHOUT_TONE", //不带声调
|
|
|
+ * WITH_TONE_NUMBER: "WITH_TONE_NUMBER", //数字代表声调
|
|
|
+ * FIRST_LETTER: "FIRST_LETTER" //首字母风格 【默认】
|
|
|
+ */
|
|
|
+ PINYIN(value, separator, format) {
|
|
|
+ if (Utils.isEmpty(value)) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ if (!separator) {
|
|
|
+ separator = "";
|
|
|
+ }
|
|
|
+ if (!format) {
|
|
|
+ format = pinyin4js.FIRST_LETTER;
|
|
|
+ }
|
|
|
+ return pinyin4js.convertToPinyinString(value, separator, format);
|
|
|
+ },
|
|
|
+};
|
|
|
+export default FormulaUtil;
|