优化资产编辑表单,移除第三方资产和无库存限制选项,新增配送方式选项,优化图片URL处理逻辑
This commit is contained in:
@@ -19,14 +19,7 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="第三方资产">
|
||||
<el-switch v-model="ruleForm.sourceType" inline-prompt active-text="是" inactive-text="否" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="8">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="资产分类" prop="categoryId">
|
||||
<el-cascader
|
||||
v-model="ruleForm.categoryId"
|
||||
@@ -35,10 +28,14 @@
|
||||
placeholder="请选择资产分类"
|
||||
clearable
|
||||
class="w100"
|
||||
:disabled="isEdit"
|
||||
@change="onCategoryChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="上线时间">
|
||||
<el-date-picker
|
||||
@@ -188,71 +185,15 @@
|
||||
<template v-if="ruleForm.type === 'physical'">
|
||||
<el-divider content-position="left">实物资产配置</el-divider>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="无库存限制">
|
||||
<el-switch v-model="ruleForm.physicalAssetConfig.unlimitedStock" inline-prompt active-text="是" inactive-text="否" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="配送方式">
|
||||
<el-select v-model="ruleForm.physicalAssetConfig.shipping.deliveryMethod" placeholder="请选择配送方式" class="w100">
|
||||
<el-option label="快递" value="express" />
|
||||
<el-option label="自提" value="self_pickup" />
|
||||
<el-option label="同城配送" value="city_delivery" disabled />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" v-if="ruleForm.physicalAssetConfig.shipping.deliveryMethod === 'express'">
|
||||
<el-form-item label="发货周期">
|
||||
<el-input-number v-model="ruleForm.physicalAssetConfig.shipping.deliveryTime" :min="1" :max="720" class="w100" />
|
||||
<span class="unit-text">小时</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<!-- 虚拟资产配置 -->
|
||||
<template v-if="ruleForm.type === 'virtual'">
|
||||
<el-divider content-position="left">虚拟资产配置</el-divider>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="HTTP方法">
|
||||
<el-select v-model="ruleForm.virtualAssetConfig.method" placeholder="请选择HTTP方法" class="w100">
|
||||
<el-option label="GET" value="GET" />
|
||||
<el-option label="POST" value="POST" />
|
||||
<el-option label="PUT" value="PUT" />
|
||||
<el-option label="DELETE" value="DELETE" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="请求地址">
|
||||
<el-input v-model="ruleForm.virtualAssetConfig.requestURL" placeholder="请输入请求地址" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="认证类型">
|
||||
<el-select v-model="ruleForm.virtualAssetConfig.authType" placeholder="请选择认证类型" class="w100">
|
||||
<el-option label="无认证" value="none" />
|
||||
<el-option label="API Key" value="apikey" />
|
||||
<el-option label="Bearer Token" value="bearer" />
|
||||
<el-option label="OAuth" value="oauth" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24" v-if="ruleForm.virtualAssetConfig.authType && ruleForm.virtualAssetConfig.authType !== 'none'">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="认证配置">
|
||||
<el-input
|
||||
v-model="ruleForm.virtualAssetConfig.authConfig"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder='请输入认证配置JSON,例如:{"api_key": "your_api_key"}'
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
@@ -280,12 +221,6 @@
|
||||
<span class="unit-text">分钟</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="最大用户">
|
||||
<el-input-number v-model="ruleForm.serviceAssetConfig.capacity.maxUsers" :min="0" class="w100" />
|
||||
<span class="unit-text">0=无限</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 时间段配置 -->
|
||||
@@ -301,7 +236,15 @@
|
||||
<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">添加时间段</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Plus"
|
||||
size="small"
|
||||
@click="addTimeSlot"
|
||||
:disabled="isTimeSlotLimitReached"
|
||||
>
|
||||
添加时间段
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
@@ -351,8 +294,9 @@ export default {
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, watch } from 'vue';
|
||||
import { ref, reactive, watch, computed } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import type { FormInstance, FormRules } from 'element-plus';
|
||||
import { Plus, Delete } from '@element-plus/icons-vue';
|
||||
import { getAsset, createAsset, updateAsset } from '/@/api/assets/asset';
|
||||
import { getCategoryTree, getCategory } from '/@/api/assets/category';
|
||||
@@ -385,14 +329,12 @@ interface CategoryAttr {
|
||||
interface RuleForm {
|
||||
id: string;
|
||||
name: string;
|
||||
sourceType: boolean;
|
||||
type: string;
|
||||
categoryId: string;
|
||||
description: string;
|
||||
onlineTime: string;
|
||||
offlineTime: string;
|
||||
physicalAssetConfig: {
|
||||
unlimitedStock: boolean;
|
||||
shipping: {
|
||||
deliveryMethod: string;
|
||||
deliveryTime: number;
|
||||
@@ -423,13 +365,16 @@ interface RuleForm {
|
||||
|
||||
const emit = defineEmits(['getAssetList']);
|
||||
|
||||
const formRef = ref();
|
||||
const formRef = ref<FormInstance>();
|
||||
const editAssetRef = ref();
|
||||
const MAX_TIME_SLOTS = 7;
|
||||
const isShowDialog = ref(false);
|
||||
const isEdit = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
const formLoading = ref(false);
|
||||
const categoryOptions = ref<any[]>([]);
|
||||
const categoryAttrs = ref<CategoryAttr[]>([]);
|
||||
const isTimeSlotLimitReached = computed(() => ruleForm.serviceAssetConfig.schedule.timeSlots.length >= MAX_TIME_SLOTS);
|
||||
|
||||
// 获取属性的key
|
||||
const getAttrKey = (attr: CategoryAttr): string => {
|
||||
@@ -447,19 +392,38 @@ const mainImagePreview = ref('');
|
||||
const imageFileList = ref<UploadUserFile[]>([]);
|
||||
const dialogVisible = ref(false);
|
||||
const dialogImageUrl = ref('');
|
||||
// 图片拼接
|
||||
const imgAddressPrefix = ref('');
|
||||
|
||||
const formatImageUrl = (url?: string) => {
|
||||
if (!url) return '';
|
||||
if (/^https?:\/\//i.test(url)) return url;
|
||||
return `${imgAddressPrefix.value || ''}${url}`;
|
||||
};
|
||||
|
||||
const createDefaultTimeSlots = (): TimeSlot[] => {
|
||||
const slots: TimeSlot[] = [];
|
||||
for (let i = 1; i <= MAX_TIME_SLOTS; i++) {
|
||||
slots.push({
|
||||
dayOfWeek: String(i),
|
||||
startTime: '09:00',
|
||||
endTime: '18:00',
|
||||
capacity: 100,
|
||||
});
|
||||
}
|
||||
return slots;
|
||||
};
|
||||
|
||||
// 初始表单数据
|
||||
const getInitialForm = (): RuleForm => ({
|
||||
id: '',
|
||||
name: '',
|
||||
sourceType: false,
|
||||
type: 'physical',
|
||||
categoryId: '',
|
||||
description: '',
|
||||
onlineTime: '',
|
||||
offlineTime: '',
|
||||
physicalAssetConfig: {
|
||||
unlimitedStock: false,
|
||||
shipping: {
|
||||
deliveryMethod: 'express',
|
||||
deliveryTime: 24,
|
||||
@@ -473,7 +437,7 @@ const getInitialForm = (): RuleForm => ({
|
||||
},
|
||||
serviceAssetConfig: {
|
||||
schedule: {
|
||||
timeSlots: [],
|
||||
timeSlots: createDefaultTimeSlots(),
|
||||
exceptions: [],
|
||||
},
|
||||
booking: {
|
||||
@@ -490,10 +454,19 @@ const getInitialForm = (): RuleForm => ({
|
||||
|
||||
const ruleForm = reactive<RuleForm>(getInitialForm());
|
||||
|
||||
const rules = {
|
||||
const validateOfflineTime = (_rule: any, value: string, callback: Function) => {
|
||||
if (value && ruleForm.onlineTime && new Date(value).getTime() < new Date(ruleForm.onlineTime).getTime()) {
|
||||
callback(new Error('下线时间不能早于上线时间'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
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' }],
|
||||
};
|
||||
|
||||
// 主图上传处理
|
||||
@@ -506,6 +479,8 @@ const handleMainImageChange = (file: UploadFile) => {
|
||||
|
||||
// 图片列表预览
|
||||
const handlePictureCardPreview = (file: UploadFile) => {
|
||||
console.log(file,'111');
|
||||
|
||||
dialogImageUrl.value = file.url || '';
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
@@ -564,6 +539,7 @@ const resetForm = () => {
|
||||
mainImagePreview.value = '';
|
||||
imageFileList.value = [];
|
||||
categoryAttrs.value = [];
|
||||
imgAddressPrefix.value = '';
|
||||
};
|
||||
|
||||
// 获取分类数据
|
||||
@@ -608,9 +584,9 @@ const openDialog = (row?: any, edit?: boolean) => {
|
||||
getAsset(row.id)
|
||||
.then((res: any) => {
|
||||
const data = res.data;
|
||||
imgAddressPrefix.value = data.imgAddressPrefix || '';
|
||||
ruleForm.id = data.id || '';
|
||||
ruleForm.name = data.name || '';
|
||||
ruleForm.sourceType = data.sourceType || false;
|
||||
ruleForm.type = data.type || 'physical';
|
||||
ruleForm.categoryId = data.categoryId || '';
|
||||
ruleForm.description = data.description || '';
|
||||
@@ -619,14 +595,14 @@ const openDialog = (row?: any, edit?: boolean) => {
|
||||
|
||||
// 主图预览
|
||||
if (data.imageUrl) {
|
||||
mainImagePreview.value = data.imageUrl;
|
||||
mainImagePreview.value = formatImageUrl(data.imageUrl);
|
||||
}
|
||||
|
||||
// 图片列表
|
||||
if (data.images && Array.isArray(data.images)) {
|
||||
imageFileList.value = data.images.map((url: string, index: number) => ({
|
||||
name: `image-${index}`,
|
||||
url: url,
|
||||
url: formatImageUrl(url),
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -687,7 +663,6 @@ const buildFormData = (): FormData => {
|
||||
formData.append('id', ruleForm.id);
|
||||
}
|
||||
formData.append('name', ruleForm.name);
|
||||
formData.append('sourceType', String(ruleForm.sourceType));
|
||||
formData.append('type', ruleForm.type);
|
||||
formData.append('categoryId', ruleForm.categoryId);
|
||||
formData.append('description', ruleForm.description || '');
|
||||
@@ -729,7 +704,9 @@ const buildFormData = (): FormData => {
|
||||
|
||||
// 提交
|
||||
const onSubmit = () => {
|
||||
formRef.value.validate((valid: boolean) => {
|
||||
const form = formRef.value;
|
||||
if (!form) return;
|
||||
form.validate((valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
const formData = buildFormData();
|
||||
|
||||
Reference in New Issue
Block a user