liding
2026-05-20 842da1670c7b652ab131982c73f3eb78e82212e4
feat:1.销售产品从库存选择
已修改2个文件
118 ■■■■ 文件已修改
src/api/basicData/product.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/salesLedger/index.vue 109 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/basicData/product.js
@@ -64,4 +64,13 @@
        method: 'get',
        responseType: 'blob'
    })
}
// 成品库存列表(用于销售台账产品选择)
export function finishedProductList(query) {
    return request({
        url: '/stockInventory/finishedProductList',
        method: 'get',
        params: query
    })
}
src/views/salesManagement/salesLedger/index.vue
@@ -344,10 +344,10 @@
                </el-row>
                <el-row :gutter="30">
                    <el-col :span="24">
                        <el-form-item label="规格型号:" prop="productModelId">
                            <el-select v-model="productForm.productModelId" placeholder="请选择" clearable
                        <el-form-item label="电压:" prop="stockId">
                            <el-select v-model="productForm.stockId" placeholder="请选择" clearable
                                @change="getProductModel" filterable>
                                <el-option v-for="item in modelOptions" :key="item.id" :label="item.model"
                                <el-option v-for="item in modelOptions" :key="item.id" :label="item.label"
                                    :value="item.id" />
                            </el-select>
                        </el-form-item>
