From 31faa5d08bf553ce13cda13a49a79356e8ded45e Mon Sep 17 00:00:00 2001 From: WUSIJIAN <13825895+wsj0228@user.noreply.gitee.com> Date: Wed, 14 Jan 2026 16:53:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=BA=93=E5=AD=98=E7=94=9F?= =?UTF-8?q?=E6=88=90=E5=8A=9F=E8=83=BD,=E6=94=AF=E6=8C=81=E6=98=8E?= =?UTF-8?q?=E7=BB=86=E6=A8=A1=E5=BC=8F=E5=92=8C=E6=89=B9=E6=AC=A1=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E4=B8=A4=E7=A7=8D=E5=AD=98=E5=82=A8=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?,=E5=9C=A8SKU=E7=AE=A1=E7=90=86=E4=B8=AD=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E8=A1=A8=E5=8D=95=E5=AD=97=E6=AE=B5=E7=9A=84?= =?UTF-8?q?=E5=BA=93=E5=AD=98=E6=93=8D=E4=BD=9C,=E5=90=8C=E6=97=B6?= =?UTF-8?q?=E5=9C=A8=E8=B5=84=E4=BA=A7=E7=BC=96=E8=BE=91=E4=B8=AD=E4=B8=BA?= =?UTF-8?q?=E7=A7=9F=E6=88=B7ID=E4=B8=BA1=E7=9A=84=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=AD=98=E5=82=A8=E6=A8=A1=E5=BC=8F=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/assets/asset/index.ts | 28 ++++ .../assets/asset/component/editAsset.vue | 20 +++ .../assets/asset/component/skuDialog.vue | 149 +++++++++++++++++- 3 files changed, 192 insertions(+), 5 deletions(-) diff --git a/src/api/assets/asset/index.ts b/src/api/assets/asset/index.ts index 88bbd65..0529548 100644 --- a/src/api/assets/asset/index.ts +++ b/src/api/assets/asset/index.ts @@ -163,3 +163,31 @@ export function getSpecsUnitOptions(assetType: string) { params: { assetType }, }); } + +// 获取库存表单字段 +export function getStockFormFields(assetSkuId: string) { + return newService({ + url: '/assets/stock/manage/getStockFormFields', + method: 'get', + params: { assetSkuId }, + }); +} + +// 库存操作 +export interface StockOperationParams { + assetSkuId: string; + stock?: number; + batchNo?: string; + productionDate?: string; + expiryDate?: string; + expiryWarningDate?: string; + [key: string]: any; // 支持动态字段 +} + +export function stockOperation(data: StockOperationParams) { + return newService({ + url: '/assets/stock/manage/stockOperation', + method: 'post', + data, + }); +} diff --git a/src/views/assets/asset/component/editAsset.vue b/src/views/assets/asset/component/editAsset.vue index 55d27f0..ff4e32a 100644 --- a/src/views/assets/asset/component/editAsset.vue +++ b/src/views/assets/asset/component/editAsset.vue @@ -70,6 +70,14 @@ + + + + 明细模式 + 批次模式 + + + @@ -454,6 +462,7 @@ 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 { Session } from '/@/utils/storage'; import Editor from '/@/components/editor/index.vue'; import type { UploadFile, UploadUserFile, UploadRequestOptions } from 'element-plus'; @@ -495,6 +504,7 @@ interface RuleForm { onlineTime: string; offlineTime: string; unlimitedStock: boolean; + stockMode: number; physicalAssetConfig: { shipping: { deliveryMethod: string; @@ -568,6 +578,9 @@ const fileAddressPrefix = ref(''); // 使用通用工具函数保存原始数据,用于最小化传参 const assetFormDiff = createFormDiff>(); +// 获取租户ID +const tenantId = ref(Session.get('userInfo')?.tenantId || ''); + const formatImageUrl = (url?: string) => { if (!url) return ''; if (/^https?:\/\//i.test(url)) return url; @@ -598,6 +611,7 @@ const getInitialForm = (): RuleForm => ({ onlineTime: '', offlineTime: '', unlimitedStock: false, + stockMode: 1, physicalAssetConfig: { shipping: { deliveryMethod: 'express', @@ -903,6 +917,7 @@ const openDialog = (row?: any, edit?: boolean) => { ruleForm.onlineTime = data.onlineTime || ''; ruleForm.offlineTime = data.offlineTime || ''; ruleForm.unlimitedStock = data.unlimitedStock || false; + ruleForm.stockMode = data.stockMode || 1; // 主图预览 (支持 imageUrl 和 fileURL) const mainImg = data.imageUrl || data.fileURL; @@ -1110,6 +1125,11 @@ const buildRequestBody = async (): Promise => { // 库存类型 body.unlimitedStock = ruleForm.unlimitedStock; + // 库存存储模式(仅租户ID为1时提交) + if (tenantId.value === '1') { + body.stockMode = ruleForm.stockMode; + } + // 主图 (已在上传时直接赋值给 ruleForm.mainImage) if (ruleForm.mainImage) { body.imageURL = ruleForm.mainImage; diff --git a/src/views/assets/asset/component/skuDialog.vue b/src/views/assets/asset/component/skuDialog.vue index c812a6b..964744a 100644 --- a/src/views/assets/asset/component/skuDialog.vue +++ b/src/views/assets/asset/component/skuDialog.vue @@ -81,7 +81,7 @@ @@ -163,6 +163,50 @@ 确认 + + + + + + + + + + + @@ -170,7 +214,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 { listAssetSkus, createAssetSku, updateAssetSku, deleteAssetSku, getAssetSku, getAsset, uploadAssetImage, getSpecsUnitOptions, getStockFormFields, stockOperation } from '/@/api/assets/asset'; import { createFormDiff } from '/@/utils/diffUtils'; import type { UploadRequestOptions, UploadUserFile } from 'element-plus'; @@ -185,6 +229,18 @@ interface AssetSpecAttr { dictType?: string; } +// 库存表单字段接口 +interface StockFormField { + name: string; + label: string; + type: string; + required?: boolean; + min?: number; + max?: number; + maxLength?: number; + default?: string | number; +} + const dialogVisible = ref(false); const loading = ref(false); const submitLoading = ref(false); @@ -193,6 +249,16 @@ const skuFormVisible = ref(false); const isEditSku = ref(false); const editSkuId = ref(''); +// 库存弹窗相关 +const stockFormVisible = ref(false); +const stockFormLoading = ref(false); +const stockSubmitLoading = ref(false); +const stockFormFields = ref([]); +const stockFormRef = ref(); +const stockForm = reactive>({}); +const currentSkuId = ref(''); +const currentSkuName = ref(''); + const assetId = ref(''); const assetName = ref(''); const assetType = ref(''); @@ -479,9 +545,82 @@ const onDeleteSku = (row: any) => { }; // 生成库存 -const onGenerateStock = (row: any) => { - // TODO: 实现生成库存功能 - ElMessage.info(`生成库存功能待实现,SKU: ${row.skuName}`); +const onGenerateStock = async (row: any) => { + currentSkuId.value = row.id; + currentSkuName.value = row.skuName; + stockFormVisible.value = true; + stockFormLoading.value = true; + + // 重置表单 + Object.keys(stockForm).forEach((key) => delete stockForm[key]); + + try { + const res = await getStockFormFields(row.id); + stockFormFields.value = res.data.fields || []; + + // 设置默认值 + stockFormFields.value.forEach((field) => { + if (field.default !== undefined) { + stockForm[field.name] = field.default; + } else if (field.type === 'number') { + stockForm[field.name] = field.min || 0; + } else { + stockForm[field.name] = ''; + } + }); + } catch (error) { + console.error('获取库存表单字段失败:', error); + ElMessage.error('获取库存表单字段失败'); + stockFormVisible.value = false; + } finally { + stockFormLoading.value = false; + } +}; + +// 提交库存操作 +const onSubmitStock = async () => { + const form = stockFormRef.value; + if (!form) return; + + form.validate(async (valid: boolean) => { + if (valid) { + stockSubmitLoading.value = true; + try { + await stockOperation({ + assetSkuId: currentSkuId.value, + ...stockForm, + }); + ElMessage.success('库存生成成功'); + stockFormVisible.value = false; + getSkuList(); + } catch (error) { + console.error('库存操作失败:', error); + } finally { + stockSubmitLoading.value = false; + } + } + }); +}; + +// 生成库存表单验证规则 +const getStockFormRules = () => { + const rules: Record = {}; + stockFormFields.value.forEach((field) => { + const fieldRules: any[] = []; + if (field.required) { + fieldRules.push({ required: true, message: `${field.label}不能为空`, trigger: 'blur' }); + } + if (field.type === 'number' && field.min !== undefined) { + fieldRules.push({ type: 'number', min: field.min, message: `${field.label}最小值为${field.min}`, trigger: 'blur' }); + } + if (field.maxLength) { + fieldRules.push({ max: field.maxLength, message: `${field.label}最大长度为${field.maxLength}`, trigger: 'blur' }); + } + if (fieldRules.length > 0) { + rules[field.name] = fieldRules; + } + }); + return rules; }; // 重置 SKU 表单