数据处理分类新增数组处理、时间处理、字符串处理

This commit is contained in:
fofolee 2025-01-11 01:14:13 +08:00
parent e7da2d3a26
commit 44b740de5c
18 changed files with 2116 additions and 108 deletions

View File

@ -0,0 +1,238 @@
const array = {
// 安全的条件解析器
_parseCondition: function (item, condition) {
// 支持的操作符
const operators = {
"===": (a, b) => a === b,
"!==": (a, b) => a !== b,
">=": (a, b) => a >= b,
"<=": (a, b) => a <= b,
">": (a, b) => a > b,
"<": (a, b) => a < b,
"&&": (a, b) => a && b,
"||": (a, b) => a || b,
includes: (a, b) => String(a).includes(b),
startsWith: (a, b) => String(a).startsWith(b),
endsWith: (a, b) => String(a).endsWith(b),
};
try {
// 简单属性访问
if (/^[a-zA-Z0-9_]+$/.test(condition)) {
return item[condition];
}
// 解析复杂条件
for (const [op, func] of Object.entries(operators)) {
if (condition.includes(op)) {
const [left, right] = condition.split(op).map((s) => s.trim());
const leftValue = left.includes(".")
? left.split(".").reduce((obj, key) => obj[key], item)
: /^[a-zA-Z0-9_]+$/.test(left)
? item[left]
: this._parseValue(left);
const rightValue = right.includes(".")
? right.split(".").reduce((obj, key) => obj[key], item)
: /^[a-zA-Z0-9_]+$/.test(right)
? item[right]
: this._parseValue(right);
return func(leftValue, rightValue);
}
}
return false;
} catch (error) {
return false;
}
},
// 解析值
_parseValue: function (value) {
if (value === "true") return true;
if (value === "false") return false;
if (value === "null") return null;
if (value === "undefined") return undefined;
if (value.startsWith("'") && value.endsWith("'")) return value.slice(1, -1);
if (value.startsWith('"') && value.endsWith('"')) return value.slice(1, -1);
if (!isNaN(value)) return Number(value);
return value;
},
// 数组过滤
filter: function (array, condition) {
if (!Array.isArray(array)) return [];
return array.filter((item) => this._parseCondition(item, condition));
},
// 查找元素
find: function (array, condition) {
if (!Array.isArray(array)) return null;
return array.find((item) => this._parseCondition(item, condition));
},
// 数组映射
map: function (array, transform) {
if (!Array.isArray(array)) return [];
return array.map((item) => {
if (/^[a-zA-Z0-9_.]+$/.test(transform)) {
return transform.split(".").reduce((obj, key) => obj?.[key], item);
}
return item;
});
},
// 数组排序
sort: function (array, key, order = "asc") {
if (!Array.isArray(array)) return [];
return [...array].sort((a, b) => {
const valueA = key ? a[key] : a;
const valueB = key ? b[key] : b;
if (typeof valueA === "string" && typeof valueB === "string") {
return order === "asc"
? valueA.localeCompare(valueB)
: valueB.localeCompare(valueA);
}
return order === "asc" ? valueA - valueB : valueB - valueA;
});
},
// 数组分组
group: function (array, key) {
if (!Array.isArray(array) || !key) return {};
return array.reduce((groups, item) => {
const value = key.split(".").reduce((obj, k) => obj?.[k], item);
if (value !== undefined) {
if (!groups[value]) {
groups[value] = [];
}
groups[value].push(item);
}
return groups;
}, {});
},
// 数组去重
unique: function (array, key) {
if (!Array.isArray(array)) return [];
if (!key) {
return [...new Set(array)];
}
const seen = new Set();
return array.filter((item) => {
const value = key.split(".").reduce((obj, k) => obj?.[k], item);
if (value === undefined || seen.has(value)) {
return false;
}
seen.add(value);
return true;
});
},
// 数组聚合
aggregate: function (array, operation, key) {
if (!Array.isArray(array)) return null;
const values = key
? array.map((item) => key.split(".").reduce((obj, k) => obj?.[k], item))
: array;
const validNumbers = values.filter((v) => !isNaN(v));
switch (operation) {
case "sum":
return validNumbers.reduce((sum, val) => sum + val, 0);
case "avg":
return validNumbers.length
? validNumbers.reduce((sum, val) => sum + val, 0) /
validNumbers.length
: 0;
case "max":
return validNumbers.length ? Math.max(...validNumbers) : null;
case "min":
return validNumbers.length ? Math.min(...validNumbers) : null;
case "count":
return array.length;
default:
return null;
}
},
// 数组切片
slice: function (array, start, end) {
if (!Array.isArray(array)) return [];
return array.slice(start, end);
},
// 数组扁平化
flatten: function (array, depth = 1) {
if (!Array.isArray(array)) return [];
return array.flat(depth);
},
// 数组差集
diff: function (array1, array2, key) {
if (!Array.isArray(array1) || !Array.isArray(array2)) return [];
if (!key) {
return array1.filter((item) => !array2.includes(item));
}
const set2 = new Set(
array2.map((item) => key.split(".").reduce((obj, k) => obj?.[k], item))
);
return array1.filter(
(item) => !set2.has(key.split(".").reduce((obj, k) => obj?.[k], item))
);
},
// 数组交集
intersect: function (array1, array2, key) {
if (!Array.isArray(array1) || !Array.isArray(array2)) return [];
if (!key) {
return array1.filter((item) => array2.includes(item));
}
const set2 = new Set(
array2.map((item) => key.split(".").reduce((obj, k) => obj?.[k], item))
);
return array1.filter((item) =>
set2.has(key.split(".").reduce((obj, k) => obj?.[k], item))
);
},
// 数组并集
union: function (array1, array2, key) {
if (!Array.isArray(array1) || !Array.isArray(array2)) return [];
if (!key) {
return [...new Set([...array1, ...array2])];
}
const seen = new Set();
return [...array1, ...array2].filter((item) => {
const value = key.split(".").reduce((obj, k) => obj?.[k], item);
if (value === undefined || seen.has(value)) {
return false;
}
seen.add(value);
return true;
});
},
// 数组分块
chunk: function (array, size = 1) {
if (!Array.isArray(array) || size < 1) return [];
const chunks = [];
for (let i = 0; i < array.length; i += size) {
chunks.push(array.slice(i, i + size));
}
return chunks;
},
// 数组随机排序
shuffle: function (array) {
if (!Array.isArray(array)) return [];
const result = [...array];
for (let i = result.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[result[i], result[j]] = [result[j], result[i]];
}
return result;
},
};
module.exports = array;

