chore: sync current WechatHookBot workspace
This commit is contained in:
84
utils/webui_static/components/ConfigSection.js
Normal file
84
utils/webui_static/components/ConfigSection.js
Normal file
@@ -0,0 +1,84 @@
|
||||
window.ConfigSection = {
|
||||
props: {
|
||||
section: String,
|
||||
label: String,
|
||||
fields: Object,
|
||||
modelValue: Object,
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
setup(props, { emit }) {
|
||||
const { computed } = Vue;
|
||||
|
||||
const flatFields = computed(() => {
|
||||
const result = [];
|
||||
for (const [key, val] of Object.entries(props.fields)) {
|
||||
if (typeof val === 'object' && !Array.isArray(val)) continue;
|
||||
result.push({ key, val });
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
function updateField(key, newVal) {
|
||||
props.modelValue[key] = newVal;
|
||||
}
|
||||
|
||||
function fieldType(val) {
|
||||
if (typeof val === 'boolean') return 'boolean';
|
||||
if (typeof val === 'number') return 'number';
|
||||
if (Array.isArray(val)) return 'array';
|
||||
return 'string';
|
||||
}
|
||||
|
||||
function removeTag(key, index) {
|
||||
props.modelValue[key].splice(index, 1);
|
||||
}
|
||||
|
||||
function addTag(key, val) {
|
||||
if (!val || !val.trim()) return;
|
||||
if (!Array.isArray(props.modelValue[key])) props.modelValue[key] = [];
|
||||
props.modelValue[key].push(val.trim());
|
||||
}
|
||||
|
||||
return { flatFields, updateField, fieldType, removeTag, addTag };
|
||||
},
|
||||
template: `
|
||||
<el-card shadow="never" class="config-card">
|
||||
<template #header>
|
||||
<div class="config-card-header">
|
||||
<span class="config-card-title">{{ label }}</span>
|
||||
<span class="config-card-section">[{{ section }}]</span>
|
||||
</div>
|
||||
</template>
|
||||
<div v-for="item in flatFields" :key="item.key"
|
||||
class="config-row">
|
||||
<div class="config-key">
|
||||
{{ item.key }}
|
||||
</div>
|
||||
<div class="config-val">
|
||||
<el-switch v-if="fieldType(item.val) === 'boolean'"
|
||||
:model-value="modelValue[item.key]"
|
||||
@update:model-value="updateField(item.key, $event)"
|
||||
active-text="开" inactive-text="关" />
|
||||
<el-input-number v-else-if="fieldType(item.val) === 'number'"
|
||||
:model-value="modelValue[item.key]"
|
||||
@update:model-value="updateField(item.key, $event)"
|
||||
:step="Number.isInteger(item.val) ? 1 : 0.1"
|
||||
controls-position="right" style="width: 200px" />
|
||||
<div v-else-if="fieldType(item.val) === 'array'" class="config-tags">
|
||||
<el-tag v-for="(tag, ti) in modelValue[item.key]" :key="ti"
|
||||
closable @close="removeTag(item.key, ti)"
|
||||
style="margin-bottom:2px">
|
||||
{{ tag }}
|
||||
</el-tag>
|
||||
<el-input size="small" style="width:140px"
|
||||
placeholder="回车添加"
|
||||
@keyup.enter="addTag(item.key, $event.target.value); $event.target.value=''" />
|
||||
</div>
|
||||
<el-input v-else
|
||||
:model-value="String(modelValue[item.key] ?? '')"
|
||||
@update:model-value="updateField(item.key, $event)" />
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
`
|
||||
};
|
||||
Reference in New Issue
Block a user