更新模型配置和订阅页面

- 修改模型模块的字段名称,从 `keyword` 更改为 `modelName`,以提高一致性。
- 添加模型类型和访问类型的选择功能,增强用户交互体验。
- 移除不必要的调试日志,优化代码整洁性。
- 更新订阅页面的错误处理逻辑,确保用户在加载失败时获得清晰反馈。
This commit is contained in:
2026-05-11 13:48:20 +08:00
parent 76420713fa
commit 0a42e700e2
9 changed files with 617 additions and 249 deletions

View File

@@ -19,7 +19,7 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-col :span="8">
<el-form-item label="资产分类" prop="categoryId">
<el-cascader
v-model="ruleForm.categoryId"
@@ -33,7 +33,6 @@
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="8">
@@ -98,12 +97,7 @@
class="w100"
clearable
>
<el-option
v-for="opt in attr.options"
:key="opt.value"
:label="opt.label"
:value="opt.value"
/>
<el-option v-for="opt in attr.options" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
<!-- 多选类型 -->
<el-select
@@ -114,12 +108,7 @@
multiple
clearable
>
<el-option
v-for="opt in attr.options"
:key="opt.value"
:label="opt.label"
:value="opt.value"
/>
<el-option v-for="opt in attr.options" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
<!-- 文本类型 -->
<el-input
@@ -128,11 +117,7 @@
:placeholder="'请输入' + getAttrLabel(attr)"
/>
<!-- 数字类型 -->
<el-input-number
v-else-if="attr.type === 'number'"
v-model="ruleForm.metadata[getAttrKey(attr)]"
class="w100"
/>
<el-input-number v-else-if="attr.type === 'number'" v-model="ruleForm.metadata[getAttrKey(attr)]" class="w100" />
<!-- 日期类型 -->
<el-date-picker
v-else-if="attr.type === 'date'"
@@ -142,10 +127,7 @@
class="w100"
/>
<!-- 布尔类型 -->
<el-switch
v-else-if="attr.type === 'boolean'"
v-model="ruleForm.metadata[getAttrKey(attr)]"
/>
<el-switch v-else-if="attr.type === 'boolean'" v-model="ruleForm.metadata[getAttrKey(attr)]" />
<!-- 图片类型 -->
<div v-else-if="attr.type === 'image'" class="w100">
<el-upload
@@ -185,13 +167,7 @@
<el-col :span="8">
<el-form-item label="主图" prop="mainImage">
<div class="w100">
<el-upload
class="avatar-uploader"
:show-file-list="false"
:auto-upload="true"
:http-request="handleMainImageUpload"
accept="image/*"
>
<el-upload class="avatar-uploader" :show-file-list="false" :auto-upload="true" :http-request="handleMainImageUpload" accept="image/*">
<img v-if="mainImagePreview" :src="mainImagePreview" class="avatar" />
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
</el-upload>
@@ -220,7 +196,6 @@
</el-col>
</el-row>
<!-- 资产描述 -->
<el-divider content-position="left">资产描述</el-divider>
<el-form-item label="描述内容" label-width="100px">
@@ -229,7 +204,6 @@
</div>
</el-form-item>
<!-- 实物资产配置 -->
<template v-if="ruleForm.type === 'physical'">
<el-divider content-position="left">实物资产配置</el-divider>
@@ -249,7 +223,7 @@
<!-- 虚拟资产配置 -->
<template v-if="ruleForm.type === 'virtual'">
<el-divider content-position="left">虚拟资产配置</el-divider>
<!-- 虚拟类型选择 -->
<el-row :gutter="24">
<el-col :span="8">
@@ -302,9 +276,17 @@
<el-input v-model="item.key" placeholder="Key" style="width: 200px" />
<span class="separator">:</span>
<el-input v-model="item.value" placeholder="Value" style="width: 200px" />
<el-button type="danger" :icon="Delete" circle size="small" @click="removeKeyValuePair(ruleForm.virtualAssetConfig.apiConfig.headers, index)" />
<el-button
type="danger"
:icon="Delete"
circle
size="small"
@click="removeKeyValuePair(ruleForm.virtualAssetConfig.apiConfig.headers, index)"
/>
</div>
<el-button type="primary" :icon="Plus" size="small" @click="addKeyValuePair(ruleForm.virtualAssetConfig.apiConfig.headers)">添加请求头</el-button>
<el-button type="primary" :icon="Plus" size="small" @click="addKeyValuePair(ruleForm.virtualAssetConfig.apiConfig.headers)"
>添加请求头</el-button
>
</div>
</el-form-item>
</el-col>
@@ -317,9 +299,17 @@
<el-input v-model="item.key" placeholder="Key" style="width: 200px" />
<span class="separator">:</span>
<el-input v-model="item.value" placeholder="Value" style="width: 200px" />
<el-button type="danger" :icon="Delete" circle size="small" @click="removeKeyValuePair(ruleForm.virtualAssetConfig.apiConfig.params, index)" />
<el-button
type="danger"
:icon="Delete"
circle
size="small"
@click="removeKeyValuePair(ruleForm.virtualAssetConfig.apiConfig.params, index)"
/>
</div>
<el-button type="primary" :icon="Plus" size="small" @click="addKeyValuePair(ruleForm.virtualAssetConfig.apiConfig.params)">添加请求参数</el-button>
<el-button type="primary" :icon="Plus" size="small" @click="addKeyValuePair(ruleForm.virtualAssetConfig.apiConfig.params)"
>添加请求参数</el-button
>
</div>
</el-form-item>
</el-col>
@@ -337,7 +327,13 @@
</el-col>
<el-col :span="16" v-if="ruleForm.virtualAssetConfig.apiConfig.authType !== 'none'">
<el-form-item label="认证配置" prop="virtualAssetConfig.apiConfig.authConfig">
<el-input v-model="ruleForm.virtualAssetConfig.apiConfig.authConfig" type="textarea" :rows="2" placeholder="请输入认证配置" class="w100" />
<el-input
v-model="ruleForm.virtualAssetConfig.apiConfig.authConfig"
type="textarea"
:rows="2"
placeholder="请输入认证配置"
class="w100"
/>
</el-form-item>
</el-col>
</el-row>
@@ -346,7 +342,7 @@
<!-- 服务资产配置 -->
<template v-if="ruleForm.type === 'service'">
<el-divider content-position="left">服务资产配置</el-divider>
<!-- 服务类型选择 -->
<el-row :gutter="24">
<el-col :span="8">
@@ -386,9 +382,13 @@
<!-- 时间段配置 -->
<el-form-item label="服务时间" prop="serviceAssetConfig.serviceAssetArrivalConfig.schedule.timeSlots">
<div class="config-list-container">
<div v-for="(slot, index) in ruleForm.serviceAssetConfig.serviceAssetArrivalConfig.schedule.timeSlots" :key="index" class="config-list-item">
<div
v-for="(slot, index) in ruleForm.serviceAssetConfig.serviceAssetArrivalConfig.schedule.timeSlots"
:key="index"
class="config-list-item"
>
<el-select v-model="slot.dayOfWeek" placeholder="星期" style="width: 100px">
<el-option v-for="d in 7" :key="d" :label="'周' + ['一','二','三','四','五','六','日'][d-1]" :value="String(d)" />
<el-option v-for="d in 7" :key="d" :label="'周' + ['一', '二', '三', '四', '五', '六', '日'][d - 1]" :value="String(d)" />
</el-select>
<el-time-picker v-model="slot.startTime" format="HH:mm" value-format="HH:mm" placeholder="开始" style="width: 100px" />
<span class="separator">-</span>
@@ -396,29 +396,33 @@
<el-input-number v-model="slot.capacity" :min="1" placeholder="容量" style="width: 100px" controls-position="right" />
<el-button type="danger" :icon="Delete" circle size="small" @click="removeTimeSlot(index)" />
</div>
<el-button
type="primary"
:icon="Plus"
size="small"
@click="addTimeSlot"
:disabled="isTimeSlotLimitReached"
>
添加时间段
</el-button>
<el-button type="primary" :icon="Plus" size="small" @click="addTimeSlot" :disabled="isTimeSlotLimitReached"> 添加时间段 </el-button>
</div>
</el-form-item>
<!-- 例外日期配置 -->
<el-form-item label="休息时间">
<div class="config-list-container">
<div v-for="(exc, index) in ruleForm.serviceAssetConfig.serviceAssetArrivalConfig.schedule.exceptions" :key="index" class="config-list-item">
<div
v-for="(exc, index) in ruleForm.serviceAssetConfig.serviceAssetArrivalConfig.schedule.exceptions"
:key="index"
class="config-list-item"
>
<el-select v-model="exc.exceptionType" placeholder="类型" style="width: 100px" @change="onExceptionTypeChange(exc)">
<el-option label="指定日期" value="date" />
<el-option label="指定星期" value="dayOfWeek" />
</el-select>
<el-date-picker v-if="exc.exceptionType === 'date'" v-model="exc.date" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" placeholder="日期" style="width: 130px" />
<el-date-picker
v-if="exc.exceptionType === 'date'"
v-model="exc.date"
type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
placeholder="日期"
style="width: 130px"
/>
<el-select v-if="exc.exceptionType === 'dayOfWeek'" v-model="exc.dayOfWeek" placeholder="星期" style="width: 100px">
<el-option v-for="d in 7" :key="d" :label="'周' + ['一','二','三','四','五','六','日'][d-1]" :value="String(d)" />
<el-option v-for="d in 7" :key="d" :label="'周' + ['一', '二', '三', '四', '五', '六', '日'][d - 1]" :value="String(d)" />
</el-select>
<el-select v-model="exc.status" placeholder="状态" style="width: 90px">
<el-option label="可用" :value="1" />
@@ -591,8 +595,6 @@ const assetFormDiff = createFormDiff<Record<string, any>>();
// 获取租户ID
const tenantId = ref(Session.get('userInfo')?.tenantId || '');
console.log(tenantId.value,'租户id');
const formatImageUrl = (url?: string) => {
if (!url) return '';
@@ -980,7 +982,7 @@ const openDialog = (row?: any, edit?: boolean) => {
if (data.type === 'virtual' && data.virtualAssetConfig) {
// 先处理 headers 和 params 为数组格式,再赋值
const config = { ...data.virtualAssetConfig };
// 确保 apiConfig 存在
if (!config.apiConfig) {
config.apiConfig = {
@@ -1036,7 +1038,7 @@ const openDialog = (row?: any, edit?: boolean) => {
exc.exceptionType = 'dayOfWeek';
} else {
// 默认值
exc.exceptionType = 'date';
exc.exceptionType = 'date';
}
}
});
@@ -1121,7 +1123,7 @@ const onCancel = () => {
// 上传图片并返回URL
const uploadImage = async (file: File): Promise<string> => {
const res: any = await uploadAssetImage(file);
// 1. 尝试获取并设置 fileAddressPrefix
// 优先检查顶层,再检查 data 内部
if (res.fileAddressPrefix) {
@@ -1133,7 +1135,7 @@ const uploadImage = async (file: File): Promise<string> => {
// 2. 尝试获取 fileURL / url
// 优先检查顶层 fileURL
if (res.fileURL) return res.fileURL;
// 检查 data 对象中的 fileURL 或 url
if (res.data && typeof res.data === 'object') {
if (res.data.fileURL) return res.data.fileURL;
@@ -1205,7 +1207,7 @@ const buildRequestBody = async (): Promise<any> => {
} else if (ruleForm.type === 'virtual') {
// 深拷贝 virtualAssetConfig 以避免修改原对象
const virtualConfig = JSON.parse(JSON.stringify(ruleForm.virtualAssetConfig));
// 将数组转换为对象
if (virtualConfig.apiConfig) {
if (Array.isArray(virtualConfig.apiConfig.headers)) {
@@ -1215,7 +1217,7 @@ const buildRequestBody = async (): Promise<any> => {
});
virtualConfig.apiConfig.headers = headersObj;
}
if (Array.isArray(virtualConfig.apiConfig.params)) {
const paramsObj: Record<string, string> = {};
virtualConfig.apiConfig.params.forEach((item: KeyValuePair) => {
@@ -1224,7 +1226,7 @@ const buildRequestBody = async (): Promise<any> => {
virtualConfig.apiConfig.params = paramsObj;
}
}
body.virtualAssetConfig = virtualConfig;
} else if (ruleForm.type === 'service') {
body.serviceAssetConfig = ruleForm.serviceAssetConfig;
@@ -1252,9 +1254,7 @@ const buildRequestBody = async (): Promise<any> => {
// 只有单选和多选类型才传递 options且只传递选中的值对应的选项
if ((attr.type === 'select' || attr.type === 'multi_select') && attr.options && value) {
const selectedValues = Array.isArray(value) ? value : [value];
metaItem.options = attr.options.filter((opt: { label: string; value: string }) =>
selectedValues.includes(opt.value)
);
metaItem.options = attr.options.filter((opt: { label: string; value: string }) => selectedValues.includes(opt.value));
}
metadataArray.push(metaItem);
@@ -1269,13 +1269,13 @@ const buildRequestBody = async (): Promise<any> => {
const onSubmit = async () => {
const form = formRef.value;
if (!form) return;
form.validate(async (valid: boolean) => {
if (valid) {
submitLoading.value = true;
try {
const fullRequestBody = await buildRequestBody();
let requestBody: any;
if (isEdit.value) {
// 编辑模式:通过 _originalData 让拦截器自动处理最小化传参
@@ -1296,7 +1296,7 @@ const onSubmit = async () => {
closeDialog();
emit('getAssetList');
} catch (error) {
console.error('提交失败:', error);
ElMessage.error('提交失败');
} finally {
submitLoading.value = false;
}