sh-tools 2.1.4 → 2.1.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sh-tools",
3
- "version": "2.1.4",
3
+ "version": "2.1.6",
4
4
  "description": "基于xe-ajax和xe-utils二次封装",
5
5
  "main": "packages/index.js",
6
6
  "scripts": {
@@ -170,6 +170,8 @@ export default {
170
170
  }
171
171
  // 对于多选获取数组类型值进行解析 赋值
172
172
  let oriArray = []
173
+ // 是否需要对原值进行重写 默认为false
174
+ let resetValue = false
173
175
  // 进行默认赋值 若没有任何解析原数返回
174
176
  rvalue = value
175
177
  // 首先提取公式进行公式计算
@@ -178,7 +180,7 @@ export default {
178
180
  switch (rname) {
179
181
  case '$vInput':
180
182
  case '$vMoney':
181
- if (editable && (type === '$vMoney' || ['integer', 'number', 'float'].includes(type)) && !$vUtils.isNone(value)) {
183
+ if (editable && (rname === '$vMoney' || ['integer', 'number', 'float'].includes(type)) && !$vUtils.isNone(value)) {
182
184
  if ($vUtils.isNumber(+max) && +value > +max) {
183
185
  value = +max
184
186
  } else if ($vUtils.isNumber(+min) && +value < +min) {
@@ -191,14 +193,18 @@ export default {
191
193
  rvalue = $vUtils.truncate(value, digits)
192
194
  }
193
195
  if ($vUtils.isString(rvalue)) rvalue = $vUtils.replaceNutrim(rvalue)
194
- if (type === '$vMoney' && !$vUtils.isNone(rvalue)) {
196
+ if (rname === '$vMoney' && !$vUtils.isNone(rvalue)) {
195
197
  rtext = $vUtils.truncate($vUtils.divide(rvalue, moneyUnit), digits)
196
198
  }
197
199
  if (commafy && !bill && bill !== '0') rtext = $vUtils.commafy(rtext, { digits })
198
200
  break
199
201
  case '$vTime':
200
202
  format = format ? format.replace('YYYY', 'yyyy').replace('DD', 'dd').replace('hh', 'HH') : defaultDateFormat[type]
201
- if (!$vUtils.isNone(value) && format) rvalue = $vUtils.toDateString(value, format)
203
+ if ($vUtils.isNumber(value)) value = String(value)
204
+ if (!$vUtils.isNone(value) && format) {
205
+ rvalue = $vUtils.toDateString(value, format)
206
+ resetValue = true
207
+ }
202
208
  break
203
209
  case '$vSelect':
204
210
  case '$vCheckgroup':
@@ -230,8 +236,10 @@ export default {
230
236
  }
231
237
  rvalue = oriArray
232
238
  } else {
233
- let valueOption = options.find(option => $vUtils.isEqual(option[optionValue], value))
234
- rtext = valueOption ? valueOption[optionLabel] : ''
239
+ if (options && options.length) {
240
+ let valueOption = options.find(option => $vUtils.isEqual(option[optionValue], value))
241
+ rtext = valueOption ? valueOption[optionLabel] : ''
242
+ }
235
243
  rvalue = rname === '$vTree' ? (value ? [value] : []) : value
236
244
  }
237
245
  if (format) {
@@ -251,7 +259,7 @@ export default {
251
259
  break
252
260
  }
253
261
  if ($vUtils.isString(rvalue)) rvalue = $vUtils.replaceNutrim(rvalue)
254
- if (formula) {
262
+ if (formula || resetValue) {
255
263
  $vUtils.set(rowData, key, rvalue)
256
264
  }
257
265
  rtext = rtext || rvalue
@@ -1,227 +1,54 @@
1
- import XEUtils from 'xe-utils'
2
-
3
- // 数据格式化获取keys
4
- function getFormatKeys(format) {
5
- let regR = new RegExp('({[a-zA-Z0-9_.]*})', 'ig')
6
- let formatStr = String(format)
7
- return (formatStr.match(regR) || []).map((key, keyIndex) => {
8
- return key.replace(/{|}/gi, '')
9
- })
10
- }
11
-
12
- // 格式化数据结构
13
- function format(format, data) {
14
- let keys = getFormatKeys(format)
15
- let formatStr = String(format)
16
- keys.map((key, indexkey) => {
17
- let value = XEUtils.get(data, key) || ''
18
- formatStr = formatStr.replace(new RegExp('{' + key + '}', 'ig'), value)
19
- })
20
- return formatStr
21
- }
22
-
23
- // 生成随机字符串
24
- function randomStr(len = 32) {
25
- const $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
26
- const maxPos = $chars.length
27
- let str = ''
28
- for (let i = 0; i < len; i++) {
29
- str += $chars.charAt(Math.floor(Math.random() * maxPos))
30
- }
31
- return str
32
- }
33
-
34
- export default {
35
- randomStr,
36
- getFormatKeys,
37
- format,
38
- replaceNutrim(str) {
39
- return String(str).replace(/null|undefined|(^\s*)|(\s*$)/gi, '')
40
- },
41
- replaceAll(str, from, to) {
42
- // 替换全部 将str中的所有from替换为to
43
- return str.replace(new RegExp(from, 'gm'), to)
44
- },
45
- filterTag(str) {
46
- /* 过滤html代码(把<>转换字符串) */
47
- let me = this
48
- str = me.replaceAll(str, /&/gi, '&amp;')
49
- str = me.replaceAll(str, /</gi, '&lt;')
50
- str = me.replaceAll(str, />/gi, '&gt;')
51
- str = me.replaceAll(str, ' ', '&nbsp;')
52
- return str
53
- },
54
- setWaterMark(text, settings) {
55
- // 生成水印 推荐 canvas
56
- class WaterMark {
57
- constructor(text, settings) {
58
- this.settings = Object.assign(
59
- {
60
- container: document.body,
61
- id: 'waterMark',
62
- showType: 'canvas', // div 还是 canvas
63
- x: 0, // 水印起始位置x轴坐标
64
- y: 100, // 水印起始位置Y轴坐标
65
- xSpace: 150, // 水印x轴间隔
66
- ySpace: 100, // 水印y轴间隔
67
- color: '#cfcccc', // 水印字体颜色
68
- alpha: 0.5, // 水印透明度
69
- fontsize: '15px', // 水印字体大小
70
- angle: 20, // 水印倾斜度数
71
- curTime: false // 是否自动拼接当前时间
72
- },
73
- settings || {}
74
- )
75
- this.globalWidth = this.settings.container.clientWidth
76
- this.globalHeight = this.settings.container.clientHeight
77
- this.initCanvas()
78
- this.draw(text)
79
- this.insertWaterMark()
80
- }
81
- initCanvas() {
82
- this.renderCanvas = document.createElement('canvas')
83
- this.renderContext = this.renderCanvas.getContext('2d')
84
- this.renderCanvas.width = this.globalWidth
85
- this.renderCanvas.height = this.globalHeight
86
- this.div = document.createElement('div')
87
- this.oldData = this.renderContext.getImageData(0, 0, this.globalWidth, this.globalHeight)
88
- }
89
- insertWaterMark() {
90
- const { type, id, alpha, container } = this.settings
91
- this.WaterMarkEl = this.renderCanvas
92
- if (type === 'div') {
93
- this.WaterMarkEl = this.div
94
- this.WaterMarkEl.style.backgroundImage = 'url(' + this.renderCanvas.toDataURL('image/png') + ')'
95
- }
96
- const style = this.WaterMarkEl.style
97
- style.position = 'absolute'
98
- style.opacity = alpha
99
- style.top = style.left = 0
100
- style.zIndex = '9999'
101
- style.width = this.globalWidth + 'px'
102
- style.height = this.globalHeight + 'px'
103
- style.pointerEvents = 'none'
104
- this.WaterMarkEl.id = id
105
- container.append(this.WaterMarkEl)
106
- }
107
- draw(waterMarkText, settings) {
108
- this.settings = Object.assign(this.settings, settings || {})
109
- let { x, y, xSpace, ySpace, color, fontsize, angle, curTime } = this.settings
110
- let { globalWidth, globalHeight, renderContext } = this
111
- let timeStr = ''
112
- if (curTime) {
113
- let today = new Date()
114
- timeStr =
115
- today.getFullYear() +
116
- '-' +
117
- String(today.getMonth() + 1).padStart(2, 0) +
118
- '-' +
119
- String(today.getDate()).padStart(2, 0) +
120
- ' ' +
121
- String(today.getHours()).padStart(2, 0) +
122
- ':' +
123
- String(today.getMinutes()).padStart(2, 0) +
124
- ':' +
125
- String(today.getSeconds()).padStart(2, 0)
126
- }
127
- waterMarkText = waterMarkText ? waterMarkText + ' ' + timeStr : timeStr
128
- renderContext.clearRect(0, 0, globalWidth, globalHeight)
129
- renderContext.font = fontsize + ' microsoft yahei'
130
- renderContext.fillStyle = color
131
- renderContext.textAlign = 'left'
132
- renderContext.textBaseline = 'Middle'
133
- let measureText = renderContext.measureText(waterMarkText)
134
- let width = measureText.width
135
- let height = Math.ceil(width / Math.tan(angle) + 50)
136
- for (let xx = x; xx < globalWidth; xx += xSpace + width) {
137
- for (let yy = y; yy < globalHeight; yy += ySpace + height) {
138
- // 填充文字,x 间距, y 间距
139
- renderContext.save()
140
- renderContext.translate(xx, yy)
141
- renderContext.rotate(0 - (angle * Math.PI) / 180)
142
- renderContext.fillText(waterMarkText, 0, 0)
143
- renderContext.restore()
144
- }
145
- }
146
- }
147
- // 图片的像素信息里存储着 RGB 的色值,R、G、B 分别为该像素的红、绿、蓝通道,每个通道的分量值范围在 0~255,16 进制则是 00~FF。在 CSS 中经常使用其 16 进制形式,比如指定博客头部背景色为 #A9D5F4。其中 R(红色)的 16 进制值为 A9,换算成十进制为 169。这时候,对 R 分量的值 + 1,即为 170,整个像素 RGB 值为 #AAD5F4,别说你看不出差别,就连火眼金金的“ 像素眼” 设计师都察觉不出来呢。于此同时,修改 G、B 的分量值,也是我们无法察觉的。因此可以得出重要结论:RGB 分量值的小量变动,是肉眼无法分辨的,不影响对图片的识别。
148
- // 有了这个结论,那就给我们了利用空间,常用手段的就是对二进制最低位进行操作,下面就用 canvas 来演示一下。
149
- inVisible(ctx, newData, originalData, color = 'R') {
150
- var oData = originalData.data
151
- var bit, offset // offset的作用是找到alpha通道值,这里需要大家自己动动脑筋
152
- switch (color) {
153
- case 'R':
154
- bit = 0
155
- offset = 3
156
- break
157
- case 'G':
158
- bit = 1
159
- offset = 2
160
- break
161
- case 'B':
162
- bit = 2
163
- offset = 1
164
- break
165
- }
166
- for (var i = 0; i < oData.length; i++) {
167
- if (i % 4 === bit) {
168
- // 只处理目标通道
169
- if (newData[i + offset] === 0 && oData[i] % 2 === 1) {
170
- // 没有信息的像素,该通道最低位置0,但不要越界
171
- if (oData[i] === 255) {
172
- oData[i]--
173
- } else {
174
- oData[i]++
175
- }
176
- } else if (newData[i + offset] !== 0 && oData[i] % 2 === 0) {
177
- // // 有信息的像素,该通道最低位置1,可以想想上面的斑点效果是怎么实现的
178
- oData[i]++
179
- }
180
- }
181
- }
182
- ctx.putImageData(originalData, 0, 0)
183
- }
184
- visible(ctx, originalData, color = 'R') {
185
- var bit, offset // offset的作用是找到alpha通道值,这里需要大家自己动动脑筋
186
- switch (color) {
187
- case 'R':
188
- bit = 0
189
- offset = 3
190
- break
191
- case 'G':
192
- bit = 1
193
- offset = 2
194
- break
195
- case 'B':
196
- bit = 2
197
- offset = 1
198
- break
199
- }
200
- var data = originalData.data
201
- for (var i = 0; i < data.length; i++) {
202
- if (i % 4 === bit) {
203
- // 只处理目标通道
204
- if (data[i] % 2 === 0) {
205
- // 没有信息的像素,该通道最低位置0,但不要越界
206
- if (data[i] % 2 === 0) {
207
- data[i] = 0
208
- } else if (i % 4 === 3) {
209
- // alpha通道不做处理
210
- continue
211
- } else {
212
- // 关闭其他分量,不关闭也不影响答案
213
- data[i] = 0
214
- }
215
- }
216
- }
217
- ctx.putImageData(originalData, 0, 0)
218
- }
219
- }
220
- }
221
- return new WaterMark(text, settings)
222
- },
223
- removeWaterMark(container, id) {
224
- const body = container || document.body
225
- body.removeChild(document.getElementById(id || 'waterMark'))
226
- }
227
- }
1
+ import XEUtils from 'xe-utils'
2
+
3
+ // 数据格式化获取keys
4
+ function getFormatKeys(format) {
5
+ let regR = new RegExp('({[a-zA-Z0-9_.]*})', 'ig')
6
+ let formatStr = String(format)
7
+ return (formatStr.match(regR) || []).map((key, keyIndex) => {
8
+ return key.replace(/{|}/gi, '')
9
+ })
10
+ }
11
+
12
+ // 格式化数据结构
13
+ function format(format, data) {
14
+ let keys = getFormatKeys(format)
15
+ let formatStr = String(format)
16
+ keys.map((key, indexkey) => {
17
+ let value = XEUtils.get(data, key) || ''
18
+ formatStr = formatStr.replace(new RegExp('{' + key + '}', 'ig'), value)
19
+ })
20
+ return formatStr
21
+ }
22
+
23
+ // 生成随机字符串
24
+ function randomStr(len = 32) {
25
+ const $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
26
+ const maxPos = $chars.length
27
+ let str = ''
28
+ for (let i = 0; i < len; i++) {
29
+ str += $chars.charAt(Math.floor(Math.random() * maxPos))
30
+ }
31
+ return str
32
+ }
33
+
34
+ export default {
35
+ randomStr,
36
+ getFormatKeys,
37
+ format,
38
+ replaceNutrim(str) {
39
+ return String(str).replace(/null|undefined|(^\s*)|(\s*$)/gi, '')
40
+ },
41
+ replaceAll(str, from, to) {
42
+ // 替换全部 将str中的所有from替换为to
43
+ return str.replace(new RegExp(from, 'gm'), to)
44
+ },
45
+ filterTag(str) {
46
+ /* 过滤html代码(把<>转换字符串) */
47
+ let me = this
48
+ str = me.replaceAll(str, /&/gi, '&amp;')
49
+ str = me.replaceAll(str, /</gi, '&lt;')
50
+ str = me.replaceAll(str, />/gi, '&gt;')
51
+ str = me.replaceAll(str, ' ', '&nbsp;')
52
+ return str
53
+ }
54
+ }