package util import ( "apigo.cc/apigo/plugin" "encoding/hex" "github.com/ssgo/u" "gopkg.in/yaml.v3" "time" ) func init() { plugin.Register(plugin.Plugin{ Id: "apigo.cc/apigo/plugins/util", Name: "基础工具", JsCode: ` ${OBJECT}.formatDate = function (date, fmt) { let ret if (!date) return '' if (!fmt) fmt = 'YYYY-mm-dd HH:MM:SS' const opt = { 'YYYY': date.getFullYear().toString(), 'YY': date.getFullYear().toString().substring(2), 'm+': (date.getMonth() + 1).toString(), 'd+': date.getDate().toString(), 'H+': date.getHours().toString(), 'h+': (date.getHours() % 12).toString(), 'APM': (date.getHours() > 12 ? 'PM' : 'AM'), 'M+': date.getMinutes().toString(), 'S+': date.getSeconds().toString(), 'YW': 'W' + Math.ceil(((date.getTime() - new Date(date.getFullYear(), 0, 0))) / (24 * 60 * 60 * 1000) / 7), } for (let k in opt) { ret = new RegExp('(' + k + ')').exec(fmt) if (ret) { fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, '0'))) } } return fmt } ${OBJECT}.parseDate = function (str) { if (typeof str === 'number') str = str + '' if (/^\d+[\\.]?\d*$/.test(str)) { if (str.length === 10) str += '000' return new Date(${OBJECT}.int(str)) } if (str.length === 19) { return new Date(parseInt(str.substr(0, 4)), parseInt(str.substr(5, 2)) - 1, parseInt(str.substr(8, 2)), parseInt(str.substr(11, 2)), parseInt(str.substr(14, 2)), parseInt(str.substr(17, 2))) } else if (str.length === 10) { return new Date(parseInt(str.substr(0, 4)), parseInt(str.substr(5, 2)) - 1, parseInt(str.substr(8, 2))) } else if (str.length === 7) { return new Date(parseInt(str.substr(0, 4)), parseInt(str.substr(5, 2)) - 1, 1) } else if (str.length === 8) { let date = new Date() return new Date(date.getFullYear(), date.getMonth(), date.getDate(), parseInt(str.substr(0, 2)), parseInt(str.substr(3, 2)), parseInt(str.substr(6, 2))) } else if (str.length === 5) { let date = new Date() return new Date(date.getFullYear(), date.getMonth(), date.getDate(), parseInt(str.substr(0, 2)), parseInt(str.substr(3, 2)), 0) } return new Date(str) } ${OBJECT}.int = function (v) { if (!v) return 0 if (typeof v === 'number' || v instanceof Number) return v if (typeof v === 'object') v = v.toString ? v.toString() : '' if (typeof v !== 'string') return 0 try { return Math.round(parseFloat(v.replace(/,/g, '').trim())) || 0 } catch (e) { return 0 } } ${OBJECT}.float = function (v) { if (!v) return 0.0 if (typeof v === 'number' || v instanceof Number) return v if (typeof v === 'object') v = v.toString ? v.toString() : '' if (typeof v !== 'string') return 0.0 try { return parseFloat(v.replace(/,/g, '').trim()) || 0.0 } catch (e) { return 0.0 } } ${OBJECT}.str = function (v) { if (!v) return '' if (typeof v === 'string') return v if (v.toString) return v.toString() return '' } ${OBJECT}.keysBy = function (obj, ...fieldAndValues) { let keys = [] for (let k in obj) { let match = true if (fieldAndValues.length === 1) { // 查找一位数组 if (obj[k] != fieldAndValues[0]) { match = false } } else { // 查找二维数组 for (let i = 0; i < fieldAndValues.length; i += 2) { if (obj[k][fieldAndValues[i]] != fieldAndValues[i + 1]) { match = false break } } } if (match) { keys.push(k) } } return keys } ${OBJECT}.listBy = function (obj, ...fieldAndValues) { let list = obj instanceof Array || obj instanceof NodeList ? [] : {} let keys = ${OBJECT}.keysBy(obj, ...fieldAndValues) for (let k of keys) { if (obj instanceof Array || obj instanceof NodeList) { list.push(obj[k]) } else { list[k] = obj[k] } } return list } ${OBJECT}.hasBy = function (obj, ...fieldAndValues) { let keys = ${OBJECT}.keysBy(obj, ...fieldAndValues) return keys.length > 0 } ${OBJECT}.getBy = function (obj, ...fieldAndValues) { let keys = ${OBJECT}.keysBy(obj, ...fieldAndValues) if (keys.length > 0) return obj[keys[0]] return null } ${OBJECT}.setBy = function (obj, value, ...fieldAndValues) { let keys = ${OBJECT}.keysBy(obj, ...fieldAndValues) if (keys.length > 0) obj[keys[0]] = value } ${OBJECT}.indexBy = function (obj, ...fieldAndValues) { let keys = ${OBJECT}.keysBy(obj, ...fieldAndValues) if (keys.length > 0) { return obj instanceof Array || obj instanceof NodeList ? ${OBJECT}.int(keys[0]) : keys[0] } return -1 } ${OBJECT}.removeBy = function (obj, ...fieldAndValues) { let keys = ${OBJECT}.keysBy(obj, ...fieldAndValues) let n = 0 for (let i = keys.length - 1; i >= 0; i--) { let k = keys[i] if (obj instanceof Array || obj instanceof NodeList) { obj.splice(k, 1) } else { delete obj[k] } n++ } return n } ${OBJECT}.removeArrayItem = function (list, item) { let pos = list.indexOf(item) if (pos !== -1) list.splice(pos, 1) } ${OBJECT}.last = function (arr) { if (arr && arr.length) { return arr[arr.length - 1] } return null } ${OBJECT}.len = function (obj) { if (obj instanceof Array || obj instanceof NodeList) { return obj.length } else { let n = 0 for (let k in obj) n++ return n } } ${OBJECT}.mergeBy = function (olds, news, ...fields) { if (!olds) return news for (let newItem of news) { let fieldAndValues = [] for (let field of fields) { fieldAndValues.push(field, newItem[field]) } let oldIndex = ${OBJECT}.indexBy(olds, ...fieldAndValues) if (oldIndex === -1) { olds.push(newItem) } else { olds[oldIndex] = newItem } } return olds } ${OBJECT}.sortBy = function (obj, field, isReverse = false, sortType) { let list = obj instanceof Array || obj instanceof NodeList ? [] : {} let sortedKeys = {} let sortArr = [] for (let k in obj) { let v = '' if (field instanceof Array) { for (let f of field) v += obj[k][f] } else { v = obj[k][field] } if (!sortedKeys[v]) { sortedKeys[v] = true sortArr.push(v) } } sortArr.sort((a, b) => { if(sortType === 'int'){ a = ${OBJECT}.int(a) b = ${OBJECT}.int(b) } else if(sortType === 'float'){ a = ${OBJECT}.float(a) b = ${OBJECT}.float(b) } if (a == b) return 0 if (typeof a === 'number' && typeof b === 'number') { return isReverse ? b - a : a - b } else { return (isReverse ? a < b : a > b) ? 1 : -1 } }) for (let sortKey of sortArr) { for (let k in obj) { let v = '' if (field instanceof Array) { for (let f of field) v += obj[k][f] } else { v = obj[k][field] } if (obj instanceof Array || obj instanceof NodeList) { if (v == sortKey) list.push(obj[k]) } else { if (v == sortKey) list[k] = obj[k] } } } return list } ${OBJECT}.in = function (v1, v2) { if (!(v1 instanceof Array)) v1 = ${OBJECT}.split(v1, /,\s*/) return v1.indexOf(String(v2)) !== -1 } ${OBJECT}.uniquePush = function (arr, ...values) { for (let v of values) { if (arr.indexOf(v) === -1) arr.push(v) } } ${OBJECT}.clearEmpty = function (arr) { let a = [] for (let v of arr) if (v) a.push(v) return a } ${OBJECT}.split = function (v1, v2) { return ${OBJECT}.clearEmpty(${OBJECT}.str(v1).split(v2)) } ${OBJECT}.join = function (arr, separator) { return ${OBJECT}.clearEmpty(arr).join(separator) } ${OBJECT}.copy = function (obj, isDeepCopy) { let newObj if (obj instanceof Array || obj instanceof NodeList) { newObj = [] for (let o of obj) { if (isDeepCopy && typeof o === 'object' && o) o = ${OBJECT}.copy(o) newObj.push(o) } } else { newObj = {} for (let k in obj) { let v = obj[k] if (isDeepCopy && typeof v === 'object' && v) v = ${OBJECT}.copy(v) newObj[k] = v } } return newObj } `, Objects: map[string]interface{}{ // makeToken 生成指定长度的随机二进制数组 // makeToken size token长度 // makeToken return Hex编码的字符串 "makeToken": func(size int) string { return hex.EncodeToString(u.MakeToken(size)) }, // makeTokenBytes 生成指定长度的随机二进制数组 // makeTokenBytes size token长度 // makeTokenBytes return 二进制数据 "makeTokenBytes": u.MakeToken, // makeId 生成指定长度的随机ID // makeId size ID长度(6~20) // makeId return 二进制数据 "makeId": func(size int) string { if size > 20 { return u.UniqueId() } else if size > 14 { return u.UniqueId()[0:size] } else if size > 12 { return u.ShortUniqueId()[0:size] } else if size > 10 { return u.Id12()[0:size] } else if size > 8 { return u.Id10()[0:size] } else if size >= 6 { return u.Id8()[0:size] } else { return u.Id6() } }, // encodeYaml 将对象转换为YAML格式 // encodeYaml content 对象 // encodeYaml return YAML字符串 "encodeYaml": func(content interface{}) (string, error) { buf, err := yaml.Marshal(content) return string(buf), err }, // decodeYaml 将YAML转化为对象 // decodeYaml content YAML字符串 // decodeYaml return 对象 "decodeYaml": func(content string) (interface{}, error) { var data interface{} err := yaml.Unmarshal([]byte(content), &data) return data, err }, "now": func() *Time { return &Time{tm: time.Now()} }, "makeTime": func(year, month, day, hour, min, sec, msec int, location *string) *Time { loc := time.Local if location != nil { if loc2, err := time.LoadLocation(*location); err == nil { loc = loc2 } } return makeTime(time.Date(year, time.Month(month), day, hour, min, sec, msec*1000000, loc)) }, "unixTime": func(milliUnix int64) *Time { return makeTime(time.UnixMilli(milliUnix)) }, "int": func(v any) int { return 0 }, "float": func(v any) float64 { return 0 }, "str": func(v any) string { return "" }, "keysBy": func(obj []any, fieldAndValues ...any) []string { return nil }, "listBy": func(obj []any, fieldAndValues ...any) []any { return nil }, "hasBy": func(obj []any, fieldAndValues ...any) bool { return false }, "getBy": func(obj []any, fieldAndValues ...any) any { return nil }, "setBy": func(obj []any, value any, fieldAndValues ...any) {}, "indexBy": func(obj []any, fieldAndValues ...any) int { return 0 }, "removeBy": func(obj []any, fieldAndValues ...any) int { return 0 }, "removeArrayItem": func(list []any, item any) {}, "last": func(arr []any) any { return nil }, "len": func(obj any) int { return 0 }, "mergeBy": func(olds []any, news []any, fields ...string) []any { return nil }, "sortBy": func(arr []any, field string, isReverse *bool, sortType *string) []any { return nil }, "in": func(arr []any, v any) bool { return false }, "uniquePush": func(arr []any, values ...any) {}, "clearEmpty": func(arr []any) []any { return nil }, "split": func(str string, separator string) []string { return nil }, "join": func(arr []any, separator string) string { return "" }, "copy": func(obj any, isDeepCopy bool) any { return nil }, }, }) } func makeTime(tm time.Time) *Time { return &Time{tm: tm} } type Time struct { tm time.Time } func (t *Time) After(u *Time) bool { return t.tm.After(u.tm) } func (t *Time) Before(u *Time) bool { return t.tm.Before(u.tm) } func (t *Time) Compare(u *Time) int { return t.tm.Compare(u.tm) } func (t *Time) Equal(u *Time) bool { return t.tm.Equal(u.tm) } func (t *Time) Year() int { return t.tm.Year() } func (t *Time) Month() int { return int(t.tm.Month()) } func (t *Time) Day() int { return t.tm.Day() } func (t *Time) Weekday() int { return int(t.tm.Weekday()) } func (t *Time) ISOWeek() (year, week int) { return t.tm.ISOWeek() } func (t *Time) Hour() int { return t.tm.Hour() } func (t *Time) Minute() int { return t.tm.Minute() } func (t *Time) Second() int { return t.tm.Second() } func (t *Time) Millisecond() int { return t.tm.Nanosecond() / 1000000 } func (t *Time) YearDay() int { return t.tm.YearDay() } func (t *Time) Add(msec int) *Time { return makeTime(t.tm.Add(time.Duration(msec) * time.Millisecond)) } func (t *Time) Sub(u *Time) int { return int(t.tm.Sub(u.tm) / time.Millisecond) } func (t *Time) AddDate(years int, months int, days int) *Time { return makeTime(t.tm.AddDate(years, months, days)) } func (t *Time) UTC() *Time { return makeTime(t.tm.UTC()) } func (t *Time) Local() *Time { return makeTime(t.tm.Local()) } func (t *Time) Location() string { return t.tm.Location().String() } func (t *Time) Zone() string { name, _ := t.tm.Zone() return name } func (t *Time) ZoneOffset() int { _, offset := t.tm.Zone() return offset } func (t *Time) Unix() int64 { return t.tm.UnixMilli() } func (t *Time) Format(fmt *string) string { if fmt == nil || *fmt == "" { fmt2 := "2006-01-02 15:04:05" fmt = &fmt2 } return t.tm.Format(*fmt) } func (t *Time) String() string { return t.Format(nil) }