| | |
| | | <span class="search_title">供应商名称:</span> |
| | | <el-input v-model="searchForm.supplierName" style="width: 240px" placeholder="请输入" @change="handleQuery" |
| | | clearable prefix-icon="Search" /> |
| | | <span class="search_title ml10">入库日期:</span> |
| | | <el-date-picker |
| | | v-model="searchForm.timeStr" |
| | | type="date" |
| | | placeholder="请选择日期" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> |
| | | </div> |
| | | <div> |
| | |
| | | <div class="table_list"> |
| | | <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange" |
| | | :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%" |
| | | :row-class-name="tableRowClassName" |
| | | :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)"> |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column align="center" label="序号" type="index" width="60" /> |
| | | <el-table-column label="库存日期" prop="createTime" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="入库日期" prop="createTime" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="供应商名称" prop="supplierName" width="240" show-overflow-tooltip /> |
| | | <el-table-column label="产品大类" prop="productCategory" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="规格型号" prop="specificationModel" width="200" show-overflow-tooltip /> |
| | | <el-table-column label="单位" prop="unit" width="80" show-overflow-tooltip /> |
| | | <el-table-column label="库存数量" prop="inboundNum0" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="库存预警数量" prop="warnNum" width="130" show-overflow-tooltip /> |
| | | <el-table-column label="含税单价" prop="taxInclusiveUnitPrice" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="含税总价" prop="taxInclusiveTotalPrice" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="税率(%)" prop="taxRate" width="100" show-overflow-tooltip /> |
| | |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="产品大类:" prop="productId"> |
| | | <el-select disabled v-model="form.productCategory" placeholder="请选择" clearable filterable @change="handleProductChange"> |
| | | <el-select disabled v-model="form.productCategory" placeholder="请选择" clearable filterable> |
| | | <el-option v-for="item in productList" :key="item.id" :label="item.productName" |
| | | :value="item.productName" /> |
| | | </el-select> |
| | |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="规格型号:" prop="productManageId"> |
| | | <el-select disabled v-model="form.specificationModel" placeholder="请先选择产品大类" clearable filterable :disabled="!form.productCategory" |
| | | @change="handleModelChange"> |
| | | <el-select disabled v-model="form.specificationModel" placeholder="请先选择产品大类" clearable filterable :disabled="!form.productCategory"> |
| | | <el-option v-for="item in productModelList" :key="item.id" :label="item.model" |
| | | :value="item.id" /> |
| | | </el-select> |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="最低库存:" prop="minStock"> |
| | | <el-input v-model="form.minStock" placeholder="请输入最低库存" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <!-- <el-col :span="12">--> |
| | | <!-- <el-form-item label="库存预警数量:" prop="warnNum">--> |
| | | <!-- <el-input v-model="form.warnNum" placeholder="请输入最低库存" clearable />--> |
| | | <!-- </el-form-item>--> |
| | | <!-- </el-col>--> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | |
| | | |
| | | <script setup> |
| | | import pagination from '@/components/PIMTable/Pagination.vue' |
| | | import { ref } from 'vue' |
| | | import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue' |
| | | import { ElMessageBox } from "element-plus"; |
| | | import useUserStore from '@/store/modules/user' |
| | | import { userListNoPageByTenantId } from "@/api/system/user.js"; |
| | | import { productTreeList,modelList } from "@/api/basicData/product.js" |
| | | import { |
| | | getStockManagePage , |
| | | updateStockManage, |
| | | getStockManagePage, |
| | | delStockManage, |
| | | exportStockManage |
| | | } from "@/api/inventoryManagement/stockManage.js"; |
| | | import { |
| | | updateManagement, |
| | | |
| | | updateManagement,updateStockIn |
| | | } from "@/api/inventoryManagement/stockIn.js"; |
| | | |
| | | |
| | | |
| | | const userStore = useUserStore() |
| | | const { proxy } = getCurrentInstance() |
| | | const tableData = ref([]) |
| | |
| | | }) |
| | | const total = ref(0) |
| | | const fileList = ref([]) |
| | | |
| | | const loading = ref(false); |
| | | // 用户信息表单弹框数据 |
| | | const operationType = ref('') |
| | | const dialogFormVisible = ref(false) |
| | | const data = reactive({ |
| | | searchForm: { |
| | | supplierName: '', |
| | | timeStr: '', |
| | | }, |
| | | form: { |
| | | supplierId: null, |
| | |
| | | inboundBatch: '', |
| | | stockQuantity: '', |
| | | boundTime: '', |
| | | minStock: '', // 新增最低库存字段 |
| | | warnNum: '', // 新增最低库存字段 |
| | | salesLedgerProductId: null, |
| | | }, |
| | | rules: { |
| | | supplierName: [{ required: true, message: '请输入供应商名称', trigger: 'blur' }], |
| | |
| | | boundTime: [{ required: true, message: '请选择库存时间', trigger: 'change' }], |
| | | inboundTime: [{ required: true, message: '请选择入库时间', trigger: 'change' }], |
| | | inboundPerson: [{ required: true, message: '请选择出库人', trigger: 'change' }], |
| | | minStock: [{ required: true, message: '请输入最低库存', trigger: 'blur' }], |
| | | warnNum: [{ required: true, message: '请输入最低库存', trigger: 'blur' }], |
| | | } |
| | | }) |
| | | const { searchForm, form, rules } = toRefs(data) |
| | |
| | | getStockManagePage({ ...searchForm.value, ...page }).then(res => { |
| | | tableLoading.value = false |
| | | tableData.value = res.data.records |
| | | console.log('res', res) |
| | | // tableData.value.map(item => { |
| | | // item.children = [] |
| | | // }) |
| | | total.value = res.data.total |
| | | // 数据加载完成后检查库存 |
| | | // checkStockAndCreatePurchase(); |
| | | }).catch(() => { |
| | | tableLoading.value = false |
| | | }) |
| | |
| | | return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']); |
| | | }; |
| | | |
| | | // 表格行类名 |
| | | const tableRowClassName = ({ row }) => { |
| | | const stock = Number(row?.inboundNum0 ?? 0); |
| | | const warn = Number(row?.warnNum ?? 0); |
| | | if (!Number.isFinite(stock) || !Number.isFinite(warn)) { |
| | | return ''; |
| | | } |
| | | return stock < warn ? 'row-low-stock' : ''; |
| | | }; |
| | | |
| | | // 打开弹框 |
| | | const openForm = async (type, row) => { |
| | | operationType.value = type |
| | |
| | | productData.value = [] |
| | | let userLists = await userListNoPageByTenantId() |
| | | userList.value = userLists.data |
| | | // customerList().then(res => { |
| | | // customerOption.value = res |
| | | // }) |
| | | // console.log('userStore.id', userStore.id) |
| | | // form.value.entryPerson = userStore.id |
| | | if (type === 'edit') { |
| | | form.value = { ...row } |
| | | productTreeList().then(res =>{ |
| | |
| | | } |
| | | }) |
| | | }) |
| | | |
| | | |
| | | // getSalesLedgerWithProducts({ id: row.id, type: 1 }).then(res => { |
| | | |
| | | // form.value.entryPerson = Number(res.entryPerson) |
| | | // productData.value = form.value.productData |
| | | // fileList.value = form.value.salesLedgerFiles |
| | | // }) |
| | | } |
| | | form.value.entryDate = getCurrentDate() // 设置默认录入日期为当前日期 |
| | | dialogFormVisible.value = true |
| | |
| | | console.log(form.value) |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // if (productData.value.length > 0) { |
| | | // form.value.productData = proxy.HaveJson(productData.value) |
| | | // } else { |
| | | // proxy.$modal.msgWarning('请添加产品信息') |
| | | // return |
| | | // } |
| | | // let tempFileIds = [] |
| | | // if (fileList.value.length > 0) { |
| | | // tempFileIds = fileList.value.map(item => item.tempId) |
| | | // } |
| | | // form.value.tempFileIds = tempFileIds |
| | | // form.value.type = 1 |
| | | |
| | | updateManagement(form.value).then(res => { |
| | | proxy.$modal.msgSuccess("提交成功") |
| | | closeDia() |
| | | getList() |
| | | // 提交后检查库存并尝试创建请购单 |
| | | checkStockAndAutoCreatePurchase(); |
| | | // checkStockAndCreatePurchase(); |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | // 检查库存并自动创建请购单 |
| | | const checkStockAndAutoCreatePurchase = async () => { |
| | | try { |
| | | await checkStockAndCreatePurchase(); |
| | | } catch (error) { |
| | | console.error('自动补货失败:', error); |
| | | proxy.$modal.msgError('自动补货失败,请手动处理'); |
| | | } |
| | | }; |
| | | // 检查库存并创建请购单 |
| | | // const checkStockAndCreatePurchase = async () => { |
| | | // const stockList = tableData.value; |
| | | // // handList() |
| | | // for (const item of stockList) { |
| | | // if (item.inboundNum0 < item.warnNum) { |
| | | // try { |
| | | // const stockInData = { |
| | | // id: item.id, |
| | | // quantityStock: item.warnNum + item.totalInboundNum,// 使用新格式化函数 |
| | | // }; |
| | | // loading.value = true |
| | | // await updateStockIn(stockInData) |
| | | // proxy.$modal.msgSuccess(`产品 ${item.productCategory} 修改入库成功`) |
| | | // loading.value = false |
| | | // } catch (error) { |
| | | // proxy.$modal.msgError(`产品 ${item.productCategory} 生成请购单失败,请手动处理`); |
| | | // |
| | | // } |
| | | // } |
| | | // } |
| | | // }; |
| | | // 关闭弹框 |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef") |
| | |
| | | } |
| | | onMounted(() => { |
| | | getList() |
| | | checkStockAndAutoCreatePurchase(); |
| | | // checkStockAndCreatePurchase(); |
| | | // 每小时检查一次库存 |
| | | // const intervalId = setInterval(checkStockAndCreatePurchase, 60 * 60 * 1000); |
| | | |
| | | // onUnmounted(() => { |
| | | // // 组件卸载时清除定时器 |
| | | // clearInterval(intervalId); |
| | | // }); |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"></style> |
| | | <style scoped lang="scss"> |
| | | :deep(.row-low-stock td) { |
| | | background-color: #fde2e2; |
| | | color: #c45656; |
| | | } |
| | | |
| | | :deep(.row-low-stock:hover > td) { |
| | | background-color: #fcd4d4; |
| | | } |
| | | </style> |