@@ -672,7 +672,7 @@
  delProduct,
  delLedgerFile, getProductInventory,
} from "@/api/salesManagement/salesLedger.js";
import { modelList, productTreeList } from "@/api/basicData/product.js";
import { finishedProductList } from "@/api/basicData/product.js";
import useFormData from "@/hooks/useFormData.js";
import dayjs from "dayjs";
import { getCurrentDate } from "@/utils/index.js";
@@ -686,6 +686,7 @@
const userList = ref([]);
const customerOption = ref([]);
const productOptions = ref([]);
const productOptionsRaw = ref([]); // 保存原始数据(包含 children)
const modelOptions = ref([]);
const tableLoading = ref(false);
const page = reactive({
@@ -920,35 +921,71 @@
// 获取产品大类tree数据
const getProductOptions = () => {
    // 返回 Promise,便于在编辑产品时等待加载完成
    return productTreeList({productName: '成品'}).then((res) => {
        const tree = convertIdToValue(res);
        const finishedNode = tree.find(
            (item) => item?.label === '成品' || item?.productName === '成品'
        );
        productOptions.value = finishedNode?.children || tree;
    return finishedProductList({}).then((res) => {
        // 保存原始数据(包含 children)用于后续提取电压列表
        productOptionsRaw.value = res || [];
        // 产品大类下拉选项
        productOptions.value = (res || []).map(item => ({
            ...item,
            value: item.productId,  // 用 productId 作为 value
            children: undefined     // 去掉下拉箭头
        }));
        return productOptions.value;
    });
};
const formattedNumber = (row, column, cellValue) => {
    return parseFloat(cellValue).toFixed(2);
};
// 获取tree子数据
// 获取tree子数据(从 children 中提取电压列表)
const getModels = (value) => {
    productForm.value.productCategory = findNodeById(productOptions.value, value);
    modelList({ id: value }).then((res) => {
        modelOptions.value = res;
    });
    // 从原始数据中找到选中的节点(包含 children)
    const selectedNode = productOptionsRaw.value.find(item => item.productId === value);
    if (selectedNode && selectedNode.children && selectedNode.children.length > 0) {
        // 提取 children 中的型号数据,拼接显示文本
        modelOptions.value = selectedNode.children
            .map(item => {
                // 拼接显示文本:model - processCategory - voltage(过滤空字符串)
                const parts = [];
                if (item.model && item.model.trim()) parts.push(item.model);
                if (item.processCategory && item.processCategory.trim()) parts.push(item.processCategory);
                if (item.voltage && item.voltage.trim()) parts.push(item.voltage);
                return {
                    ...item,
                    id: item.stockId,  // 用 stockId 作为唯一标识
                    productModelId: item.productModelId,  // 保存 productModelId 用于提交
                    label: parts.join('-')
                };
            })
            .filter(item => item.label);  // 过滤掉 label 为空的选项
    } else {
        modelOptions.value = [];
    }
};
const getProductModel = (value) => {
    const index = modelOptions.value.findIndex((item) => item.id === value);
    if (index !== -1) {
        productForm.value.specificationModel = modelOptions.value[index].model;
        productForm.value.unit = modelOptions.value[index].unit;
        productForm.value.materialCode = modelOptions.value[index].materialCode;
        const selectedItem = modelOptions.value[index];
        // 规格型号存储拼接值,用于表格显示
        productForm.value.specificationModel = selectedItem.label;
        productForm.value.unit = selectedItem.unit;
        productForm.value.materialCode = selectedItem.materialCode;
        // 保存电压信息
        productForm.value.voltage = selectedItem.voltage;
        // 保存工序类别
        productForm.value.processCategory = selectedItem.processCategory;
        // 保存 productModelId 用于提交
        productForm.value.productModelId = selectedItem.productModelId;
        // 保存 stockId 用于提交
        productForm.value.stockId = selectedItem.stockId;
    } else {
        productForm.value.specificationModel = null;
        productForm.value.unit = null;
        productForm.value.materialCode = null;
        productForm.value.voltage = null;
        productForm.value.processCategory = null;
        productForm.value.productModelId = null;
        productForm.value.stockId = null;
    }
};
const findNodeById = (nodes, productId) => {
@@ -967,13 +1004,13 @@
};
function convertIdToValue(data) {
    return data.map((item) => {
        const { id, children, ...rest } = item;
        const { productId, children, ...rest } = item;
        const newItem = {
            ...rest,
            value: id, // 将 id 改为 value
            value: productId, // 产品大类用 productId 作为 value
        };
        if (children && children.length > 0) {
            newItem.children = convertIdToValue(children);
            newItem.children = children;  // children 保持原样
        }
        return newItem;
@@ -1272,22 +1309,36 @@
    if (type === "edit") {
        productForm.value = { ...row };
        productIndex.value = index;
        // 编辑时根据产品大类名称反查 tree 节点 id,并加载规格型号列表
        // 编辑时根据产品大类名称反查 tree 节点 id,并加载电压列表
        try {
            const options = productOptions.value && productOptions.value.length > 0
                ? productOptions.value
                : await getProductOptions();
            const categoryId = findNodeIdByLabel(options, productForm.value.productCategory);
            if (categoryId) {
                const models = await modelList({ id: categoryId });
                modelOptions.value = models || [];
                // 根据当前规格型号名称反查并设置 productModelId,便于下拉框显示已选值
                const currentModel = (modelOptions.value || []).find(
                    (m) => m.model === productForm.value.specificationModel
                );
                if (currentModel) {
                    productForm.value.productModelId = currentModel.id;
                // 从原始数据中找到选中的节点,提取 children
                const selectedNode = productOptionsRaw.value.find(item => item.productId === categoryId);
                if (selectedNode && selectedNode.children && selectedNode.children.length > 0) {
                    modelOptions.value = selectedNode.children
                        .map(item => {
                            // 拼接显示文本:model - processCategory - voltage(过滤空字符串)
                            const parts = [];
                            if (item.model && item.model.trim()) parts.push(item.model);
                            if (item.processCategory && item.processCategory.trim()) parts.push(item.processCategory);
                            if (item.voltage && item.voltage.trim()) parts.push(item.voltage);
                            return {
                                ...item,
                                id: item.stockId,  // 用 stockId 作为唯一标识
                                productModelId: item.productModelId,
                                label: parts.join('-')
                            };
                        })
                        .filter(item => item.label);  // 过滤掉 label 为空的选项
                }
                // 根据当前 stockId 设置选中值(用于下拉框回显)
                productForm.value.stockId = row.stockId;
                // 同时保存 productModelId
                productForm.value.productModelId = row.productModelId;
            }
        } catch (e) {
            // 加载失败时保持可编辑,不中断弹窗