优化资产编辑表单验证和服务资产配置,新增上下线时间联动校验、主图必填校验
This commit is contained in:
@@ -45,6 +45,7 @@
|
|||||||
format="YYYY-MM-DD HH:mm:ss"
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
class="w100"
|
class="w100"
|
||||||
|
@change="onOnlineTimeChange"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -57,6 +58,7 @@
|
|||||||
format="YYYY-MM-DD HH:mm:ss"
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
class="w100"
|
class="w100"
|
||||||
|
:disabled-date="disabledOfflineDate"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -139,19 +141,11 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</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-divider content-position="left">图片信息</el-divider>
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="主图">
|
<el-form-item label="主图" prop="mainImage">
|
||||||
<el-upload
|
<el-upload
|
||||||
class="avatar-uploader"
|
class="avatar-uploader"
|
||||||
:show-file-list="false"
|
:show-file-list="false"
|
||||||
@@ -181,6 +175,16 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</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'">
|
<template v-if="ruleForm.type === 'physical'">
|
||||||
<el-divider content-position="left">实物资产配置</el-divider>
|
<el-divider content-position="left">实物资产配置</el-divider>
|
||||||
@@ -204,19 +208,19 @@
|
|||||||
<!-- 预订配置 -->
|
<!-- 预订配置 -->
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="6">
|
<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" />
|
<el-input-number v-model="ruleForm.serviceAssetConfig.booking.minAdvance" :min="0" class="w100" />
|
||||||
<span class="unit-text">分钟</span>
|
<span class="unit-text">分钟</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<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" />
|
<el-input-number v-model="ruleForm.serviceAssetConfig.booking.minDuration" :min="0" class="w100" />
|
||||||
<span class="unit-text">分钟</span>
|
<span class="unit-text">分钟</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<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" />
|
<el-input-number v-model="ruleForm.serviceAssetConfig.booking.cancelWindow" :min="0" class="w100" />
|
||||||
<span class="unit-text">分钟</span>
|
<span class="unit-text">分钟</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -224,7 +228,7 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 时间段配置 -->
|
<!-- 时间段配置 -->
|
||||||
<el-form-item label="时间段">
|
<el-form-item label="服务时间" prop="serviceAssetConfig.schedule.timeSlots">
|
||||||
<div class="config-list-container">
|
<div class="config-list-container">
|
||||||
<div v-for="(slot, index) in ruleForm.serviceAssetConfig.schedule.timeSlots" :key="index" class="config-list-item">
|
<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">
|
<el-select v-model="slot.dayOfWeek" placeholder="星期" style="width: 100px">
|
||||||
@@ -249,7 +253,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<!-- 例外日期配置 -->
|
<!-- 例外日期配置 -->
|
||||||
<el-form-item label="例外日期">
|
<el-form-item label="休息时间">
|
||||||
<div class="config-list-container">
|
<div class="config-list-container">
|
||||||
<div v-for="(exc, index) in ruleForm.serviceAssetConfig.schedule.exceptions" :key="index" class="config-list-item">
|
<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)">
|
<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-input v-model="exc.reason" placeholder="原因" style="width: 120px" />
|
||||||
<el-button type="danger" :icon="Delete" circle size="small" @click="removeException(index)" />
|
<el-button type="danger" :icon="Delete" circle size="small" @click="removeException(index)" />
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
@@ -361,6 +365,7 @@ interface RuleForm {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
metadata: Record<string, any>;
|
metadata: Record<string, any>;
|
||||||
|
mainImage?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const emit = defineEmits(['getAssetList']);
|
const emit = defineEmits(['getAssetList']);
|
||||||
@@ -450,6 +455,7 @@ const getInitialForm = (): RuleForm => ({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
metadata: {},
|
metadata: {},
|
||||||
|
mainImage: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const ruleForm = reactive<RuleForm>(getInitialForm());
|
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 = {
|
const rules: FormRules = {
|
||||||
name: [{ required: true, message: '资产名称不能为空', trigger: 'blur' }],
|
name: [{ required: true, message: '资产名称不能为空', trigger: 'blur' }],
|
||||||
type: [{ required: true, message: '请选择资产类型', trigger: 'change' }],
|
type: [{ required: true, message: '请选择资产类型', trigger: 'change' }],
|
||||||
categoryId: [{ required: true, message: '请选择资产分类', trigger: 'change' }],
|
categoryId: [{ required: true, message: '请选择资产分类', trigger: 'change' }],
|
||||||
offlineTime: [{ validator: validateOfflineTime, 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) {
|
if (file.raw) {
|
||||||
mainImageFile.value = file.raw;
|
mainImageFile.value = file.raw;
|
||||||
mainImagePreview.value = URL.createObjectURL(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 = () => {
|
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({
|
ruleForm.serviceAssetConfig.schedule.timeSlots.push({
|
||||||
dayOfWeek: '1',
|
dayOfWeek: '1',
|
||||||
startTime: '09:00',
|
startTime: '09:00',
|
||||||
endTime: '18:00',
|
endTime: '18:00',
|
||||||
capacity: 100,
|
capacity: 100,
|
||||||
});
|
});
|
||||||
|
formRef.value?.validateField('serviceAssetConfig.schedule.timeSlots');
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeTimeSlot = (index: number) => {
|
const removeTimeSlot = (index: number) => {
|
||||||
ruleForm.serviceAssetConfig.schedule.timeSlots.splice(index, 1);
|
ruleForm.serviceAssetConfig.schedule.timeSlots.splice(index, 1);
|
||||||
|
formRef.value?.validateField('serviceAssetConfig.schedule.timeSlots');
|
||||||
};
|
};
|
||||||
|
|
||||||
// 例外日期操作
|
// 例外日期操作
|
||||||
const addException = () => {
|
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({
|
ruleForm.serviceAssetConfig.schedule.exceptions.push({
|
||||||
exceptionType: 'date',
|
exceptionType: 'date',
|
||||||
date: '',
|
date: '',
|
||||||
@@ -596,6 +649,7 @@ const openDialog = (row?: any, edit?: boolean) => {
|
|||||||
// 主图预览
|
// 主图预览
|
||||||
if (data.imageUrl) {
|
if (data.imageUrl) {
|
||||||
mainImagePreview.value = formatImageUrl(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) {
|
if (data.type === 'service' && data.serviceAssetConfig) {
|
||||||
Object.assign(ruleForm.serviceAssetConfig, 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