| | |
| | | <el-form-item label="参数类型" |
| | | prop="paramType"> |
| | | <el-select v-model="formData.paramType" |
| | | @change="handleParamTypeChange" |
| | | placeholder="请选择参数类型"> |
| | | <el-option label="数值格式" |
| | | value="1" /> |
| | |
| | | <el-form-item label="取值模式" |
| | | prop="valueMode"> |
| | | <el-select v-model="formData.valueMode" |
| | | @change="handleValueModeChange" |
| | | placeholder="请选择取值模式"> |
| | | <el-option label="单值" |
| | | value="1" /> |
| | |
| | | <el-input v-model="formData.unit" |
| | | placeholder="请输入单位" /> |
| | | </el-form-item> |
| | | <el-form-item label="默认值" |
| | | v-if="formData.valueMode === '1'" |
| | | prop="defaultValue"> |
| | | <el-input v-model="formData.defaultValue" |
| | | placeholder="请输入默认值" /> |
| | | <el-form-item label="取值格式" |
| | | v-if="formData.paramType == '1' || formData.paramType == '2'" |
| | | prop="paramFormat"> |
| | | <el-input v-model="formData.paramFormat" |
| | | placeholder="请输入取值格式" /> |
| | | </el-form-item> |
| | | <el-form-item label="最小值" |
| | | v-if="formData.valueMode === '2'" |
| | | prop="defaultMin"> |
| | | <el-input v-model="formData.defaultMin" |
| | | placeholder="请输入最小值" /> |
| | | <el-form-item label="下拉字典" |
| | | v-else-if="formData.paramType == '3'" |
| | | prop="paramFormat"> |
| | | <el-select v-model="formData.paramFormat" |
| | | placeholder="请选择取值模式"> |
| | | <el-option v-for="item in dictTypes" |
| | | :key="item.dictType" |
| | | :label="item.dictName" |
| | | :value="item.dictType" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="最大值" |
| | | v-if="formData.valueMode === '2'" |
| | | prop="defaultMax"> |
| | | <el-input v-model="formData.defaultMax" |
| | | placeholder="请输入最大值" /> |
| | | <el-form-item label="时间格式" |
| | | v-else-if="formData.paramType == '4'" |
| | | prop="paramFormat"> |
| | | <el-select v-model="formData.paramFormat" |
| | | placeholder="请选择取值模式"> |
| | | <el-option label="YYYY-MM-DD" |
| | | value="YYYY-MM-DD" /> |
| | | <el-option label="YYYY-MM-DD HH:mm:ss" |
| | | value="YYYY-MM-DD HH:mm:ss" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="是否必填" |
| | | prop="isRequired"> |
| | |
| | | prop: "unit", |
| | | }, |
| | | { |
| | | label: "默认值", |
| | | prop: "defaultValue", |
| | | label: "取值格式", |
| | | prop: "paramFormat", |
| | | formatData: (val, row) => { |
| | | return row.valueMode === 2 ? "-" : val; |
| | | }, |
| | | }, |
| | | { |
| | | label: "最小值", |
| | | prop: "defaultMin", |
| | | formatData: (val, row) => { |
| | | return row.valueMode === 1 ? "-" : val; |
| | | }, |
| | | }, |
| | | { |
| | | label: "最大值", |
| | | prop: "defaultMax", |
| | | formatData: (val, row) => { |
| | | return row.valueMode === 1 ? "-" : val; |
| | | if (row.paramType == "3") { |
| | | const dict = dictTypes.value.find(item => item.dictType === val); |
| | | return dict ? "字典:" + dict.dictName : val; |
| | | } |
| | | return val; |
| | | }, |
| | | }, |
| | | { |
| | |
| | | size: 10, |
| | | total: 0, |
| | | }); |
| | | const handleValueModeChange = val => { |
| | | if (val === "2") { |
| | | formData.defaultMin = ""; |
| | | formData.defaultMax = ""; |
| | | } else { |
| | | formData.defaultValue = ""; |
| | | } |
| | | }; |
| | | |
| | | // 搜索表单 |
| | | const searchForm = reactive({ |
| | | paramName: "", |
| | |
| | | paramType: "", |
| | | valueMode: "1", |
| | | unit: "", |
| | | defaultValue: "", |
| | | defaultMin: "", |
| | | defaultMax: "", |
| | | isRequired: "0", |
| | | remark: "", |
| | | }); |
| | |
| | | paramName: [{ required: true, message: "请输入参数名称", trigger: "blur" }], |
| | | paramType: [{ required: true, message: "请选择参数类型", trigger: "change" }], |
| | | valueMode: [{ required: true, message: "请选择取值模式", trigger: "change" }], |
| | | unit: [{ required: true, message: "请输入单位", trigger: "blur" }], |
| | | unit: [ |
| | | { |
| | | required: false, |
| | | message: "请输入单位", |
| | | trigger: "blur", |
| | | validator: (rule, value, callback) => { |
| | | if (formData.paramType === "1" && !value) { |
| | | callback(new Error("数值类型必须填写单位")); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }, |
| | | }, |
| | | ], |
| | | }); |
| | | // const productTypes = ref([]); |
| | | const isEdit = ref(false); |
| | |
| | | // typeName: [{ required: true, message: "请输入类型名称", trigger: "blur" }], |
| | | // }); |
| | | // const isProductTypeEdit = ref(false); |
| | | const handleParameterTypeChange = () => { |
| | | if (formData.parameterType === "数值格式") { |
| | | formData.parameterFormat = "#.0000"; |
| | | } else if (formData.parameterType === "时间格式") { |
| | | formData.parameterFormat = "YYYY-MM-DD HH:mm:ss"; |
| | | const handleParamTypeChange = () => { |
| | | if (formData.paramType === "1") { |
| | | formData.paramFormat = "#.0000"; |
| | | } else if (formData.paramType === "4") { |
| | | formData.paramFormat = "YYYY-MM-DD HH:mm:ss"; |
| | | } else { |
| | | formData.parameterFormat = ""; |
| | | formData.paramFormat = ""; |
| | | } |
| | | // 触发单位字段验证 |
| | | if (formRef.value) { |
| | | formRef.value.validateField("unit"); |
| | | } |
| | | }; |
| | | // 产品类型维护按钮点击事件 - 已注释 |
| | |
| | | formData.paramType = ""; |
| | | formData.valueMode = "1"; |
| | | formData.unit = ""; |
| | | formData.defaultValue = ""; |
| | | formData.defaultMin = ""; |
| | | formData.defaultMax = ""; |
| | | formData.isRequired = "0"; |
| | | formData.remark = ""; |
| | | dialogVisible.value = true; |
| | |
| | | formData.valueMode = |
| | | row.valueMode !== undefined ? String(row.valueMode) : "1"; |
| | | formData.unit = row.unit || ""; |
| | | formData.defaultValue = |
| | | row.defaultValue !== undefined ? String(row.defaultValue) : ""; |
| | | formData.defaultMin = |
| | | row.defaultMin !== undefined ? String(row.defaultMin) : ""; |
| | | formData.defaultMax = |
| | | row.defaultMax !== undefined ? String(row.defaultMax) : ""; |
| | | formData.isRequired = |
| | | row.isRequired !== undefined ? String(row.isRequired) : "0"; |
| | | formData.remark = row.remark || ""; |
| | |
| | | <template> |
| | | <el-dialog v-model="visible" title="选择产品" width="900px" destroy-on-close :close-on-click-modal="false"> |
| | | <el-form :inline="true" :model="query" class="mb-2"> |
| | | <el-form-item label="产品大类"> |
| | | <el-input v-model="query.productName" placeholder="输入产品大类" clearable @keyup.enter="onSearch" /> |
| | | <el-dialog v-model="visible" |
| | | title="选择产品" |
| | | width="900px" |
| | | destroy-on-close |
| | | :close-on-click-modal="false"> |
| | | <el-form :inline="true" |
| | | :model="query" |
| | | class="mb-2"> |
| | | <el-form-item label="规格"> |
| | | <el-input v-model="query.specification" |
| | | placeholder="输入规格" |
| | | clearable |
| | | @keyup.enter="onSearch" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="型号名称"> |
| | | <el-input v-model="query.model" placeholder="输入型号名称" clearable @keyup.enter="onSearch" /> |
| | | <el-form-item label="物料编码"> |
| | | <el-input v-model="query.materialCode" |
| | | placeholder="输入物料编码" |
| | | clearable |
| | | @keyup.enter="onSearch" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-button type="primary" @click="onSearch">搜索</el-button> |
| | | <el-button type="primary" |
| | | @click="onSearch">搜索</el-button> |
| | | <el-button @click="onReset">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <!-- 列表 --> |
| | | <el-table ref="tableRef" v-loading="loading" :data="tableData" height="420" highlight-current-row row-key="id" |
| | | @selection-change="handleSelectionChange" @select="handleSelect"> |
| | | <el-table-column type="selection" width="55" /> |
| | | <el-table-column type="index" label="序号" width="60" /> |
| | | <el-table-column prop="productName" label="产品大类" min-width="160" /> |
| | | <el-table-column prop="model" label="型号名称" min-width="200" /> |
| | | <el-table-column prop="unit" label="单位" min-width="160" /> |
| | | <el-table ref="tableRef" |
| | | v-loading="loading" |
| | | :data="tableData" |
| | | height="420" |
| | | highlight-current-row |
| | | row-key="skuId" |
| | | @selection-change="handleSelectionChange" |
| | | @select="handleSelect"> |
| | | <el-table-column type="selection" |
| | | width="55" /> |
| | | <el-table-column type="index" |
| | | label="序号" |
| | | width="60" /> |
| | | <el-table-column prop="materialName" |
| | | label="产品名称" |
| | | min-width="160" /> |
| | | <el-table-column prop="materialCode" |
| | | label="物料编码" |
| | | min-width="200" /> |
| | | <el-table-column prop="specification" |
| | | label="规格" |
| | | min-width="200" /> |
| | | <el-table-column prop="baseUnit" |
| | | label="单位" |
| | | min-width="160" /> |
| | | </el-table> |
| | | |
| | | <div class="mt-3 flex justify-end"> |
| | | <el-pagination background layout="total, sizes, prev, pager, next, jumper" :total="total" |
| | | v-model:page-size="page.pageSize" v-model:current-page="page.pageNum" :page-sizes="[10, 20, 50, 100]" |
| | | @size-change="onPageChange" @current-change="onPageChange" /> |
| | | <el-pagination background |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :total="total" |
| | | v-model:page-size="page.pageSize" |
| | | v-model:current-page="page.pageNum" |
| | | :page-sizes="[10, 20, 50, 100]" |
| | | @size-change="onPageChange" |
| | | @current-change="onPageChange" /> |
| | | </div> |
| | | |
| | | <template #footer> |
| | | <el-button @click="close()">取消</el-button> |
| | | <el-button type="primary" :disabled="multipleSelection.length === 0" @click="onConfirm"> |
| | | <el-button type="primary" |
| | | :disabled="multipleSelection.length === 0" |
| | | @click="onConfirm"> |
| | | 确定 |
| | | </el-button> |
| | | </template> |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { computed, onMounted, reactive, ref, watch, nextTick } from "vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import { productModelList } from '@/api/basicData/productModel' |
| | | import { computed, onMounted, reactive, ref, watch, nextTick } from "vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import { modelListPage } from "@/api/basicData/newProduct"; |
| | | |
| | | export type ProductRow = { |
| | | id: number; |
| | | productName: string; |
| | | model: string; |
| | | unit?: string; |
| | | }; |
| | | export type ProductRow = { |
| | | skuId: number; |
| | | specification: string; |
| | | materialCode: string; |
| | | baseUnit?: string; |
| | | materialName?: string; |
| | | }; |
| | | |
| | | const props = defineProps<{ |
| | | modelValue: boolean; |
| | | single?: boolean; // 是否只能选择一个,默认false(可选择多个) |
| | | }>(); |
| | | const props = defineProps<{ |
| | | modelValue: boolean; |
| | | single?: boolean; // 是否只能选择一个,默认false(可选择多个) |
| | | }>(); |
| | | |
| | | const emit = defineEmits(['update:modelValue', 'confirm']); |
| | | const emit = defineEmits(["update:modelValue", "confirm"]); |
| | | |
| | | const visible = computed({ |
| | | get: () => props.modelValue, |
| | | set: (v) => emit("update:modelValue", v), |
| | | }); |
| | | const visible = computed({ |
| | | get: () => props.modelValue, |
| | | set: v => emit("update:modelValue", v), |
| | | }); |
| | | |
| | | const query = reactive({ |
| | | productName: "", |
| | | model: "", |
| | | }); |
| | | const query = reactive({ |
| | | specification: "", |
| | | materialCode: "", |
| | | }); |
| | | |
| | | const page = reactive({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | }); |
| | | const page = reactive({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | }); |
| | | |
| | | const loading = ref(false); |
| | | const tableData = ref<ProductRow[]>([]); |
| | | const total = ref(0); |
| | | const multipleSelection = ref<ProductRow[]>([]); |
| | | const tableRef = ref(); |
| | | const loading = ref(false); |
| | | const tableData = ref<ProductRow[]>([]); |
| | | const total = ref(0); |
| | | const multipleSelection = ref<ProductRow[]>([]); |
| | | const tableRef = ref(); |
| | | |
| | | function close() { |
| | | visible.value = false; |
| | | } |
| | | |
| | | const handleSelectionChange = (val: ProductRow[]) => { |
| | | if (props.single && val.length > 1) { |
| | | // 如果限制为单个选择,只保留最后一个选中的 |
| | | const lastSelected = val[val.length - 1]; |
| | | multipleSelection.value = [lastSelected]; |
| | | // 清空表格选中状态,然后重新选中最后一个 |
| | | nextTick(() => { |
| | | if (tableRef.value) { |
| | | tableRef.value.clearSelection(); |
| | | tableRef.value.toggleRowSelection(lastSelected, true); |
| | | } |
| | | }); |
| | | } else { |
| | | multipleSelection.value = val; |
| | | function close() { |
| | | visible.value = false; |
| | | } |
| | | } |
| | | |
| | | // 处理单个选择 |
| | | const handleSelect = (selection: ProductRow[], row: ProductRow) => { |
| | | if (props.single) { |
| | | // 如果限制为单个,清空其他选择,只保留当前行 |
| | | if (selection.includes(row)) { |
| | | // 选中当前行时,清空其他选中 |
| | | multipleSelection.value = [row]; |
| | | const handleSelectionChange = (val: ProductRow[]) => { |
| | | if (props.single && val.length > 1) { |
| | | // 如果限制为单个选择,只保留最后一个选中的 |
| | | const lastSelected = val[val.length - 1]; |
| | | multipleSelection.value = [lastSelected]; |
| | | // 清空表格选中状态,然后重新选中最后一个 |
| | | nextTick(() => { |
| | | if (tableRef.value) { |
| | | tableData.value.forEach((item) => { |
| | | if (item.id !== row.id) { |
| | | tableRef.value.toggleRowSelection(item, false); |
| | | } |
| | | }); |
| | | tableRef.value.clearSelection(); |
| | | tableRef.value.toggleRowSelection(lastSelected, true); |
| | | } |
| | | }); |
| | | } else { |
| | | multipleSelection.value = val; |
| | | } |
| | | }; |
| | | |
| | | // 处理单个选择 |
| | | const handleSelect = (selection: ProductRow[], row: ProductRow) => { |
| | | if (props.single) { |
| | | // 如果限制为单个,清空其他选择,只保留当前行 |
| | | if (selection.includes(row)) { |
| | | // 选中当前行时,清空其他选中 |
| | | multipleSelection.value = [row]; |
| | | nextTick(() => { |
| | | if (tableRef.value) { |
| | | tableData.value.forEach(item => { |
| | | if (item.skuId !== row.skuId) { |
| | | tableRef.value.toggleRowSelection(item, false); |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | function onSearch() { |
| | | page.pageNum = 1; |
| | | loadData(); |
| | | } |
| | | |
| | | function onReset() { |
| | | query.specification = ""; |
| | | query.materialCode = ""; |
| | | page.pageNum = 1; |
| | | loadData(); |
| | | } |
| | | |
| | | function onPageChange() { |
| | | loadData(); |
| | | } |
| | | |
| | | function onConfirm() { |
| | | if (multipleSelection.value.length === 0) { |
| | | ElMessage.warning("请选择一条产品"); |
| | | return; |
| | | } |
| | | if (props.single && multipleSelection.value.length > 1) { |
| | | ElMessage.warning("只能选择一个产品"); |
| | | return; |
| | | } |
| | | emit( |
| | | "confirm", |
| | | props.single ? [multipleSelection.value[0]] : multipleSelection.value |
| | | ); |
| | | close(); |
| | | } |
| | | |
| | | async function loadData() { |
| | | loading.value = true; |
| | | try { |
| | | multipleSelection.value = []; // 翻页/搜索后清空选择更符合预期 |
| | | const res: any = await modelListPage({ |
| | | specification: query.specification.trim(), |
| | | materialCode: query.materialCode.trim(), |
| | | current: page.pageNum, |
| | | size: page.pageSize, |
| | | }); |
| | | tableData.value = res.data.records; |
| | | total.value = res.data.total; |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | } |
| | | } |
| | | |
| | | function onSearch() { |
| | | page.pageNum = 1; |
| | | loadData(); |
| | | } |
| | | // 监听弹窗打开,重置选择 |
| | | watch( |
| | | () => props.modelValue, |
| | | visible => { |
| | | if (visible) { |
| | | multipleSelection.value = []; |
| | | } |
| | | } |
| | | ); |
| | | |
| | | function onReset() { |
| | | query.productName = ""; |
| | | query.model = ""; |
| | | page.pageNum = 1; |
| | | loadData(); |
| | | } |
| | | |
| | | function onPageChange() { |
| | | loadData(); |
| | | } |
| | | |
| | | function onConfirm() { |
| | | if (multipleSelection.value.length === 0) { |
| | | ElMessage.warning("请选择一条产品"); |
| | | return; |
| | | } |
| | | if (props.single && multipleSelection.value.length > 1) { |
| | | ElMessage.warning("只能选择一个产品"); |
| | | return; |
| | | } |
| | | emit("confirm", props.single ? [multipleSelection.value[0]] : multipleSelection.value); |
| | | close(); |
| | | } |
| | | |
| | | async function loadData() { |
| | | loading.value = true; |
| | | try { |
| | | multipleSelection.value = []; // 翻页/搜索后清空选择更符合预期 |
| | | const res: any = await productModelList({ |
| | | productName: query.productName.trim(), |
| | | model: query.model.trim(), |
| | | current: page.pageNum, |
| | | size: page.pageSize, |
| | | }); |
| | | tableData.value = res.records; |
| | | total.value = res.total; |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | } |
| | | |
| | | // 监听弹窗打开,重置选择 |
| | | watch(() => props.modelValue, (visible) => { |
| | | if (visible) { |
| | | multipleSelection.value = []; |
| | | } |
| | | }); |
| | | |
| | | onMounted(() => { |
| | | loadData() |
| | | }) |
| | | onMounted(() => { |
| | | loadData(); |
| | | }); |
| | | </script> |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog |
| | | v-model="isShow" |
| | | title="新增库存" |
| | | width="800" |
| | | @close="closeModal" |
| | | > |
| | | <el-form label-width="140px" :model="formState" label-position="top" ref="formRef"> |
| | | <el-form-item |
| | | label="产品名称" |
| | | prop="productModelId" |
| | | :rules="[ |
| | | <el-dialog v-model="isShow" |
| | | title="新增库存" |
| | | width="800" |
| | | @close="closeModal"> |
| | | <el-form label-width="140px" |
| | | :model="formState" |
| | | label-position="top" |
| | | ref="formRef"> |
| | | <el-form-item label="产品名称" |
| | | prop="productModelId" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: '请选择产品', |
| | | trigger: 'change', |
| | | } |
| | | ]" |
| | | > |
| | | <el-button type="primary" @click="showProductSelectDialog = true"> |
| | | ]"> |
| | | <el-button type="primary" |
| | | @click="showProductSelectDialog = true"> |
| | | {{ formState.productName ? formState.productName : '选择产品' }} |
| | | </el-button> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="规格" |
| | | prop="productModelName" |
| | | > |
| | | <el-input v-model="formState.productModelName" disabled /> |
| | | <el-form-item label="规格" |
| | | prop="productModelName"> |
| | | <el-input v-model="formState.productModelName" |
| | | disabled /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="单位" |
| | | prop="unit" |
| | | > |
| | | <el-input v-model="formState.unit" disabled /> |
| | | <el-form-item label="单位" |
| | | prop="unit"> |
| | | <el-input v-model="formState.unit" |
| | | disabled /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="库存数量" |
| | | prop="qualitity" |
| | | > |
| | | <el-input-number v-model="formState.qualitity" :step="1" :min="1" style="width: 100%" /> |
| | | <el-form-item label="库存数量" |
| | | prop="qualitity"> |
| | | <el-input-number v-model="formState.qualitity" |
| | | :step="1" |
| | | :min="1" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | v-if="type === 'qualified'" |
| | | label="库存预警数量" |
| | | prop="warnNum" |
| | | > |
| | | <el-input-number v-model="formState.warnNum" :step="1" :min="0" :max="formState.qualitity" style="width: 100%" /> |
| | | <el-form-item v-if="type === 'qualified'" |
| | | label="库存预警数量" |
| | | prop="warnNum"> |
| | | <el-input-number v-model="formState.warnNum" |
| | | :step="1" |
| | | :min="0" |
| | | :max="formState.qualitity" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="备注" prop="remark"> |
| | | <el-input v-model="formState.remark" type="textarea" /> |
| | | <el-form-item label="备注" |
| | | prop="remark"> |
| | | <el-input v-model="formState.remark" |
| | | type="textarea" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <!-- 产品选择弹窗 --> |
| | | <ProductSelectDialog |
| | | v-model="showProductSelectDialog" |
| | | @confirm="handleProductSelect" |
| | | single |
| | | /> |
| | | <ProductSelectDialog v-model="showProductSelectDialog" |
| | | @confirm="handleProductSelect" |
| | | single /> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="handleSubmit">确认</el-button> |
| | | <el-button type="primary" |
| | | @click="handleSubmit">确认</el-button> |
| | | <el-button @click="closeModal">取消</el-button> |
| | | </div> |
| | | </template> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref, computed, getCurrentInstance} from "vue"; |
| | | import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; |
| | | import {createStockInventory} from "@/api/inventoryManagement/stockInventory.js"; |
| | | import {createStockUnInventory} from "@/api/inventoryManagement/stockUninventory.js"; |
| | | import { ref, computed, getCurrentInstance } from "vue"; |
| | | import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; |
| | | import { createStockInventory } from "@/api/inventoryManagement/stockInventory.js"; |
| | | import { createStockUnInventory } from "@/api/inventoryManagement/stockUninventory.js"; |
| | | |
| | | const props = defineProps({ |
| | | visible: { |
| | | type: Boolean, |
| | | required: true, |
| | | }, |
| | | const props = defineProps({ |
| | | visible: { |
| | | type: Boolean, |
| | | required: true, |
| | | }, |
| | | |
| | | type: { |
| | | type: String, |
| | | required: true, |
| | | default: 'qualified', |
| | | }, |
| | | }); |
| | | type: { |
| | | type: String, |
| | | required: true, |
| | | default: "qualified", |
| | | }, |
| | | }); |
| | | |
| | | const emit = defineEmits(['update:visible', 'completed']); |
| | | const emit = defineEmits(["update:visible", "completed"]); |
| | | |
| | | // 响应式数据(替代选项式的 data) |
| | | const formState = ref({ |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | unit: "", |
| | | qualitity: 0, |
| | | warnNum: 0, |
| | | remark: '', |
| | | }); |
| | | |
| | | const isShow = computed({ |
| | | get() { |
| | | return props.visible; |
| | | }, |
| | | set(val) { |
| | | emit('update:visible', val); |
| | | }, |
| | | }); |
| | | |
| | | const showProductSelectDialog = ref(false); |
| | | |
| | | let { proxy } = getCurrentInstance() |
| | | |
| | | const closeModal = () => { |
| | | // 重置表单数据 |
| | | formState.value = { |
| | | // 响应式数据(替代选项式的 data) |
| | | const formState = ref({ |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | description: '', |
| | | unit: "", |
| | | qualitity: 0, |
| | | warnNum: 0, |
| | | remark: "", |
| | | }); |
| | | |
| | | const isShow = computed({ |
| | | get() { |
| | | return props.visible; |
| | | }, |
| | | set(val) { |
| | | emit("update:visible", val); |
| | | }, |
| | | }); |
| | | |
| | | const showProductSelectDialog = ref(false); |
| | | |
| | | let { proxy } = getCurrentInstance(); |
| | | |
| | | const closeModal = () => { |
| | | // 重置表单数据 |
| | | formState.value = { |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | description: "", |
| | | }; |
| | | isShow.value = false; |
| | | }; |
| | | isShow.value = false; |
| | | }; |
| | | |
| | | // 产品选择处理 |
| | | const handleProductSelect = async (products) => { |
| | | if (products && products.length > 0) { |
| | | const product = products[0]; |
| | | formState.value.productId = product.productId; |
| | | formState.value.productName = product.productName; |
| | | formState.value.productModelName = product.model; |
| | | formState.value.productModelId = product.id; |
| | | formState.value.unit = product.unit; |
| | | showProductSelectDialog.value = false; |
| | | // 触发表单验证更新 |
| | | proxy.$refs["formRef"]?.validateField('productModelId'); |
| | | } |
| | | }; |
| | | // 产品选择处理 |
| | | const handleProductSelect = async products => { |
| | | if (products && products.length > 0) { |
| | | const product = products[0]; |
| | | formState.value.productId = product.skuId; |
| | | formState.value.productName = product.materialName; |
| | | formState.value.productModelName = product.specification; |
| | | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // 验证是否选择了产品和规格 |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("请选择产品"); |
| | | return; |
| | | } |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("请选择规格"); |
| | | return; |
| | | } |
| | | if (props.type === 'qualified') { |
| | | createStockInventory(formState.value).then(res => { |
| | | // 关闭模态框 |
| | | isShow.value = false; |
| | | // 告知父组件已完成 |
| | | emit('completed'); |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | }) |
| | | } else { |
| | | createStockUnInventory(formState.value).then(res => { |
| | | // 关闭模态框 |
| | | isShow.value = false; |
| | | // 告知父组件已完成 |
| | | emit('completed'); |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | }) |
| | | } |
| | | |
| | | formState.value.productModelId = product.skuId; |
| | | formState.value.unit = product.baseUnit; |
| | | showProductSelectDialog.value = false; |
| | | // 触发表单验证更新 |
| | | proxy.$refs["formRef"]?.validateField("productModelId"); |
| | | } |
| | | }) |
| | | }; |
| | | }; |
| | | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // 验证是否选择了产品和规格 |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("请选择产品"); |
| | | return; |
| | | } |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("请选择规格"); |
| | | return; |
| | | } |
| | | if (props.type === "qualified") { |
| | | createStockInventory(formState.value).then(res => { |
| | | // 关闭模态框 |
| | | isShow.value = false; |
| | | // 告知父组件已完成 |
| | | emit("completed"); |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | }); |
| | | } else { |
| | | createStockUnInventory(formState.value).then(res => { |
| | | // 关闭模态框 |
| | | isShow.value = false; |
| | | // 告知父组件已完成 |
| | | emit("completed"); |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | defineExpose({ |
| | | closeModal, |
| | | handleSubmit, |
| | | isShow, |
| | | }); |
| | | defineExpose({ |
| | | closeModal, |
| | | handleSubmit, |
| | | isShow, |
| | | }); |
| | | </script> |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog |
| | | v-model="isShow" |
| | | title="领用" |
| | | width="800" |
| | | @close="closeModal" |
| | | > |
| | | <el-form label-width="140px" :model="formState" label-position="top" ref="formRef"> |
| | | <el-form-item |
| | | label="产品名称" |
| | | prop="productModelId" |
| | | :rules="[ |
| | | <el-dialog v-model="isShow" |
| | | title="领用" |
| | | width="800" |
| | | @close="closeModal"> |
| | | <el-form label-width="140px" |
| | | :model="formState" |
| | | label-position="top" |
| | | ref="formRef"> |
| | | <el-form-item label="产品名称" |
| | | prop="productModelId" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: '请选择产品', |
| | | trigger: 'change', |
| | | } |
| | | ]" |
| | | > |
| | | <el-button type="primary" @click="showProductSelectDialog = true" disabled> |
| | | ]"> |
| | | <el-button type="primary" |
| | | @click="showProductSelectDialog = true" |
| | | disabled> |
| | | {{ formState.productName ? formState.productName : '选择产品' }} |
| | | </el-button> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="规格" |
| | | prop="productModelName" |
| | | > |
| | | <el-input v-model="formState.model" disabled /> |
| | | <el-form-item label="规格" |
| | | prop="productModelName"> |
| | | <el-input v-model="formState.model" |
| | | disabled /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="单位" |
| | | prop="unit" |
| | | > |
| | | <el-input v-model="formState.unit" disabled /> |
| | | <el-form-item label="单位" |
| | | prop="unit"> |
| | | <el-input v-model="formState.unit" |
| | | disabled /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="数量" |
| | | prop="qualitity" |
| | | > |
| | | <el-input-number v-model="formState.qualitity" :step="1" :min="1" :max="maxQuality" style="width: 100%" /> |
| | | <el-form-item label="数量" |
| | | prop="qualitity"> |
| | | <el-input-number v-model="formState.qualitity" |
| | | :step="1" |
| | | :min="1" |
| | | :max="maxQuality" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="备注" prop="remark"> |
| | | <el-input v-model="formState.remark" type="textarea" /> |
| | | <el-form-item label="备注" |
| | | prop="remark"> |
| | | <el-input v-model="formState.remark" |
| | | type="textarea" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <!-- 产品选择弹窗 --> |
| | | <ProductSelectDialog |
| | | v-model="showProductSelectDialog" |
| | | @confirm="handleProductSelect" |
| | | single |
| | | /> |
| | | <ProductSelectDialog v-model="showProductSelectDialog" |
| | | @confirm="handleProductSelect" |
| | | single /> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="handleSubmit">确认</el-button> |
| | | <el-button type="primary" |
| | | @click="handleSubmit">确认</el-button> |
| | | <el-button @click="closeModal">取消</el-button> |
| | | </div> |
| | | </template> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref, computed, getCurrentInstance} from "vue"; |
| | | import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; |
| | | import {subtractStockInventory} from "@/api/inventoryManagement/stockInventory.js"; |
| | | import {subtractStockUnInventory} from "@/api/inventoryManagement/stockUninventory.js"; |
| | | import { ref, computed, getCurrentInstance } from "vue"; |
| | | import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; |
| | | import { subtractStockInventory } from "@/api/inventoryManagement/stockInventory.js"; |
| | | import { subtractStockUnInventory } from "@/api/inventoryManagement/stockUninventory.js"; |
| | | |
| | | const props = defineProps({ |
| | | visible: { |
| | | type: Boolean, |
| | | required: true, |
| | | }, |
| | | record: { |
| | | type: Object, |
| | | default: () => {}, |
| | | }, |
| | | type: { |
| | | type: String, |
| | | required: true, |
| | | default: 'qualified', |
| | | }, |
| | | }); |
| | | const props = defineProps({ |
| | | visible: { |
| | | type: Boolean, |
| | | required: true, |
| | | }, |
| | | record: { |
| | | type: Object, |
| | | default: () => {}, |
| | | }, |
| | | type: { |
| | | type: String, |
| | | required: true, |
| | | default: "qualified", |
| | | }, |
| | | }); |
| | | |
| | | const emit = defineEmits(['update:visible', 'completed']); |
| | | const emit = defineEmits(["update:visible", "completed"]); |
| | | |
| | | onMounted(() => { |
| | | initFormData() |
| | | }) |
| | | onMounted(() => { |
| | | initFormData(); |
| | | }); |
| | | |
| | | const maxQuality = computed(() => { |
| | | return props.record.unLockedQuantity ? props.record.unLockedQuantity : 0; |
| | | }) |
| | | const maxQuality = computed(() => { |
| | | return props.record.unLockedQuantity ? props.record.unLockedQuantity : 0; |
| | | }); |
| | | |
| | | const initFormData = () => { |
| | | if (props.record) { |
| | | formState.value = { |
| | | ...props.record, |
| | | const initFormData = () => { |
| | | if (props.record) { |
| | | formState.value = { |
| | | ...props.record, |
| | | }; |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | |
| | | // 响应式数据(替代选项式的 data) |
| | | const formState = ref({ |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | | model: "", |
| | | unit: "", |
| | | qualitity: 0, |
| | | remark: '', |
| | | }); |
| | | |
| | | const isShow = computed({ |
| | | get() { |
| | | return props.visible; |
| | | }, |
| | | set(val) { |
| | | emit('update:visible', val); |
| | | }, |
| | | }); |
| | | |
| | | const showProductSelectDialog = ref(false); |
| | | |
| | | let { proxy } = getCurrentInstance() |
| | | |
| | | const closeModal = () => { |
| | | // 重置表单数据 |
| | | formState.value = { |
| | | // 响应式数据(替代选项式的 data) |
| | | const formState = ref({ |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | description: '', |
| | | model: "", |
| | | unit: "", |
| | | qualitity: 0, |
| | | remark: "", |
| | | }); |
| | | |
| | | const isShow = computed({ |
| | | get() { |
| | | return props.visible; |
| | | }, |
| | | set(val) { |
| | | emit("update:visible", val); |
| | | }, |
| | | }); |
| | | |
| | | const showProductSelectDialog = ref(false); |
| | | |
| | | let { proxy } = getCurrentInstance(); |
| | | |
| | | const closeModal = () => { |
| | | // 重置表单数据 |
| | | formState.value = { |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | description: "", |
| | | }; |
| | | isShow.value = false; |
| | | }; |
| | | isShow.value = false; |
| | | }; |
| | | |
| | | // 产品选择处理 |
| | | const handleProductSelect = async (products) => { |
| | | if (products && products.length > 0) { |
| | | const product = products[0]; |
| | | console.log(product) |
| | | formState.value.productId = product.productId; |
| | | formState.value.productName = product.productName; |
| | | formState.value.productModelName = product.model; |
| | | formState.value.productModelId = product.id; |
| | | formState.value.unit = product.unit; |
| | | showProductSelectDialog.value = false; |
| | | // 触发表单验证更新 |
| | | proxy.$refs["formRef"]?.validateField('productModelId'); |
| | | } |
| | | }; |
| | | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // 验证是否选择了产品和规格 |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("请选择产品"); |
| | | return; |
| | | } |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("请选择规格"); |
| | | return; |
| | | } |
| | | if (props.type === 'qualified') { |
| | | subtractStockInventory(formState.value).then(res => { |
| | | // 关闭模态框 |
| | | isShow.value = false; |
| | | // 告知父组件已完成 |
| | | emit('completed'); |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | }) |
| | | } else { |
| | | subtractStockUnInventory(formState.value).then(res => { |
| | | // 关闭模态框 |
| | | isShow.value = false; |
| | | // 告知父组件已完成 |
| | | emit('completed'); |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | }) |
| | | } |
| | | // 产品选择处理 |
| | | const handleProductSelect = async products => { |
| | | if (products && products.length > 0) { |
| | | const product = products[0]; |
| | | console.log(product); |
| | | formState.value.productId = product.skuId; |
| | | formState.value.productName = product.materialName; |
| | | formState.value.productModelName = product.specification; |
| | | formState.value.productModelId = product.skuId; |
| | | formState.value.unit = product.baseUnit; |
| | | showProductSelectDialog.value = false; |
| | | // 触发表单验证更新 |
| | | proxy.$refs["formRef"]?.validateField("productModelId"); |
| | | } |
| | | }) |
| | | }; |
| | | }; |
| | | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // 验证是否选择了产品和规格 |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("请选择产品"); |
| | | return; |
| | | } |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("请选择规格"); |
| | | return; |
| | | } |
| | | if (props.type === "qualified") { |
| | | subtractStockInventory(formState.value).then(res => { |
| | | // 关闭模态框 |
| | | isShow.value = false; |
| | | // 告知父组件已完成 |
| | | emit("completed"); |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | }); |
| | | } else { |
| | | subtractStockUnInventory(formState.value).then(res => { |
| | | // 关闭模态框 |
| | | isShow.value = false; |
| | | // 告知父组件已完成 |
| | | emit("completed"); |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | defineExpose({ |
| | | closeModal, |
| | | handleSubmit, |
| | | isShow, |
| | | }); |
| | | defineExpose({ |
| | | closeModal, |
| | | handleSubmit, |
| | | isShow, |
| | | }); |
| | | </script> |
| | |
| | | const product = products[0]; |
| | | // 先查询BOM列表(必选) |
| | | try { |
| | | const res = await getByModel(product.id); |
| | | const res = await getByModel(product.skuId); |
| | | // 处理返回的BOM数据:可能是数组、对象或包含data字段 |
| | | let bomList = []; |
| | | if (Array.isArray(res)) { |
| | |
| | | } |
| | | |
| | | if (bomList.length > 0) { |
| | | routeForm.productModelId = product.id; |
| | | routeForm.productName = product.productName; |
| | | routeForm.productModelName = product.model; |
| | | routeForm.productModelId = product.skuId; |
| | | routeForm.productName = product.materialName; |
| | | routeForm.productModelName = product.specification; |
| | | routeForm.bomId = undefined; // 重置BOM选择 |
| | | bomOptions.value = bomList; |
| | | showProductSelectDialog.value = false; |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div style="text-align: right; margin-bottom: 10px;"> |
| | | <el-button type="info" plain icon="Upload" @click="handleImport" |
| | | v-hasPermi="['product:bom:import']">导入</el-button> |
| | | <el-button type="warning" plain icon="Download" @click="handleExport" :disabled="selectedRows.length !== 1" |
| | | v-hasPermi="['product:bom:export']">导出</el-button> |
| | | <el-button type="primary" @click="handleAdd">新增</el-button> |
| | | <el-button type="danger" plain @click="handleBatchDelete" :disabled="selectedRows.length === 0">删除</el-button> |
| | | <el-button type="info" |
| | | plain |
| | | icon="Upload" |
| | | @click="handleImport" |
| | | v-hasPermi="['product:bom:import']">导入</el-button> |
| | | <el-button type="warning" |
| | | plain |
| | | icon="Download" |
| | | @click="handleExport" |
| | | :disabled="selectedRows.length !== 1" |
| | | v-hasPermi="['product:bom:export']">导出</el-button> |
| | | <el-button type="primary" |
| | | @click="handleAdd">新增</el-button> |
| | | <el-button type="danger" |
| | | plain |
| | | @click="handleBatchDelete" |
| | | :disabled="selectedRows.length === 0">删除</el-button> |
| | | </div> |
| | | <PIMTable rowKey="id" :column="tableColumn" :tableData="tableData" :page="page" :isSelection="true" |
| | | @selection-change="handleSelectionChange" :tableLoading="tableLoading" @pagination="pagination"> |
| | | <PIMTable rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination"> |
| | | <template #detail="{ row }"> |
| | | <el-button type="primary" text @click="showDetail(row)">{{ row.bomNo }} |
| | | <el-button type="primary" |
| | | text |
| | | @click="showDetail(row)">{{ row.bomNo }} |
| | | </el-button> |
| | | </template> |
| | | </PIMTable> |
| | | <StructureEdit v-if="showEdit" v-model:show-model="showEdit" :record="currentRow" /> |
| | | |
| | | <StructureEdit v-if="showEdit" |
| | | v-model:show-model="showEdit" |
| | | :record="currentRow" /> |
| | | <!-- 新增/编辑弹窗 --> |
| | | <el-dialog v-model="dialogVisible" :title="operationType === 'add' ? '新增BOM' : '编辑BOM'" width="600px" |
| | | @close="closeDialog"> |
| | | <el-form ref="formRef" :model="form" :rules="rules" label-width="120px"> |
| | | <el-form-item label="产品名称" prop="productModelId"> |
| | | <el-button type="primary" @click="showProductSelectDialog = true"> |
| | | <el-dialog v-model="dialogVisible" |
| | | :title="operationType === 'add' ? '新增BOM' : '编辑BOM'" |
| | | width="600px" |
| | | @close="closeDialog"> |
| | | <el-form ref="formRef" |
| | | :model="form" |
| | | :rules="rules" |
| | | label-width="120px"> |
| | | <el-form-item label="产品名称" |
| | | prop="productModelId"> |
| | | <el-button type="primary" |
| | | @click="showProductSelectDialog = true"> |
| | | {{ form.productName || '选择产品' }} |
| | | </el-button> |
| | | </el-form-item> |
| | | <el-form-item label="版本号" prop="version"> |
| | | <el-input v-model="form.version" placeholder="请输入版本号" clearable /> |
| | | <el-form-item label="版本号" |
| | | prop="version"> |
| | | <el-input v-model="form.version" |
| | | placeholder="请输入版本号" |
| | | clearable /> |
| | | </el-form-item> |
| | | <el-form-item label="备注" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注" clearable /> |
| | | <el-form-item label="备注" |
| | | prop="remark"> |
| | | <el-input v-model="form.remark" |
| | | type="textarea" |
| | | :rows="3" |
| | | placeholder="请输入备注" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="closeDialog">取消</el-button> |
| | | <el-button type="primary" @click="handleSubmit">确定</el-button> |
| | | <el-button type="primary" |
| | | @click="handleSubmit">确定</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- 产品选择弹窗 --> |
| | | <ProductSelectDialog v-model="showProductSelectDialog" @confirm="handleProductSelect" single /> |
| | | |
| | | <ProductSelectDialog v-model="showProductSelectDialog" |
| | | @confirm="handleProductSelect" |
| | | single /> |
| | | <!-- BOM导入对话框 --> |
| | | <ImportDialog ref="uploadRef" v-model="upload.open" :title="upload.title" :action="upload.url" |
| | | :headers="upload.headers" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" |
| | | :on-success="handleFileSuccess" :show-download-template="true" @confirm="submitFileForm" |
| | | @download-template="handleDownloadTemplate" @close="handleImportClose" /> |
| | | <ImportDialog ref="uploadRef" |
| | | v-model="upload.open" |
| | | :title="upload.title" |
| | | :action="upload.url" |
| | | :headers="upload.headers" |
| | | :disabled="upload.isUploading" |
| | | :on-progress="handleFileUploadProgress" |
| | | :on-success="handleFileSuccess" |
| | | :show-download-template="true" |
| | | @confirm="submitFileForm" |
| | | @download-template="handleDownloadTemplate" |
| | | @close="handleImportClose" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, toRefs, onMounted, getCurrentInstance, defineAsyncComponent } from "vue"; |
| | | import { getToken } from "@/utils/auth"; |
| | | import { listPage, add, update, batchDelete, exportBom, downloadTemplate } from "@/api/productionManagement/productBom.js"; |
| | | import { useRouter } from 'vue-router' |
| | | import { ElMessageBox } from 'element-plus' |
| | | import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; |
| | | import ImportDialog from "@/components/Dialog/ImportDialog.vue"; |
| | | import { |
| | | ref, |
| | | reactive, |
| | | toRefs, |
| | | onMounted, |
| | | getCurrentInstance, |
| | | defineAsyncComponent, |
| | | } from "vue"; |
| | | import { getToken } from "@/utils/auth"; |
| | | import { |
| | | listPage, |
| | | add, |
| | | update, |
| | | batchDelete, |
| | | exportBom, |
| | | downloadTemplate, |
| | | } from "@/api/productionManagement/productBom.js"; |
| | | import { useRouter } from "vue-router"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; |
| | | import ImportDialog from "@/components/Dialog/ImportDialog.vue"; |
| | | |
| | | const router = useRouter() |
| | | const { proxy } = getCurrentInstance() |
| | | const StructureEdit = defineAsyncComponent(() => import('@/views/productionManagement/productStructure/StructureEdit.vue')) |
| | | const router = useRouter(); |
| | | const { proxy } = getCurrentInstance(); |
| | | const StructureEdit = defineAsyncComponent(() => |
| | | import("@/views/productionManagement/productStructure/StructureEdit.vue") |
| | | ); |
| | | |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "BOM编号", |
| | | prop: "bomNo", |
| | | dataType: 'slot', |
| | | slot: "detail", |
| | | minWidth: 140 |
| | | }, |
| | | { |
| | | label: "产品名称", |
| | | prop: "productName", |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "BOM编号", |
| | | prop: "bomNo", |
| | | dataType: "slot", |
| | | slot: "detail", |
| | | minWidth: 140, |
| | | }, |
| | | { |
| | | label: "产品名称", |
| | | prop: "productName", |
| | | |
| | | minWidth: 160 |
| | | }, |
| | | { |
| | | label: "规格型号", |
| | | prop: "productModelName", |
| | | minWidth: 140 |
| | | }, |
| | | { |
| | | label: "版本号", |
| | | prop: "version", |
| | | width: 100 |
| | | }, |
| | | { |
| | | label: "备注", |
| | | prop: "remark", |
| | | minWidth: 160 |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "操作", |
| | | align: "center", |
| | | fixed: "right", |
| | | width: 150, |
| | | operation: [ |
| | | { |
| | | name: "编辑", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | handleEdit(row) |
| | | } |
| | | }, |
| | | { |
| | | name: "删除", |
| | | type: "danger", |
| | | link: true, |
| | | clickFun: (row) => { |
| | | handleDelete(row) |
| | | } |
| | | } |
| | | ] |
| | | } |
| | | ]); |
| | | minWidth: 160, |
| | | }, |
| | | { |
| | | label: "规格型号", |
| | | prop: "productModelName", |
| | | minWidth: 140, |
| | | }, |
| | | { |
| | | label: "版本号", |
| | | prop: "version", |
| | | width: 100, |
| | | }, |
| | | { |
| | | label: "备注", |
| | | prop: "remark", |
| | | minWidth: 160, |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "操作", |
| | | align: "center", |
| | | fixed: "right", |
| | | width: 150, |
| | | operation: [ |
| | | { |
| | | name: "编辑", |
| | | type: "text", |
| | | clickFun: row => { |
| | | handleEdit(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "删除", |
| | | type: "danger", |
| | | link: true, |
| | | clickFun: row => { |
| | | handleDelete(row); |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | ]); |
| | | |
| | | const tableData = ref([]); |
| | | const tableLoading = ref(false); |
| | | const showEdit = ref(false); |
| | | const selectedRows = ref([]); |
| | | const currentRow = ref({}); |
| | | const dialogVisible = ref(false); |
| | | const operationType = ref('add'); // add | edit |
| | | const formRef = ref(null); |
| | | const showProductSelectDialog = ref(false); |
| | | const tableData = ref([]); |
| | | const tableLoading = ref(false); |
| | | const showEdit = ref(false); |
| | | const selectedRows = ref([]); |
| | | const currentRow = ref({}); |
| | | const dialogVisible = ref(false); |
| | | const operationType = ref("add"); // add | edit |
| | | const formRef = ref(null); |
| | | const showProductSelectDialog = ref(false); |
| | | |
| | | // BOM导入参数 |
| | | const upload = reactive({ |
| | | // 是否显示弹出层(BOM导入) |
| | | open: false, |
| | | // 弹出层标题(BOM导入) |
| | | title: "", |
| | | // 是否禁用上传 |
| | | isUploading: false, |
| | | // 设置上传的请求头部 |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | // 上传的地址 |
| | | url: import.meta.env.VITE_APP_BASE_API + "/productBom/uploadBom" |
| | | }); |
| | | |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0, |
| | | }); |
| | | |
| | | const data = reactive({ |
| | | form: { |
| | | id: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | productModelId: "", |
| | | remark: "", |
| | | version: "" |
| | | }, |
| | | rules: { |
| | | productModelId: [{ required: true, message: "请选择产品", trigger: "change" }], |
| | | version: [{ required: true, message: "请输入版本号", trigger: "blur" }] |
| | | } |
| | | }); |
| | | |
| | | const { form, rules } = toRefs(data); |
| | | |
| | | // 表格选择数据 |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | |
| | | // 分页 |
| | | const pagination = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | |
| | | // 查询列表 |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | listPage({ |
| | | current: page.current, |
| | | size: page.size, |
| | | }) |
| | | .then((res) => { |
| | | const records = res?.data?.records || []; |
| | | tableData.value = records; |
| | | page.total = res?.data?.total || 0; |
| | | }) |
| | | .catch((err) => { |
| | | console.error("获取列表失败:", err); |
| | | }) |
| | | .finally(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | // 新增 |
| | | const handleAdd = () => { |
| | | operationType.value = 'add'; |
| | | Object.assign(form.value, { |
| | | id: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | productModelId: "", |
| | | remark: "", |
| | | version: "" |
| | | // BOM导入参数 |
| | | const upload = reactive({ |
| | | // 是否显示弹出层(BOM导入) |
| | | open: false, |
| | | // 弹出层标题(BOM导入) |
| | | title: "", |
| | | // 是否禁用上传 |
| | | isUploading: false, |
| | | // 设置上传的请求头部 |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | // 上传的地址 |
| | | url: import.meta.env.VITE_APP_BASE_API + "/productBom/uploadBom", |
| | | }); |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | // 编辑 |
| | | const handleEdit = (row) => { |
| | | operationType.value = 'edit'; |
| | | Object.assign(form.value, { |
| | | id: row.id, |
| | | productName: row.productName || "", |
| | | productModelName: row.productModelName || "", |
| | | productModelId: row.productModelId || "", |
| | | remark: row.remark || "", |
| | | version: row.version || "" |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0, |
| | | }); |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | // 删除(单条) |
| | | const handleDelete = (row) => { |
| | | ElMessageBox.confirm('确认删除该BOM?', '提示', { |
| | | confirmButtonText: '确认', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }) |
| | | .then(() => { |
| | | batchDelete([row.id]) |
| | | .then(() => { |
| | | proxy.$modal.msgSuccess('删除成功'); |
| | | getList(); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msgError('删除失败'); |
| | | }); |
| | | }) |
| | | .catch(() => { }); |
| | | }; |
| | | |
| | | // 批量删除 |
| | | const handleBatchDelete = () => { |
| | | if (!selectedRows.value.length) { |
| | | proxy.$modal.msgWarning('请选择数据'); |
| | | return; |
| | | } |
| | | const ids = selectedRows.value.map(item => item.id); |
| | | ElMessageBox.confirm('选中的内容将被删除,是否确认删除?', '删除提示', { |
| | | confirmButtonText: '确认', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }) |
| | | .then(() => { |
| | | batchDelete(ids) |
| | | .then(() => { |
| | | proxy.$modal.msgSuccess('删除成功'); |
| | | getList(); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msgError('删除失败'); |
| | | }); |
| | | }) |
| | | .catch(() => { }); |
| | | }; |
| | | |
| | | // 产品选择 |
| | | const handleProductSelect = (products) => { |
| | | if (products && products.length > 0) { |
| | | const product = products[0]; |
| | | form.value.productModelId = product.id; |
| | | form.value.productName = product.productName; |
| | | form.value.productModelName = product.model; |
| | | } |
| | | showProductSelectDialog.value = false; |
| | | }; |
| | | |
| | | // 提交表单 |
| | | const handleSubmit = () => { |
| | | formRef.value.validate((valid) => { |
| | | if (valid) { |
| | | const payload = { ...form.value }; |
| | | if (operationType.value === 'add') { |
| | | add(payload) |
| | | .then(() => { |
| | | proxy.$modal.msgSuccess('新增成功'); |
| | | closeDialog(); |
| | | getList(); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msgError('新增失败'); |
| | | }); |
| | | } else { |
| | | update(payload) |
| | | .then(() => { |
| | | proxy.$modal.msgSuccess('修改成功'); |
| | | closeDialog(); |
| | | getList(); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msgError('修改失败'); |
| | | }); |
| | | } |
| | | } |
| | | const data = reactive({ |
| | | form: { |
| | | id: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | productModelId: "", |
| | | remark: "", |
| | | version: "", |
| | | }, |
| | | rules: { |
| | | productModelId: [ |
| | | { required: true, message: "请选择产品", trigger: "change" }, |
| | | ], |
| | | version: [{ required: true, message: "请输入版本号", trigger: "blur" }], |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | // 关闭弹窗 |
| | | const closeDialog = () => { |
| | | dialogVisible.value = false; |
| | | formRef.value?.resetFields(); |
| | | }; |
| | | const { form, rules } = toRefs(data); |
| | | |
| | | // 导入按钮操作 |
| | | const handleImport = () => { |
| | | upload.title = "BOM导入"; |
| | | upload.open = true; |
| | | }; |
| | | // 表格选择数据 |
| | | const handleSelectionChange = selection => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | |
| | | // 关闭导入对话框时清除文件 |
| | | const handleImportClose = () => { |
| | | proxy.$refs["uploadRef"].clearFiles(); |
| | | }; |
| | | |
| | | // 文件上传中处理 |
| | | const handleFileUploadProgress = (event, file, fileList) => { |
| | | upload.isUploading = true; |
| | | }; |
| | | |
| | | // 文件上传成功处理 |
| | | const handleFileSuccess = (response, file, fileList) => { |
| | | upload.open = false; |
| | | upload.isUploading = false; |
| | | proxy.$refs["uploadRef"].clearFiles(); |
| | | if (response.code === 200) { |
| | | proxy.$modal.msgSuccess(response.msg || "导入成功"); |
| | | // 分页 |
| | | const pagination = obj => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | } else { |
| | | proxy.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true }); |
| | | } |
| | | }; |
| | | }; |
| | | |
| | | // 提交上传文件 |
| | | const submitFileForm = () => { |
| | | proxy.$refs["uploadRef"].submit(); |
| | | }; |
| | | // 查询列表 |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | listPage({ |
| | | current: page.current, |
| | | size: page.size, |
| | | }) |
| | | .then(res => { |
| | | const records = res?.data?.records || []; |
| | | tableData.value = records; |
| | | page.total = res?.data?.total || 0; |
| | | }) |
| | | .catch(err => { |
| | | console.error("获取列表失败:", err); |
| | | }) |
| | | .finally(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | // 导出按钮操作 |
| | | const handleExport = () => { |
| | | if (selectedRows.value.length !== 1) { |
| | | proxy.$modal.msgWarning("请选择一条数据进行导出"); |
| | | return; |
| | | } |
| | | // 新增 |
| | | const handleAdd = () => { |
| | | operationType.value = "add"; |
| | | Object.assign(form.value, { |
| | | id: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | productModelId: "", |
| | | remark: "", |
| | | version: "", |
| | | }); |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | const bomId = selectedRows.value[0].id; |
| | | const fileName = `BOM_${selectedRows.value[0].bomNo || bomId}.xlsx`; |
| | | // 编辑 |
| | | const handleEdit = row => { |
| | | operationType.value = "edit"; |
| | | Object.assign(form.value, { |
| | | id: row.id, |
| | | productName: row.productName || "", |
| | | productModelName: row.productModelName || "", |
| | | productModelId: row.productModelId || "", |
| | | remark: row.remark || "", |
| | | version: row.version || "", |
| | | }); |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | exportBom(bomId).then(res => { |
| | | // 返回的数据是否为空 |
| | | if (!res) { |
| | | proxy.$modal.msgError("导出失败,返回数据为空"); |
| | | // 删除(单条) |
| | | const handleDelete = row => { |
| | | ElMessageBox.confirm("确认删除该BOM?", "提示", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "取消", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | batchDelete([row.id]) |
| | | .then(() => { |
| | | proxy.$modal.msgSuccess("删除成功"); |
| | | getList(); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msgError("删除失败"); |
| | | }); |
| | | }) |
| | | .catch(() => {}); |
| | | }; |
| | | |
| | | // 批量删除 |
| | | const handleBatchDelete = () => { |
| | | if (!selectedRows.value.length) { |
| | | proxy.$modal.msgWarning("请选择数据"); |
| | | return; |
| | | } |
| | | const ids = selectedRows.value.map(item => item.id); |
| | | ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "删除提示", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "取消", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | batchDelete(ids) |
| | | .then(() => { |
| | | proxy.$modal.msgSuccess("删除成功"); |
| | | getList(); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msgError("删除失败"); |
| | | }); |
| | | }) |
| | | .catch(() => {}); |
| | | }; |
| | | |
| | | // 产品选择 |
| | | const handleProductSelect = products => { |
| | | if (products && products.length > 0) { |
| | | const product = products[0]; |
| | | form.value.productModelId = product.skuId; |
| | | form.value.productName = product.materialName; |
| | | form.value.productModelName = product.specification; |
| | | } |
| | | showProductSelectDialog.value = false; |
| | | }; |
| | | |
| | | // 提交表单 |
| | | const handleSubmit = () => { |
| | | formRef.value.validate(valid => { |
| | | if (valid) { |
| | | const payload = { ...form.value }; |
| | | if (operationType.value === "add") { |
| | | add(payload) |
| | | .then(() => { |
| | | proxy.$modal.msgSuccess("新增成功"); |
| | | closeDialog(); |
| | | getList(); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msgError("新增失败"); |
| | | }); |
| | | } else { |
| | | update(payload) |
| | | .then(() => { |
| | | proxy.$modal.msgSuccess("修改成功"); |
| | | closeDialog(); |
| | | getList(); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msgError("修改失败"); |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // 关闭弹窗 |
| | | const closeDialog = () => { |
| | | dialogVisible.value = false; |
| | | formRef.value?.resetFields(); |
| | | }; |
| | | |
| | | // 导入按钮操作 |
| | | const handleImport = () => { |
| | | upload.title = "BOM导入"; |
| | | upload.open = true; |
| | | }; |
| | | |
| | | // 关闭导入对话框时清除文件 |
| | | const handleImportClose = () => { |
| | | proxy.$refs["uploadRef"].clearFiles(); |
| | | }; |
| | | |
| | | // 文件上传中处理 |
| | | const handleFileUploadProgress = (event, file, fileList) => { |
| | | upload.isUploading = true; |
| | | }; |
| | | |
| | | // 文件上传成功处理 |
| | | const handleFileSuccess = (response, file, fileList) => { |
| | | upload.open = false; |
| | | upload.isUploading = false; |
| | | proxy.$refs["uploadRef"].clearFiles(); |
| | | if (response.code === 200) { |
| | | proxy.$modal.msgSuccess(response.msg || "导入成功"); |
| | | getList(); |
| | | } else { |
| | | proxy.$alert( |
| | | "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + |
| | | response.msg + |
| | | "</div>", |
| | | "导入结果", |
| | | { dangerouslyUseHTMLString: true } |
| | | ); |
| | | } |
| | | }; |
| | | |
| | | // 提交上传文件 |
| | | const submitFileForm = () => { |
| | | proxy.$refs["uploadRef"].submit(); |
| | | }; |
| | | |
| | | // 导出按钮操作 |
| | | const handleExport = () => { |
| | | if (selectedRows.value.length !== 1) { |
| | | proxy.$modal.msgWarning("请选择一条数据进行导出"); |
| | | return; |
| | | } |
| | | |
| | | const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); |
| | | const downloadElement = document.createElement('a'); |
| | | const bomId = selectedRows.value[0].id; |
| | | const fileName = `BOM_${selectedRows.value[0].bomNo || bomId}.xlsx`; |
| | | |
| | | exportBom(bomId) |
| | | .then(res => { |
| | | // 返回的数据是否为空 |
| | | if (!res) { |
| | | proxy.$modal.msgError("导出失败,返回数据为空"); |
| | | return; |
| | | } |
| | | |
| | | const blob = new Blob([res], { |
| | | type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", |
| | | }); |
| | | const downloadElement = document.createElement("a"); |
| | | const href = window.URL.createObjectURL(blob); |
| | | |
| | | downloadElement.style.display = "none"; |
| | | downloadElement.href = href; |
| | | downloadElement.download = fileName; |
| | | |
| | | document.body.appendChild(downloadElement); |
| | | downloadElement.click(); |
| | | |
| | | document.body.removeChild(downloadElement); |
| | | window.URL.revokeObjectURL(href); |
| | | |
| | | proxy.$modal.msgSuccess("导出成功"); |
| | | }) |
| | | .catch(err => { |
| | | console.error("导出异常:", err); |
| | | proxy.$modal.msgError("系统异常,导出失败"); |
| | | }); |
| | | }; |
| | | |
| | | // 下载模板 |
| | | const handleDownloadTemplate = async () => { |
| | | const res = await downloadTemplate(); |
| | | // 返回的数据是否为空 |
| | | if (!res) { |
| | | proxy.$modal.msgError("下载失败,返回数据为空"); |
| | | return; |
| | | } |
| | | |
| | | const blob = new Blob([res], { |
| | | type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", |
| | | }); |
| | | const downloadElement = document.createElement("a"); |
| | | const href = window.URL.createObjectURL(blob); |
| | | |
| | | downloadElement.style.display = 'none'; |
| | | downloadElement.href = href; |
| | | downloadElement.download = fileName; |
| | | downloadElement.download = "BOM模板.xlsx"; |
| | | |
| | | document.body.appendChild(downloadElement); |
| | | downloadElement.click(); |
| | |
| | | document.body.removeChild(downloadElement); |
| | | window.URL.revokeObjectURL(href); |
| | | |
| | | proxy.$modal.msgSuccess("导出成功"); |
| | | }).catch(err => { |
| | | console.error("导出异常:", err); |
| | | proxy.$modal.msgError("系统异常,导出失败"); |
| | | proxy.$modal.msgSuccess("下载成功"); |
| | | }; |
| | | |
| | | // 查看详情 |
| | | const showDetail = row => { |
| | | router.push({ |
| | | path: "/productionManagement/productStructureDetail", |
| | | query: { |
| | | id: row.id, |
| | | bomNo: row.bomNo || "", |
| | | productName: row.productName || "", |
| | | productModelName: row.productModelName || "", |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | | }; |
| | | |
| | | // 下载模板 |
| | | const handleDownloadTemplate = async () => { |
| | | const res = await downloadTemplate(); |
| | | // 返回的数据是否为空 |
| | | if (!res) { |
| | | proxy.$modal.msgError("下载失败,返回数据为空"); |
| | | return; |
| | | } |
| | | |
| | | const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); |
| | | const downloadElement = document.createElement('a'); |
| | | const href = window.URL.createObjectURL(blob); |
| | | |
| | | downloadElement.href = href; |
| | | downloadElement.download = "BOM模板.xlsx"; |
| | | |
| | | document.body.appendChild(downloadElement); |
| | | downloadElement.click(); |
| | | |
| | | document.body.removeChild(downloadElement); |
| | | window.URL.revokeObjectURL(href); |
| | | |
| | | proxy.$modal.msgSuccess("下载成功"); |
| | | }; |
| | | |
| | | // 查看详情 |
| | | const showDetail = (row) => { |
| | | router.push({ |
| | | path: '/productionManagement/productStructureDetail', |
| | | query: { |
| | | id: row.id, |
| | | bomNo: row.bomNo || '', |
| | | productName: row.productName || '', |
| | | productModelName: row.productModelName || '' |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | | </script> |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog |
| | | v-model="isShow" |
| | | title="新增生产订单" |
| | | width="800" |
| | | @close="closeModal" |
| | | > |
| | | <el-form label-width="140px" :model="formState" label-position="top" ref="formRef"> |
| | | <el-form-item |
| | | label="产品名称" |
| | | prop="productModelId" |
| | | :rules="[ |
| | | <el-dialog v-model="isShow" |
| | | title="新增生产订单" |
| | | width="800" |
| | | @close="closeModal"> |
| | | <el-form label-width="140px" |
| | | :model="formState" |
| | | label-position="top" |
| | | ref="formRef"> |
| | | <el-form-item label="产品名称" |
| | | prop="productModelId" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: '请选择产品', |
| | | trigger: 'change', |
| | | } |
| | | ]" |
| | | > |
| | | <el-button type="primary" @click="showProductSelectDialog = true"> |
| | | ]"> |
| | | <el-button type="primary" |
| | | @click="showProductSelectDialog = true"> |
| | | {{ formState.productName ? formState.productName : '选择产品' }} |
| | | </el-button> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="规格" |
| | | prop="productModelName" |
| | | > |
| | | <el-input v-model="formState.productModelName" disabled /> |
| | | <el-form-item label="规格" |
| | | prop="productModelName"> |
| | | <el-input v-model="formState.productModelName" |
| | | disabled /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="单位" |
| | | prop="unit" |
| | | > |
| | | <el-input v-model="formState.unit" disabled /> |
| | | <el-form-item label="单位" |
| | | prop="unit"> |
| | | <el-input v-model="formState.unit" |
| | | disabled /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="工艺路线"> |
| | | <el-select v-model="formState.routeId" |
| | | placeholder="请选择工艺路线" |
| | |
| | | :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="需求数量" |
| | | prop="quantity" |
| | | > |
| | | <el-input-number v-model="formState.quantity" :step="1" :min="1" style="width: 100%" /> |
| | | <el-form-item label="需求数量" |
| | | prop="quantity"> |
| | | <el-input-number v-model="formState.quantity" |
| | | :step="1" |
| | | :min="1" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <!-- 产品选择弹窗 --> |
| | | <ProductSelectDialog |
| | | v-model="showProductSelectDialog" |
| | | @confirm="handleProductSelect" |
| | | single |
| | | /> |
| | | <ProductSelectDialog v-model="showProductSelectDialog" |
| | | @confirm="handleProductSelect" |
| | | single /> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="handleSubmit">确认</el-button> |
| | | <el-button type="primary" |
| | | @click="handleSubmit">确认</el-button> |
| | | <el-button @click="closeModal">取消</el-button> |
| | | </div> |
| | | </template> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref, computed, getCurrentInstance} from "vue"; |
| | | import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; |
| | | import {addProductOrder, listProcessRoute} from "@/api/productionManagement/productionOrder.js"; |
| | | import { ref, computed, getCurrentInstance } from "vue"; |
| | | import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; |
| | | import { |
| | | addProductOrder, |
| | | listProcessRoute, |
| | | } from "@/api/productionManagement/productionOrder.js"; |
| | | |
| | | const props = defineProps({ |
| | | visible: { |
| | | type: Boolean, |
| | | required: true, |
| | | }, |
| | | const props = defineProps({ |
| | | visible: { |
| | | type: Boolean, |
| | | required: true, |
| | | }, |
| | | |
| | | type: { |
| | | type: String, |
| | | required: true, |
| | | default: 'qualified', |
| | | }, |
| | | }); |
| | | type: { |
| | | type: String, |
| | | required: true, |
| | | default: "qualified", |
| | | }, |
| | | }); |
| | | |
| | | const emit = defineEmits(['update:visible', 'completed']); |
| | | const emit = defineEmits(["update:visible", "completed"]); |
| | | |
| | | // 响应式数据(替代选项式的 data) |
| | | const formState = ref({ |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | routeId: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | unit: "", |
| | | quantity: 0, |
| | | }); |
| | | |
| | | const isShow = computed({ |
| | | get() { |
| | | return props.visible; |
| | | }, |
| | | set(val) { |
| | | emit('update:visible', val); |
| | | }, |
| | | }); |
| | | |
| | | const showProductSelectDialog = ref(false); |
| | | |
| | | let { proxy } = getCurrentInstance() |
| | | |
| | | const closeModal = () => { |
| | | // 重置表单数据 |
| | | formState.value = { |
| | | // 响应式数据(替代选项式的 data) |
| | | const formState = ref({ |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | routeId: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | quantity: '', |
| | | unit: "", |
| | | quantity: 0, |
| | | }); |
| | | |
| | | const isShow = computed({ |
| | | get() { |
| | | return props.visible; |
| | | }, |
| | | set(val) { |
| | | emit("update:visible", val); |
| | | }, |
| | | }); |
| | | |
| | | const showProductSelectDialog = ref(false); |
| | | |
| | | let { proxy } = getCurrentInstance(); |
| | | |
| | | const closeModal = () => { |
| | | // 重置表单数据 |
| | | formState.value = { |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | routeId: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | quantity: "", |
| | | }; |
| | | isShow.value = false; |
| | | }; |
| | | isShow.value = false; |
| | | }; |
| | | |
| | | // 产品选择处理 |
| | | const handleProductSelect = async (products) => { |
| | | if (products && products.length > 0) { |
| | | const product = products[0]; |
| | | formState.value.productId = product.productId; |
| | | formState.value.productName = product.productName; |
| | | formState.value.productModelName = product.model; |
| | | formState.value.productModelId = product.id; |
| | | formState.value.unit = product.unit; |
| | | showProductSelectDialog.value = false; |
| | | fetchRouteOptions( product.id); |
| | | // 触发表单验证更新 |
| | | proxy.$refs["formRef"]?.validateField('productModelId'); |
| | | } |
| | | }; |
| | | |
| | | const routeOptions = ref([]); |
| | | const bindRouteLoading = ref(false); |
| | | const fetchRouteOptions = (productModelId) => { |
| | | formState.value.routeId = undefined; |
| | | routeOptions.value = [] |
| | | bindRouteLoading.value = true; |
| | | listProcessRoute({ productModelId: productModelId }).then(res => { |
| | | routeOptions.value = res.data || []; |
| | | }).finally(() => { |
| | | bindRouteLoading.value = false; |
| | | }) |
| | | } |
| | | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // 验证是否选择了产品和规格 |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("请选择产品"); |
| | | return; |
| | | } |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("请选择规格"); |
| | | return; |
| | | } |
| | | |
| | | addProductOrder(formState.value).then(res => { |
| | | // 关闭模态框 |
| | | isShow.value = false; |
| | | // 告知父组件已完成 |
| | | emit('completed'); |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | }) |
| | | // 产品选择处理 |
| | | const handleProductSelect = async products => { |
| | | if (products && products.length > 0) { |
| | | const product = products[0]; |
| | | formState.value.productId = product.skuId; |
| | | formState.value.productName = product.materialName; |
| | | formState.value.productModelName = product.specification; |
| | | formState.value.productModelId = product.skuId; |
| | | formState.value.unit = product.baseUnit; |
| | | showProductSelectDialog.value = false; |
| | | fetchRouteOptions(product.skuId); |
| | | // 触发表单验证更新 |
| | | proxy.$refs["formRef"]?.validateField("productModelId"); |
| | | } |
| | | }) |
| | | }; |
| | | }; |
| | | |
| | | const routeOptions = ref([]); |
| | | const bindRouteLoading = ref(false); |
| | | const fetchRouteOptions = productModelId => { |
| | | formState.value.routeId = undefined; |
| | | routeOptions.value = []; |
| | | bindRouteLoading.value = true; |
| | | listProcessRoute({ productModelId: productModelId }) |
| | | .then(res => { |
| | | routeOptions.value = res.data || []; |
| | | }) |
| | | .finally(() => { |
| | | bindRouteLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | defineExpose({ |
| | | closeModal, |
| | | handleSubmit, |
| | | isShow, |
| | | }); |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // 验证是否选择了产品和规格 |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("请选择产品"); |
| | | return; |
| | | } |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("请选择规格"); |
| | | return; |
| | | } |
| | | |
| | | addProductOrder(formState.value).then(res => { |
| | | // 关闭模态框 |
| | | isShow.value = false; |
| | | // 告知父组件已完成 |
| | | emit("completed"); |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | defineExpose({ |
| | | closeModal, |
| | | handleSubmit, |
| | | isShow, |
| | | }); |
| | | </script> |
| | |
| | | </el-icon>新增工序 |
| | | </el-button> |
| | | </div> |
| | | <div class="process-card-list"> |
| | | <div v-for="process in processList" |
| | | <div class="process-card-list" |
| | | v-loading="processLoading"> |
| | | <div v-for="process in processValueList" |
| | | :key="process.id" |
| | | class="process-card" |
| | | :class="{ active: selectedProcess?.id === process.id }" |
| | | @click="selectProcess(process)"> |
| | | <div class="card-header"> |
| | | <span class="process-code">{{ process.processCode }}</span> |
| | | <div class="process-name">{{ process.name }} <span class="process-code">{{ process.no }}</span></div> |
| | | <div class="card-actions"> |
| | | <el-button link |
| | | type="primary" |
| | |
| | | </div> |
| | | </div> |
| | | <div class="card-body"> |
| | | <div class="process-name">{{ process.processName }}</div> |
| | | <div class="process-desc">{{ process.processDesc || '暂无描述' }}</div> |
| | | <!-- <div class="process-name">{{ process.name }}</div> --> |
| | | <div class="process-desc">{{ process.remark || '暂无描述' }}</div> |
| | | </div> |
| | | <div class="card-footer"> |
| | | <el-tag size="small" |
| | | :type="process.status === '1' ? 'success' : 'info'"> |
| | | {{ process.status === '1' ? '启用' : '停用' }} |
| | | </el-tag> |
| | | <span class="param-count">参数: {{ process.paramCount || 0 }}个</span> |
| | | <div class="status-tag"> <el-tag size="small" |
| | | :type="process.status ? 'success' : 'info'"> |
| | | {{ process.status ? '启用' : '停用' }} |
| | | </el-tag> |
| | | <el-tag size="small" |
| | | :type="process.isQuality ? 'warning' : 'info'" |
| | | style="margin-left: 8px"> |
| | | {{ process.isQuality ? '质检' : '非质检' }} |
| | | </el-tag> |
| | | </div> |
| | | <span class="param-count">工资定额: ¥{{ process.salaryQuota || 0 }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="param-list-section"> |
| | | <div class="section-header"> |
| | | <h3 class="section-title"> |
| | | {{ selectedProcess ? selectedProcess.processName + ' - 参数配置' : '请选择工序' }} |
| | | {{ selectedProcess ? selectedProcess.name + ' - 参数配置' : '请选择工序' }} |
| | | </h3> |
| | | <el-button type="primary" |
| | | size="small" |
| | |
| | | ref="processFormRef" |
| | | label-width="100px"> |
| | | <el-form-item label="工序编码" |
| | | prop="processCode"> |
| | | <el-input v-model="processForm.processCode" |
| | | prop="no"> |
| | | <el-input v-model="processForm.no" |
| | | placeholder="请输入工序编码" /> |
| | | </el-form-item> |
| | | <el-form-item label="工序名称" |
| | | prop="processName"> |
| | | <el-input v-model="processForm.processName" |
| | | prop="name"> |
| | | <el-input v-model="processForm.name" |
| | | placeholder="请输入工序名称" /> |
| | | </el-form-item> |
| | | <el-form-item label="工资定额" |
| | | prop="salaryQuota"> |
| | | <el-input v-model="processForm.salaryQuota" |
| | | type="number" |
| | | :step="0.001" /> |
| | | </el-form-item> |
| | | <el-form-item label="是否质检" |
| | | prop="isQuality"> |
| | | <el-switch v-model="processForm.isQuality" |
| | | :active-value="true" |
| | | inactive-value="false" /> |
| | | </el-form-item> |
| | | <el-form-item label="工序描述" |
| | | prop="processDesc"> |
| | | <el-input v-model="processForm.processDesc" |
| | | prop="remark"> |
| | | <el-input v-model="processForm.remark" |
| | | type="textarea" |
| | | :rows="3" |
| | | placeholder="请输入工序描述" /> |
| | |
| | | <el-form-item label="状态" |
| | | prop="status"> |
| | | <el-radio-group v-model="processForm.status"> |
| | | <el-radio label="1">启用</el-radio> |
| | | <el-radio label="0">停用</el-radio> |
| | | <el-radio :label="true">启用</el-radio> |
| | | <el-radio :label="false">停用</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-form> |
| | |
| | | <el-table-column prop="parameterCode" |
| | | label="参数编号" |
| | | width="100" /> |
| | | <el-table-column prop="parameterName" |
| | | <el-table-column prop="paramName" |
| | | label="参数名称" /> |
| | | <el-table-column prop="parameterType" |
| | | <el-table-column prop="paramType" |
| | | label="参数类型" |
| | | width="100"> |
| | | <template #default="scope"> |
| | | <el-tag size="small" |
| | | :type="getParamTypeTag(scope.row.parameterType)"> |
| | | {{ scope.row.parameterType }} |
| | | :type="getParamTypeTag(scope.row.paramType)"> |
| | | {{ scope.row.paramType }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | <span class="detail-text">{{ selectedParam.parameterCode }}</span> |
| | | </el-form-item> |
| | | <el-form-item label="参数名称"> |
| | | <span class="detail-text">{{ selectedParam.parameterName }}</span> |
| | | <span class="detail-text">{{ selectedParam.paramName }}</span> |
| | | </el-form-item> |
| | | <el-form-item label="参数模式"> |
| | | <el-tag size="small" |
| | | :type="selectedParam.parameterType2 === '1' ? 'success' : 'warning'"> |
| | | {{ selectedParam.parameterType2 === '1' ? '单值' : '区间' }} |
| | | :type="selectedParam.valueMode == '1' ? 'success' : 'warning'"> |
| | | {{ selectedParam.valueMode == '1' ? '单值' : '区间' }} |
| | | </el-tag> |
| | | </el-form-item> |
| | | <el-form-item label="参数类型"> |
| | | <el-tag size="small" |
| | | :type="getParamTypeTag(selectedParam.parameterType)"> |
| | | {{ selectedParam.parameterType }} |
| | | :type="getParamTypeTag(selectedParam.paramType)"> |
| | | {{ selectedParam.paramType }} |
| | | </el-tag> |
| | | </el-form-item> |
| | | <el-form-item label="参数格式"> |
| | | <span class="detail-text">{{ selectedParam.parameterFormat || '-' }}</span> |
| | | </el-form-item> |
| | | <el-form-item label="标准值"> |
| | | <span class="detail-text">{{ selectedParam.standardValue }}</span> |
| | | <span class="detail-text">{{ selectedParam.paramFormat || '-' }}</span> |
| | | </el-form-item> |
| | | <el-form-item label="单位"> |
| | | <span class="detail-text">{{ selectedParam.unit || '-' }}</span> |
| | | </el-form-item> |
| | | <el-form-item label="默认值" |
| | | v-if="selectedParam.valueMode === '1'"> |
| | | <el-input v-model="selectedParam.defaultValue" |
| | | placeholder="请输入默认值" /> |
| | | </el-form-item> |
| | | <el-form-item label="最小值" |
| | | v-if="selectedParam.valueMode === '2'"> |
| | | <el-input v-model="selectedParam.defaultMin" |
| | | placeholder="请输入最小值" /> |
| | | </el-form-item> |
| | | <el-form-item label="最大值" |
| | | v-if="selectedParam.valueMode === '2'"> |
| | | <el-input v-model="selectedParam.defaultMax" |
| | | placeholder="请输入最大值" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-empty v-else |
| | |
| | | import { Plus, Edit, Delete, Search } from "@element-plus/icons-vue"; |
| | | import PIMTable from "@/components/PIMTable/PIMTable.vue"; |
| | | import { listType } from "@/api/system/dict/type"; |
| | | import { |
| | | add, |
| | | update, |
| | | del, |
| | | list as getProcessListApi, |
| | | processList, |
| | | } from "@/api/productionManagement/productionProcess.js"; |
| | | |
| | | // 工序列表数据 |
| | | const processList = ref([]); |
| | | const processValueList = ref([]); |
| | | const selectedProcess = ref(null); |
| | | const processLoading = ref(false); |
| | | |
| | |
| | | const processFormRef = ref(null); |
| | | const processForm = reactive({ |
| | | id: null, |
| | | processCode: "", |
| | | processName: "", |
| | | processDesc: "", |
| | | status: "1", |
| | | no: "", |
| | | name: "", |
| | | salaryQuota: null, |
| | | isQuality: false, |
| | | remark: "", |
| | | status: true, |
| | | }); |
| | | const processRules = { |
| | | processCode: [{ required: true, message: "请输入工序编码", trigger: "blur" }], |
| | | processName: [{ required: true, message: "请输入工序名称", trigger: "blur" }], |
| | | no: [{ required: true, message: "请输入工序编码", trigger: "blur" }], |
| | | name: [{ required: true, message: "请输入工序名称", trigger: "blur" }], |
| | | salaryQuota: [ |
| | | { |
| | | required: true, |
| | | message: "请输入工资定额", |
| | | trigger: "blur", |
| | | validator: (rule, value, callback) => { |
| | | if (value === null || value === undefined || value === "") { |
| | | callback(new Error("请输入工资定额")); |
| | | } else if (isNaN(value) || value < 0) { |
| | | callback(new Error("工资定额必须是非负数字")); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }, |
| | | }, |
| | | ], |
| | | }; |
| | | |
| | | // 参数对话框 |
| | |
| | | }, |
| | | { |
| | | label: "参数名称", |
| | | prop: "parameterName", |
| | | prop: "paramName", |
| | | }, |
| | | { |
| | | label: "参数模式", |
| | | prop: "parameterType2", |
| | | prop: "valueMode", |
| | | dataType: "tag", |
| | | formatType: row => (row.parameterType2 === "1" ? "success" : "warning"), |
| | | formatData: row => (row.parameterType2 === "1" ? "单值" : "区间"), |
| | | formatType: row => (row.valueMode === "1" ? "success" : "warning"), |
| | | formatData: row => (row.valueMode === "1" ? "单值" : "区间"), |
| | | }, |
| | | { |
| | | label: "参数类型", |
| | | prop: "parameterType", |
| | | prop: "paramType", |
| | | dataType: "tag", |
| | | formatType: row => { |
| | | const typeMap = { |
| | |
| | | 下拉选项: "warning", |
| | | 时间格式: "success", |
| | | }; |
| | | return typeMap[row.parameterType] || "default"; |
| | | return typeMap[row.paramType] || "default"; |
| | | }, |
| | | }, |
| | | { |
| | | label: "参数格式", |
| | | prop: "parameterFormat", |
| | | prop: "paramFormat", |
| | | }, |
| | | { |
| | | label: "标准值", |
| | | prop: "standardValue", |
| | | className: row => (row.parameterType === "数值格式" ? "quantity-cell" : ""), |
| | | prop: "defaultValue", |
| | | className: row => (row.paramType === "数值格式" ? "quantity-cell" : ""), |
| | | }, |
| | | { |
| | | label: "默认值", |
| | | prop: "defaultValue", |
| | | formatData: (val, row) => { |
| | | return row.valueMode === "1" ? val : "-"; |
| | | }, |
| | | }, |
| | | { |
| | | label: "最小值", |
| | | prop: "defaultMin", |
| | | formatData: (val, row) => { |
| | | return row.valueMode === "2" ? val : "-"; |
| | | }, |
| | | }, |
| | | { |
| | | label: "最大值", |
| | | prop: "defaultMax", |
| | | formatData: (val, row) => { |
| | | return row.valueMode === "2" ? val : "-"; |
| | | }, |
| | | }, |
| | | { |
| | | label: "单位", |
| | |
| | | |
| | | // 获取工序列表 |
| | | const getProcessList = () => { |
| | | // 假数据 |
| | | processList.value = [ |
| | | { |
| | | id: 1, |
| | | processCode: "PROC001", |
| | | processName: "原料配比", |
| | | processDesc: "原材料配比工序", |
| | | status: "1", |
| | | paramCount: 3, |
| | | }, |
| | | { |
| | | id: 2, |
| | | processCode: "PROC002", |
| | | processName: "搅拌混合", |
| | | processDesc: "搅拌混合工序", |
| | | status: "1", |
| | | paramCount: 2, |
| | | }, |
| | | { |
| | | id: 3, |
| | | processCode: "PROC003", |
| | | processName: "浇筑成型", |
| | | processDesc: "浇筑成型工序", |
| | | status: "1", |
| | | paramCount: 4, |
| | | }, |
| | | { |
| | | id: 4, |
| | | processCode: "PROC004", |
| | | processName: "蒸压养护", |
| | | processDesc: "蒸压养护工序", |
| | | status: "0", |
| | | paramCount: 2, |
| | | }, |
| | | { |
| | | id: 5, |
| | | processCode: "PROC005", |
| | | processName: "切割加工", |
| | | processDesc: "切割加工工序", |
| | | status: "1", |
| | | paramCount: 3, |
| | | }, |
| | | ]; |
| | | processLoading.value = true; |
| | | getProcessListApi() |
| | | .then(res => { |
| | | processValueList.value = res.data || []; |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.error("获取工序列表失败"); |
| | | }) |
| | | .finally(() => { |
| | | processLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | // 获取参数列表 |
| | | const getParamList = processId => { |
| | | paramLoading.value = true; |
| | | // 假数据 |
| | | setTimeout(() => { |
| | | paramLoading.value = false; |
| | | const mockData = { |
| | | 1: [ |
| | | { |
| | | id: 1, |
| | | parameterCode: "P001", |
| | | parameterName: "水泥比例", |
| | | parameterType2: "1", |
| | | parameterType: "数值格式", |
| | | parameterFormat: "", |
| | | standardValue: "30", |
| | | unit: "%", |
| | | }, |
| | | { |
| | | id: 2, |
| | | parameterCode: "P002", |
| | | parameterName: "砂比例", |
| | | parameterType2: "1", |
| | | parameterType: "数值格式", |
| | | parameterFormat: "", |
| | | standardValue: "60", |
| | | unit: "%", |
| | | }, |
| | | { |
| | | id: 3, |
| | | parameterCode: "P003", |
| | | parameterName: "水比例", |
| | | parameterType2: "1", |
| | | parameterType: "数值格式", |
| | | parameterFormat: "", |
| | | standardValue: "10", |
| | | unit: "%", |
| | | }, |
| | | ], |
| | | 2: [ |
| | | { |
| | | id: 4, |
| | | parameterCode: "P004", |
| | | parameterName: "搅拌时间", |
| | | parameterType2: "1", |
| | | parameterType: "数值格式", |
| | | parameterFormat: "", |
| | | standardValue: "5", |
| | | unit: "分钟", |
| | | }, |
| | | { |
| | | id: 5, |
| | | parameterCode: "P005", |
| | | parameterName: "搅拌速度", |
| | | parameterType2: "2", |
| | | parameterType: "数值格式", |
| | | parameterFormat: "", |
| | | standardValue: "100-200", |
| | | unit: "rpm", |
| | | }, |
| | | ], |
| | | 3: [ |
| | | { |
| | | id: 6, |
| | | parameterCode: "P006", |
| | | parameterName: "浇筑温度", |
| | | parameterType2: "2", |
| | | parameterType: "数值格式", |
| | | parameterFormat: "", |
| | | standardValue: "20-30", |
| | | unit: "℃", |
| | | }, |
| | | { |
| | | id: 7, |
| | | parameterCode: "P007", |
| | | parameterName: "浇筑压力", |
| | | parameterType2: "1", |
| | | parameterType: "数值格式", |
| | | parameterFormat: "", |
| | | standardValue: "0.5", |
| | | unit: "MPa", |
| | | }, |
| | | { |
| | | id: 8, |
| | | parameterCode: "P008", |
| | | parameterName: "成型状态", |
| | | parameterType2: "1", |
| | | parameterType: "下拉选项", |
| | | parameterFormat: "status", |
| | | standardValue: "正常", |
| | | unit: "", |
| | | }, |
| | | { |
| | | id: 9, |
| | | parameterCode: "P009", |
| | | parameterName: "成型时间", |
| | | parameterType2: "1", |
| | | parameterType: "时间格式", |
| | | parameterFormat: "YYYY-MM-DD HH:mm:ss", |
| | | standardValue: "2024-01-01 08:00:00", |
| | | unit: "", |
| | | }, |
| | | ], |
| | | 4: [ |
| | | { |
| | | id: 10, |
| | | parameterCode: "P010", |
| | | parameterName: "蒸压温度", |
| | | parameterType2: "2", |
| | | parameterType: "数值格式", |
| | | parameterFormat: "", |
| | | standardValue: "180-200", |
| | | unit: "℃", |
| | | }, |
| | | { |
| | | id: 11, |
| | | parameterCode: "P011", |
| | | parameterName: "蒸压压力", |
| | | parameterType2: "1", |
| | | parameterType: "数值格式", |
| | | parameterFormat: "", |
| | | standardValue: "1.2", |
| | | unit: "MPa", |
| | | }, |
| | | ], |
| | | 5: [ |
| | | { |
| | | id: 12, |
| | | parameterCode: "P012", |
| | | parameterName: "切割尺寸", |
| | | parameterType2: "1", |
| | | parameterType: "文本格式", |
| | | parameterFormat: "", |
| | | standardValue: "600x200x100", |
| | | unit: "mm", |
| | | }, |
| | | { |
| | | id: 13, |
| | | parameterCode: "P013", |
| | | parameterName: "切割精度", |
| | | parameterType2: "1", |
| | | parameterType: "数值格式", |
| | | parameterFormat: "", |
| | | standardValue: "±1", |
| | | unit: "mm", |
| | | }, |
| | | { |
| | | id: 14, |
| | | parameterCode: "P014", |
| | | parameterName: "切割速度", |
| | | parameterType2: "1", |
| | | parameterType: "数值格式", |
| | | parameterFormat: "", |
| | | standardValue: "2", |
| | | unit: "m/min", |
| | | }, |
| | | ], |
| | | }; |
| | | paramList.value = mockData[processId] || []; |
| | | paramPage.total = paramList.value.length; |
| | | }, 300); |
| | | getProcessParamList(processId) |
| | | .then(res => { |
| | | paramList.value = res.data || []; |
| | | paramPage.total = paramList.value.length; |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.error("获取参数列表失败"); |
| | | }) |
| | | .finally(() => { |
| | | paramLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | // 选择工序 |
| | |
| | | const handleAddProcess = () => { |
| | | isProcessEdit.value = false; |
| | | processForm.id = null; |
| | | processForm.processCode = ""; |
| | | processForm.processName = ""; |
| | | processForm.processDesc = ""; |
| | | processForm.status = "1"; |
| | | processForm.no = ""; |
| | | processForm.name = ""; |
| | | processForm.salaryQuota = null; |
| | | processForm.isQuality = false; |
| | | processForm.remark = ""; |
| | | processForm.status = true; |
| | | processDialogVisible.value = true; |
| | | }; |
| | | |
| | | const handleEditProcess = process => { |
| | | isProcessEdit.value = true; |
| | | processForm.id = process.id; |
| | | processForm.processCode = process.processCode; |
| | | processForm.processName = process.processName; |
| | | processForm.processDesc = process.processDesc; |
| | | processForm.no = process.no; |
| | | processForm.name = process.name; |
| | | processForm.salaryQuota = process.salaryQuota; |
| | | processForm.isQuality = process.isQuality || false; |
| | | processForm.remark = process.remark || ""; |
| | | processForm.status = process.status; |
| | | processDialogVisible.value = true; |
| | | }; |
| | |
| | | cancelButtonText: "取消", |
| | | type: "warning", |
| | | }).then(() => { |
| | | ElMessage.success("删除成功"); |
| | | getProcessList(); |
| | | if (selectedProcess.value?.id === process.id) { |
| | | selectedProcess.value = null; |
| | | paramList.value = []; |
| | | } |
| | | del([process.id]) |
| | | .then(() => { |
| | | ElMessage.success("删除成功"); |
| | | getProcessList(); |
| | | if (selectedProcess.value?.id === process.id) { |
| | | selectedProcess.value = null; |
| | | paramList.value = []; |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.error("删除失败"); |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | const handleProcessSubmit = () => { |
| | | processFormRef.value.validate(valid => { |
| | | if (valid) { |
| | | ElMessage.success(isProcessEdit.value ? "编辑成功" : "新增成功"); |
| | | processDialogVisible.value = false; |
| | | getProcessList(); |
| | | const apiMethod = isProcessEdit.value ? update : add; |
| | | apiMethod(processForm) |
| | | .then(() => { |
| | | ElMessage.success(isProcessEdit.value ? "编辑成功" : "新增成功"); |
| | | processDialogVisible.value = false; |
| | | getProcessList(); |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.error(isProcessEdit.value ? "编辑失败" : "新增失败"); |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | |
| | | { |
| | | id: 101, |
| | | parameterCode: "P101", |
| | | parameterName: "温度", |
| | | parameterType2: "2", |
| | | parameterType: "数值格式", |
| | | parameterFormat: "", |
| | | standardValue: "20-30", |
| | | paramName: "温度", |
| | | valueMode: "2", |
| | | paramType: "数值格式", |
| | | paramFormat: "", |
| | | defaultValue: "20-30", |
| | | unit: "℃", |
| | | }, |
| | | { |
| | | id: 102, |
| | | parameterCode: "P102", |
| | | parameterName: "压力", |
| | | parameterType2: "1", |
| | | parameterType: "数值格式", |
| | | parameterFormat: "", |
| | | standardValue: "0.5", |
| | | paramName: "压力", |
| | | valueMode: "1", |
| | | paramType: "数值格式", |
| | | paramFormat: "", |
| | | defaultValue: "0.5", |
| | | unit: "MPa", |
| | | }, |
| | | { |
| | | id: 103, |
| | | parameterCode: "P103", |
| | | parameterName: "湿度", |
| | | parameterType2: "2", |
| | | parameterType: "数值格式", |
| | | parameterFormat: "", |
| | | standardValue: "40-60", |
| | | paramName: "湿度", |
| | | valueMode: "2", |
| | | paramType: "数值格式", |
| | | paramFormat: "", |
| | | defaultValue: "40-60", |
| | | unit: "%", |
| | | }, |
| | | { |
| | | id: 104, |
| | | parameterCode: "P104", |
| | | parameterName: "速度", |
| | | parameterType2: "1", |
| | | parameterType: "数值格式", |
| | | parameterFormat: "", |
| | | standardValue: "100", |
| | | paramName: "速度", |
| | | valueMode: "1", |
| | | paramType: "数值格式", |
| | | paramFormat: "", |
| | | defaultValue: "100", |
| | | unit: "m/min", |
| | | }, |
| | | { |
| | | id: 105, |
| | | parameterCode: "P105", |
| | | parameterName: "状态", |
| | | parameterType2: "1", |
| | | parameterType: "下拉选项", |
| | | parameterFormat: "status", |
| | | standardValue: "正常", |
| | | paramName: "状态", |
| | | valueMode: "1", |
| | | paramType: "下拉选项", |
| | | paramFormat: "status", |
| | | defaultValue: "正常", |
| | | unit: "", |
| | | }, |
| | | { |
| | | id: 106, |
| | | parameterCode: "P106", |
| | | parameterName: "记录时间", |
| | | parameterType2: "1", |
| | | parameterType: "时间格式", |
| | | parameterFormat: "YYYY-MM-DD HH:mm:ss", |
| | | standardValue: "2024-01-01 08:00:00", |
| | | paramName: "记录时间", |
| | | valueMode: "1", |
| | | paramType: "时间格式", |
| | | paramFormat: "YYYY-MM-DD HH:mm:ss", |
| | | defaultValue: "2024-01-01 08:00:00", |
| | | unit: "", |
| | | }, |
| | | { |
| | | id: 107, |
| | | parameterCode: "P107", |
| | | parameterName: "备注", |
| | | parameterType2: "1", |
| | | parameterType: "文本格式", |
| | | parameterFormat: "", |
| | | standardValue: "无", |
| | | paramName: "备注", |
| | | valueMode: "1", |
| | | paramType: "文本格式", |
| | | paramFormat: "", |
| | | defaultValue: "无", |
| | | unit: "", |
| | | }, |
| | | ]; |
| | |
| | | filteredParamList.value = availableParamList.value; |
| | | } else { |
| | | filteredParamList.value = availableParamList.value.filter(item => |
| | | item.parameterName.toLowerCase().includes(keyword) |
| | | item.paramName.toLowerCase().includes(keyword) |
| | | ); |
| | | } |
| | | }; |
| | |
| | | cancelButtonText: "取消", |
| | | type: "warning", |
| | | }).then(() => { |
| | | ElMessage.success("删除成功"); |
| | | getParamList(selectedProcess.value.id); |
| | | deleteProcessParam(row.id) |
| | | .then(() => { |
| | | ElMessage.success("删除成功"); |
| | | getParamList(selectedProcess.value.id); |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.error("删除失败"); |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | |
| | | ElMessage.warning("请先选择一个参数"); |
| | | return; |
| | | } |
| | | ElMessage.success("添加成功"); |
| | | paramDialogVisible.value = false; |
| | | getParamList(selectedProcess.value.id); |
| | | addProcessParam({ |
| | | processId: selectedProcess.value.id, |
| | | paramId: selectedParam.value.id, |
| | | defaultValue: selectedParam.value.defaultValue, |
| | | defaultMin: selectedParam.value.defaultMin, |
| | | defaultMax: selectedParam.value.defaultMax, |
| | | }) |
| | | .then(() => { |
| | | ElMessage.success("添加成功"); |
| | | paramDialogVisible.value = false; |
| | | getParamList(selectedProcess.value.id); |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.error("添加失败"); |
| | | }); |
| | | }; |
| | | |
| | | const handleParamPagination = obj => { |
| | |
| | | |
| | | .process-code { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | // color: #909399; |
| | | color: #cb9b18; |
| | | font-family: "Courier New", monospace; |
| | | } |
| | | |