View File

@ -1,11 +1,15 @@
const string = require("./string");
const buffer = require("./buffer");
const zlib = require("./zlib");
const htmlParser = require("./htmlParser");
const { htmlParser } = require("./htmlParser");
const array = require("./array");
const time = require("./time");
module.exports = {
...string,
...htmlParser,
htmlParser,
string,
buffer,
zlib,
array,
time,
};

View File

@ -1,25 +1,196 @@
const string = {
// 字符串反转
reverseString: function (text) {
reverse: function (text) {
return text.split("").reverse().join("");
},
// 字符串替换
replaceString: function (text, oldStr, newStr) {
replace: function (text, oldStr, newStr) {
return text.replaceAll(oldStr, newStr);
},
// 字符串截取
substring: function (text, start, end) {
return text.substring(start, end);
},
// 正则处理
regexTransform: function (text, regex, replace) {
try {
if (replace === undefined) return text.match(regex);
return text.replace(regex, replace);
} catch (e) {
throw "正则表达式格式错误";
// 去除空白
trim: function (text, mode = "both") {
switch (mode) {
case "start":
return text.trimStart();
case "end":
return text.trimEnd();
default:
return text.trim();
}
},
// 大小写转换
case: function (text, mode = "upper") {
switch (mode) {
case "upper":
return text.toUpperCase();
case "lower":
return text.toLowerCase();
case "capitalize":
return text
.toLowerCase()
.split(" ")
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ");
case "camel":
return text
.toLowerCase()
.split(/[^a-zA-Z0-9]+/)
.map((word, index) =>
index === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1)
)
.join("");
case "snake":
return text
.toLowerCase()
.replace(/[^a-zA-Z0-9]+/g, "_")
.replace(/([A-Z])/g, "_$1")
.replace(/^_/, "");
case "kebab":
return text
.toLowerCase()
.replace(/[^a-zA-Z0-9]+/g, "-")
.replace(/([A-Z])/g, "-$1")
.replace(/^-/, "");
case "constant":
return text
.toUpperCase()
.replace(/[^A-Z0-9]+/g, "_")
.replace(/^_/, "");
default:
return text;
}
},
// 字符串填充
pad: function (text, length, padString = " ", mode = "end") {
const totalPadding = Math.max(0, length - text.length);
switch (mode) {
case "start":
return text.padStart(length, padString);
case "end":
return text.padEnd(length, padString);
case "both":
const leftPadding = Math.floor(totalPadding / 2);
const rightPadding = totalPadding - leftPadding;
return text
.padStart(text.length + leftPadding, padString)
.padEnd(length, padString);
default:
return text;
}
},
// 字符串分割
split: function (text, separator = ",") {
return text.split(separator);
},
// 数组合并
join: function (array, separator = ",") {
return Array.isArray(array) ? array.join(separator) : String(array);
},
// 字符串重复
repeat: function (text, count = 1) {
return text.repeat(Math.max(0, count));
},
// 提取字符
extract: function (text, mode = "number") {
const patterns = {
number: /\d+/g,
letter: /[a-zA-Z]+/g,
chinese: /[\u4e00-\u9fa5]+/g,
punctuation: /[^\w\s\u4e00-\u9fa5]+/g,
whitespace: /\s+/g,
};
const matches = text.match(patterns[mode] || patterns.number);
return matches ? matches : [];
},
// 字符统计
count: function (text, mode = "char") {
switch (mode) {
case "char":
return text.length;
case "word":
return text.trim().split(/\s+/).length;
case "line":
return text.split(/\r\n|\r|\n/).length;
case "number":
return (text.match(/\d/g) || []).length;
case "letter":
return (text.match(/[a-zA-Z]/g) || []).length;
case "chinese":
return (text.match(/[\u4e00-\u9fa5]/g) || []).length;
case "whitespace":
return (text.match(/\s/g) || []).length;
default:
return 0;
}
},
// 文本换行
wrap: function (text, width = 80) {
const words = text.split(/(\s+)/);
let line = "";
let result = "";
for (const word of words) {
if (line.length + word.length > width) {
result += line.trimEnd() + "\n";
line = "";
}
line += word;
}
return result + line.trimEnd();
},
// 文本对齐
align: function (text, mode = "left", width = 80) {
const lines = text.split("\n");
return lines
.map((line) => {
const spaces = width - line.length;
if (spaces <= 0) return line;
switch (mode) {
case "right":
return " ".repeat(spaces) + line;
case "center":
const leftSpaces = Math.floor(spaces / 2);
return (
" ".repeat(leftSpaces) + line + " ".repeat(spaces - leftSpaces)
);
case "justify":
if (line.trim() === "") return line;
const words = line.trim().split(/\s+/);
if (words.length === 1) return line;
const totalSpaces = width - words.join("").length;
const spaceBetween = Math.floor(totalSpaces / (words.length - 1));
const extraSpaces = totalSpaces % (words.length - 1);
return words
.map((word, i) =>
i < words.length - 1
? word + " ".repeat(spaceBetween + (i < extraSpaces ? 1 : 0))
: word
)
.join("");
default:
return line;
}
})
.join("\n");
},
};
module.exports = string;

View File

@ -0,0 +1,350 @@
const time = {
// 解析时间字符串或时间戳为 Date 对象
_parseTime: function (time) {
if (!time || time === "now") {
return new Date();
}
if (typeof time === "number") {
return new Date(time.toString().length === 10 ? time * 1000 : time);
}
return new Date(time);
},
// 格式化数字为两位数
_pad: function (number) {
return number.toString().padStart(2, "0");
},
// 格式化时间
format: function (time, format) {
const date = this._parseTime(time);
if (!date.getTime()) return "";
const year = date.getFullYear();
const month = this._pad(date.getMonth() + 1);
const day = this._pad(date.getDate());
const hours = this._pad(date.getHours());
const minutes = this._pad(date.getMinutes());
const seconds = this._pad(date.getSeconds());
switch (format) {
case "YYYY-MM-DD":
return `${year}-${month}-${day}`;
case "YYYY-MM-DD HH:mm:ss":
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
case "YYYY年MM月DD日":
return `${year}${month}${day}`;
case "MM/DD/YYYY":
return `${month}/${day}/${year}`;
case "DD/MM/YYYY":
return `${day}/${month}/${year}`;
case "HH:mm:ss":
return `${hours}:${minutes}:${seconds}`;
case "YYYY-MM-DD HH:mm":
return `${year}-${month}-${day} ${hours}:${minutes}`;
case "timestamp":
return Math.floor(date.getTime() / 1000);
case "timestamp_ms":
return date.getTime();
case "relative":
return this._getRelativeTime(date);
default:
return date.toLocaleString();
}
},
// 获取相对时间描述
_getRelativeTime: function (date) {
const now = new Date();
const diff = now - date;
const seconds = Math.floor(diff / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
const months = Math.floor(days / 30);
const years = Math.floor(days / 365);
if (seconds < 60) return "刚刚";
if (minutes < 60) return `${minutes}分钟前`;
if (hours < 24) return `${hours}小时前`;
if (days < 30) return `${days}天前`;
if (months < 12) return `${months}个月前`;
return `${years}年前`;
},
// 解析时间
parse: function (time, format) {
if (!time) return null;
// 处理时间戳
if (format === "timestamp") {
return new Date(Number(time) * 1000);
}
if (format === "timestamp_ms") {
return new Date(Number(time));
}
// 处理标准格式
const now = new Date();
const year = now.getFullYear();
let result;
switch (format) {
case "YYYY-MM-DD":
case "YYYY-MM-DD HH:mm:ss":
case "YYYY-MM-DD HH:mm":
result = new Date(time);
break;
case "YYYY年MM月DD日":
time = time.replace(/[年月日]/g, (match) => {
return { : "-", : "-", : "" }[match];
});
result = new Date(time);
break;
case "MM/DD/YYYY":
const [month, day, yyyy] = time.split("/");
result = new Date(yyyy, month - 1, day);
break;
case "DD/MM/YYYY":
const [dd, mm, yy] = time.split("/");
result = new Date(yy, mm - 1, dd);
break;
default:
result = new Date(time);
}
return result.getTime() ? result : null;
},
// 时间加减
add: function (time, value, unit) {
const date = this._parseTime(time);
if (!date.getTime()) return null;
const unitMap = {
years: "FullYear",
months: "Month",
weeks: "Date",
days: "Date",
hours: "Hours",
minutes: "Minutes",
seconds: "Seconds",
};
const methodName = `set${unitMap[unit]}`;
const getValue = `get${unitMap[unit]}`;
if (unit === "weeks") {
value *= 7;
}
date[methodName](date[getValue]() + value);
return date;
},
// 时间差值
diff: function (time1, time2, unit = "days", absolute = true) {
const date1 = this._parseTime(time1);
const date2 = this._parseTime(time2);
if (!date1.getTime() || !date2.getTime()) return null;
const milliseconds = date2 - date1;
let result;
switch (unit) {
case "years":
result = date2.getFullYear() - date1.getFullYear();
break;
case "months":
result =
(date2.getFullYear() - date1.getFullYear()) * 12 +
(date2.getMonth() - date1.getMonth());
break;
case "weeks":
result = milliseconds / (7 * 24 * 60 * 60 * 1000);
break;
case "days":
result = milliseconds / (24 * 60 * 60 * 1000);
break;
case "hours":
result = milliseconds / (60 * 60 * 1000);
break;
case "minutes":
result = milliseconds / (60 * 1000);
break;
case "seconds":
result = milliseconds / 1000;
break;
case "milliseconds":
result = milliseconds;
break;
default:
result = milliseconds / (24 * 60 * 60 * 1000);
}
return absolute ? Math.abs(result) : result;
},
// 时间边界
startOf: function (time, unit, type = "start") {
const date = this._parseTime(time);
if (!date.getTime()) return null;
const isEnd = type === "end";
switch (unit) {
case "year":
date.setMonth(isEnd ? 11 : 0, 1);
date.setHours(
isEnd ? 23 : 0,
isEnd ? 59 : 0,
isEnd ? 59 : 0,
isEnd ? 999 : 0
);
break;
case "month":
date.setDate(1);
if (isEnd) {
date.setMonth(date.getMonth() + 1, 0);
date.setHours(23, 59, 59, 999);
} else {
date.setHours(0, 0, 0, 0);
}
break;
case "week":
const day = date.getDay();
const diff = date.getDate() - day + (day === 0 ? -6 : 1);
date.setDate(diff);
if (isEnd) {
date.setDate(date.getDate() + 6);
date.setHours(23, 59, 59, 999);
} else {
date.setHours(0, 0, 0, 0);
}
break;
case "day":
date.setHours(
isEnd ? 23 : 0,
isEnd ? 59 : 0,
isEnd ? 59 : 0,
isEnd ? 999 : 0
);
break;
case "hour":
date.setMinutes(isEnd ? 59 : 0, isEnd ? 59 : 0, isEnd ? 999 : 0);
break;
case "minute":
date.setSeconds(isEnd ? 59 : 0, isEnd ? 999 : 0);
break;
case "second":
date.setMilliseconds(isEnd ? 999 : 0);
break;
}
return date;
},
// 时间验证
isValid: function (time, format) {
if (!time) return false;
const date = this.parse(time, format);
return date && date.getTime() > 0;
},
// 日历信息
calendar: function (time) {
const date = this._parseTime(time);
if (!date.getTime()) return null;
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const week = date.getDay();
const weekText = ["日", "一", "二", "三", "四", "五", "六"][week];
// 星座计算
const constellation = this._getConstellation(month, day);
return {
year,
month,
day,
week,
weekText: `星期${weekText}`,
constellation,
isWeekend: week === 0 || week === 6,
isLeapYear: (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0,
daysInMonth: new Date(year, month, 0).getDate(),
timestamp: Math.floor(date.getTime() / 1000),
timestamp_ms: date.getTime(),
};
},
// 获取星座
_getConstellation: function (month, day) {
const constellations = [
"魔羯",
"水瓶",
"双鱼",
"白羊",
"金牛",
"双子",
"巨蟹",
"狮子",
"处女",
"天秤",
"天蝎",
"射手",
"魔羯",
];
const dates = [20, 19, 21, 20, 21, 22, 23, 23, 23, 24, 23, 22];
return day < dates[month - 1]
? constellations[month - 1]
: constellations[month];
},
// 工作日计算
workday: function (startTime, days, weekends = false, holidays = []) {
const date = this._parseTime(startTime);
if (!date.getTime()) return null;
let currentDate = new Date(date);
let remainingDays = Math.abs(days);
const direction = days >= 0 ? 1 : -1;
const holidaySet = new Set(
holidays.map((h) => this.format(h, "YYYY-MM-DD"))
);
while (remainingDays > 0) {
currentDate.setDate(currentDate.getDate() + direction);
const isWeekend =
currentDate.getDay() === 0 || currentDate.getDay() === 6;
const isHoliday = holidaySet.has(this.format(currentDate, "YYYY-MM-DD"));
if ((!isWeekend || weekends) && !isHoliday) {
remainingDays--;
}
}
return currentDate;
},
// 时间范围判断
between: function (time, startTime, endTime, inclusive = true) {
const date = this._parseTime(time);
const start = this._parseTime(startTime);
const end = this._parseTime(endTime);
if (!date.getTime() || !start.getTime() || !end.getTime()) {
return false;
}
if (inclusive) {
return date >= start && date <= end;
}
return date > start && date < end;
},
};
module.exports = time;

View File

@ -96,7 +96,18 @@ export default defineComponent({
},
saveFlow() {
const flow = window.lodashM.cloneDeep(this.commandFlow);
const uselessProps = ["config", "argvs", "label", "component", "subCommands", "options", "defaultValue"];
const uselessProps = [
"config",
"argvs",
"label",
"component",
"subCommands",
"options",
"defaultValue",
"icon",
"width",
"placeholder",
];
//
flow.forEach((cmd) => {
for (const props of uselessProps) {

View File

@ -6,15 +6,16 @@
:model-value="isCollapse"
>
<div class="array-editor">
<div v-for="(row, index) in rows" :key="index" class="row items-center">
<template v-if="columns">
<div
v-for="(row, index) in rows"
:key="index"
class="row items-center q-gutter-sm"
>
<template v-if="!!columns">
<div
v-for="column in processedColumns"
:key="column.key"
:class="[
column.width ? `col-${column.width}` : 'col',
Object.keys(columns).length > 1 ? 'q-pr-sm' : '',
]"
:class="[column.width ? `col-${column.width}` : 'col']"
>
<VariableInput
:model-value="row[column.key]"

View File

@ -0,0 +1,145 @@
<template>
<div class="check-btn-group">
<q-btn
:color="modelValue ? 'primary' : 'grey-7'"
:flat="!modelValue"
:outline="modelValue"
dense
:class="['check-btn', { 'check-btn--selected': modelValue }]"
@click="toggleValue"
>
<template #default>
<div class="row items-center full-width">
<div class="check-btn-content">
<div class="check-btn-label">{{ label }}</div>
</div>
<q-icon
:name="modelValue ? 'check_circle' : 'radio_button_unchecked'"
size="14px"
class="q-ml-xs check-btn-icon"
/>
</div>
<q-tooltip v-if="tooltip">{{ tooltip }}</q-tooltip>
</template>
</q-btn>
</div>
</template>
<script>
import { defineComponent } from "vue";
export default defineComponent({
name: "CheckButton",
props: {
modelValue: {
type: Boolean,
default: false,
},
label: {
type: String,
default: "",
},
icon: {
type: String,
default: "",
},
tooltip: {
type: String,
default: "",
},
isCollapse: {
type: Boolean,
default: false,
},
},
emits: ["update:model-value"],
methods: {
toggleValue() {
this.$emit("update:model-value", !this.modelValue);
},
},
});
</script>
<style scoped>
.check-btn-group {
display: flex;
flex-wrap: wrap;
gap: 4px;
width: 100%;
}
.check-btn {
min-width: 100%;
max-width: 100% !important;
height: auto !important;
min-height: 36px;
font-size: 12px;
padding: 4px 12px;
border-radius: 4px !important;
transition: all 0.3s;
background-color: rgba(0, 0, 0, 0.03);
}
.check-btn :deep(.q-btn__content) {
min-width: 0;
height: auto;
white-space: normal;
}
.check-btn-content {
flex: 1;
min-width: 0;
margin-right: 4px;
}
.check-btn-label {
text-align: center;
line-height: 1.2;
word-break: break-word;
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
}
.check-btn-icon {
flex: none;
opacity: 0.8;
transition: all 0.3s;
margin-top: 2px;
}
.check-btn--selected .check-btn-icon {
opacity: 1;
transform: scale(1.1);
}
.check-btn:hover {
opacity: 0.9;
transform: translateY(-1px);
border-color: var(--q-primary);
}
.body--dark .check-btn {
background-color: rgba(255, 255, 255, 0.03);
}
.check-btn--selected {
background-color: transparent !important;
border-color: var(--q-primary) !important;
}
.check-btn.q-btn--flat {
color: var(--q-primary);
opacity: 0.8;
}
.body--dark .check-btn.q-btn--flat {
color: rgba(255, 255, 255, 0.9);
}
.check-btn.q-btn--outline {
opacity: 1;
background-color: transparent;
}
</style>

View File

@ -4,6 +4,7 @@
<div class="cards-wrapper">
<div
v-for="option in options"
ref="operationCard"
:key="option.value"
:class="['operation-card', { active: modelValue === option.value }]"
:data-value="option.value"
@ -71,14 +72,19 @@ export default {
},
},
watch: {
modelValue(newVal) {
document
.querySelector(`.operation-card[data-value="${newVal}"]`)
?.scrollIntoView({
behavior: "smooth",
block: "nearest",
inline: "nearest",
modelValue: {
immediate: true,
handler(newVal) {
this.$nextTick(() => {
this.$refs.operationCard
?.find((card) => card.dataset.value === newVal)
?.scrollIntoView({
behavior: "smooth",
block: "nearest",
inline: "nearest",
});
});
},
},
},
};

View File

@ -41,7 +41,7 @@ import DictEditor from "./DictEditor.vue";
import ButtonGroup from "./ButtonGroup.vue";
import ControlInput from "./ControlInput.vue";
import CheckGroup from "./CheckGroup.vue";
import CheckButton from "./CheckButton.vue";
export default defineComponent({
name: "OptionEditor",
components: {
@ -53,6 +53,7 @@ export default defineComponent({
ButtonGroup,
ControlInput,
CheckGroup,
CheckButton,
},
emits: ["update:modelValue"],
props: {

View File

@ -34,6 +34,7 @@ import ButtonGroup from "./ButtonGroup.vue";
import ControlInput from "./ControlInput.vue";
import CheckGroup from "./CheckGroup.vue";
import OptionEditor from "./OptionEditor.vue";
import CheckButton from "./CheckButton.vue";
/**
* 参数输入组件
@ -57,6 +58,7 @@ export default defineComponent({
ControlInput,
CheckGroup,
OptionEditor,
CheckButton,
},
props: {
configs: {

View File

@ -223,13 +223,12 @@ export default defineComponent({
},
title: {
label: "标题",
width: 4,
noIcon: true,
},
description: {
label: "描述",
width: 4,
noIcon: true,
width: 4,
},
},
};

File diff suppressed because it is too large Load Diff

View File

@ -259,7 +259,7 @@ export const networkCommands = {
},
{
label: "返回所有地址",
component: "q-checkbox",
component: "CheckButton",
defaultValue: false,
width: 2.5,
},

View File

@ -270,7 +270,7 @@ export const systemCommands = {
},
{
label: "包含内部接口",
component: "q-checkbox",
component: "CheckButton",
defaultValue: false,
width: 12,
condition: "values[0] === 'networkInterfaces'",

View File

@ -115,6 +115,7 @@ export const uiCommands = {
isAsync: true,
outputVariable: "{id,text}",
saveOutput: true,
width: 12,
config: [
{
label: "按钮",
@ -133,6 +134,7 @@ export const uiCommands = {
isAsync: true,
outputVariable: "[inputValue1]",
saveOutput: true,
width: 12,
config: [
{
label: "输入框",

View File

@ -40,7 +40,7 @@ export const userdataCommands = {
},
{
label: "不同步",
component: "q-checkbox",
component: "CheckButton",
defaultValue: true,
width: 2,
},

View File

@ -113,32 +113,32 @@ export const utoolsCommands = {
forward: {
label: "向前查找",
icon: "arrow_right",
width: 2,
component: "q-checkbox",
width: 2.4,
component: "CheckButton",
},
findNext: {
label: "查找下一个",
icon: "arrow_down",
width: 2,
component: "q-checkbox",
width: 2.4,
component: "CheckButton",
},
matchCase: {
label: "区分大小写",
icon: "arrow_up",
width: 2,
component: "q-checkbox",
width: 2.4,
component: "CheckButton",
},
wordStart: {
label: "单词开头",
icon: "arrow_right",
width: 2,
component: "q-checkbox",
width: 2.4,
component: "CheckButton",
},
medialCapitalAsWordStart: {
label: "中缀大写作为单词开头",
label: "中缀大写开头",
icon: "arrow_right",
width: 4,
component: "q-checkbox",
width: 2.4,
component: "CheckButton",
},
},
defaultValue: {

View File

@ -16,7 +16,11 @@ export const availableCommands = categories.reduce((commands, category) => {
}, []);
export const findCommandByValue = (value) => {
return availableCommands.find((cmd) => cmd.value === value);
return availableCommands.find(
(cmd) =>
cmd.value === value ||
cmd.subCommands?.find((subCmd) => subCmd.value === value)
);
};
export const commandCategories = categories;