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 表单