@haluo/util 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.js +2 -0
- package/dist/types/modules/cookie/index.d.ts +25 -0
- package/dist/types/modules/date/index.d.ts +1 -0
- package/dist/types/modules/dom/index.d.ts +1 -0
- package/dist/types/modules/filter/index.d.ts +25 -0
- package/dist/types/modules/format/index.d.ts +13 -0
- package/dist/types/modules/match/index.d.ts +1 -0
- package/dist/types/modules/monitor/index.d.ts +3 -0
- package/dist/types/modules/monitor/lib/jsError.d.ts +1 -0
- package/dist/types/modules/monitor/lib/timing.d.ts +1 -0
- package/dist/types/modules/monitor/lib/xhr.d.ts +1 -0
- package/dist/types/modules/monitor/utils/onload.d.ts +1 -0
- package/dist/types/modules/monitor/utils/tracker.d.ts +7 -0
- package/dist/types/modules/number/index.d.ts +39 -0
- package/dist/types/modules/sentry/index.d.ts +15 -0
- package/dist/types/modules/tools/index.d.ts +1 -0
- package/dist/types/types/index.d.ts +3 -0
- package/package.json +2 -1
- package/.babelrc +0 -21
- package/.eslintrc.js +0 -216
- package/__tests__/unit/date/date.spec.js +0 -14
- package/__tests__/unit/jest.conf.js +0 -25
- package/__tests__/unit/specs/date.test.js +0 -11
- package/global.d.ts +0 -0
- package/publish.sh +0 -11
- package/specification/CSS.md +0 -25
- package/specification/JS.md +0 -9
- package/specification/VUE.md +0 -1
- package/src/consts/httpCode.js +0 -10
- package/src/index.ts +0 -51
- package/src/modules/cookie/index.ts +0 -69
- package/src/modules/date/index.ts +0 -196
- package/src/modules/dom/index.ts +0 -78
- package/src/modules/filter/index.ts +0 -43
- package/src/modules/format/index.ts +0 -19
- package/src/modules/match/index.ts +0 -31
- package/src/modules/monitor/index.ts +0 -13
- package/src/modules/monitor/lib/jsError.ts +0 -57
- package/src/modules/monitor/lib/timing.ts +0 -75
- package/src/modules/monitor/lib/xhr.ts +0 -40
- package/src/modules/monitor/utils/onload.ts +0 -8
- package/src/modules/monitor/utils/tracker.ts +0 -47
- package/src/modules/number/index.ts +0 -108
- package/src/modules/sentry/index.ts +0 -82
- package/src/modules/tools/index.ts +0 -427
- package/tsconfig.json +0 -34
package/src/consts/httpCode.js
DELETED
package/src/index.ts
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @Author: wanghui
|
|
3
|
-
* createBy: @2020.05.21
|
|
4
|
-
*/
|
|
5
|
-
'use strict'
|
|
6
|
-
|
|
7
|
-
const modules: any = {
|
|
8
|
-
cookie: require('./modules/cookie'),
|
|
9
|
-
date: require('./modules/date'),
|
|
10
|
-
dom: require('./modules/dom'),
|
|
11
|
-
filter: require('./modules/filter'),
|
|
12
|
-
format: require('./modules/format'),
|
|
13
|
-
match: require('./modules/match'),
|
|
14
|
-
number: require('./modules/number'),
|
|
15
|
-
tools: require('./modules/tools'),
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
class Utils {
|
|
19
|
-
[key: string]: Object
|
|
20
|
-
|
|
21
|
-
constructor() {
|
|
22
|
-
Object.assign(this, modules)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* 挂载各组件
|
|
27
|
-
* 示例:this.$cookie、this.$date、this.$match、this.$number、this.$tools
|
|
28
|
-
* @param {Object} Vue 需要挂载的目标对象
|
|
29
|
-
*/
|
|
30
|
-
install(app: any) {
|
|
31
|
-
Object.keys(modules).forEach((key) => {
|
|
32
|
-
const globalProperties = app.config.globalProperties
|
|
33
|
-
globalProperties['$' + key] = modules[key]
|
|
34
|
-
})
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// loadModules() {
|
|
38
|
-
// const modules = require['context']('./modules/', true, /.js$/)
|
|
39
|
-
// modules.keys().forEach((modulesKey: string) => {
|
|
40
|
-
// const attr: string = modulesKey.replace('./', '').replace('.js', '').replace('/index', '')
|
|
41
|
-
// const haveDefault = ['sentry']
|
|
42
|
-
// if (haveDefault.includes(attr)) {
|
|
43
|
-
// this[attr] = modules(modulesKey).default
|
|
44
|
-
// } else {
|
|
45
|
-
// this[attr] = modules(modulesKey)
|
|
46
|
-
// }
|
|
47
|
-
// })
|
|
48
|
-
// }
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
module.exports = new Utils()
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Cookie
|
|
3
|
-
* @Author: wanghui
|
|
4
|
-
* @createBy: @2021.01.21
|
|
5
|
-
*/
|
|
6
|
-
'use strict'
|
|
7
|
-
interface ICookie {
|
|
8
|
-
name: string,
|
|
9
|
-
value: string,
|
|
10
|
-
exdays: number,
|
|
11
|
-
path?: string,
|
|
12
|
-
domain?: string,
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
class CookieClass {
|
|
16
|
-
/**
|
|
17
|
-
* 获取cookie
|
|
18
|
-
* @param {String} name
|
|
19
|
-
* @return {String}
|
|
20
|
-
*/
|
|
21
|
-
getCookie(name: string) {
|
|
22
|
-
const _name = name + '='
|
|
23
|
-
const ca = document.cookie.split(';')
|
|
24
|
-
for (let i = 0; i < ca.length; i++) {
|
|
25
|
-
let c = ca[i]
|
|
26
|
-
while (c.charAt(0) === ' ') c = c.substring(1)
|
|
27
|
-
if (c.includes(_name)) return c.substring(_name.length, c.length)
|
|
28
|
-
}
|
|
29
|
-
return ''
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* 设置cookie
|
|
34
|
-
* @param {Object} ICookie
|
|
35
|
-
*/
|
|
36
|
-
setCookie({
|
|
37
|
-
name = '',
|
|
38
|
-
value = '',
|
|
39
|
-
exdays = -1,
|
|
40
|
-
path = '/',
|
|
41
|
-
domain = '.jddmoto.com',
|
|
42
|
-
}: ICookie) {
|
|
43
|
-
var d = new Date();
|
|
44
|
-
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000))
|
|
45
|
-
var expires = `expires=${d.toUTCString()}`
|
|
46
|
-
document.cookie = `${name}=${value};${expires};path=${path};domain=${domain};`
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* 清除Cookie
|
|
51
|
-
* @param {String} name
|
|
52
|
-
*/
|
|
53
|
-
clearCookie({
|
|
54
|
-
name = '',
|
|
55
|
-
path = '/',
|
|
56
|
-
domain = '.jddmoto.com',
|
|
57
|
-
}: ICookie) {
|
|
58
|
-
this.setCookie({
|
|
59
|
-
name,
|
|
60
|
-
value: '',
|
|
61
|
-
exdays: -1,
|
|
62
|
-
path,
|
|
63
|
-
domain
|
|
64
|
-
})
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
module.exports = new CookieClass()
|
|
69
|
-
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file date 格式化
|
|
3
|
-
* @Author: wanghui
|
|
4
|
-
* @createBy: @2020.05.21
|
|
5
|
-
*/
|
|
6
|
-
'use strict'
|
|
7
|
-
|
|
8
|
-
import { IObjectKey } from '../../types/index'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* 格式化时间 详情内容里的时间格式
|
|
12
|
-
* @param {Object} data 格式,可参考format 中的o属性
|
|
13
|
-
* @param {String} fmt 想要格式化的格式 'YYYY-MM-DD HH:mm:ss'、'YYYY-MM-DD'、'YYYY年MM月DD日 HH时mm分ss秒'、'YYYY年MM月DD日'
|
|
14
|
-
* @return 返回fmt 格式 时间
|
|
15
|
-
*/
|
|
16
|
-
function replacementDate(data: IObjectKey<any>, fmt: string) {
|
|
17
|
-
for (var k in data) {
|
|
18
|
-
if (new RegExp('(' + k + ')').test(fmt)) {
|
|
19
|
-
fmt = fmt.replace(RegExp.$1,
|
|
20
|
-
(RegExp.$1.length === 1) ? (data[k]) : ((`00${data[k]}`).substr(('' + data[k]).length))
|
|
21
|
-
)
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return fmt
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* 格式化年份
|
|
29
|
-
* @param {String} date Date 格式
|
|
30
|
-
* @param {String} fmt 想要格式化的格式 'YYYY-MM-DD HH:mm:ss'、'YYYY-MM-DD'、'YYYY年MM月DD日 HH时mm分ss秒'、'YYYY年MM月DD日'
|
|
31
|
-
* @return 仅返回年份
|
|
32
|
-
*/
|
|
33
|
-
function replacementYear(date: Date, fmt: string) {
|
|
34
|
-
if (/(Y+)/.test(fmt)) {
|
|
35
|
-
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
|
|
36
|
-
}
|
|
37
|
-
return fmt
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
class DateClass {
|
|
41
|
-
/**
|
|
42
|
-
* 格式化时间
|
|
43
|
-
* @param {String|Number} date 需要格式化的时间 2017-11-11、2017/11/11、linux time
|
|
44
|
-
* @param {String} fmt 想要格式化的格式 'YYYY-MM-DD HH:mm:ss'、'YYYY-MM-DD'、'YYYY年MM月DD日 HH时mm分ss秒'、'YYYY年MM月DD日'
|
|
45
|
-
* date.format(new Date()) // 默认格式 'YYYY-MM-DD HH:mm:ss'
|
|
46
|
-
* date.format(1586840260500) // 默认格式,传参为linux时间
|
|
47
|
-
* date.format(new Date(), 'YYYY:MM:DD') // 自定义格式 'YYYY:MM:DD'
|
|
48
|
-
* @return {String} fmt 'YYYY-MM-DD HH:mm:ss'
|
|
49
|
-
*/
|
|
50
|
-
format(date: string, fmt: string = 'YYYY-MM-DD HH:mm:ss') {
|
|
51
|
-
if (!date) return ''
|
|
52
|
-
let timeData: any = typeof date === 'string' ? new Date(date.replace(/-/g, '/')) : date
|
|
53
|
-
timeData = typeof date === 'number' ? new Date(date) : timeData
|
|
54
|
-
var o: IObjectKey<number> = {
|
|
55
|
-
'M+': timeData.getMonth() + 1,
|
|
56
|
-
'D+': timeData.getDate(),
|
|
57
|
-
'h+': timeData.getHours() % 12 === 0 ? 12 : timeData.getHours() % 12,
|
|
58
|
-
'H+': timeData.getHours(),
|
|
59
|
-
'm+': timeData.getMinutes(),
|
|
60
|
-
's+': timeData.getSeconds(),
|
|
61
|
-
'q+': Math.floor((timeData.getMonth() + 3) / 3),
|
|
62
|
-
'S': timeData.getMilliseconds()
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const week: IObjectKey<string> = {
|
|
66
|
-
'0': '\u65e5',
|
|
67
|
-
'1': '\u4e00',
|
|
68
|
-
'2': '\u4e8c',
|
|
69
|
-
'3': '\u4e09',
|
|
70
|
-
'4': '\u56db',
|
|
71
|
-
'5': '\u4e94',
|
|
72
|
-
'6': '\u516d'
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
fmt = replacementYear(timeData, fmt)
|
|
76
|
-
if (/(E+)/.test(fmt)) {
|
|
77
|
-
fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? '\u661f\u671f' : '\u5468') : '') + week[`${timeData.getDay()} `])
|
|
78
|
-
}
|
|
79
|
-
return replacementDate(o, fmt)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* 天数加减
|
|
84
|
-
* @param {string | Date} date 传入的时间 2020-10-15 or Date
|
|
85
|
-
* @param {String} days 天数
|
|
86
|
-
* addDaysToDate('2020-10-15', 10) // '2020-10-25'
|
|
87
|
-
* addDaysToDate('2020-10-15', -10) // '2020-10-05'
|
|
88
|
-
* @return {String} fmt 'YYYY-MM-DD'
|
|
89
|
-
*/
|
|
90
|
-
addDaysToDate(date: string | Date, days: number) {
|
|
91
|
-
const d = typeof date === 'object' ? date : new Date(date)
|
|
92
|
-
d.setDate(d.getDate() + days)
|
|
93
|
-
return d.toISOString().split('T')[0]
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* 获取倒计时剩余时间
|
|
98
|
-
* @param {Date | Number} endTime 截止时间
|
|
99
|
-
* @param {Date | Number} startTime 开始时间,默认取客户端当前时间
|
|
100
|
-
* date.format(new Date()) // 返回 {dd: '天', hh: '时', mm: '分', ss: '秒'}
|
|
101
|
-
* date.format(1586840260500) // 返回 {dd: '天', hh: '时', mm: '分', ss: '秒'}
|
|
102
|
-
* @return {object | boolean} {dd: '天', hh: '时', mm: '分', ss: '秒'}
|
|
103
|
-
*/
|
|
104
|
-
remainTime(endTime: Date | Number, startTime: Date | Number = new Date()) : object | boolean {
|
|
105
|
-
const ts: number = Number(endTime) - Number(startTime) // 计算剩余的毫秒数
|
|
106
|
-
let dd = Math.floor(ts / 1000 / 60 / 60 / 24) // 计算剩余的天数
|
|
107
|
-
let hh = Math.floor(ts / 1000 / 60 / 60 % 24) // 计算剩余的小时数
|
|
108
|
-
let mm = Math.floor(ts / 1000 / 60 % 60) // 计算剩余的分钟数
|
|
109
|
-
let ss = Math.floor(ts / 1000 % 60) // 计算剩余的秒数
|
|
110
|
-
if (ts <= 0) return false
|
|
111
|
-
return {
|
|
112
|
-
dd: (dd < 10 ? `0${dd}` : dd),
|
|
113
|
-
hh: (hh < 10 ? `0${hh}` : hh),
|
|
114
|
-
mm: (mm < 10 ? `0${mm}` : mm),
|
|
115
|
-
ss: (ss < 10 ? `0${ss}` : ss)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* 格式化现在的已过时间
|
|
121
|
-
* @param {Number} startTime
|
|
122
|
-
* @return {String} *年前 *个月前 *天前 *小时前 *分钟前 刚刚
|
|
123
|
-
*/
|
|
124
|
-
formatPassTime(startTime: any) {
|
|
125
|
-
const currentTime: any = new Date();
|
|
126
|
-
const time: any = currentTime - startTime;
|
|
127
|
-
const year = Math.floor(time / (1000 * 60 * 60 * 24) / 30 / 12);
|
|
128
|
-
if (year) return `${year}年前`;
|
|
129
|
-
const month = Math.floor(time / (1000 * 60 * 60 * 24) / 30);
|
|
130
|
-
if (month) return `${month}个月前`;
|
|
131
|
-
const day = Math.floor(time / (1000 * 60 * 60 * 24));
|
|
132
|
-
if (day) return `${day}天前`;
|
|
133
|
-
const hour = Math.floor(time / (1000 * 60 * 60));
|
|
134
|
-
if (hour) return `${hour}小时前`;
|
|
135
|
-
const min = Math.floor(time / (1000 * 60))
|
|
136
|
-
if (min) return `${min}分钟前`;
|
|
137
|
-
else return '刚刚';
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* 格式化时间 列表里的时间内容格式 待废弃,统一时间格式
|
|
142
|
-
* @param {Number} time 1494141000*1000
|
|
143
|
-
* @return {String} *年*月*日 *月*日 刚刚(1-60秒) 1-60分钟前 1-24小时前 1-3天前
|
|
144
|
-
*/
|
|
145
|
-
formatPassTimeForList(time: string) {
|
|
146
|
-
return DateClass.prototype.formatPassTimeForDetail(time, 'YYYY年MM月DD日', true)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* 格式化时间 详情内容里的时间格式
|
|
151
|
-
* @param {Number} time 1494141000*1000
|
|
152
|
-
* @param {String} fmt 想要格式化的格式
|
|
153
|
-
* @param {Boolean} noYear 是否显示年
|
|
154
|
-
* @return {String} *年*月*日 *月*日 刚刚(1-60秒) 1-60分钟前 1-24小时前 1-3天前
|
|
155
|
-
*/
|
|
156
|
-
formatPassTimeForDetail(time: string, fmt: string = 'YYYY-MM-DD', noYear: Boolean) {
|
|
157
|
-
const date = (typeof time === 'number') ? new Date(time) : new Date((time || '').replace(/-/g, '/'));
|
|
158
|
-
const diff = (((new Date()).getTime() - date.getTime()) / 1000);
|
|
159
|
-
const dayDiff = Math.floor(diff / 86400);
|
|
160
|
-
const isValidDate = Object.prototype.toString.call(date) === '[object Date]' && !isNaN(date.getTime());
|
|
161
|
-
|
|
162
|
-
if (!isValidDate) return '';
|
|
163
|
-
|
|
164
|
-
const formatDate = function () {
|
|
165
|
-
const today = new Date(date);
|
|
166
|
-
var o: IObjectKey<string | number> = {
|
|
167
|
-
'Y+': today.getFullYear(),
|
|
168
|
-
'M+': ('0' + (today.getMonth() + 1)).slice(-2),
|
|
169
|
-
'D+': ('0' + today.getDate()).slice(-2)
|
|
170
|
-
};
|
|
171
|
-
fmt = replacementYear(date, fmt)
|
|
172
|
-
const year = today.getFullYear();
|
|
173
|
-
|
|
174
|
-
if (!(new Date().getFullYear() > year) && noYear) {
|
|
175
|
-
const backData = replacementDate(o, fmt);
|
|
176
|
-
return backData.split('年')[1];
|
|
177
|
-
}
|
|
178
|
-
return replacementDate(o, fmt);
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
if (dayDiff === -1) {
|
|
182
|
-
return '刚刚';
|
|
183
|
-
} else if (isNaN(dayDiff) || dayDiff < 0 || dayDiff >= 15) {
|
|
184
|
-
return formatDate();
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
return (dayDiff === 0 && (
|
|
188
|
-
(diff < 60 && '刚刚') ||
|
|
189
|
-
(diff < 120 && '1分钟前') ||
|
|
190
|
-
(diff < 3600 && Math.floor(diff / 60) + '分钟前') ||
|
|
191
|
-
(diff < 7200 && '1小时前') ||
|
|
192
|
-
(diff < 86400 && Math.floor(diff / 3600) + '小时前'))) || (dayDiff < 16 && dayDiff + '天前');
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
module.exports = new DateClass()
|
package/src/modules/dom/index.ts
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Cookie
|
|
3
|
-
* @Author: wanghui
|
|
4
|
-
* @createBy: @2021.08.17
|
|
5
|
-
*/
|
|
6
|
-
'use strict'
|
|
7
|
-
|
|
8
|
-
import { IObjectKey } from '../../types/index'
|
|
9
|
-
|
|
10
|
-
interface IDom {
|
|
11
|
-
name: string,
|
|
12
|
-
innerHTML?: string,
|
|
13
|
-
style?: IObjectKey<string>,
|
|
14
|
-
parent?: string,
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
class DomClass {
|
|
18
|
-
/**
|
|
19
|
-
* 创建一个子元素并添加至父节点
|
|
20
|
-
* @param {Object} { name = 'div', innerHTML = '', style = {}, parent, }
|
|
21
|
-
* @return {String}
|
|
22
|
-
*/
|
|
23
|
-
createElement({
|
|
24
|
-
name = 'div',
|
|
25
|
-
innerHTML = '',
|
|
26
|
-
style = {},
|
|
27
|
-
parent,
|
|
28
|
-
}: IDom) {
|
|
29
|
-
if (!(window && window.document)) {
|
|
30
|
-
return new Error('仅支持浏览器')
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const element: any = document.createElement(name)
|
|
34
|
-
|
|
35
|
-
element.innerHTML = innerHTML
|
|
36
|
-
Object.keys(style).map((_: string) => element.style[_] = style[_])
|
|
37
|
-
if (parent) {
|
|
38
|
-
const body = document.querySelector(parent)
|
|
39
|
-
body && body.append(element)
|
|
40
|
-
}
|
|
41
|
-
return element
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* 获取文本中的url并用a标签包裹
|
|
46
|
-
* @param {Object} ICookie
|
|
47
|
-
*/
|
|
48
|
-
wrapperA(text: string) {
|
|
49
|
-
if (!(window && window.document)) {
|
|
50
|
-
return new Error('仅支持浏览器')
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return text.replace(/((https|http|ftp|file):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|])/g, '<a href="$1">$1</a>')
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* 对象转化为formdata
|
|
58
|
-
* getFormData({a: 1, b: 2})
|
|
59
|
-
* @param {Object} object
|
|
60
|
-
*/
|
|
61
|
-
getFormData(object: IObjectKey<any>) {
|
|
62
|
-
const formData = new FormData()
|
|
63
|
-
Object.keys(object).forEach(key => {
|
|
64
|
-
const value = object[key]
|
|
65
|
-
if (Array.isArray(value)) {
|
|
66
|
-
value.forEach((subValue, i) =>
|
|
67
|
-
formData.append(key + `[${i}]`, subValue)
|
|
68
|
-
)
|
|
69
|
-
} else {
|
|
70
|
-
formData.append(key, object[key])
|
|
71
|
-
}
|
|
72
|
-
})
|
|
73
|
-
return formData
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
module.exports = new DomClass()
|
|
78
|
-
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file 过滤器
|
|
3
|
-
* @Author: wanghui
|
|
4
|
-
* @createBy: @2020.05.28
|
|
5
|
-
*/
|
|
6
|
-
'use strict'
|
|
7
|
-
|
|
8
|
-
const dateClass = require('../date')
|
|
9
|
-
const numberClass = require('../number')
|
|
10
|
-
const toolsClass = require('../tools')
|
|
11
|
-
|
|
12
|
-
class FilterClass {
|
|
13
|
-
/**
|
|
14
|
-
* 格式化时间,示例:1586840260500 | format('YYYY-MM-DD HH:mm:ss')
|
|
15
|
-
* @param {String|Number} date
|
|
16
|
-
* @param {String} fmt 'YYYY-MM-DD HH:mm:ss'
|
|
17
|
-
* @return {String} 'YYYY-MM-DD HH:mm:ss'
|
|
18
|
-
*/
|
|
19
|
-
format(date: string | number, fmt: string = 'YYYY-MM-DD HH:mm:ss') {
|
|
20
|
-
return dateClass.format(date, fmt)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* 格式化金额,示例:123456 | formatMoney
|
|
25
|
-
* @param {Number} num
|
|
26
|
-
* @return {String} 123,456
|
|
27
|
-
*/
|
|
28
|
-
formatMoney(money: number | string): string {
|
|
29
|
-
return numberClass.formatMoney(money)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* 截取数组或字符串,示例:'1234' | slice(3)
|
|
34
|
-
* @param {Array|String} target 数组或字符串
|
|
35
|
-
* @param {Number} length 截取长度,从0开始
|
|
36
|
-
* @return {any}
|
|
37
|
-
*/
|
|
38
|
-
slice(target: Array<any> | string = '', length: number = 0) {
|
|
39
|
-
return toolsClass.slice(target, length)
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
module.exports = new FilterClass()
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
interface Obj {
|
|
2
|
-
[prop: string]: any
|
|
3
|
-
}
|
|
4
|
-
class Format {
|
|
5
|
-
/**
|
|
6
|
-
* @desc 对于对象非数字与布尔值的value,当其为falsy时,转换成separator
|
|
7
|
-
* @param {object} obj 传入的对象
|
|
8
|
-
* @param {string} separator 替换后的值
|
|
9
|
-
* transformObjectNullVal({ a: null, b: 0}, '23') // {a: "23", b: 0}
|
|
10
|
-
* @return {object}
|
|
11
|
-
*/
|
|
12
|
-
transformObjectNullVal<T extends Obj>(obj: T, separator: string = '-'): T {
|
|
13
|
-
return Object.keys(obj).reduce((cur, key) => {
|
|
14
|
-
(cur as Obj)[key] = obj[key] || ((obj[key] === 0 || obj[key] === false) ? obj[key] : separator)
|
|
15
|
-
return cur
|
|
16
|
-
}, {} as { [key in keyof T]: T[key] })
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
module.exports = new Format()
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @file: tools 常用的工具函数
|
|
4
|
-
* @Author: wanghui
|
|
5
|
-
*/
|
|
6
|
-
'use strict'
|
|
7
|
-
import { IObjectKey } from '../../types/index'
|
|
8
|
-
|
|
9
|
-
class MatchClass {
|
|
10
|
-
/**
|
|
11
|
-
* 根据类型返回正则
|
|
12
|
-
* @param {String} str 检测的内容
|
|
13
|
-
* @param {String} type 检测类型
|
|
14
|
-
* checkType('10.120.33.11', 'ip') // true
|
|
15
|
-
* @return {Boolean} true or false
|
|
16
|
-
*/
|
|
17
|
-
checkType(str: string, type: string): boolean {
|
|
18
|
-
const regexp: IObjectKey<boolean> = {
|
|
19
|
-
'ip': /((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}/.test(str),
|
|
20
|
-
'port': /^(\d|[1-5]\d{4}|6[1-4]\d{3}|65[1-4]\d{2}|655[1-2]\d|6553[1-5])$/.test(str),
|
|
21
|
-
'phone': /^1[3|4|5|6|7|8][0-9]{9}$/.test(str), // 手机号
|
|
22
|
-
'number': /^[0-9]+$/.test(str), // 是否全数字
|
|
23
|
-
'email': /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/.test(str),
|
|
24
|
-
'IDCard': /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/.test(str),
|
|
25
|
-
'url': /[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/i.test(str)
|
|
26
|
-
};
|
|
27
|
-
return regexp[type];
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
module.exports = new MatchClass()
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { injectJsError } from './lib/jsError'
|
|
2
|
-
import injectXhrError from './lib/xhr'
|
|
3
|
-
import Tracker from './utils/tracker'
|
|
4
|
-
|
|
5
|
-
// import timing from './lib/timing'
|
|
6
|
-
export default function setup(data:any) {
|
|
7
|
-
injectJsError(data)
|
|
8
|
-
injectXhrError(data)
|
|
9
|
-
}
|
|
10
|
-
export {
|
|
11
|
-
Tracker
|
|
12
|
-
}
|
|
13
|
-
// timing()
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import track from '../utils/tracker'
|
|
2
|
-
export function injectJsError (data:any={}) {
|
|
3
|
-
window.addEventListener('error', (e: any) => {
|
|
4
|
-
if (e.target && (e.target.src || e.target.href)) {
|
|
5
|
-
track.send({
|
|
6
|
-
kind: 'stability',
|
|
7
|
-
type: 'error',
|
|
8
|
-
title: 'resourceError',
|
|
9
|
-
filename: e.target.src || e.target.href,
|
|
10
|
-
tagName: e.target.tagName,
|
|
11
|
-
reason: e.target.src || e.target.href,
|
|
12
|
-
...data
|
|
13
|
-
// selector: lastEvent ? get
|
|
14
|
-
})
|
|
15
|
-
return
|
|
16
|
-
}
|
|
17
|
-
track.send({
|
|
18
|
-
kind: 'stability',
|
|
19
|
-
type: 'error',
|
|
20
|
-
title: 'jsError',
|
|
21
|
-
message: e.message,
|
|
22
|
-
filename: e.filename,
|
|
23
|
-
position: `${e.lineno}:${e.colno}`,
|
|
24
|
-
reason: e.error.stack,
|
|
25
|
-
...data
|
|
26
|
-
// selector: lastEvent ? get
|
|
27
|
-
})
|
|
28
|
-
}, true)
|
|
29
|
-
|
|
30
|
-
window.addEventListener('unhandledrejection', (e) => {
|
|
31
|
-
let message, filename, line, column, stack
|
|
32
|
-
const reason = e.reason
|
|
33
|
-
if (typeof reason === 'string') {
|
|
34
|
-
message = reason
|
|
35
|
-
} else if (typeof reason === 'object') {
|
|
36
|
-
if (reason.stack) {
|
|
37
|
-
const matchResult = reason.stack.match(/at\s+(.+):(\d+):(\d+)/)
|
|
38
|
-
filename = matchResult[1]
|
|
39
|
-
line = matchResult[2]
|
|
40
|
-
column = matchResult[3]
|
|
41
|
-
}
|
|
42
|
-
message = reason.message
|
|
43
|
-
stack = reason.stack
|
|
44
|
-
}
|
|
45
|
-
track.send({
|
|
46
|
-
kind: 'stability',
|
|
47
|
-
type: 'error',
|
|
48
|
-
title: 'promiseError',
|
|
49
|
-
message,
|
|
50
|
-
filename,
|
|
51
|
-
position: `${line}:${column}`,
|
|
52
|
-
reason: stack,
|
|
53
|
-
...data
|
|
54
|
-
// selector: lastEvent ? get
|
|
55
|
-
})
|
|
56
|
-
})
|
|
57
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import onload from '../utils/onload'
|
|
2
|
-
import tracker from '../utils/tracker';
|
|
3
|
-
export default function timing() {
|
|
4
|
-
let FMP:any, LCP:any
|
|
5
|
-
new PerformanceObserver((entryList, observer) => {
|
|
6
|
-
const perfEntries = entryList.getEntries()
|
|
7
|
-
FMP = perfEntries[0]
|
|
8
|
-
observer.disconnect() // 不再观察
|
|
9
|
-
}).observe({ entryTypes: ['element'] }) // 观察页面中有意义的元素
|
|
10
|
-
new PerformanceObserver((entryList, observer) => {
|
|
11
|
-
const perfEntries = entryList.getEntries()
|
|
12
|
-
LCP = perfEntries[0]
|
|
13
|
-
observer.disconnect() // 不再观察
|
|
14
|
-
}).observe({ entryTypes: ['largest-contentful-paint'] }) // 观察页面中最大的元素
|
|
15
|
-
new PerformanceObserver((entryList, observer) => {
|
|
16
|
-
const firstInput:any = entryList.getEntries()
|
|
17
|
-
console.log('FID', firstInput);
|
|
18
|
-
if(firstInput) {
|
|
19
|
-
let inputDelay = firstInput.processingStart - firstInput.startTime
|
|
20
|
-
const duration = firstInput.duration
|
|
21
|
-
if(inputDelay > 0 || duration >0) {
|
|
22
|
-
tracker.send({
|
|
23
|
-
kind: 'experience',
|
|
24
|
-
type: 'firstInputDelay',
|
|
25
|
-
inputDelay, // 延迟时间
|
|
26
|
-
duration, // 处理时间
|
|
27
|
-
startTime: firstInput.startTime
|
|
28
|
-
})
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
observer.disconnect() // 不再观察
|
|
32
|
-
}).observe({ type: 'first-input', buffered: true }) // 观察页面中最大的元素
|
|
33
|
-
onload(function() {
|
|
34
|
-
setTimeout(() => {
|
|
35
|
-
console.dir(window.performance);
|
|
36
|
-
const {
|
|
37
|
-
fetchStart,
|
|
38
|
-
connectStart,
|
|
39
|
-
connectEnd,
|
|
40
|
-
requestStart,
|
|
41
|
-
responseStart,
|
|
42
|
-
responseEnd,
|
|
43
|
-
domInteractive,
|
|
44
|
-
domContentLoadedEventStart,
|
|
45
|
-
domContentLoadedEventEnd,
|
|
46
|
-
loadEventStart,
|
|
47
|
-
// loadEventEnd
|
|
48
|
-
} = performance.getEntriesByType('navigation')[0] as any
|
|
49
|
-
tracker.send({
|
|
50
|
-
kind: 'experience',
|
|
51
|
-
type: 'timing',
|
|
52
|
-
connectTime: connectEnd - connectStart, // 连接时间
|
|
53
|
-
ttfbTime: responseStart - requestStart, // 首字节到达时间
|
|
54
|
-
responseTime: responseEnd - responseStart, // 响应的读取时间
|
|
55
|
-
domContentLoadedTime: domContentLoadedEventEnd - domContentLoadedEventStart,
|
|
56
|
-
timeToInteractive: domInteractive - fetchStart,// 首次可交互时间
|
|
57
|
-
loadTime: loadEventStart - fetchStart // 完整的页面加载时间
|
|
58
|
-
})
|
|
59
|
-
let FP = performance.getEntriesByName('first-paint')[0]
|
|
60
|
-
let FCP = performance.getEntriesByName('first-contentful-paint')[0]
|
|
61
|
-
console.log('FP', FP);
|
|
62
|
-
console.log('FCP', FCP);
|
|
63
|
-
console.log('FMP', FMP);
|
|
64
|
-
console.log('LCP', LCP);
|
|
65
|
-
tracker.send({
|
|
66
|
-
kind: 'experience',
|
|
67
|
-
type: 'paint',
|
|
68
|
-
FP: FP.startTime,
|
|
69
|
-
FCP: FCP.startTime,
|
|
70
|
-
FMP: FMP.startTime,
|
|
71
|
-
LCP: LCP.startTime,
|
|
72
|
-
})
|
|
73
|
-
}, 3000);
|
|
74
|
-
})
|
|
75
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import tracker from "../utils/tracker"
|
|
2
|
-
|
|
3
|
-
export default function injectXHR(data:any={}){
|
|
4
|
-
let XMLHttpRequest:any = window.XMLHttpRequest
|
|
5
|
-
let oldOpen = XMLHttpRequest.prototype.open as any
|
|
6
|
-
XMLHttpRequest.prototype.open = function(method: string, url:string, async:boolean) {
|
|
7
|
-
this.logData = { method, url, async }
|
|
8
|
-
return oldOpen.apply(this, arguments)
|
|
9
|
-
}
|
|
10
|
-
let oldSend = XMLHttpRequest.prototype.send
|
|
11
|
-
XMLHttpRequest.prototype.send = function(body:any) {
|
|
12
|
-
if(this.logData) {
|
|
13
|
-
const startTime = Date.now()
|
|
14
|
-
const handler = (type:string) => (event:any) => {
|
|
15
|
-
if(this.logData.url.indexOf('app/collect/original/info/report/v2') > -1 ) return
|
|
16
|
-
if(type !== 'error') return
|
|
17
|
-
let duration = Date.now() - startTime
|
|
18
|
-
let status = this.status
|
|
19
|
-
let statusText = this.statusText
|
|
20
|
-
tracker.send({
|
|
21
|
-
kind: 'stability',
|
|
22
|
-
type: 'xhr',
|
|
23
|
-
eventType: event.type,
|
|
24
|
-
pathname: this.logData.url,
|
|
25
|
-
status: status + '-'+statusText,
|
|
26
|
-
duration,
|
|
27
|
-
response: this.response ? JSON.stringify(this.response) : '',
|
|
28
|
-
params: body || '',
|
|
29
|
-
title: 'xhr',
|
|
30
|
-
reason: status + '-'+statusText+` ${this.logData.url} ${this.response ? JSON.stringify(this.response) : ''}`,
|
|
31
|
-
...data
|
|
32
|
-
})
|
|
33
|
-
}
|
|
34
|
-
this.addEventListener('load', handler('load'), false)
|
|
35
|
-
this.addEventListener('error', handler('error'), false)
|
|
36
|
-
this.addEventListener('abort', handler('abort'), false)
|
|
37
|
-
}
|
|
38
|
-
return oldSend.apply(this, arguments)
|
|
39
|
-
}
|
|
40
|
-
}
|