优化资产编辑表单验证和服务资产配置,新增上下线时间联动校验、主图必填校验
This commit is contained in:
@@ -45,6 +45,7 @@
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
class="w100"
|
||||
@change="onOnlineTimeChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -57,6 +58,7 @@
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
class="w100"
|
||||
:disabled-date="disabledOfflineDate"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -139,19 +141,11 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<!-- 资产描述 -->
|
||||
<el-divider content-position="left">资产描述</el-divider>
|
||||
<el-form-item label="描述内容" label-width="100px">
|
||||
<div class="editor-wrapper">
|
||||
<Editor v-model="ruleForm.description" height="200px" placeholder="请输入资产描述" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 图片上传 -->
|
||||
<el-divider content-position="left">图片信息</el-divider>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="主图">
|
||||
<el-form-item label="主图" prop="mainImage">
|
||||
<el-upload
|
||||
class="avatar-uploader"
|
||||
:show-file-list="false"
|
||||
@@ -181,6 +175,16 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
||||
<!-- 资产描述 -->
|
||||
<el-divider content-position="left">资产描述</el-divider>
|
||||
<el-form-item label="描述内容" label-width="100px">
|
||||
<div class="editor-wrapper">
|
||||
<Editor v-model="ruleForm.description" height="200px" placeholder="请输入资产描述" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<!-- 实物资产配置 -->
|
||||
<template v-if="ruleForm.type === 'physical'">
|
||||
<el-divider content-position="left">实物资产配置</el-divider>
|
||||
@@ -204,19 +208,19 @@
|
||||
<!-- 预订配置 -->
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="最小提前">
|
||||
<el-form-item label="最小提前" prop="serviceAssetConfig.booking.minAdvance">
|
||||
<el-input-number v-model="ruleForm.serviceAssetConfig.booking.minAdvance" :min="0" class="w100" />
|
||||
<span class="unit-text">分钟</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="最小时长">
|
||||
<el-form-item label="最小时长" prop="serviceAssetConfig.booking.minDuration">
|
||||
<el-input-number v-model="ruleForm.serviceAssetConfig.booking.minDuration" :min="0" class="w100" />
|
||||
<span class="unit-text">分钟</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="取消提前">
|
||||
<el-form-item label="取消提前" prop="serviceAssetConfig.booking.cancelWindow">
|
||||
<el-input-number v-model="ruleForm.serviceAssetConfig.booking.cancelWindow" :min="0" class="w100" />
|
||||
<span class="unit-text">分钟</span>
|
||||
</el-form-item>
|
||||
@@ -224,7 +228,7 @@
|
||||
</el-row>
|
||||
|
||||
<!-- 时间段配置 -->
|
||||
<el-form-item label="时间段">
|
||||
<el-form-item label="服务时间" prop="serviceAssetConfig.schedule.timeSlots">
|
||||
<div class="config-list-container">
|
||||
<div v-for="(slot, index) in ruleForm.serviceAssetConfig.schedule.timeSlots" :key="index" class="config-list-item">
|
||||
<el-select v-model="slot.dayOfWeek" placeholder="星期" style="width: 100px">
|
||||
@@ -249,7 +253,7 @@
|
||||
</el-form-item>
|
||||
|
||||
<!-- 例外日期配置 -->
|
||||
<el-form-item label="例外日期">
|
||||
<el-form-item label="休息时间">
|
||||
<div class="config-list-container">
|
||||
<div v-for="(exc, index) in ruleForm.serviceAssetConfig.schedule.exceptions" :key="index" class="config-list-item">
|
||||
<el-select v-model="exc.exceptionType" placeholder="类型" style="width: 100px" @change="onExceptionTypeChange(exc)">
|
||||
@@ -267,7 +271,7 @@
|
||||
<el-input v-model="exc.reason" placeholder="原因" style="width: 120px" />
|
||||
<el-button type="danger" :icon="Delete" circle size="small" @click="removeException(index)" />
|
||||
</div>
|
||||
<el-button type="primary" :icon="Plus" size="small" @click="addException">添加例外</el-button>
|
||||
<el-button type="primary" :icon="Plus" size="small" @click="addException">添加休息时间</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</template>
|
||||
@@ -361,6 +365,7 @@ interface RuleForm {
|
||||
};
|
||||
};
|
||||
metadata: Record<string, any>;
|
||||
mainImage?: string;
|
||||
}
|
||||
|
||||
const emit = defineEmits(['getAssetList']);
|
||||
@@ -450,6 +455,7 @@ const getInitialForm = (): RuleForm => ({
|
||||
},
|
||||
},
|
||||
metadata: {},
|
||||
mainImage: '',
|
||||
});
|
||||
|
||||
const ruleForm = reactive<RuleForm>(getInitialForm());
|
||||
@@ -462,11 +468,42 @@ const validateOfflineTime = (_rule: any, value: string, callback: Function) => {
|
||||
}
|
||||
};
|
||||
|
||||
const disabledOfflineDate = (time: Date) => {
|
||||
if (!ruleForm.onlineTime) return false;
|
||||
return time.getTime() < new Date(ruleForm.onlineTime).setHours(0, 0, 0, 0);
|
||||
};
|
||||
|
||||
const validateTimeSlots = (_rule: any, value: TimeSlot[], callback: Function) => {
|
||||
if (!value || value.length === 0) {
|
||||
callback(new Error('请至少添加一个服务时间段'));
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
const slot = value[i];
|
||||
if (!slot.dayOfWeek || !slot.startTime || !slot.endTime || !slot.capacity) {
|
||||
callback(new Error(`第 ${i + 1} 行服务时间配置不完整`));
|
||||
return;
|
||||
}
|
||||
}
|
||||
callback();
|
||||
};
|
||||
|
||||
const onOnlineTimeChange = () => {
|
||||
if (ruleForm.offlineTime) {
|
||||
formRef.value?.validateField('offlineTime');
|
||||
}
|
||||
};
|
||||
|
||||
const rules: FormRules = {
|
||||
name: [{ required: true, message: '资产名称不能为空', trigger: 'blur' }],
|
||||
type: [{ required: true, message: '请选择资产类型', trigger: 'change' }],
|
||||
categoryId: [{ required: true, message: '请选择资产分类', trigger: 'change' }],
|
||||
offlineTime: [{ validator: validateOfflineTime, trigger: 'change' }],
|
||||
mainImage: [{ required: true, message: '请上传主图', trigger: 'change' }],
|
||||
'serviceAssetConfig.booking.minAdvance': [{ required: true, message: '请输入最小提前时间', trigger: 'blur' }],
|
||||
'serviceAssetConfig.booking.minDuration': [{ required: true, message: '请输入最小时长', trigger: 'blur' }],
|
||||
'serviceAssetConfig.booking.cancelWindow': [{ required: true, message: '请输入取消提前时间', trigger: 'blur' }],
|
||||
'serviceAssetConfig.schedule.timeSlots': [{ validator: validateTimeSlots, trigger: 'change' }],
|
||||
};
|
||||
|
||||
// 主图上传处理
|
||||
@@ -474,6 +511,8 @@ const handleMainImageChange = (file: UploadFile) => {
|
||||
if (file.raw) {
|
||||
mainImageFile.value = file.raw;
|
||||
mainImagePreview.value = URL.createObjectURL(file.raw);
|
||||
ruleForm.mainImage = 'set'; // 标记已上传
|
||||
formRef.value?.validateField('mainImage');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -495,20 +534,34 @@ const handleRemove = (file: UploadFile) => {
|
||||
|
||||
// 时间段操作
|
||||
const addTimeSlot = () => {
|
||||
if (!ruleForm.serviceAssetConfig.schedule) {
|
||||
ruleForm.serviceAssetConfig.schedule = { timeSlots: [], exceptions: [] };
|
||||
}
|
||||
if (!ruleForm.serviceAssetConfig.schedule.timeSlots) {
|
||||
ruleForm.serviceAssetConfig.schedule.timeSlots = [];
|
||||
}
|
||||
ruleForm.serviceAssetConfig.schedule.timeSlots.push({
|
||||
dayOfWeek: '1',
|
||||
startTime: '09:00',
|
||||
endTime: '18:00',
|
||||
capacity: 100,
|
||||
});
|
||||
formRef.value?.validateField('serviceAssetConfig.schedule.timeSlots');
|
||||
};
|
||||
|
||||
const removeTimeSlot = (index: number) => {
|
||||
ruleForm.serviceAssetConfig.schedule.timeSlots.splice(index, 1);
|
||||
formRef.value?.validateField('serviceAssetConfig.schedule.timeSlots');
|
||||
};
|
||||
|
||||
// 例外日期操作
|
||||
const addException = () => {
|
||||
if (!ruleForm.serviceAssetConfig.schedule) {
|
||||
ruleForm.serviceAssetConfig.schedule = { timeSlots: [], exceptions: [] };
|
||||
}
|
||||
if (!ruleForm.serviceAssetConfig.schedule.exceptions) {
|
||||
ruleForm.serviceAssetConfig.schedule.exceptions = [];
|
||||
}
|
||||
ruleForm.serviceAssetConfig.schedule.exceptions.push({
|
||||
exceptionType: 'date',
|
||||
date: '',
|
||||
@@ -596,6 +649,7 @@ const openDialog = (row?: any, edit?: boolean) => {
|
||||
// 主图预览
|
||||
if (data.imageUrl) {
|
||||
mainImagePreview.value = formatImageUrl(data.imageUrl);
|
||||
ruleForm.mainImage = data.imageUrl;
|
||||
}
|
||||
|
||||
// 图片列表
|
||||
@@ -615,6 +669,31 @@ const openDialog = (row?: any, edit?: boolean) => {
|
||||
}
|
||||
if (data.type === 'service' && data.serviceAssetConfig) {
|
||||
Object.assign(ruleForm.serviceAssetConfig, data.serviceAssetConfig);
|
||||
// 确保 schedule 对象存在
|
||||
if (!ruleForm.serviceAssetConfig.schedule) {
|
||||
ruleForm.serviceAssetConfig.schedule = { timeSlots: [], exceptions: [] };
|
||||
}
|
||||
// 确保数组存在,防止后端返回 null 或 undefined 导致 push 报错
|
||||
if (!ruleForm.serviceAssetConfig.schedule.exceptions) {
|
||||
ruleForm.serviceAssetConfig.schedule.exceptions = [];
|
||||
} else {
|
||||
// 补充缺失的 exceptionType
|
||||
ruleForm.serviceAssetConfig.schedule.exceptions.forEach((exc) => {
|
||||
if (!exc.exceptionType) {
|
||||
if (exc.date) {
|
||||
exc.exceptionType = 'date';
|
||||
} else if (exc.dayOfWeek) {
|
||||
exc.exceptionType = 'dayOfWeek';
|
||||
} else {
|
||||
// 默认值
|
||||
exc.exceptionType = 'date';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!ruleForm.serviceAssetConfig.schedule.timeSlots) {
|
||||
ruleForm.serviceAssetConfig.schedule.timeSlots = [];
|
||||
}
|
||||
}
|
||||
|
||||
// 元数据
|
||||
|
||||
Reference in New Issue
Block a user