优化PUT请求传参机制,实现最小化传参以减少网络传输和提高性能,在请求拦截器中自动计算差异只传递修改过的字段,同时新增通用的表单差异比较工具函数,
This commit is contained in:
@@ -445,6 +445,7 @@ import type { FormInstance, FormRules } from 'element-plus';
|
||||
import { Plus, Delete } from '@element-plus/icons-vue';
|
||||
import { getAsset, createAsset, updateAsset, uploadAssetImage } from '/@/api/assets/asset';
|
||||
import { getCategoryTree, getCategory } from '/@/api/assets/category';
|
||||
import { createFormDiff } from '/@/utils/diffUtils';
|
||||
import Editor from '/@/components/editor/index.vue';
|
||||
import type { UploadFile, UploadUserFile, UploadRequestOptions } from 'element-plus';
|
||||
|
||||
@@ -555,6 +556,8 @@ const dialogVisible = ref(false);
|
||||
const dialogImageUrl = ref('');
|
||||
// 图片拼接
|
||||
const fileAddressPrefix = ref('');
|
||||
// 使用通用工具函数保存原始数据,用于最小化传参
|
||||
const assetFormDiff = createFormDiff<Record<string, any>>();
|
||||
|
||||
const formatImageUrl = (url?: string) => {
|
||||
if (!url) return '';
|
||||
@@ -1021,6 +1024,9 @@ const openDialog = (row?: any, edit?: boolean) => {
|
||||
categoryAttrs.value = [];
|
||||
});
|
||||
}
|
||||
|
||||
// 保存原始数据用于最小化传参
|
||||
assetFormDiff.saveOriginal(JSON.parse(JSON.stringify(ruleForm)));
|
||||
})
|
||||
.finally(() => {
|
||||
formLoading.value = false;
|
||||
@@ -1187,7 +1193,21 @@ const onSubmit = async () => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
const requestBody = await buildRequestBody();
|
||||
const fullRequestBody = await buildRequestBody();
|
||||
|
||||
let requestBody: any;
|
||||
if (isEdit.value) {
|
||||
// 编辑模式:通过 _originalData 让拦截器自动处理最小化传参
|
||||
const originalData = assetFormDiff.getOriginal();
|
||||
requestBody = {
|
||||
...fullRequestBody,
|
||||
_originalData: originalData,
|
||||
};
|
||||
} else {
|
||||
// 新增模式:传递所有字段
|
||||
requestBody = fullRequestBody;
|
||||
}
|
||||
|
||||
const request = isEdit.value ? updateAsset(requestBody) : createAsset(requestBody);
|
||||
|
||||
await request;
|
||||
|
||||
@@ -174,6 +174,7 @@ import { ref, reactive } from 'vue';
|
||||
import { ElMessage, type FormInstance, type FormRules } from 'element-plus';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { listAssetSkus, createAssetSku, updateAssetSku, deleteAssetSku, getAssetSku, getAsset, uploadAssetImage, getSpecsUnitOptions } from '/@/api/assets/asset';
|
||||
import { createFormDiff } from '/@/utils/diffUtils';
|
||||
import type { UploadRequestOptions, UploadUserFile } from 'element-plus';
|
||||
|
||||
interface SpecValueItem {
|
||||
@@ -228,6 +229,9 @@ const skuForm = reactive({
|
||||
|
||||
const specValuesList = ref<SpecValueItem[]>([{ key: '', value: '' }]);
|
||||
const specValuesMap = reactive<Record<string, string>>({});
|
||||
// 使用通用工具函数保存原始数据,用于最小化传参
|
||||
const skuFormDiff = createFormDiff<Record<string, any>>();
|
||||
const specValuesMapDiff = createFormDiff<Record<string, string>>();
|
||||
|
||||
const skuRules: FormRules = {
|
||||
skuName: [{ required: true, message: '请输入SKU名称', trigger: 'blur' }],
|
||||
@@ -402,6 +406,19 @@ const onEditSku = async (row: any) => {
|
||||
skuForm.specsUnit = data.specsUnit || '';
|
||||
}
|
||||
skuForm.specsCount = data.specsCount || 1;
|
||||
// 使用工具函数保存原始数据用于最小化传参
|
||||
skuFormDiff.saveOriginal({
|
||||
skuName: skuForm.skuName,
|
||||
price: skuForm.price,
|
||||
stock: skuForm.stock,
|
||||
unlimitedStock: skuForm.unlimitedStock,
|
||||
status: skuForm.status,
|
||||
sort: skuForm.sort,
|
||||
imageUrl: skuForm.imageUrl,
|
||||
description: skuForm.description,
|
||||
specsUnit: skuForm.specsUnit,
|
||||
specsCount: skuForm.specsCount,
|
||||
});
|
||||
// 图片预览回显
|
||||
if (data.imageUrl) {
|
||||
skuImagePreview.value = formatImageUrl(data.imageUrl);
|
||||
@@ -437,6 +454,8 @@ const onEditSku = async (row: any) => {
|
||||
} else {
|
||||
specValuesList.value = [{ key: '', value: '' }];
|
||||
}
|
||||
// 保存原始规格属性数据
|
||||
specValuesMapDiff.saveOriginal({ ...specValuesMap });
|
||||
} catch (error) {
|
||||
skuFormVisible.value = false;
|
||||
} finally {
|
||||
@@ -599,7 +618,7 @@ const onSubmitSku = async () => {
|
||||
});
|
||||
|
||||
// 构建 specsUnit 对象格式
|
||||
let specsUnitObj = undefined;
|
||||
let specsUnitObj: { key: string; value: string } | undefined = undefined;
|
||||
if (skuForm.specsUnit) {
|
||||
const unitOption = specsUnitOptions.value.find((opt) => opt.key === skuForm.specsUnit);
|
||||
specsUnitObj = {
|
||||
@@ -608,26 +627,57 @@ const onSubmitSku = async () => {
|
||||
};
|
||||
}
|
||||
|
||||
const data = {
|
||||
assetId: assetId.value,
|
||||
assetName: assetName.value,
|
||||
skuName: skuForm.skuName,
|
||||
imageUrl: skuForm.imageUrl || undefined,
|
||||
specValues: specValues.length > 0 ? specValues : undefined,
|
||||
price: Math.round(skuForm.price * 100),
|
||||
unlimitedStock: skuForm.unlimitedStock,
|
||||
stock: skuForm.stock,
|
||||
sort: skuForm.sort,
|
||||
status: skuForm.status,
|
||||
description: skuForm.description,
|
||||
specsUnit: specsUnitObj,
|
||||
specsCount: skuForm.specsCount || undefined,
|
||||
};
|
||||
|
||||
try {
|
||||
if (isEditSku.value) {
|
||||
await updateAssetSku({ ...data, id: editSkuId.value });
|
||||
// 编辑模式:使用工具函数获取修改过的字段
|
||||
const currentFormData = {
|
||||
skuName: skuForm.skuName,
|
||||
price: skuForm.price,
|
||||
stock: skuForm.stock,
|
||||
unlimitedStock: skuForm.unlimitedStock,
|
||||
status: skuForm.status,
|
||||
sort: skuForm.sort,
|
||||
imageUrl: skuForm.imageUrl,
|
||||
description: skuForm.description,
|
||||
specsUnit: skuForm.specsUnit,
|
||||
specsCount: skuForm.specsCount,
|
||||
};
|
||||
|
||||
const changedFields = skuFormDiff.getChanges(currentFormData, {
|
||||
alwaysInclude: ['id'],
|
||||
transformers: {
|
||||
price: (val) => Math.round(val * 100),
|
||||
specsUnit: () => specsUnitObj,
|
||||
imageUrl: (val) => val || undefined,
|
||||
},
|
||||
});
|
||||
|
||||
// 添加 id
|
||||
const changedData: Record<string, any> = { id: editSkuId.value, ...changedFields };
|
||||
|
||||
// 比较规格属性
|
||||
if (specValuesMapDiff.hasChanges(specValuesMap) && specValues.length > 0) {
|
||||
changedData.specValues = specValues;
|
||||
}
|
||||
|
||||
await updateAssetSku(changedData as any);
|
||||
} else {
|
||||
// 新增模式:传递所有字段
|
||||
const data = {
|
||||
assetId: assetId.value,
|
||||
assetName: assetName.value,
|
||||
skuName: skuForm.skuName,
|
||||
imageUrl: skuForm.imageUrl || undefined,
|
||||
specValues: specValues.length > 0 ? specValues : undefined,
|
||||
price: Math.round(skuForm.price * 100),
|
||||
unlimitedStock: skuForm.unlimitedStock,
|
||||
stock: skuForm.stock,
|
||||
sort: skuForm.sort,
|
||||
status: skuForm.status,
|
||||
description: skuForm.description,
|
||||
specsUnit: specsUnitObj,
|
||||
specsCount: skuForm.specsCount || undefined,
|
||||
};
|
||||
await createAssetSku(data);
|
||||
}
|
||||
ElMessage.success(isEditSku.value ? '编辑成功' : '添加成功');
|
||||
|
||||
@@ -126,6 +126,7 @@ import { ElMessage } from 'element-plus';
|
||||
import { Plus, Delete } from '@element-plus/icons-vue';
|
||||
import { getCategoryTree, getCategory, addCategory, updateCategory, getCategoryAttrTypeOptions } from '/@/api/assets/category';
|
||||
import { getDicts } from '/@/api/system/dict/data';
|
||||
import { createFormDiff } from '/@/utils/diffUtils';
|
||||
|
||||
interface CategoryRow {
|
||||
id: string;
|
||||
@@ -181,6 +182,8 @@ const attrTypeOptions = ref<{ key: string; value: string }[]>([]);
|
||||
const dictTypeOptions = ref<DictInfo[]>([]);
|
||||
const dictValueOptions = ref<any[]>([]);
|
||||
const dictLoading = ref(false);
|
||||
// 使用通用工具函数保存原始数据,用于最小化传参
|
||||
const categoryFormDiff = createFormDiff<Record<string, any>>();
|
||||
|
||||
const ruleForm = reactive<RuleForm>({
|
||||
id: '',
|
||||
@@ -362,7 +365,12 @@ const openDialog = (row?: CategoryRow | string, edit?: boolean) => {
|
||||
}
|
||||
}
|
||||
});
|
||||
// 保存原始数据用于最小化传参
|
||||
categoryFormDiff.saveOriginal(JSON.parse(JSON.stringify(ruleForm)));
|
||||
});
|
||||
} else {
|
||||
// 保存原始数据用于最小化传参
|
||||
categoryFormDiff.saveOriginal(JSON.parse(JSON.stringify(ruleForm)));
|
||||
}
|
||||
});
|
||||
} else if (row && typeof row === 'string') {
|
||||
@@ -432,10 +440,16 @@ const onSubmit = () => {
|
||||
options: [],
|
||||
};
|
||||
});
|
||||
const submitData = { ...ruleForm, attrs: processedAttrs };
|
||||
|
||||
if (isEdit.value) {
|
||||
// 修改
|
||||
// 编辑模式:通过 _originalData 让拦截器自动处理最小化传参
|
||||
const originalData = categoryFormDiff.getOriginal();
|
||||
const submitData = {
|
||||
...ruleForm,
|
||||
attrs: processedAttrs,
|
||||
_originalData: originalData,
|
||||
};
|
||||
|
||||
updateCategory(submitData)
|
||||
.then(() => {
|
||||
ElMessage.success('修改成功');
|
||||
@@ -446,7 +460,8 @@ const onSubmit = () => {
|
||||
submitLoading.value = false;
|
||||
});
|
||||
} else {
|
||||
// 新增
|
||||
// 新增模式:传递所有字段
|
||||
const submitData = { ...ruleForm, attrs: processedAttrs };
|
||||
addCategory(submitData)
|
||||
.then(() => {
|
||||
ElMessage.success('添加成功');
|
||||
|
||||
Reference in New Issue
Block a user