mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-28 22:43:51 +08:00
对通用dict类型的字段进行处理
This commit is contained in:
@@ -66,13 +66,12 @@
|
|||||||
<div :key="rowIndex" style="display: flex; gap: 20px; margin-bottom: 0;">
|
<div :key="rowIndex" style="display: flex; gap: 20px; margin-bottom: 0;">
|
||||||
<el-form-item v-for="field in row" :key="field.prop" :label="field.label" :prop="field.prop"
|
<el-form-item v-for="field in row" :key="field.prop" :label="field.label" :prop="field.prop"
|
||||||
style="flex: 1;">
|
style="flex: 1;">
|
||||||
<el-input v-if="field.type !== 'json-textarea'" v-model="form.configJson[field.prop]" :placeholder="field.placeholder"
|
<template v-if="field.type === 'json-textarea'">
|
||||||
:type="field.type" class="custom-input-bg" :show-password="field.type === 'password'">
|
<el-input v-model="fieldJsonMap[field.prop]" type="textarea" :rows="3" placeholder="请输入JSON格式变量(示例:{'key':'value'})"
|
||||||
</el-input>
|
class="custom-input-bg" @change="(val) => handleJsonChange(field.prop, val)"></el-input>
|
||||||
|
</template>
|
||||||
<el-input v-else v-model="variablesJson" type="textarea" :rows="3" placeholder="请输入JSON格式变量(示例:{'key':'value'})"
|
<el-input v-else v-model="form.configJson[field.prop]" :placeholder="field.placeholder" :type="field.type"
|
||||||
class="custom-input-bg" @change="handleVariablesChange">
|
class="custom-input-bg" :show-password="field.type === 'password'"></el-input>
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -116,7 +115,7 @@ export default {
|
|||||||
pendingProviderType: null,
|
pendingProviderType: null,
|
||||||
pendingModelData: null,
|
pendingModelData: null,
|
||||||
dynamicCallInfoFields: [],
|
dynamicCallInfoFields: [],
|
||||||
variablesJson: '',
|
fieldJsonMap: {}, // 用于存储JSON字段的字符串形式
|
||||||
form: {
|
form: {
|
||||||
id: "",
|
id: "",
|
||||||
modelType: "",
|
modelType: "",
|
||||||
@@ -178,12 +177,9 @@ export default {
|
|||||||
docLink: "",
|
docLink: "",
|
||||||
remark: "",
|
remark: "",
|
||||||
sort: 0,
|
sort: 0,
|
||||||
configJson: {},
|
configJson: {}
|
||||||
variablesJson: {},
|
|
||||||
};
|
};
|
||||||
this.dynamicCallInfoFields.forEach(field => {
|
this.fieldJsonMap = {};
|
||||||
this.$set(this.form.configJson, field.prop, '');
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
resetProviders() {
|
resetProviders() {
|
||||||
this.providers = [];
|
this.providers = [];
|
||||||
@@ -209,17 +205,14 @@ export default {
|
|||||||
handleSave() {
|
handleSave() {
|
||||||
this.saving = true; // 开始保存加载
|
this.saving = true; // 开始保存加载
|
||||||
|
|
||||||
// 确保 variables 是字典
|
// 处理所有JSON字段
|
||||||
if (typeof this.form.configJson.variables === 'string') {
|
Object.keys(this.fieldJsonMap).forEach(key => {
|
||||||
const parsed = this.validateVariablesJson(this.form.configJson.variables);
|
const parsed = this.validateJson(this.fieldJsonMap[key]);
|
||||||
if (parsed === null) {
|
if (parsed !== null) {
|
||||||
this.saving = false;
|
this.form.configJson[key] = parsed;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
this.form.configJson.variables = parsed;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
const provideCode = this.form.configJson.type;
|
|
||||||
const formData = {
|
const formData = {
|
||||||
id: this.modelData.id,
|
id: this.modelData.id,
|
||||||
modelCode: this.form.modelCode,
|
modelCode: this.form.modelCode,
|
||||||
@@ -229,13 +222,11 @@ export default {
|
|||||||
docLink: this.form.docLink,
|
docLink: this.form.docLink,
|
||||||
remark: this.form.remark,
|
remark: this.form.remark,
|
||||||
sort: this.form.sort || 0,
|
sort: this.form.sort || 0,
|
||||||
configJson: {
|
configJson: { ...this.form.configJson }
|
||||||
...this.form.configJson,
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$emit("save", {
|
this.$emit("save", {
|
||||||
provideCode,
|
provideCode: this.form.configJson.type,
|
||||||
formData,
|
formData,
|
||||||
done: () => {
|
done: () => {
|
||||||
this.saving = false; // 保存完成后回调
|
this.saving = false; // 保存完成后回调
|
||||||
@@ -256,7 +247,6 @@ export default {
|
|||||||
value: String(item.providerCode)
|
value: String(item.providerCode)
|
||||||
}));
|
}));
|
||||||
this.providersLoaded = true;
|
this.providersLoaded = true;
|
||||||
|
|
||||||
this.allProvidersData = data;
|
this.allProvidersData = data;
|
||||||
|
|
||||||
if (this.pendingProviderType) {
|
if (this.pendingProviderType) {
|
||||||
@@ -271,7 +261,7 @@ export default {
|
|||||||
this.dynamicCallInfoFields = JSON.parse(provider.fields || '[]').map(f => ({
|
this.dynamicCallInfoFields = JSON.parse(provider.fields || '[]').map(f => ({
|
||||||
label: f.label,
|
label: f.label,
|
||||||
prop: f.key,
|
prop: f.key,
|
||||||
type: f.key === 'variables' ? 'json-textarea' : (f.type === 'password' ? 'password' : 'text'),
|
type: f.type === 'dict' ? 'json-textarea' : (f.type === 'password' ? 'password' : 'text'),
|
||||||
placeholder: `请输入${f.label}`
|
placeholder: `请输入${f.label}`
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -288,7 +278,10 @@ export default {
|
|||||||
this.dynamicCallInfoFields.forEach(field => {
|
this.dynamicCallInfoFields.forEach(field => {
|
||||||
if (!configJson.hasOwnProperty(field.prop)) {
|
if (!configJson.hasOwnProperty(field.prop)) {
|
||||||
configJson[field.prop] = '';
|
configJson[field.prop] = '';
|
||||||
} else if (field.prop !== 'variables' && typeof configJson[field.prop] !== 'string') {
|
} else if (field.type === 'json-textarea') {
|
||||||
|
this.$set(this.fieldJsonMap, field.prop, this.formatJson(configJson[field.prop]));
|
||||||
|
configJson[field.prop] = this.ensureObject(configJson[field.prop]);
|
||||||
|
} else if (typeof configJson[field.prop] !== 'string') {
|
||||||
configJson[field.prop] = String(configJson[field.prop]);
|
configJson[field.prop] = String(configJson[field.prop]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -303,42 +296,43 @@ export default {
|
|||||||
docLink: model.docLink,
|
docLink: model.docLink,
|
||||||
remark: model.remark,
|
remark: model.remark,
|
||||||
sort: Number(model.sort) || 0,
|
sort: Number(model.sort) || 0,
|
||||||
configJson: {
|
configJson: { ...configJson }
|
||||||
...configJson
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
// 读出时的JSON转换
|
},
|
||||||
if (this.form.configJson.variables) {
|
handleJsonChange(field, value) {
|
||||||
this.variablesJson = JSON.stringify(this.form.configJson.variables, null, 2)
|
const parsed = this.validateJson(value);
|
||||||
|
if (parsed !== null) {
|
||||||
|
this.form.configJson[field] = parsed;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
validateJson(value) {
|
||||||
// 输入监听
|
|
||||||
handleVariablesChange(value) {
|
|
||||||
const parsed = this.validateVariablesJson(value);
|
|
||||||
if (parsed !== null) this.form.configJson.variables = parsed;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 数据校验
|
|
||||||
validateVariablesJson(value) {
|
|
||||||
try {
|
try {
|
||||||
const parsed = JSON.parse(value);
|
const parsed = JSON.parse(value);
|
||||||
// 校验是否为非空字典
|
|
||||||
if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
|
if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
|
||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
this.$message.error({
|
this.$message.error({
|
||||||
message: '必须输入字典格式(如 {"key":"value"}),保存则保留原数据',
|
message: '必须输入字典格式(如 {"key":"value"}),保存则使用原数据',
|
||||||
showClose: true
|
showClose: true
|
||||||
});
|
});
|
||||||
return null;
|
return null;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.$message.error({
|
this.$message.error({
|
||||||
message: 'JSON格式错误(如 {"key":"value"}),保存则保留原数据',
|
message: 'JSON格式错误(如 {"key":"value"}),保存则使用原数据',
|
||||||
showClose: true
|
showClose: true
|
||||||
});
|
});
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
formatJson(obj) {
|
||||||
|
try {
|
||||||
|
return JSON.stringify(obj, null, 2);
|
||||||
|
} catch {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ensureObject(value) {
|
||||||
|
return typeof value === 'object' ? value : {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -364,7 +358,6 @@ export default {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.custom-close-btn {
|
.custom-close-btn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 20px;
|
top: 20px;
|
||||||
@@ -500,21 +493,14 @@ export default {
|
|||||||
height: 32px;
|
height: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.custom-form .el-form-item {
|
.custom-form .el-form-item {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.custom-input-bg .el-input__inner {
|
|
||||||
height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.custom-form .el-form-item__label {
|
.custom-form .el-form-item__label {
|
||||||
color: #3d4566;
|
color: #3d4566;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user