vue-super-crud 1.7.2 → 1.7.4
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 +1 -1
- package/src/config/common.js +2 -1
- package/src/config/crud.js +3 -3
- package/src/index.js +4 -0
- package/src/template/formatData.js +75 -87
package/package.json
CHANGED
package/src/config/common.js
CHANGED
@@ -9,7 +9,7 @@ export const renderItem = {
|
|
9
9
|
},
|
10
10
|
dict: {
|
11
11
|
strict: true,
|
12
|
-
type: [String, Object],
|
12
|
+
type: [String, Object, Function],
|
13
13
|
properties: {
|
14
14
|
request: Function,
|
15
15
|
label: String, // 数据字典中label字段的属性名
|
@@ -54,6 +54,7 @@ export const renderItem = {
|
|
54
54
|
},
|
55
55
|
}, // 验证规则
|
56
56
|
position: Boolean, // 是否开启位置渲染
|
57
|
+
formatData: [Object, String], // 响应式数据格式化
|
57
58
|
};
|
58
59
|
|
59
60
|
export const buttonItem = {
|
package/src/config/crud.js
CHANGED
@@ -140,6 +140,7 @@ export default {
|
|
140
140
|
},
|
141
141
|
},
|
142
142
|
}),
|
143
|
+
addChild: buttonItem, // 子级新增按钮配置
|
143
144
|
batchDelete: buttonItem, // 批量删除按钮配置
|
144
145
|
delete: buttonItem, // 删除按钮配置
|
145
146
|
view: buttonItem, // 查看按钮配置,仅限`dialog`模式
|
@@ -250,9 +251,6 @@ export default {
|
|
250
251
|
default: () => ({
|
251
252
|
pageNum: "pageNum",
|
252
253
|
pageSize: "pageSize",
|
253
|
-
detailResult: "data",
|
254
|
-
listResult: "data",
|
255
|
-
total: "total",
|
256
254
|
}),
|
257
255
|
},
|
258
256
|
// 是否本地生成唯一标识
|
@@ -405,6 +403,7 @@ export default {
|
|
405
403
|
calcWidth: Number,
|
406
404
|
defaultWidth: Number,
|
407
405
|
sameRowSpan: [String, Boolean],
|
406
|
+
spanProp: [String, Boolean],
|
408
407
|
fixed: [String, Boolean],
|
409
408
|
handles: {
|
410
409
|
type: Array,
|
@@ -465,6 +464,7 @@ export default {
|
|
465
464
|
hiddenList: Boolean, // 是否只隐藏列表
|
466
465
|
children: Array, // 嵌套列子列
|
467
466
|
sameRowSpan: [String, Boolean], // 是否合并单元格
|
467
|
+
spanProp: [String, Boolean], // 是否合并单元格
|
468
468
|
spanMethod: Function, // 合并单元格方法
|
469
469
|
isEdit: [Boolean, Function], // 是否允许编辑
|
470
470
|
summary: {
|
package/src/index.js
CHANGED
@@ -12,6 +12,8 @@ import tabs from "pak/tabs";
|
|
12
12
|
import verifyInput from "pak/verifyInput";
|
13
13
|
import button from "pak/button";
|
14
14
|
import position from "pak/core/components/position";
|
15
|
+
import grid from "pak/grid/index.vue";
|
16
|
+
import cell from "pak/grid/cell.vue";
|
15
17
|
|
16
18
|
import { mergeTemplate } from "./template";
|
17
19
|
import directive from "pak/directive";
|
@@ -33,6 +35,8 @@ const components = [
|
|
33
35
|
verifyInput,
|
34
36
|
button,
|
35
37
|
position,
|
38
|
+
grid,
|
39
|
+
cell,
|
36
40
|
];
|
37
41
|
|
38
42
|
const install = function (Vue, opts = {}) {
|
@@ -241,12 +241,11 @@ export default {
|
|
241
241
|
numberFormat: (item) => {
|
242
242
|
const config = {
|
243
243
|
precision: 2, // 精度(小数位数)
|
244
|
-
round:
|
244
|
+
round: false, // 是否四舍五入
|
245
245
|
toFixed: false, // 是否固定小数位数
|
246
246
|
thousandth: false, // 是否显示千分位
|
247
247
|
prefix: "", // 前缀
|
248
248
|
suffix: "", // 后缀
|
249
|
-
keepZero: false, // 是否保留末尾0
|
250
249
|
...(get(item, "formatData") || item),
|
251
250
|
};
|
252
251
|
|
@@ -258,23 +257,50 @@ export default {
|
|
258
257
|
};
|
259
258
|
|
260
259
|
// 处理数字精度
|
261
|
-
const formatPrecision = (num) => {
|
260
|
+
const formatPrecision = (num, originalStr = "") => {
|
262
261
|
if (typeof num !== "number") return num;
|
262
|
+
let result;
|
263
|
+
if (config.precision !== 0) {
|
264
|
+
const endsWithDot = originalStr.endsWith(".");
|
265
|
+
// 检查原始字符串是否以0结尾的小数
|
266
|
+
const endsWithZero =
|
267
|
+
originalStr.includes(".") && originalStr.endsWith("0");
|
268
|
+
const decimalPlaces = endsWithZero
|
269
|
+
? originalStr.split(".")[1].length
|
270
|
+
: 0;
|
271
|
+
|
272
|
+
// 使用字符串操作来保持精确度
|
273
|
+
const numStr = String(num);
|
274
|
+
const parts = numStr.split(".");
|
275
|
+
if (parts.length > 1) {
|
276
|
+
const integerPart = parts[0];
|
277
|
+
const decimalPart = parts[1];
|
278
|
+
if (config.round) {
|
279
|
+
result = Number(Number(num).toFixed(config.precision));
|
280
|
+
} else {
|
281
|
+
// 直接截取所需的小数位数
|
282
|
+
result = Number(
|
283
|
+
integerPart + "." + decimalPart.slice(0, config.precision)
|
284
|
+
);
|
285
|
+
}
|
286
|
+
} else {
|
287
|
+
result = num;
|
288
|
+
}
|
263
289
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
if (!config.keepZero) {
|
274
|
-
num = String(Number(num));
|
290
|
+
// 如果原始输入以0结尾,使用原始小数位数
|
291
|
+
if (endsWithZero && !config.toFixed) {
|
292
|
+
result = Number(result).toFixed(
|
293
|
+
Math.min(config.precision, decimalPlaces)
|
294
|
+
);
|
295
|
+
} else if (endsWithDot && !String(result).includes(".")) {
|
296
|
+
result = result + ".";
|
297
|
+
} else if (config.toFixed) {
|
298
|
+
result = Number(result).toFixed(config.precision);
|
275
299
|
}
|
300
|
+
} else {
|
301
|
+
result = Number(num).toFixed(0);
|
276
302
|
}
|
277
|
-
return
|
303
|
+
return result;
|
278
304
|
};
|
279
305
|
|
280
306
|
// 处理多个小数点的情况(只保留第一个)
|
@@ -297,26 +323,12 @@ export default {
|
|
297
323
|
rawStr = String(value);
|
298
324
|
}
|
299
325
|
|
300
|
-
|
301
|
-
if (!/^-?\d*\.?\d*$/.test(rawStr)) {
|
302
|
-
return value;
|
303
|
-
}
|
326
|
+
const num = Number(rawStr) || 0;
|
304
327
|
|
305
|
-
//
|
306
|
-
|
307
|
-
|
308
|
-
const num = Number(rawStr);
|
309
|
-
if (isNaN(num)) {
|
310
|
-
return value;
|
311
|
-
}
|
312
|
-
let formatted = formatPrecision(num);
|
328
|
+
// 传入原始字符串,用于处理特殊情况
|
329
|
+
let formatted = formatPrecision(num, rawStr);
|
313
330
|
formatted = String(formatted);
|
314
331
|
|
315
|
-
// 如果原始输入以小数点结尾,但格式化后中没有小数点,则补回
|
316
|
-
if (endsWithDot && !formatted.includes(".")) {
|
317
|
-
formatted += ".";
|
318
|
-
}
|
319
|
-
|
320
332
|
if (config.thousandth) {
|
321
333
|
formatted = formatThousandth(formatted);
|
322
334
|
}
|
@@ -354,50 +366,16 @@ export default {
|
|
354
366
|
},
|
355
367
|
};
|
356
368
|
},
|
357
|
-
//
|
358
|
-
|
359
|
-
// 预设的正则规则
|
360
|
-
const REGEX_RULES = {
|
361
|
-
number: /[^\d]/g, // 仅数字
|
362
|
-
phone: /[^\d]/g, // 手机号
|
363
|
-
decimal: /[^\d.]/g, // 小数
|
364
|
-
letter: /[^a-zA-Z]/g, // 仅字母
|
365
|
-
chinese: /[^\u4e00-\u9fa5]/g, // 仅中文
|
366
|
-
letterNumber: /[^a-zA-Z0-9]/g, // 字母和数字
|
367
|
-
email: /[^a-zA-Z0-9@._-]/g, // 邮箱
|
368
|
-
custom: null, // 自定义正则
|
369
|
-
};
|
370
|
-
|
369
|
+
// 自定义正则格式化
|
370
|
+
regexFormat: (item) => {
|
371
371
|
// 默认配置
|
372
372
|
const config = {
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
decimal: undefined, // 小数位数(type为decimal时使用)
|
373
|
+
pattern: "", // 自定义正则表达式
|
374
|
+
flags: "g", // 正则标志,默认全局匹配
|
375
|
+
replace: "", // 替换值,默认为空字符串
|
377
376
|
...(get(item, "formatData") || item),
|
378
377
|
};
|
379
378
|
|
380
|
-
// 处理小数格式化
|
381
|
-
const formatDecimal = (value) => {
|
382
|
-
if (!value) return value;
|
383
|
-
|
384
|
-
// 先去除非数字和小数点
|
385
|
-
let formatted = value.replace(/[^\d.]/g, "");
|
386
|
-
|
387
|
-
// 只保留第一个小数点
|
388
|
-
const parts = formatted.split(".");
|
389
|
-
if (parts.length > 2) {
|
390
|
-
formatted = parts[0] + "." + parts.slice(1).join("");
|
391
|
-
}
|
392
|
-
|
393
|
-
// 处理小数位数
|
394
|
-
if (config.decimal !== undefined && parts[1]) {
|
395
|
-
formatted = parts[0] + "." + parts[1].slice(0, config.decimal);
|
396
|
-
}
|
397
|
-
|
398
|
-
return formatted;
|
399
|
-
};
|
400
|
-
|
401
379
|
return {
|
402
380
|
input: (value) => {
|
403
381
|
if (!value) return value;
|
@@ -405,28 +383,38 @@ export default {
|
|
405
383
|
try {
|
406
384
|
let formatted = String(value);
|
407
385
|
|
408
|
-
//
|
409
|
-
if (config.
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
386
|
+
// 验证并应用正则表达式
|
387
|
+
if (config.pattern) {
|
388
|
+
let regex;
|
389
|
+
if (config.pattern instanceof RegExp) {
|
390
|
+
// 如果已经是RegExp对象,直接使用
|
391
|
+
regex = config.pattern;
|
392
|
+
} else {
|
393
|
+
// 如果是字符串,创建RegExp对象
|
394
|
+
regex = new RegExp(config.pattern, config.flags);
|
395
|
+
}
|
396
|
+
|
397
|
+
// 如果是验证模式(以^开头且以$结尾),则进行完整匹配
|
398
|
+
if (
|
399
|
+
config.pattern.toString().startsWith("/^") &&
|
400
|
+
config.pattern.toString().endsWith("$/")
|
401
|
+
) {
|
402
|
+
return regex.test(formatted) ? formatted : "";
|
403
|
+
} else {
|
404
|
+
// 否则进行替换
|
405
|
+
formatted = formatted.replace(regex, config.replace);
|
406
|
+
}
|
416
407
|
}
|
417
408
|
|
418
|
-
|
419
|
-
const rule = config.pattern
|
420
|
-
? new RegExp(config.pattern, "g")
|
421
|
-
: REGEX_RULES[config.inputType];
|
422
|
-
|
423
|
-
return formatted.replace(rule, "");
|
409
|
+
return formatted;
|
424
410
|
} catch (error) {
|
425
|
-
console.warn("
|
411
|
+
console.warn("自定义正则格式化失败:", error);
|
426
412
|
return value;
|
427
413
|
}
|
428
414
|
},
|
429
|
-
output: (value) =>
|
415
|
+
output: (value) => {
|
416
|
+
return value;
|
417
|
+
},
|
430
418
|
};
|
431
419
|
},
|
432
420
|
// 百分比格式化
|