mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-06-08 22:51:25 +08:00
OS/URL/PATH/BUFFER组件调整
This commit is contained in:
parent
807da38e2e
commit
e23d3e5e11
@ -1,32 +1,57 @@
|
||||
const url = require("url");
|
||||
|
||||
// URL 解析
|
||||
function parse(urlString, parseQueryString = false) {
|
||||
return url.parse(urlString, parseQueryString);
|
||||
function parse(urlString) {
|
||||
try {
|
||||
return url.parse(urlString, false);
|
||||
} catch (error) {
|
||||
throw new Error(`URL解析失败: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// URL 格式化
|
||||
function format(urlObject) {
|
||||
// 格式化 URL
|
||||
function format(protocol, auth, hostname, port, pathname, search, hash) {
|
||||
try {
|
||||
const urlObject = {
|
||||
protocol,
|
||||
auth,
|
||||
hostname,
|
||||
port,
|
||||
pathname,
|
||||
search,
|
||||
hash,
|
||||
};
|
||||
return url.format(urlObject);
|
||||
} catch (error) {
|
||||
throw new Error(`URL格式化失败: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 解析查询字符串
|
||||
function parseQuery(query) {
|
||||
const searchParams = new URLSearchParams(query);
|
||||
function parseQuery(queryString) {
|
||||
try {
|
||||
const searchParams = new URLSearchParams(queryString);
|
||||
const result = {};
|
||||
for (const [key, value] of searchParams) {
|
||||
result[key] = value;
|
||||
}
|
||||
return result;
|
||||
} catch (error) {
|
||||
throw new Error(`查询字符串解析失败: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 格式化查询字符串
|
||||
function formatQuery(queryObject) {
|
||||
function formatQuery(queryParams) {
|
||||
try {
|
||||
const searchParams = new URLSearchParams();
|
||||
for (const [key, value] of Object.entries(queryObject)) {
|
||||
for (const [key, value] of Object.entries(queryParams)) {
|
||||
searchParams.append(key, value);
|
||||
}
|
||||
return searchParams.toString();
|
||||
} catch (error) {
|
||||
throw new Error(`查询字符串格式化失败: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 解析路径名
|
||||
|
@ -6,7 +6,7 @@ function arch() {
|
||||
}
|
||||
|
||||
// 获取CPU信息
|
||||
function cpus({ format = "full" } = {}) {
|
||||
function cpus(format = "full") {
|
||||
const cpuInfo = os.cpus();
|
||||
if (format === "simple") {
|
||||
return cpuInfo.map(({ model, speed }) => ({ model, speed }));
|
||||
@ -15,7 +15,7 @@ function cpus({ format = "full" } = {}) {
|
||||
}
|
||||
|
||||
// 获取内存信息
|
||||
function memory({ type = "totalmem" } = {}) {
|
||||
function memory(type = "totalmem") {
|
||||
switch (type) {
|
||||
case "totalmem":
|
||||
return os.totalmem();
|
||||
@ -27,7 +27,7 @@ function memory({ type = "totalmem" } = {}) {
|
||||
}
|
||||
|
||||
// 获取网络信息
|
||||
function network({ type = "hostname", internal = false } = {}) {
|
||||
function network(type = "hostname", internal = false) {
|
||||
switch (type) {
|
||||
case "hostname":
|
||||
return os.hostname();
|
||||
@ -50,7 +50,7 @@ function network({ type = "hostname", internal = false } = {}) {
|
||||
}
|
||||
|
||||
// 获取平台信息
|
||||
function platform({ type = "platform" } = {}) {
|
||||
function platform(type = "platform") {
|
||||
switch (type) {
|
||||
case "platform":
|
||||
return os.platform();
|
||||
|
@ -5,7 +5,7 @@ const path = require("path");
|
||||
* @param {string} p 要规范化的路径
|
||||
* @returns {string} 规范化后的路径
|
||||
*/
|
||||
async function normalize(p) {
|
||||
function normalize(p) {
|
||||
try {
|
||||
return path.normalize(p);
|
||||
} catch (error) {
|
||||
@ -18,7 +18,7 @@ async function normalize(p) {
|
||||
* @param {...string} paths 路径片段
|
||||
* @returns {string} 连接后的路径
|
||||
*/
|
||||
async function join(...paths) {
|
||||
function join(...paths) {
|
||||
try {
|
||||
return path.join(...paths);
|
||||
} catch (error) {
|
||||
@ -31,7 +31,7 @@ async function join(...paths) {
|
||||
* @param {string} p 要解析的路径
|
||||
* @returns {Object} 解析结果,包含 root, dir, base, ext, name
|
||||
*/
|
||||
async function parse(p) {
|
||||
function parse(p) {
|
||||
try {
|
||||
return path.parse(p);
|
||||
} catch (error) {
|
||||
@ -44,7 +44,7 @@ async function parse(p) {
|
||||
* @param {string} p 路径
|
||||
* @returns {string} 目录名
|
||||
*/
|
||||
async function dirname(p) {
|
||||
function dirname(p) {
|
||||
try {
|
||||
return path.dirname(p);
|
||||
} catch (error) {
|
||||
@ -58,7 +58,7 @@ async function dirname(p) {
|
||||
* @param {string} [ext] 可选的扩展名,如果提供则从结果中移除
|
||||
* @returns {string} 文件名
|
||||
*/
|
||||
async function basename(p, ext) {
|
||||
function basename(p, ext = undefined) {
|
||||
try {
|
||||
return path.basename(p, ext);
|
||||
} catch (error) {
|
||||
@ -71,7 +71,7 @@ async function basename(p, ext) {
|
||||
* @param {string} p 路径
|
||||
* @returns {string} 扩展名
|
||||
*/
|
||||
async function extname(p) {
|
||||
function extname(p) {
|
||||
try {
|
||||
return path.extname(p);
|
||||
} catch (error) {
|
||||
@ -84,7 +84,7 @@ async function extname(p) {
|
||||
* @param {string} p 路径
|
||||
* @returns {boolean} 是否为绝对路径
|
||||
*/
|
||||
async function isAbsolute(p) {
|
||||
function isAbsolute(p) {
|
||||
try {
|
||||
return path.isAbsolute(p);
|
||||
} catch (error) {
|
||||
@ -98,7 +98,7 @@ async function isAbsolute(p) {
|
||||
* @param {string} to 目标路径
|
||||
* @returns {string} 相对路径
|
||||
*/
|
||||
async function relative(from, to) {
|
||||
function relative(from, to) {
|
||||
try {
|
||||
return path.relative(from, to);
|
||||
} catch (error) {
|
||||
@ -111,7 +111,7 @@ async function relative(from, to) {
|
||||
* @param {...string} paths 路径片段
|
||||
* @returns {string} 解析后的绝对路径
|
||||
*/
|
||||
async function resolve(...paths) {
|
||||
function resolve(...paths) {
|
||||
try {
|
||||
return path.resolve(...paths);
|
||||
} catch (error) {
|
||||
@ -121,11 +121,16 @@ async function resolve(...paths) {
|
||||
|
||||
/**
|
||||
* 格式化路径对象为路径字符串
|
||||
* @param {Object} pathObject 路径对象,包含 dir, root, base, name, ext
|
||||
* @param {string} root 根路径
|
||||
* @param {string} dir 目录
|
||||
* @param {string} base 基本名称
|
||||
* @param {string} name 文件名
|
||||
* @param {string} ext 扩展名
|
||||
* @returns {string} 格式化后的路径
|
||||
*/
|
||||
async function format(pathObject) {
|
||||
function format(root, dir, base, name, ext) {
|
||||
try {
|
||||
const pathObject = { root, dir, base, name, ext };
|
||||
return path.format(pathObject);
|
||||
} catch (error) {
|
||||
throw new Error(`格式化路径失败: ${error.message}`);
|
||||
|
@ -55,7 +55,11 @@
|
||||
<MultiParams
|
||||
v-else
|
||||
v-model="localCommand"
|
||||
:class="localCommand.config?.length ? 'col q-mt-sm' : 'col'"
|
||||
:class="
|
||||
localCommand.config?.length || localCommand.functionSelector
|
||||
? 'col q-mt-sm'
|
||||
: 'col'
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -111,7 +111,6 @@ export default defineComponent({
|
||||
this.updateModelValue(this.funcName, newArgvs);
|
||||
},
|
||||
generateCode(funcName, argvs) {
|
||||
console.log("argvs", argvs);
|
||||
/**
|
||||
* 字符串模式stringfiy后,null会变成'"null"', ''变成'""'
|
||||
* 变量模式stringify后,null变成'null', ''保持''
|
||||
|
70
src/components/composer/common/ButtonGroup.vue
Normal file
70
src/components/composer/common/ButtonGroup.vue
Normal file
@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<div class="button-group">
|
||||
<div
|
||||
v-for="opt in options"
|
||||
:key="opt.value"
|
||||
:class="['button-item', { active: modelValue === opt.value }]"
|
||||
@click="$emit('update:modelValue', opt.value)"
|
||||
>
|
||||
{{ opt.label }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "ButtonGroup",
|
||||
props: {
|
||||
modelValue: {
|
||||
required: true,
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
emits: ["update:modelValue"],
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.button-group {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
padding: 10px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.button-item {
|
||||
flex: 1;
|
||||
min-width: 80px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 26px;
|
||||
padding: 0 12px;
|
||||
font-size: 12px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
background: var(--q-primary-opacity-5);
|
||||
border: 1px solid var(--q-primary-opacity-5);
|
||||
color: var(--q-primary);
|
||||
white-space: nowrap;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.button-item:hover {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.button-item.active {
|
||||
color: white;
|
||||
background: var(--q-primary);
|
||||
border-color: var(--q-primary);
|
||||
}
|
||||
</style>
|
@ -72,6 +72,12 @@
|
||||
:label="config.label"
|
||||
:icon="config.icon"
|
||||
/>
|
||||
<ButtonGroup
|
||||
v-else-if="config.type === 'buttonGroup'"
|
||||
:model-value="values[index]"
|
||||
@update:model-value="$emit('update', index, $event)"
|
||||
:options="config.options"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -82,6 +88,7 @@ import VariableInput from "./VariableInput.vue";
|
||||
import NumberInput from "./NumberInput.vue";
|
||||
import ArrayEditor from "./ArrayEditor.vue";
|
||||
import DictEditor from "./DictEditor.vue";
|
||||
import ButtonGroup from "./ButtonGroup.vue";
|
||||
|
||||
/**
|
||||
* 参数输入组件
|
||||
@ -101,6 +108,7 @@ export default defineComponent({
|
||||
NumberInput,
|
||||
ArrayEditor,
|
||||
DictEditor,
|
||||
ButtonGroup,
|
||||
},
|
||||
props: {
|
||||
configs: {
|
||||
|
@ -1,695 +0,0 @@
|
||||
<template>
|
||||
<div class="buffer-editor">
|
||||
<!-- 操作类型选择 -->
|
||||
<OperationCard
|
||||
:model-value="argvs.operation"
|
||||
@update:model-value="(val) => updateArgvs('operation', val)"
|
||||
:options="operations"
|
||||
/>
|
||||
<!-- 操作配置 -->
|
||||
<div class="operation-options q-mt-sm">
|
||||
<div class="options-container">
|
||||
<!-- 创建 Buffer -->
|
||||
<div v-if="argvs.operation === 'from'" class="row q-col-gutter-sm">
|
||||
<VariableInput
|
||||
:model-value="argvs.data"
|
||||
@update:model-value="(val) => updateArgvs('data', val)"
|
||||
label="数据"
|
||||
icon="text_fields"
|
||||
class="col"
|
||||
/>
|
||||
<q-select
|
||||
:model-value="argvs.encoding"
|
||||
@update:model-value="(val) => updateArgvs('encoding', val)"
|
||||
:options="encodings"
|
||||
label="编码"
|
||||
dense
|
||||
filled
|
||||
emit-value
|
||||
map-options
|
||||
options-dense
|
||||
class="col-3"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 转换为字符串 -->
|
||||
<div
|
||||
v-if="argvs.operation === 'toString'"
|
||||
class="column q-col-gutter-sm"
|
||||
>
|
||||
<VariableInput
|
||||
:model-value="argvs.buffer"
|
||||
@update:model-value="(val) => updateArgvs('buffer', val)"
|
||||
label="Buffer"
|
||||
icon="memory"
|
||||
/>
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div class="col-12 col-sm-4">
|
||||
<q-select
|
||||
:model-value="argvs.encoding"
|
||||
@update:model-value="(val) => updateArgvs('encoding', val)"
|
||||
:options="encodings"
|
||||
label="编码"
|
||||
dense
|
||||
filled
|
||||
emit-value
|
||||
map-options
|
||||
options-dense
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<NumberInput
|
||||
:model-value="argvs.start"
|
||||
@update:model-value="(val) => updateArgvs('start', val)"
|
||||
label="起始位置"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<NumberInput
|
||||
:model-value="argvs.end"
|
||||
@update:model-value="(val) => updateArgvs('end', val)"
|
||||
label="结束位置"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 写入数据 -->
|
||||
<div v-if="argvs.operation === 'write'" class="column q-col-gutter-sm">
|
||||
<div class="row q-col-gutter-sm">
|
||||
<VariableInput
|
||||
:model-value="argvs.buffer"
|
||||
@update:model-value="(val) => updateArgvs('buffer', val)"
|
||||
label="Buffer"
|
||||
icon="memory"
|
||||
class="col"
|
||||
/>
|
||||
<VariableInput
|
||||
:model-value="argvs.string"
|
||||
@update:model-value="(val) => updateArgvs('string', val)"
|
||||
label="要写入的字符串"
|
||||
icon="edit"
|
||||
class="col"
|
||||
/>
|
||||
</div>
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div class="col-4">
|
||||
<NumberInput
|
||||
:model-value="argvs.offset"
|
||||
@update:model-value="(val) => updateArgvs('offset', val)"
|
||||
label="偏移量"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<NumberInput
|
||||
:model-value="argvs.length"
|
||||
@update:model-value="(val) => updateArgvs('length', val)"
|
||||
label="长度"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<q-select
|
||||
:model-value="argvs.encoding"
|
||||
@update:model-value="(val) => updateArgvs('encoding', val)"
|
||||
:options="encodings"
|
||||
label="编码"
|
||||
dense
|
||||
filled
|
||||
emit-value
|
||||
map-options
|
||||
options-dense
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 填充数据 -->
|
||||
<div v-if="argvs.operation === 'fill'" class="column q-col-gutter-sm">
|
||||
<div class="row q-col-gutter-sm">
|
||||
<VariableInput
|
||||
:model-value="argvs.buffer"
|
||||
@update:model-value="(val) => updateArgvs('buffer', val)"
|
||||
label="Buffer"
|
||||
icon="memory"
|
||||
class="col"
|
||||
/>
|
||||
<VariableInput
|
||||
:model-value="argvs.value"
|
||||
@update:model-value="(val) => updateArgvs('value', val)"
|
||||
label="填充值"
|
||||
icon="format_color_fill"
|
||||
class="col"
|
||||
/>
|
||||
</div>
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div class="col-4">
|
||||
<NumberInput
|
||||
:model-value="argvs.offset"
|
||||
@update:model-value="(val) => updateArgvs('offset', val)"
|
||||
label="起始位置"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<NumberInput
|
||||
:model-value="argvs.end"
|
||||
@update:model-value="(val) => updateArgvs('end', val)"
|
||||
label="结束位置"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<q-select
|
||||
:model-value="argvs.encoding"
|
||||
@update:model-value="(val) => updateArgvs('encoding', val)"
|
||||
:options="encodings"
|
||||
label="编码"
|
||||
dense
|
||||
filled
|
||||
emit-value
|
||||
map-options
|
||||
options-dense
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 复制数据 -->
|
||||
<div v-if="argvs.operation === 'copy'" class="column q-col-gutter-sm">
|
||||
<div class="row q-col-gutter-sm">
|
||||
<VariableInput
|
||||
:model-value="argvs.source"
|
||||
@update:model-value="(val) => updateArgvs('source', val)"
|
||||
label="源Buffer"
|
||||
icon="content_copy"
|
||||
class="col"
|
||||
/>
|
||||
<VariableInput
|
||||
:model-value="argvs.target"
|
||||
@update:model-value="(val) => updateArgvs('target', val)"
|
||||
label="目标Buffer"
|
||||
icon="save"
|
||||
class="col"
|
||||
/>
|
||||
</div>
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div class="col-4">
|
||||
<NumberInput
|
||||
:model-value="argvs.targetStart"
|
||||
@update:model-value="(val) => updateArgvs('targetStart', val)"
|
||||
label="目标起始位置"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<NumberInput
|
||||
:model-value="argvs.sourceStart"
|
||||
@update:model-value="(val) => updateArgvs('sourceStart', val)"
|
||||
label="源起始位置"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<NumberInput
|
||||
:model-value="argvs.sourceEnd"
|
||||
@update:model-value="(val) => updateArgvs('sourceEnd', val)"
|
||||
label="源结束位置"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 比较数据 -->
|
||||
<div
|
||||
v-if="argvs.operation === 'compare'"
|
||||
class="column q-col-gutter-sm"
|
||||
>
|
||||
<div class="row q-col-gutter-sm">
|
||||
<VariableInput
|
||||
:model-value="argvs.buf1"
|
||||
@update:model-value="(val) => updateArgvs('buf1', val)"
|
||||
label="Buffer 1"
|
||||
icon="memory"
|
||||
class="col"
|
||||
/>
|
||||
<VariableInput
|
||||
:model-value="argvs.buf2"
|
||||
@update:model-value="(val) => updateArgvs('buf2', val)"
|
||||
label="Buffer 2"
|
||||
icon="memory"
|
||||
class="col"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 连接 Buffer -->
|
||||
<div v-if="argvs.operation === 'concat'" class="column q-gutter-sm">
|
||||
<ArrayEditor
|
||||
:model-value="argvs.buffers"
|
||||
@update:model-value="(val) => updateArgvs('buffers', val)"
|
||||
label="Buffer"
|
||||
icon="memory"
|
||||
/>
|
||||
<NumberInput
|
||||
:model-value="argvs.totalLength"
|
||||
@update:model-value="(val) => updateArgvs('totalLength', val)"
|
||||
label="总长度(可选)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 查找数据 -->
|
||||
<div
|
||||
v-if="argvs.operation === 'indexOf'"
|
||||
class="column q-col-gutter-sm"
|
||||
>
|
||||
<div class="row q-col-gutter-sm">
|
||||
<VariableInput
|
||||
:model-value="argvs.buffer"
|
||||
@update:model-value="(val) => updateArgvs('buffer', val)"
|
||||
label="Buffer"
|
||||
icon="memory"
|
||||
class="col"
|
||||
/>
|
||||
<VariableInput
|
||||
:model-value="argvs.value"
|
||||
@update:model-value="(val) => updateArgvs('value', val)"
|
||||
label="要查找的值"
|
||||
icon="search"
|
||||
class="col"
|
||||
/>
|
||||
</div>
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div class="col-12 col-sm-6">
|
||||
<NumberInput
|
||||
:model-value="argvs.byteOffset"
|
||||
@update:model-value="(val) => updateArgvs('byteOffset', val)"
|
||||
label="起始位置"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<q-select
|
||||
:model-value="argvs.encoding"
|
||||
@update:model-value="(val) => updateArgvs('encoding', val)"
|
||||
:options="encodings"
|
||||
label="编码"
|
||||
dense
|
||||
filled
|
||||
emit-value
|
||||
map-options
|
||||
options-dense
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 切片数据 -->
|
||||
<div v-if="argvs.operation === 'slice'" class="row q-col-gutter-sm">
|
||||
<VariableInput
|
||||
:model-value="argvs.buffer"
|
||||
@update:model-value="(val) => updateArgvs('buffer', val)"
|
||||
label="Buffer"
|
||||
icon="memory"
|
||||
class="col"
|
||||
/>
|
||||
<NumberInput
|
||||
:model-value="argvs.start"
|
||||
@update:model-value="(val) => updateArgvs('start', val)"
|
||||
label="起始位置"
|
||||
class="col"
|
||||
/>
|
||||
<NumberInput
|
||||
:model-value="argvs.end"
|
||||
@update:model-value="(val) => updateArgvs('end', val)"
|
||||
label="结束位置"
|
||||
class="col"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 交换字节序 -->
|
||||
<div v-if="argvs.operation === 'swap'" class="row q-col-gutter-sm">
|
||||
<VariableInput
|
||||
:model-value="argvs.buffer"
|
||||
@update:model-value="(val) => updateArgvs('buffer', val)"
|
||||
label="Buffer"
|
||||
class="col"
|
||||
icon="memory"
|
||||
/>
|
||||
<q-select
|
||||
:model-value="argvs.size"
|
||||
@update:model-value="(val) => updateArgvs('size', val)"
|
||||
:options="swapSizes"
|
||||
label="字节大小"
|
||||
class="col-3"
|
||||
dense
|
||||
filled
|
||||
emit-value
|
||||
map-options
|
||||
options-dense
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "vue";
|
||||
import { stringifyArgv, parseFunction } from "js/composer/formatString";
|
||||
import VariableInput from "components/composer/common/VariableInput.vue";
|
||||
import NumberInput from "components/composer/common/NumberInput.vue";
|
||||
import ArrayEditor from "components/composer/common/ArrayEditor.vue";
|
||||
import OperationCard from "components/composer/common/OperationCard.vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "BufferEditor",
|
||||
components: {
|
||||
VariableInput,
|
||||
NumberInput,
|
||||
ArrayEditor,
|
||||
OperationCard,
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
emits: ["update:modelValue"],
|
||||
data() {
|
||||
return {
|
||||
operations: [
|
||||
{ value: "from", label: "创建Buffer", icon: "add_box" },
|
||||
{ value: "toString", label: "转换字符串", icon: "text_fields" },
|
||||
{ value: "write", label: "写入数据", icon: "edit" },
|
||||
{ value: "fill", label: "填充数据", icon: "format_color_fill" },
|
||||
{ value: "copy", label: "复制数据", icon: "content_copy" },
|
||||
{ value: "compare", label: "比较数据", icon: "compare" },
|
||||
{ value: "concat", label: "连接Buffer", icon: "merge" },
|
||||
{ value: "indexOf", label: "查找数据", icon: "search" },
|
||||
{ value: "slice", label: "切片数据", icon: "content_cut" },
|
||||
{ value: "swap", label: "交换字节序", icon: "swap_horiz" },
|
||||
],
|
||||
encodings: [
|
||||
{ label: "UTF-8", value: "utf8" },
|
||||
{ label: "UTF-16LE", value: "utf16le" },
|
||||
{ label: "Latin1", value: "latin1" },
|
||||
{ label: "Base64", value: "base64" },
|
||||
{ label: "Hex", value: "hex" },
|
||||
{ label: "ASCII", value: "ascii" },
|
||||
{ label: "Binary", value: "binary" },
|
||||
{ label: "UCS-2", value: "ucs2" },
|
||||
],
|
||||
swapSizes: [
|
||||
{ label: "16位", value: 16 },
|
||||
{ label: "32位", value: 32 },
|
||||
{ label: "64位", value: 64 },
|
||||
],
|
||||
defaultArgvs: {
|
||||
operation: "from",
|
||||
data: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
buffer: {
|
||||
value: "",
|
||||
isString: false,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
encoding: "utf8",
|
||||
start: 0,
|
||||
end: 0,
|
||||
string: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
offset: 0,
|
||||
length: 0,
|
||||
value: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
source: {
|
||||
value: "",
|
||||
isString: false,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
target: {
|
||||
value: "",
|
||||
isString: false,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
targetStart: 0,
|
||||
sourceStart: 0,
|
||||
sourceEnd: 0,
|
||||
buf1: {
|
||||
value: "",
|
||||
isString: false,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
buf2: {
|
||||
value: "",
|
||||
isString: false,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
buffers: [
|
||||
{
|
||||
value: "",
|
||||
isString: false,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
],
|
||||
totalLength: undefined,
|
||||
byteOffset: 0,
|
||||
size: 16,
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
argvs: {
|
||||
get() {
|
||||
return (
|
||||
this.modelValue.argvs ||
|
||||
this.parseCodeToArgvs(this.modelValue.code) || {
|
||||
...this.defaultArgvs,
|
||||
}
|
||||
);
|
||||
},
|
||||
set(value) {
|
||||
this.updateModelValue(value);
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
generateCode(argvs = this.argvs) {
|
||||
switch (argvs.operation) {
|
||||
case "from":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.data
|
||||
)}, "${argvs.encoding}")`;
|
||||
|
||||
case "toString":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.buffer
|
||||
)}, "${argvs.encoding}", ${argvs.start}, ${argvs.end})`;
|
||||
|
||||
case "write":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.buffer
|
||||
)}, ${stringifyArgv(argvs.string)}, ${argvs.offset}, ${
|
||||
argvs.length
|
||||
}, "${argvs.encoding}")`;
|
||||
|
||||
case "fill":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.buffer
|
||||
)}, ${stringifyArgv(argvs.value)}, ${argvs.offset}, ${argvs.end}, "${
|
||||
argvs.encoding
|
||||
}")`;
|
||||
|
||||
case "copy":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.source
|
||||
)}, ${stringifyArgv(argvs.target)}, ${argvs.targetStart}, ${
|
||||
argvs.sourceStart
|
||||
}, ${argvs.sourceEnd})`;
|
||||
|
||||
case "compare":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.buf1
|
||||
)}, ${stringifyArgv(argvs.buf2)})`;
|
||||
|
||||
case "concat":
|
||||
const buffersStr = argvs.buffers
|
||||
.map((buf) => stringifyArgv(buf))
|
||||
.join(", ");
|
||||
return `${this.modelValue.value}.${argvs.operation}([${buffersStr}]${
|
||||
argvs.totalLength !== undefined ? `, ${argvs.totalLength}` : ""
|
||||
})`;
|
||||
|
||||
case "indexOf":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.buffer
|
||||
)}, ${stringifyArgv(argvs.value)}, ${argvs.byteOffset}, "${
|
||||
argvs.encoding
|
||||
}")`;
|
||||
|
||||
case "slice":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.buffer
|
||||
)}, ${argvs.start}, ${argvs.end})`;
|
||||
|
||||
case "swap":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.buffer
|
||||
)}, ${argvs.size})`;
|
||||
|
||||
default:
|
||||
return `${this.modelValue.value}.${argvs.operation}()`;
|
||||
}
|
||||
},
|
||||
parseCodeToArgvs(code) {
|
||||
if (!code) return null;
|
||||
|
||||
try {
|
||||
// 定义需要使用variable格式的路径
|
||||
const variableFormatPaths = ["arg0", "arg0[*]"];
|
||||
|
||||
const subFunc = code.match(/buffer\.(\w+)\((.*)\)/);
|
||||
|
||||
switch (subFunc[1]) {
|
||||
case "write":
|
||||
case "fill":
|
||||
case "copy":
|
||||
case "compare":
|
||||
case "indexOf":
|
||||
variableFormatPaths.push("arg1");
|
||||
break;
|
||||
}
|
||||
|
||||
// 使用 parseFunction 解析代码
|
||||
const result = parseFunction(code, { variableFormatPaths });
|
||||
if (!result) return this.defaultArgvs;
|
||||
|
||||
const operation = result.name.split(".").pop();
|
||||
const args = result.argvs;
|
||||
|
||||
const newArgvs = {
|
||||
...this.defaultArgvs,
|
||||
operation,
|
||||
};
|
||||
|
||||
switch (operation) {
|
||||
case "from":
|
||||
newArgvs.data = args[0];
|
||||
newArgvs.encoding = args[1]?.value || "utf8";
|
||||
break;
|
||||
|
||||
case "toString":
|
||||
newArgvs.buffer = args[0];
|
||||
newArgvs.encoding = args[1]?.value || "utf8";
|
||||
newArgvs.start = args[2] ?? 0;
|
||||
newArgvs.end = args[3] ?? 0;
|
||||
break;
|
||||
|
||||
case "write":
|
||||
newArgvs.buffer = args[0];
|
||||
newArgvs.string = args[1];
|
||||
newArgvs.offset = args[2] ?? 0;
|
||||
newArgvs.length = args[3] ?? 0;
|
||||
newArgvs.encoding = args[4]?.value || "utf8";
|
||||
break;
|
||||
|
||||
case "fill":
|
||||
newArgvs.buffer = args[0];
|
||||
newArgvs.value = args[1];
|
||||
newArgvs.offset = args[2] ?? 0;
|
||||
newArgvs.end = args[3] ?? 0;
|
||||
newArgvs.encoding = args[4]?.value || "utf8";
|
||||
break;
|
||||
|
||||
case "copy":
|
||||
newArgvs.source = args[0];
|
||||
newArgvs.target = args[1];
|
||||
newArgvs.targetStart = args[2] ?? 0;
|
||||
newArgvs.sourceStart = args[3] ?? 0;
|
||||
newArgvs.sourceEnd = args[4] ?? 0;
|
||||
break;
|
||||
|
||||
case "compare":
|
||||
newArgvs.buf1 = args[0];
|
||||
newArgvs.buf2 = args[1];
|
||||
break;
|
||||
|
||||
case "concat":
|
||||
if (Array.isArray(args[0])) {
|
||||
newArgvs.buffers = args[0];
|
||||
}
|
||||
newArgvs.totalLength = args[1];
|
||||
break;
|
||||
|
||||
case "indexOf":
|
||||
newArgvs.buffer = args[0];
|
||||
newArgvs.value = args[1];
|
||||
newArgvs.byteOffset = args[2] ?? 0;
|
||||
newArgvs.encoding = args[3]?.value || "utf8";
|
||||
break;
|
||||
|
||||
case "slice":
|
||||
newArgvs.buffer = args[0];
|
||||
newArgvs.start = args[1] ?? 0;
|
||||
newArgvs.end = args[2] ?? 0;
|
||||
break;
|
||||
|
||||
case "swap":
|
||||
newArgvs.buffer = args[0];
|
||||
newArgvs.size = args[1] ?? 16;
|
||||
break;
|
||||
}
|
||||
|
||||
return newArgvs;
|
||||
} catch (e) {
|
||||
console.error("解析Buffer参数失败:", e);
|
||||
return this.defaultArgvs;
|
||||
}
|
||||
},
|
||||
updateArgvs(key, value) {
|
||||
this.argvs = {
|
||||
...this.argvs,
|
||||
[key]: value,
|
||||
};
|
||||
},
|
||||
getSummary(argvs) {
|
||||
const op = this.operations.find(
|
||||
(op) => op.value === argvs.operation
|
||||
)?.label;
|
||||
return op;
|
||||
},
|
||||
updateModelValue(argvs) {
|
||||
this.$emit("update:modelValue", {
|
||||
...this.modelValue,
|
||||
summary: this.getSummary(argvs),
|
||||
argvs,
|
||||
code: this.generateCode(argvs),
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (!this.modelValue.argvs && !this.modelValue.code) {
|
||||
this.updateModelValue(this.defaultArgvs);
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.buffer-editor {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.options-container {
|
||||
min-height: 32px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
@ -1,455 +0,0 @@
|
||||
<template>
|
||||
<div class="url-editor">
|
||||
<!-- 操作类型选择 -->
|
||||
<OperationCard
|
||||
:model-value="argvs.operation"
|
||||
@update:model-value="(val) => updateArgvs('operation', val)"
|
||||
:options="operations"
|
||||
/>
|
||||
|
||||
<!-- 操作配置 -->
|
||||
<div class="operation-options q-mt-sm">
|
||||
<div class="options-container">
|
||||
<!-- URL 输入 -->
|
||||
<template v-if="needsUrlInput">
|
||||
<VariableInput
|
||||
:model-value="argvs.url"
|
||||
@update:model-value="(val) => updateArgvs('url', val)"
|
||||
label="URL"
|
||||
icon="link"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- 查询字符串输入 -->
|
||||
<template
|
||||
v-if="
|
||||
argvs.operation === 'parseQuery' ||
|
||||
argvs.operation === 'formatQuery'
|
||||
"
|
||||
>
|
||||
<template v-if="argvs.operation === 'parseQuery'">
|
||||
<VariableInput
|
||||
:model-value="argvs.query"
|
||||
@update:model-value="(val) => updateArgvs('query', val)"
|
||||
label="查询字符串"
|
||||
icon="search"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<DictEditor
|
||||
:model-value="argvs.queryParams"
|
||||
@update:model-value="(val) => updateArgvs('queryParams', val)"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 参数操作的参数输入 -->
|
||||
<template
|
||||
v-if="
|
||||
['getQueryParam', 'addQueryParam', 'removeQueryParam'].includes(
|
||||
argvs.operation
|
||||
)
|
||||
"
|
||||
>
|
||||
<VariableInput
|
||||
:model-value="argvs.param"
|
||||
@update:model-value="(val) => updateArgvs('param', val)"
|
||||
label="参数名"
|
||||
icon="key"
|
||||
class="q-mt-sm"
|
||||
/>
|
||||
<template v-if="argvs.operation === 'addQueryParam'">
|
||||
<div class="q-mt-sm">
|
||||
<VariableInput
|
||||
:model-value="argvs.value"
|
||||
@update:model-value="(val) => updateArgvs('value', val)"
|
||||
label="参数值"
|
||||
icon="text_fields"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 主机名输入 -->
|
||||
<template v-if="argvs.operation === 'parseHost'">
|
||||
<VariableInput
|
||||
:model-value="argvs.host"
|
||||
@update:model-value="(val) => updateArgvs('host', val)"
|
||||
label="主机名"
|
||||
icon="dns"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- 路径输入 -->
|
||||
<template v-if="argvs.operation === 'parsePath'">
|
||||
<VariableInput
|
||||
:model-value="argvs.path"
|
||||
@update:model-value="(val) => updateArgvs('path', val)"
|
||||
label="路径"
|
||||
icon="folder"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- URL 对象输入 -->
|
||||
<template v-if="argvs.operation === 'format'">
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div class="col-12 col-sm-6">
|
||||
<VariableInput
|
||||
:model-value="argvs.urlObject.protocol"
|
||||
@update:model-value="(val) => updateUrlObject('protocol', val)"
|
||||
label="协议"
|
||||
icon="security"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<VariableInput
|
||||
:model-value="argvs.urlObject.auth"
|
||||
@update:model-value="(val) => updateUrlObject('auth', val)"
|
||||
label="认证信息"
|
||||
icon="person"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<VariableInput
|
||||
:model-value="argvs.urlObject.hostname"
|
||||
@update:model-value="(val) => updateUrlObject('hostname', val)"
|
||||
label="主机名"
|
||||
icon="dns"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<VariableInput
|
||||
:model-value="argvs.urlObject.port"
|
||||
@update:model-value="(val) => updateUrlObject('port', val)"
|
||||
label="端口"
|
||||
icon="settings_ethernet"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<VariableInput
|
||||
:model-value="argvs.urlObject.pathname"
|
||||
@update:model-value="(val) => updateUrlObject('pathname', val)"
|
||||
label="路径"
|
||||
icon="folder"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<VariableInput
|
||||
:model-value="argvs.urlObject.search"
|
||||
@update:model-value="(val) => updateUrlObject('search', val)"
|
||||
label="查询字符串"
|
||||
icon="search"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<VariableInput
|
||||
:model-value="argvs.urlObject.hash"
|
||||
@update:model-value="(val) => updateUrlObject('hash', val)"
|
||||
label="锚点"
|
||||
icon="tag"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "vue";
|
||||
import { stringifyArgv, parseFunction } from "js/composer/formatString";
|
||||
import VariableInput from "components/composer/common/VariableInput.vue";
|
||||
import DictEditor from "components/composer/common/DictEditor.vue";
|
||||
import OperationCard from "components/composer/common/OperationCard.vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "UrlEditor",
|
||||
components: {
|
||||
VariableInput,
|
||||
DictEditor,
|
||||
OperationCard,
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
emits: ["update:modelValue"],
|
||||
data() {
|
||||
return {
|
||||
operations: [
|
||||
{ value: "parse", label: "解析URL", icon: "link_off" },
|
||||
{ value: "format", label: "格式化URL", icon: "link" },
|
||||
{ value: "parseQuery", label: "解析查询字符串", icon: "search" },
|
||||
{ value: "formatQuery", label: "格式化查询字符串", icon: "edit" },
|
||||
{ value: "parsePath", label: "解析路径", icon: "folder_open" },
|
||||
{ value: "parseHost", label: "解析主机名", icon: "dns" },
|
||||
{ value: "getQueryParam", label: "获取参数", icon: "find_in_page" },
|
||||
{ value: "addQueryParam", label: "添加参数", icon: "add_circle" },
|
||||
{ value: "removeQueryParam", label: "移除参数", icon: "remove_circle" },
|
||||
{ value: "isAbsolute", label: "检查绝对URL", icon: "check_circle" },
|
||||
{ value: "parseComponents", label: "解析组成部分", icon: "category" },
|
||||
],
|
||||
defaultArgvs: {
|
||||
operation: "parse",
|
||||
url: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
query: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
queryParams: {},
|
||||
param: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
value: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
host: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
path: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
urlObject: {
|
||||
protocol: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
auth: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
hostname: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
port: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
pathname: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
search: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
hash: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
argvs: {
|
||||
get() {
|
||||
return (
|
||||
this.modelValue.argvs ||
|
||||
this.parseCodeToArgvs(this.modelValue.code) || {
|
||||
...this.defaultArgvs,
|
||||
}
|
||||
);
|
||||
},
|
||||
set(value) {
|
||||
this.updateModelValue(value);
|
||||
},
|
||||
},
|
||||
needsUrlInput() {
|
||||
return [
|
||||
"parse",
|
||||
"getQueryParam",
|
||||
"addQueryParam",
|
||||
"removeQueryParam",
|
||||
"isAbsolute",
|
||||
"parseComponents",
|
||||
].includes(this.argvs.operation);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
generateCode(argvs = this.argvs) {
|
||||
switch (argvs.operation) {
|
||||
case "parse":
|
||||
case "isAbsolute":
|
||||
case "parseComponents":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.url
|
||||
)})`;
|
||||
|
||||
case "format":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.urlObject
|
||||
)})`;
|
||||
|
||||
case "parseQuery":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.query
|
||||
)})`;
|
||||
|
||||
case "formatQuery":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.queryParams
|
||||
)})`;
|
||||
|
||||
case "parsePath":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.path
|
||||
)})`;
|
||||
|
||||
case "parseHost":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.host
|
||||
)})`;
|
||||
|
||||
case "getQueryParam":
|
||||
case "removeQueryParam":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.url
|
||||
)}, ${stringifyArgv(argvs.param)})`;
|
||||
|
||||
case "addQueryParam":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.url
|
||||
)}, ${stringifyArgv(argvs.param)}, ${stringifyArgv(argvs.value)})`;
|
||||
|
||||
default:
|
||||
return `${this.modelValue.value}.${argvs.operation}()`;
|
||||
}
|
||||
},
|
||||
parseCodeToArgvs(code) {
|
||||
if (!code) return null;
|
||||
|
||||
try {
|
||||
const variableFormatPaths = ["arg*", "arg*.**"];
|
||||
|
||||
const result = parseFunction(code, { variableFormatPaths });
|
||||
if (!result) return this.defaultArgvs;
|
||||
|
||||
const operation = result.name.split(".").pop();
|
||||
const [firstArg, secondArg, thirdArg] = result.argvs;
|
||||
|
||||
const newArgvs = {
|
||||
...this.defaultArgvs,
|
||||
operation,
|
||||
};
|
||||
|
||||
switch (operation) {
|
||||
case "parse":
|
||||
case "isAbsolute":
|
||||
case "parseComponents":
|
||||
newArgvs.url = firstArg;
|
||||
break;
|
||||
|
||||
case "format":
|
||||
newArgvs.urlObject = firstArg || this.defaultArgvs.urlObject;
|
||||
break;
|
||||
|
||||
case "parseQuery":
|
||||
newArgvs.query = firstArg;
|
||||
break;
|
||||
|
||||
case "formatQuery":
|
||||
if (firstArg) {
|
||||
newArgvs.queryParams = firstArg;
|
||||
}
|
||||
break;
|
||||
|
||||
case "parsePath":
|
||||
newArgvs.path = firstArg;
|
||||
break;
|
||||
|
||||
case "parseHost":
|
||||
newArgvs.host = firstArg;
|
||||
break;
|
||||
|
||||
case "getQueryParam":
|
||||
case "removeQueryParam":
|
||||
newArgvs.url = firstArg;
|
||||
newArgvs.param = secondArg;
|
||||
break;
|
||||
|
||||
case "addQueryParam":
|
||||
newArgvs.url = firstArg;
|
||||
newArgvs.param = secondArg;
|
||||
newArgvs.value = thirdArg;
|
||||
break;
|
||||
}
|
||||
|
||||
return newArgvs;
|
||||
} catch (e) {
|
||||
console.error("解析URL参数失败:", e);
|
||||
return this.defaultArgvs;
|
||||
}
|
||||
},
|
||||
updateArgvs(key, value) {
|
||||
this.argvs = {
|
||||
...this.argvs,
|
||||
[key]: value,
|
||||
};
|
||||
},
|
||||
updateUrlObject(key, value) {
|
||||
this.updateArgvs("urlObject", {
|
||||
...this.argvs.urlObject,
|
||||
[key]: value,
|
||||
});
|
||||
},
|
||||
getSummary(argvs) {
|
||||
const op = this.operations.find(
|
||||
(op) => op.value === argvs.operation
|
||||
)?.label;
|
||||
return op + " " + argvs.url.value;
|
||||
},
|
||||
updateModelValue(argvs) {
|
||||
this.$emit("update:modelValue", {
|
||||
...this.modelValue,
|
||||
summary: this.getSummary(argvs),
|
||||
argvs,
|
||||
code: this.generateCode(argvs),
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (!this.modelValue.argvs && !this.modelValue.code) {
|
||||
this.updateModelValue(this.defaultArgvs);
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.url-editor {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.options-container {
|
||||
min-height: 32px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
@ -1,368 +0,0 @@
|
||||
<template>
|
||||
<div class="os-editor">
|
||||
<!-- 操作类型选择 -->
|
||||
<OperationCard
|
||||
:model-value="argvs.operation"
|
||||
@update:model-value="(val) => updateArgvs('operation', val)"
|
||||
:options="operations"
|
||||
/>
|
||||
|
||||
<!-- 操作配置 -->
|
||||
<div class="operation-options q-mt-sm" v-if="hasOptions">
|
||||
<div class="bubble-pointer" :style="pointerStyle"></div>
|
||||
<!-- CPU信息配置 -->
|
||||
<div v-if="argvs.operation === 'cpus'" class="options-container">
|
||||
<div class="row items-center q-gutter-x-sm">
|
||||
<div
|
||||
v-for="opt in formatOptions"
|
||||
:key="opt.value"
|
||||
:class="['custom-btn', { active: argvs.format === opt.value }]"
|
||||
@click="updateArgvs('format', opt.value)"
|
||||
>
|
||||
{{ opt.label }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 内存信息配置 -->
|
||||
<div v-if="argvs.operation === 'memory'" class="options-container">
|
||||
<div class="row items-center q-gutter-x-sm">
|
||||
<div
|
||||
v-for="opt in memoryOptions"
|
||||
:key="opt.value"
|
||||
:class="['custom-btn', { active: argvs.type === opt.value }]"
|
||||
@click="updateArgvs('type', opt.value)"
|
||||
>
|
||||
{{ opt.label }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 网络信息配置 -->
|
||||
<div v-if="argvs.operation === 'network'" class="options-container">
|
||||
<div class="row items-center q-gutter-x-sm">
|
||||
<div
|
||||
v-for="opt in networkOptions"
|
||||
:key="opt.value"
|
||||
:class="['custom-btn', { active: argvs.type === opt.value }]"
|
||||
@click="updateArgvs('type', opt.value)"
|
||||
>
|
||||
{{ opt.label }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="q-mt-xs" v-if="argvs.type === 'networkInterfaces'">
|
||||
<q-checkbox
|
||||
:model-value="argvs.internal"
|
||||
@update:model-value="(val) => updateArgvs('internal', val)"
|
||||
label="包含内部接口"
|
||||
dense
|
||||
class="text-caption"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 平台信息配置 -->
|
||||
<div v-if="argvs.operation === 'platform'" class="options-container">
|
||||
<div class="row items-center q-gutter-x-sm wrap">
|
||||
<div
|
||||
v-for="opt in platformOptions"
|
||||
:key="opt.value"
|
||||
:class="['custom-btn', { active: argvs.type === opt.value }]"
|
||||
@click="updateArgvs('type', opt.value)"
|
||||
>
|
||||
{{ opt.label }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "vue";
|
||||
import { stringifyArgv, parseFunction } from "js/composer/formatString";
|
||||
import OperationCard from "components/composer/common/OperationCard.vue";
|
||||
export default defineComponent({
|
||||
name: "OsEditor",
|
||||
components: {
|
||||
OperationCard,
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
emits: ["update:modelValue"],
|
||||
data() {
|
||||
return {
|
||||
operations: [
|
||||
{ value: "arch", label: "系统架构", icon: "memory" },
|
||||
{ value: "cpus", label: "CPU信息", icon: "developer_board" },
|
||||
{ value: "memory", label: "内存信息", icon: "storage" },
|
||||
{ value: "network", label: "网络信息", icon: "wifi" },
|
||||
{ value: "platform", label: "平台信息", icon: "computer" },
|
||||
],
|
||||
formatOptions: [
|
||||
{ label: "完整信息", value: "full" },
|
||||
{ label: "仅型号和速度", value: "simple" },
|
||||
],
|
||||
memoryOptions: [
|
||||
{ label: "总内存", value: "totalmem" },
|
||||
{ label: "空闲内存", value: "freemem" },
|
||||
],
|
||||
networkOptions: [
|
||||
{ label: "主机名", value: "hostname" },
|
||||
{ label: "网络接口", value: "networkInterfaces" },
|
||||
],
|
||||
platformOptions: [
|
||||
{ label: "操作系统名称", value: "platform" },
|
||||
{ label: "操作系统类型", value: "type" },
|
||||
{ label: "操作系统版本", value: "release" },
|
||||
{ label: "操作系统架构", value: "arch" },
|
||||
{ label: "CPU字节序", value: "endianness" },
|
||||
{ label: "系统临时目录", value: "tmpdir" },
|
||||
{ label: "主目录", value: "homedir" },
|
||||
{ label: "系统正常运行时间", value: "uptime" },
|
||||
{ label: "用户信息", value: "userInfo" },
|
||||
],
|
||||
defaultArgvs: {
|
||||
operation: "arch",
|
||||
format: "full",
|
||||
type: "platform",
|
||||
internal: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
argvs: {
|
||||
get() {
|
||||
return (
|
||||
this.modelValue.argvs ||
|
||||
this.parseCodeToArgvs(this.modelValue.code) || {
|
||||
...this.defaultArgvs,
|
||||
}
|
||||
);
|
||||
},
|
||||
set(value) {
|
||||
// 根据操作类型重置相关参数
|
||||
const newValue = { ...value };
|
||||
if (value.operation !== this.argvs.operation) {
|
||||
switch (value.operation) {
|
||||
case "cpus":
|
||||
newValue.format = "full";
|
||||
delete newValue.type;
|
||||
delete newValue.internal;
|
||||
break;
|
||||
case "memory":
|
||||
newValue.type = "totalmem";
|
||||
delete newValue.format;
|
||||
delete newValue.internal;
|
||||
break;
|
||||
case "network":
|
||||
newValue.type = "hostname";
|
||||
delete newValue.format;
|
||||
break;
|
||||
case "platform":
|
||||
newValue.type = "platform";
|
||||
delete newValue.format;
|
||||
delete newValue.internal;
|
||||
break;
|
||||
default:
|
||||
delete newValue.format;
|
||||
delete newValue.type;
|
||||
delete newValue.internal;
|
||||
}
|
||||
}
|
||||
|
||||
this.updateModelValue(newValue);
|
||||
},
|
||||
},
|
||||
hasOptions() {
|
||||
return ["cpus", "memory", "network", "platform"].includes(
|
||||
this.argvs.operation
|
||||
);
|
||||
},
|
||||
pointerStyle() {
|
||||
const activeIndex = this.operations.findIndex(
|
||||
(op) => op.value === this.argvs.operation
|
||||
);
|
||||
if (activeIndex === -1) return {};
|
||||
|
||||
// 获取操作卡片容器的宽度
|
||||
const container = document.querySelector(".operation-cards");
|
||||
if (!container) return {};
|
||||
|
||||
const containerWidth = container.offsetWidth;
|
||||
const cardCount = this.operations.length;
|
||||
|
||||
// 计算每个卡片的位置
|
||||
const cardWidth = 100; // 卡片宽度
|
||||
const pointerWidth = 12; // 尖角宽度
|
||||
|
||||
// 计算卡片之间的间距
|
||||
const totalGapWidth = containerWidth - cardWidth * cardCount;
|
||||
const gapWidth = totalGapWidth / (cardCount - 1);
|
||||
|
||||
// 计算当前选中卡片的中心位置
|
||||
const leftOffset =
|
||||
(cardWidth + gapWidth) * activeIndex + cardWidth / 2 - pointerWidth / 2;
|
||||
|
||||
return {
|
||||
left: `${leftOffset}px`,
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
generateCode(argvs = this.argvs) {
|
||||
const params = {};
|
||||
|
||||
// 根据不同操作类型添加特定参数
|
||||
switch (argvs.operation) {
|
||||
case "cpus":
|
||||
params.format = argvs.format;
|
||||
break;
|
||||
case "memory":
|
||||
params.type = argvs.type;
|
||||
break;
|
||||
case "network":
|
||||
params.type = argvs.type;
|
||||
if (argvs.type === "networkInterfaces") {
|
||||
params.internal = argvs.internal;
|
||||
}
|
||||
break;
|
||||
case "platform":
|
||||
params.type = argvs.type;
|
||||
break;
|
||||
}
|
||||
|
||||
// 如果没有参数,直接调用函数
|
||||
if (Object.keys(params).length === 0) {
|
||||
return `${this.modelValue.value}.${argvs.operation}()`;
|
||||
}
|
||||
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
params
|
||||
)})`;
|
||||
},
|
||||
parseCodeToArgvs(code) {
|
||||
if (!code) return null;
|
||||
|
||||
try {
|
||||
// 使用 parseFunction 解析代码
|
||||
const result = parseFunction(code);
|
||||
if (!result) return this.defaultArgvs;
|
||||
|
||||
// 获取操作名称(方法名)
|
||||
const operation = result.name.split(".").pop();
|
||||
const [params = {}] = result.argvs;
|
||||
|
||||
return {
|
||||
...this.defaultArgvs,
|
||||
operation,
|
||||
...params,
|
||||
};
|
||||
} catch (e) {
|
||||
console.error("解析OS参数失败:", e);
|
||||
return this.defaultArgvs;
|
||||
}
|
||||
},
|
||||
updateArgvs(key, value) {
|
||||
this.argvs = {
|
||||
...this.argvs,
|
||||
[key]: value,
|
||||
};
|
||||
},
|
||||
getSummary(argvs) {
|
||||
return this.operations.find((op) => op.value === argvs.operation).label;
|
||||
},
|
||||
updateModelValue(argvs) {
|
||||
this.$emit("update:modelValue", {
|
||||
...this.modelValue,
|
||||
summary: this.getSummary(argvs),
|
||||
argvs,
|
||||
code: this.generateCode(argvs),
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (!this.modelValue.argvs && !this.modelValue.code) {
|
||||
this.updateModelValue(this.defaultArgvs);
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.os-editor {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.operation-options {
|
||||
position: relative;
|
||||
background: #f8f8f8;
|
||||
border-radius: 4px;
|
||||
padding: 12px;
|
||||
margin-top: 12px !important;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.options-container {
|
||||
min-height: 32px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.bubble-pointer {
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background: #f8f8f8;
|
||||
transform: rotate(45deg);
|
||||
transition: left 0.3s ease;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.body--dark .operation-options,
|
||||
.body--dark .bubble-pointer {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.custom-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 24px;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
color: var(--q-primary);
|
||||
background: transparent;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.custom-btn:hover {
|
||||
background: var(--q-primary-opacity-1);
|
||||
}
|
||||
|
||||
.custom-btn.active {
|
||||
color: white;
|
||||
background: var(--q-primary);
|
||||
}
|
||||
|
||||
/* 覆盖command-composer的样式 */
|
||||
.command-composer .operation-cards {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.command-composer .operation-card {
|
||||
width: 100px;
|
||||
}
|
||||
</style>
|
@ -1,438 +0,0 @@
|
||||
<template>
|
||||
<div class="path-editor">
|
||||
<!-- 操作类型选择 -->
|
||||
<OperationCard
|
||||
:model-value="argvs.operation"
|
||||
@update:model-value="(val) => updateArgvs('operation', val)"
|
||||
:options="operations"
|
||||
/>
|
||||
|
||||
<!-- 操作配置 -->
|
||||
<div class="operation-options q-mt-sm">
|
||||
<!-- 通用路径输入 -->
|
||||
<div class="options-container">
|
||||
<template
|
||||
v-if="
|
||||
[
|
||||
'normalize',
|
||||
'parse',
|
||||
'dirname',
|
||||
'basename',
|
||||
'extname',
|
||||
'isAbsolute',
|
||||
].includes(argvs.operation)
|
||||
"
|
||||
>
|
||||
<VariableInput
|
||||
:model-value="argvs.path"
|
||||
@update:model-value="(val) => updateArgvs('path', val)"
|
||||
label="路径"
|
||||
icon="folder"
|
||||
/>
|
||||
<!-- basename 的扩展名参数 -->
|
||||
<div v-if="argvs.operation === 'basename'" class="q-mt-sm">
|
||||
<VariableInput
|
||||
:model-value="argvs.ext"
|
||||
@update:model-value="(val) => updateArgvs('ext', val)"
|
||||
label="要移除的扩展名(可选)"
|
||||
icon="extension"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- join 和 resolve 的多路径输入 -->
|
||||
<template v-if="['join', 'resolve'].includes(argvs.operation)">
|
||||
<div
|
||||
v-for="(path, index) in argvs.paths"
|
||||
:key="index"
|
||||
class="q-mb-sm"
|
||||
>
|
||||
<div class="row items-center q-gutter-sm">
|
||||
<div class="col">
|
||||
<VariableInput
|
||||
:model-value="path"
|
||||
@update:model-value="(val) => updatePathAtIndex(index, val)"
|
||||
:label="'路径片段 ' + (index + 1)"
|
||||
icon="folder"
|
||||
/>
|
||||
</div>
|
||||
<q-btn
|
||||
v-if="index === argvs.paths.length - 1"
|
||||
flat
|
||||
round
|
||||
dense
|
||||
icon="add"
|
||||
size="sm"
|
||||
color="primary"
|
||||
@click="addPath"
|
||||
/>
|
||||
<q-btn
|
||||
v-if="argvs.paths.length > 1"
|
||||
flat
|
||||
round
|
||||
dense
|
||||
icon="remove"
|
||||
color="negative"
|
||||
size="sm"
|
||||
@click="removePath(index)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- relative 的起始和目标路径 -->
|
||||
<template v-if="argvs.operation === 'relative'">
|
||||
<VariableInput
|
||||
:model-value="argvs.from"
|
||||
@update:model-value="(val) => updateArgvs('from', val)"
|
||||
label="起始路径"
|
||||
icon="folder"
|
||||
/>
|
||||
<div class="q-mt-sm">
|
||||
<VariableInput
|
||||
:model-value="argvs.to"
|
||||
@update:model-value="(val) => updateArgvs('to', val)"
|
||||
label="目标路径"
|
||||
icon="folder"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- format 的路径对象 -->
|
||||
<template v-if="argvs.operation === 'format'">
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div class="col-12 col-sm-6">
|
||||
<VariableInput
|
||||
:model-value="argvs.pathObject.root"
|
||||
@update:model-value="(val) => updatePathObject('root', val)"
|
||||
label="根路径"
|
||||
icon="folder"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<VariableInput
|
||||
:model-value="argvs.pathObject.dir"
|
||||
@update:model-value="(val) => updatePathObject('dir', val)"
|
||||
label="目录"
|
||||
icon="folder"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<VariableInput
|
||||
:model-value="argvs.pathObject.base"
|
||||
@update:model-value="(val) => updatePathObject('base', val)"
|
||||
label="基本名称"
|
||||
icon="description"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<VariableInput
|
||||
:model-value="argvs.pathObject.name"
|
||||
@update:model-value="(val) => updatePathObject('name', val)"
|
||||
label="文件名"
|
||||
icon="insert_drive_file"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<VariableInput
|
||||
:model-value="argvs.pathObject.ext"
|
||||
@update:model-value="(val) => updatePathObject('ext', val)"
|
||||
label="扩展名"
|
||||
icon="extension"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "vue";
|
||||
import { stringifyArgv, parseFunction } from "js/composer/formatString";
|
||||
import VariableInput from "components/composer/common/VariableInput.vue";
|
||||
import OperationCard from "components/composer/common/OperationCard.vue";
|
||||
export default defineComponent({
|
||||
name: "PathEditor",
|
||||
components: {
|
||||
VariableInput,
|
||||
OperationCard,
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
emits: ["update:modelValue"],
|
||||
data() {
|
||||
return {
|
||||
operations: [
|
||||
{ value: "normalize", label: "规范化路径", icon: "straighten" },
|
||||
{ value: "join", label: "连接路径", icon: "add_link" },
|
||||
{ value: "parse", label: "解析路径", icon: "account_tree" },
|
||||
{ value: "dirname", label: "获取目录名", icon: "folder" },
|
||||
{ value: "basename", label: "获取文件名", icon: "description" },
|
||||
{ value: "extname", label: "获取扩展名", icon: "extension" },
|
||||
{ value: "isAbsolute", label: "判断绝对路径", icon: "check_circle" },
|
||||
{ value: "relative", label: "计算相对路径", icon: "compare_arrows" },
|
||||
{ value: "resolve", label: "解析绝对路径", icon: "assistant_direction" },
|
||||
{ value: "format", label: "格式化路径", icon: "format_shapes" },
|
||||
],
|
||||
defaultArgvs: {
|
||||
operation: "normalize",
|
||||
path: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
paths: [
|
||||
{
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
],
|
||||
from: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
to: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
ext: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
pathObject: {
|
||||
root: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
dir: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
base: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
name: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
ext: {
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
argvs: {
|
||||
get() {
|
||||
return (
|
||||
this.modelValue.argvs ||
|
||||
this.parseCodeToArgvs(this.modelValue.code) || {
|
||||
...this.defaultArgvs,
|
||||
}
|
||||
);
|
||||
},
|
||||
set(value) {
|
||||
this.updateModelValue(value);
|
||||
},
|
||||
},
|
||||
pointerStyle() {
|
||||
const activeIndex = this.operations.findIndex(
|
||||
(op) => op.value === this.argvs.operation
|
||||
);
|
||||
if (activeIndex === -1) return {};
|
||||
|
||||
const cardWidth = 80;
|
||||
const gap = 4;
|
||||
const pointerWidth = 12;
|
||||
const leftOffset =
|
||||
(cardWidth + gap) * activeIndex + cardWidth / 2 - pointerWidth / 2;
|
||||
|
||||
return {
|
||||
left: `${leftOffset}px`,
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
generateCode(argvs = this.argvs) {
|
||||
switch (argvs.operation) {
|
||||
case "normalize":
|
||||
case "parse":
|
||||
case "dirname":
|
||||
case "extname":
|
||||
case "isAbsolute":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.path
|
||||
)})`;
|
||||
|
||||
case "basename":
|
||||
if (argvs.ext && argvs.ext.value) {
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.path
|
||||
)}, ${stringifyArgv(argvs.ext)})`;
|
||||
}
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.path
|
||||
)})`;
|
||||
|
||||
case "join":
|
||||
case "resolve":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${argvs.paths
|
||||
.map((p) => stringifyArgv(p))
|
||||
.join(", ")})`;
|
||||
|
||||
case "relative":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.from
|
||||
)}, ${stringifyArgv(argvs.to)})`;
|
||||
|
||||
case "format":
|
||||
return `${this.modelValue.value}.${argvs.operation}(${stringifyArgv(
|
||||
argvs.pathObject
|
||||
)})`;
|
||||
|
||||
default:
|
||||
return `${this.modelValue.value}.${argvs.operation}()`;
|
||||
}
|
||||
},
|
||||
parseCodeToArgvs(code) {
|
||||
if (!code) return null;
|
||||
|
||||
try {
|
||||
// 定义需要使用variable格式的路径
|
||||
const variableFormatPaths = [
|
||||
"arg*", // 所有参数
|
||||
"arg*.**", // 所有参数的所有嵌套属性
|
||||
];
|
||||
|
||||
// 使用 parseFunction 解析代码
|
||||
const result = parseFunction(code, { variableFormatPaths });
|
||||
if (!result) return this.defaultArgvs;
|
||||
|
||||
const operation = result.name.split(".").pop();
|
||||
const [firstArg, secondArg] = result.argvs;
|
||||
|
||||
const newArgvs = {
|
||||
...this.defaultArgvs,
|
||||
operation,
|
||||
};
|
||||
|
||||
switch (operation) {
|
||||
case "normalize":
|
||||
case "parse":
|
||||
case "dirname":
|
||||
case "extname":
|
||||
case "isAbsolute":
|
||||
newArgvs.path = firstArg;
|
||||
break;
|
||||
|
||||
case "basename":
|
||||
newArgvs.path = firstArg;
|
||||
if (secondArg) {
|
||||
newArgvs.ext = secondArg;
|
||||
}
|
||||
break;
|
||||
|
||||
case "join":
|
||||
case "resolve":
|
||||
newArgvs.paths = result.argvs.map((arg) => arg);
|
||||
break;
|
||||
|
||||
case "relative":
|
||||
newArgvs.from = firstArg;
|
||||
newArgvs.to = secondArg;
|
||||
break;
|
||||
|
||||
case "format":
|
||||
newArgvs.pathObject = firstArg;
|
||||
break;
|
||||
}
|
||||
|
||||
return newArgvs;
|
||||
} catch (e) {
|
||||
console.error("解析Path参数失败:", e);
|
||||
return this.defaultArgvs;
|
||||
}
|
||||
},
|
||||
updateArgvs(key, value) {
|
||||
this.argvs = {
|
||||
...this.argvs,
|
||||
[key]: value,
|
||||
};
|
||||
},
|
||||
updatePathAtIndex(index, value) {
|
||||
const newPaths = [...this.argvs.paths];
|
||||
newPaths[index] = value;
|
||||
this.updateArgvs("paths", newPaths);
|
||||
},
|
||||
updatePathObject(key, value) {
|
||||
this.updateArgvs("pathObject", {
|
||||
...this.argvs.pathObject,
|
||||
[key]: value,
|
||||
});
|
||||
},
|
||||
addPath() {
|
||||
this.updateArgvs("paths", [
|
||||
...this.argvs.paths,
|
||||
{
|
||||
value: "",
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
]);
|
||||
},
|
||||
removePath(index) {
|
||||
const newPaths = [...this.argvs.paths];
|
||||
newPaths.splice(index, 1);
|
||||
this.updateArgvs("paths", newPaths);
|
||||
},
|
||||
getSummary(argvs) {
|
||||
return this.operations.find((op) => op.value === argvs.operation)?.label;
|
||||
},
|
||||
updateModelValue(argvs) {
|
||||
this.$emit("update:modelValue", {
|
||||
...this.modelValue,
|
||||
summary: this.getSummary(argvs),
|
||||
argvs,
|
||||
code: this.generateCode(argvs),
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (!this.modelValue.argvs && !this.modelValue.code) {
|
||||
this.updateModelValue(this.defaultArgvs);
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.path-editor {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.options-container {
|
||||
min-height: 32px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
@ -60,19 +60,7 @@ export const SystemCommandEditor = defineAsyncComponent(() =>
|
||||
import("components/composer/system/SystemCommandEditor.vue")
|
||||
);
|
||||
|
||||
export const OsEditor = defineAsyncComponent(() =>
|
||||
import("components/composer/system/OsEditor.vue")
|
||||
);
|
||||
|
||||
export const PathEditor = defineAsyncComponent(() =>
|
||||
import("components/composer/system/PathEditor.vue")
|
||||
);
|
||||
export const ZlibEditor = defineAsyncComponent(() =>
|
||||
import("src/components/composer/data/ZlibEditor.vue")
|
||||
);
|
||||
export const UrlEditor = defineAsyncComponent(() =>
|
||||
import("components/composer/network/UrlEditor.vue")
|
||||
);
|
||||
export const BufferEditor = defineAsyncComponent(() =>
|
||||
import("src/components/composer/data/BufferEditor.vue")
|
||||
);
|
||||
|
@ -312,11 +312,355 @@ export const dataCommands = {
|
||||
saveOutput: true,
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.data.buffer",
|
||||
value: "quickcomposer.data.buffer.from",
|
||||
label: "Buffer操作",
|
||||
desc: "Buffer创建、转换和操作",
|
||||
component: "BufferEditor",
|
||||
config: [],
|
||||
icon: "memory",
|
||||
functionSelector: [
|
||||
{
|
||||
value: "quickcomposer.data.buffer.from",
|
||||
label: "创建Buffer",
|
||||
icon: "add_box",
|
||||
config: [
|
||||
{
|
||||
label: "数据",
|
||||
type: "varInput",
|
||||
icon: "text_fields",
|
||||
width: 9,
|
||||
},
|
||||
{
|
||||
label: "编码",
|
||||
type: "select",
|
||||
icon: "code",
|
||||
options: [
|
||||
{ label: "UTF-8", value: "utf8" },
|
||||
{ label: "UTF-16LE", value: "utf16le" },
|
||||
{ label: "Latin1", value: "latin1" },
|
||||
{ label: "Base64", value: "base64" },
|
||||
{ label: "Hex", value: "hex" },
|
||||
{ label: "ASCII", value: "ascii" },
|
||||
{ label: "Binary", value: "binary" },
|
||||
{ label: "UCS-2", value: "ucs2" },
|
||||
],
|
||||
defaultValue: "utf8",
|
||||
width: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.data.buffer.toString",
|
||||
label: "转换字符串",
|
||||
icon: "text_fields",
|
||||
config: [
|
||||
{
|
||||
label: "Buffer",
|
||||
type: "varInput",
|
||||
icon: "memory",
|
||||
width: 12,
|
||||
},
|
||||
{
|
||||
label: "编码",
|
||||
type: "select",
|
||||
icon: "code",
|
||||
options: [
|
||||
{ label: "UTF-8", value: "utf8" },
|
||||
{ label: "UTF-16LE", value: "utf16le" },
|
||||
{ label: "Latin1", value: "latin1" },
|
||||
{ label: "Base64", value: "base64" },
|
||||
{ label: "Hex", value: "hex" },
|
||||
{ label: "ASCII", value: "ascii" },
|
||||
{ label: "Binary", value: "binary" },
|
||||
{ label: "UCS-2", value: "ucs2" },
|
||||
],
|
||||
defaultValue: "utf8",
|
||||
width: 4,
|
||||
},
|
||||
{
|
||||
label: "起始位置",
|
||||
type: "numInput",
|
||||
icon: "first_page",
|
||||
width: 4,
|
||||
},
|
||||
{
|
||||
label: "结束位置",
|
||||
type: "numInput",
|
||||
icon: "last_page",
|
||||
width: 4,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.data.buffer.write",
|
||||
label: "写入数据",
|
||||
icon: "edit",
|
||||
config: [
|
||||
{
|
||||
label: "Buffer",
|
||||
type: "varInput",
|
||||
icon: "memory",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "要写入的字符串",
|
||||
type: "varInput",
|
||||
icon: "edit",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "偏移量",
|
||||
type: "numInput",
|
||||
icon: "first_page",
|
||||
width: 4,
|
||||
},
|
||||
{
|
||||
label: "长度",
|
||||
type: "numInput",
|
||||
icon: "straighten",
|
||||
width: 4,
|
||||
},
|
||||
{
|
||||
label: "编码",
|
||||
type: "select",
|
||||
icon: "code",
|
||||
options: [
|
||||
{ label: "UTF-8", value: "utf8" },
|
||||
{ label: "UTF-16LE", value: "utf16le" },
|
||||
{ label: "Latin1", value: "latin1" },
|
||||
{ label: "Base64", value: "base64" },
|
||||
{ label: "Hex", value: "hex" },
|
||||
{ label: "ASCII", value: "ascii" },
|
||||
{ label: "Binary", value: "binary" },
|
||||
{ label: "UCS-2", value: "ucs2" },
|
||||
],
|
||||
defaultValue: "utf8",
|
||||
width: 4,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.data.buffer.fill",
|
||||
label: "填充数据",
|
||||
icon: "format_color_fill",
|
||||
config: [
|
||||
{
|
||||
label: "Buffer",
|
||||
type: "varInput",
|
||||
icon: "memory",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "填充值",
|
||||
type: "varInput",
|
||||
icon: "format_color_fill",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "起始位置",
|
||||
type: "numInput",
|
||||
icon: "first_page",
|
||||
width: 4,
|
||||
},
|
||||
{
|
||||
label: "结束位置",
|
||||
type: "numInput",
|
||||
icon: "last_page",
|
||||
width: 4,
|
||||
},
|
||||
{
|
||||
label: "编码",
|
||||
type: "select",
|
||||
icon: "code",
|
||||
options: [
|
||||
{ label: "UTF-8", value: "utf8" },
|
||||
{ label: "UTF-16LE", value: "utf16le" },
|
||||
{ label: "Latin1", value: "latin1" },
|
||||
{ label: "Base64", value: "base64" },
|
||||
{ label: "Hex", value: "hex" },
|
||||
{ label: "ASCII", value: "ascii" },
|
||||
{ label: "Binary", value: "binary" },
|
||||
{ label: "UCS-2", value: "ucs2" },
|
||||
],
|
||||
defaultValue: "utf8",
|
||||
width: 4,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.data.buffer.copy",
|
||||
label: "复制数据",
|
||||
icon: "content_copy",
|
||||
config: [
|
||||
{
|
||||
label: "源Buffer",
|
||||
type: "varInput",
|
||||
icon: "content_copy",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "目标Buffer",
|
||||
type: "varInput",
|
||||
icon: "save",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "目标起始位置",
|
||||
type: "numInput",
|
||||
icon: "first_page",
|
||||
width: 4,
|
||||
},
|
||||
{
|
||||
label: "源起始位置",
|
||||
type: "numInput",
|
||||
icon: "first_page",
|
||||
width: 4,
|
||||
},
|
||||
{
|
||||
label: "源结束位置",
|
||||
type: "numInput",
|
||||
icon: "last_page",
|
||||
width: 4,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.data.buffer.compare",
|
||||
label: "比较数据",
|
||||
icon: "compare",
|
||||
config: [
|
||||
{
|
||||
label: "Buffer 1",
|
||||
type: "varInput",
|
||||
icon: "memory",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "Buffer 2",
|
||||
type: "varInput",
|
||||
icon: "memory",
|
||||
width: 6,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.data.buffer.concat",
|
||||
label: "连接Buffer",
|
||||
icon: "merge",
|
||||
config: [
|
||||
{
|
||||
label: "Buffer列表",
|
||||
type: "arrayEditor",
|
||||
icon: "memory",
|
||||
width: 12,
|
||||
defaultValue: [
|
||||
{
|
||||
value: "",
|
||||
isString: false,
|
||||
__varInputVal__: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "总长度(可选)",
|
||||
type: "numInput",
|
||||
icon: "straighten",
|
||||
width: 12,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.data.buffer.slice",
|
||||
label: "切片数据",
|
||||
icon: "content_cut",
|
||||
config: [
|
||||
{
|
||||
label: "Buffer",
|
||||
type: "varInput",
|
||||
icon: "memory",
|
||||
width: 12,
|
||||
},
|
||||
{
|
||||
label: "起始位置",
|
||||
type: "numInput",
|
||||
icon: "first_page",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "结束位置",
|
||||
type: "numInput",
|
||||
icon: "last_page",
|
||||
width: 6,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.data.buffer.indexOf",
|
||||
label: "查找数据",
|
||||
icon: "search",
|
||||
config: [
|
||||
{
|
||||
label: "Buffer",
|
||||
type: "varInput",
|
||||
icon: "memory",
|
||||
width: 12,
|
||||
},
|
||||
{
|
||||
label: "要查找的值",
|
||||
type: "varInput",
|
||||
icon: "search",
|
||||
width: 4,
|
||||
},
|
||||
{
|
||||
label: "起始位置",
|
||||
type: "numInput",
|
||||
icon: "first_page",
|
||||
width: 4,
|
||||
},
|
||||
{
|
||||
label: "编码",
|
||||
type: "select",
|
||||
icon: "code",
|
||||
options: [
|
||||
{ label: "UTF-8", value: "utf8" },
|
||||
{ label: "UTF-16LE", value: "utf16le" },
|
||||
{ label: "Latin1", value: "latin1" },
|
||||
{ label: "Base64", value: "base64" },
|
||||
{ label: "Hex", value: "hex" },
|
||||
{ label: "ASCII", value: "ascii" },
|
||||
{ label: "Binary", value: "binary" },
|
||||
{ label: "UCS-2", value: "ucs2" },
|
||||
],
|
||||
defaultValue: "utf8",
|
||||
width: 4,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.data.buffer.swap",
|
||||
label: "交换字节序",
|
||||
icon: "swap_horiz",
|
||||
config: [
|
||||
{
|
||||
label: "Buffer",
|
||||
type: "varInput",
|
||||
icon: "memory",
|
||||
width: 9,
|
||||
},
|
||||
{
|
||||
label: "字节大小",
|
||||
type: "select",
|
||||
icon: "memory",
|
||||
options: [
|
||||
{ label: "16位", value: 16 },
|
||||
{ label: "32位", value: 32 },
|
||||
{ label: "64位", value: 64 },
|
||||
],
|
||||
defaultValue: 16,
|
||||
width: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.data.zlib",
|
||||
|
@ -47,11 +47,181 @@ export const networkCommands = {
|
||||
saveOutput: true,
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.network.url",
|
||||
value: "quickcomposer.network.url.parse",
|
||||
label: "URL操作",
|
||||
desc: "URL解析、格式化和参数处理",
|
||||
component: "UrlEditor",
|
||||
icon: "link",
|
||||
config: [
|
||||
{
|
||||
label: "URL",
|
||||
type: "varInput",
|
||||
icon: "link",
|
||||
width: "auto",
|
||||
},
|
||||
],
|
||||
functionSelector: [
|
||||
{
|
||||
value: "quickcomposer.network.url.parse",
|
||||
label: "解析URL",
|
||||
icon: "link_off",
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.network.url.format",
|
||||
label: "格式化URL",
|
||||
icon: "link",
|
||||
excludeConfig: [0],
|
||||
config: [
|
||||
{
|
||||
label: "协议",
|
||||
type: "varInput",
|
||||
icon: "security",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "认证信息",
|
||||
type: "varInput",
|
||||
icon: "person",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "主机名",
|
||||
type: "varInput",
|
||||
icon: "dns",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "端口",
|
||||
type: "varInput",
|
||||
icon: "settings_ethernet",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "路径",
|
||||
type: "varInput",
|
||||
icon: "folder",
|
||||
},
|
||||
{
|
||||
label: "查询字符串",
|
||||
type: "varInput",
|
||||
icon: "search",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "锚点",
|
||||
type: "varInput",
|
||||
icon: "tag",
|
||||
width: 6,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.network.url.parseQuery",
|
||||
label: "解析查询字符串",
|
||||
icon: "search",
|
||||
excludeConfig: [0],
|
||||
config: [
|
||||
{
|
||||
label: "查询字符串",
|
||||
type: "varInput",
|
||||
icon: "search",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.network.url.formatQuery",
|
||||
label: "格式化查询字符串",
|
||||
icon: "edit",
|
||||
excludeConfig: [0],
|
||||
config: [
|
||||
{
|
||||
label: "参数",
|
||||
type: "dictEditor",
|
||||
icon: "edit",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.network.url.parsePath",
|
||||
label: "解析路径",
|
||||
icon: "folder_open",
|
||||
excludeConfig: [0],
|
||||
config: [
|
||||
{
|
||||
label: "路径",
|
||||
type: "varInput",
|
||||
icon: "folder",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.network.url.parseHost",
|
||||
label: "解析主机名",
|
||||
icon: "dns",
|
||||
excludeConfig: [0],
|
||||
config: [
|
||||
{
|
||||
label: "主机名",
|
||||
type: "varInput",
|
||||
icon: "dns",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.network.url.getQueryParam",
|
||||
label: "获取参数",
|
||||
icon: "find_in_page",
|
||||
config: [
|
||||
{
|
||||
label: "参数名",
|
||||
type: "varInput",
|
||||
icon: "key",
|
||||
width: "auto",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.network.url.addQueryParam",
|
||||
label: "添加参数",
|
||||
icon: "add_circle",
|
||||
config: [
|
||||
{
|
||||
label: "参数名",
|
||||
type: "varInput",
|
||||
icon: "key",
|
||||
width: "auto",
|
||||
},
|
||||
{
|
||||
label: "参数值",
|
||||
type: "varInput",
|
||||
icon: "text_fields",
|
||||
width: "auto",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.network.url.removeQueryParam",
|
||||
label: "移除参数",
|
||||
icon: "remove_circle",
|
||||
config: [
|
||||
{
|
||||
label: "参数名",
|
||||
type: "varInput",
|
||||
icon: "key",
|
||||
width: "auto",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.network.url.isAbsolute",
|
||||
label: "检查绝对URL",
|
||||
icon: "check_circle",
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.network.url.parseComponents",
|
||||
label: "解析组成部分",
|
||||
icon: "category",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.network.dns.lookupHost",
|
||||
|
@ -32,20 +32,252 @@ export const systemCommands = {
|
||||
isAsync: true,
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.system.os",
|
||||
value: "quickcomposer.system.os.arch",
|
||||
label: "系统信息",
|
||||
desc: "获取操作系统相关信息",
|
||||
component: "OsEditor",
|
||||
icon: "computer",
|
||||
isAsync: true,
|
||||
config: [],
|
||||
functionSelector: [
|
||||
{
|
||||
value: "quickcomposer.system.os.arch",
|
||||
label: "系统架构",
|
||||
icon: "memory",
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.system.path",
|
||||
value: "quickcomposer.system.os.cpus",
|
||||
label: "CPU信息",
|
||||
icon: "developer_board",
|
||||
config: [
|
||||
{
|
||||
label: "信息格式",
|
||||
type: "buttonGroup",
|
||||
options: [
|
||||
{ label: "完整信息", value: "full" },
|
||||
{ label: "仅型号和速度", value: "simple" },
|
||||
],
|
||||
defaultValue: "full",
|
||||
width: 12,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.system.os.memory",
|
||||
label: "内存信息",
|
||||
icon: "storage",
|
||||
config: [
|
||||
{
|
||||
label: "内存类型",
|
||||
type: "buttonGroup",
|
||||
options: [
|
||||
{ label: "总内存", value: "totalmem" },
|
||||
{ label: "空闲内存", value: "freemem" },
|
||||
],
|
||||
defaultValue: "totalmem",
|
||||
width: 12,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.system.os.network",
|
||||
label: "网络信息",
|
||||
icon: "wifi",
|
||||
config: [
|
||||
{
|
||||
label: "网络信息类型",
|
||||
type: "buttonGroup",
|
||||
options: [
|
||||
{ label: "主机名", value: "hostname" },
|
||||
{ label: "网络接口", value: "networkInterfaces" },
|
||||
],
|
||||
defaultValue: "hostname",
|
||||
width: 12,
|
||||
},
|
||||
{
|
||||
label: "包含内部接口",
|
||||
type: "checkbox",
|
||||
defaultValue: false,
|
||||
width: 12,
|
||||
condition: "values[0] === 'networkInterfaces'",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.system.os.platform",
|
||||
label: "平台信息",
|
||||
icon: "computer",
|
||||
config: [
|
||||
{
|
||||
label: "平台信息类型",
|
||||
type: "buttonGroup",
|
||||
options: [
|
||||
{ label: "操作系统名称", value: "platform" },
|
||||
{ label: "操作系统类型", value: "type" },
|
||||
{ label: "操作系统版本", value: "release" },
|
||||
{ label: "操作系统架构", value: "arch" },
|
||||
{ label: "CPU字节序", value: "endianness" },
|
||||
{ label: "系统临时目录", value: "tmpdir" },
|
||||
{ label: "主目录", value: "homedir" },
|
||||
{ label: "系统正常运行时间", value: "uptime" },
|
||||
{ label: "用户信息", value: "userInfo" },
|
||||
],
|
||||
defaultValue: "platform",
|
||||
width: 12,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.system.path.normalize",
|
||||
label: "路径操作",
|
||||
desc: "路径操作",
|
||||
component: "PathEditor",
|
||||
icon: "folder_path",
|
||||
isAsync: true,
|
||||
desc: "路径解析和处理",
|
||||
icon: "folder",
|
||||
config: [
|
||||
{
|
||||
label: "路径",
|
||||
type: "varInput",
|
||||
icon: "folder",
|
||||
width: "auto",
|
||||
},
|
||||
],
|
||||
functionSelector: [
|
||||
{
|
||||
value: "quickcomposer.system.path.normalize",
|
||||
label: "规范化路径",
|
||||
icon: "straighten",
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.system.path.parse",
|
||||
label: "解析路径",
|
||||
icon: "account_tree",
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.system.path.dirname",
|
||||
label: "获取目录名",
|
||||
icon: "folder",
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.system.path.basename",
|
||||
label: "获取文件名",
|
||||
icon: "description",
|
||||
config: [
|
||||
{
|
||||
label: "要移除的扩展名",
|
||||
type: "varInput",
|
||||
icon: "extension",
|
||||
width: "auto",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.system.path.extname",
|
||||
label: "获取扩展名",
|
||||
icon: "extension",
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.system.path.isAbsolute",
|
||||
label: "判断绝对路径",
|
||||
icon: "check_circle",
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.system.path.join",
|
||||
label: "连接路径",
|
||||
icon: "add_link",
|
||||
excludeConfig: [0],
|
||||
config: [
|
||||
{
|
||||
label: "路径片段",
|
||||
type: "varInput",
|
||||
icon: "folder",
|
||||
width: "auto",
|
||||
},
|
||||
{
|
||||
label: "路径片段",
|
||||
type: "varInput",
|
||||
icon: "folder",
|
||||
width: "auto",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.system.path.resolve",
|
||||
label: "解析绝对路径",
|
||||
icon: "assistant_direction",
|
||||
excludeConfig: [0],
|
||||
config: [
|
||||
{
|
||||
label: "路径片段",
|
||||
type: "varInput",
|
||||
icon: "folder",
|
||||
width: "auto",
|
||||
},
|
||||
{
|
||||
label: "路径片段",
|
||||
type: "varInput",
|
||||
icon: "folder",
|
||||
width: "auto",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.system.path.relative",
|
||||
label: "计算相对路径",
|
||||
icon: "compare_arrows",
|
||||
excludeConfig: [0],
|
||||
config: [
|
||||
{
|
||||
label: "起始路径",
|
||||
type: "varInput",
|
||||
icon: "folder",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "目标路径",
|
||||
type: "varInput",
|
||||
icon: "folder",
|
||||
width: 6,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.system.path.format",
|
||||
label: "格式化路径",
|
||||
icon: "format_shapes",
|
||||
excludeConfig: [0],
|
||||
config: [
|
||||
{
|
||||
label: "根路径",
|
||||
type: "varInput",
|
||||
icon: "folder",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "目录",
|
||||
type: "varInput",
|
||||
icon: "folder",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "基本名称",
|
||||
type: "varInput",
|
||||
icon: "description",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "文件名",
|
||||
type: "varInput",
|
||||
icon: "insert_drive_file",
|
||||
width: 6,
|
||||
},
|
||||
{
|
||||
label: "扩展名",
|
||||
type: "varInput",
|
||||
icon: "extension",
|
||||
width: 6,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user