| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-tabs v-model="activeTab" @tab-change="handleTabChange"> |
| | | <el-tab-pane label="成品库存" name="production"> |
| | | <el-tabs v-model="activeTab" |
| | | @tab-change="handleTabChange"> |
| | | <el-tab-pane label="成品库存" |
| | | name="production"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <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" |
| | | /> |
| | | <span class="search_title ml10">产品大类:</span> |
| | | <el-input |
| | | v-model="searchForm.productCategory" |
| | | style="width: 240px" |
| | | placeholder="请输入" |
| | | clearable |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> |
| | | <el-date-picker v-model="searchForm.timeStr" |
| | | type="date" |
| | | placeholder="请选择日期" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | @change="handleQuery" /> |
| | | <span class="search_title ml10">产品大类:</span> |
| | | <el-input v-model="searchForm.productCategory" |
| | | style="width: 240px" |
| | | placeholder="请输入" |
| | | clearable /> |
| | | <el-button type="primary" |
| | | @click="handleQuery" |
| | | style="margin-left: 10px">搜索</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button @click="handleOut">导出</el-button> |
| | | <!-- <el-button type="danger" plain @click="handleDelete">删除</el-button>--> |
| | | <!-- <el-button type="danger" plain @click="handleDelete">删除</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="salesContractNo" width="180" show-overflow-tooltip /> |
| | | <el-table-column label="产品大类" prop="productCategory" show-overflow-tooltip /> |
| | | <el-table-column label="规格型号" prop="specificationModel" show-overflow-tooltip /> |
| | | <el-table-column label="单位" prop="unit" width="80" show-overflow-tooltip /> |
| | | <el-table-column label="已出库数量" prop="totalInboundNum" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="剩余库存" prop="inboundNum0" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="单价(元)" prop="unitPrice" width="150"></el-table-column> |
| | | <el-table-column label="总价(元)" prop="totalPrice" width="150"></el-table-column> |
| | | <el-table-column fixed="right" label="操作" min-width="60" align="center"> |
| | | <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="salesContractNo" |
| | | width="180" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="产品大类" |
| | | prop="productCategory" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="规格型号" |
| | | prop="specificationModel" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="单位" |
| | | prop="unit" |
| | | width="80" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="已出库数量" |
| | | prop="totalInboundNum" |
| | | width="100" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="剩余库存" |
| | | prop="inboundNum0" |
| | | width="100" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="单价(元)" |
| | | prop="unitPrice" |
| | | width="150"></el-table-column> |
| | | <el-table-column label="总价(元)" |
| | | prop="totalPrice" |
| | | width="150"></el-table-column> |
| | | <!-- <el-table-column fixed="right" label="操作" min-width="60" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="openForm('edit', scope.row);">编辑</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> --> |
| | | </el-table> |
| | | <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" :limit="page.size" @pagination="paginationChange" /> |
| | | <pagination v-show="total > 0" |
| | | :total="total" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" |
| | | :limit="page.size" |
| | | @pagination="paginationChange" /> |
| | | </div> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="原料库存" name="purchase"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <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" |
| | | /> |
| | | <span class="search_title ml10">产品大类:</span> |
| | | <el-input |
| | | v-model="searchForm.productCategory" |
| | | style="width: 240px" |
| | | placeholder="请输入" |
| | | clearable |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button @click="handleOut">导出</el-button> |
| | | <!-- <el-button type="danger" plain @click="handleDelete">删除</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="purchaseContractNumber" width="180" show-overflow-tooltip /> |
| | | <el-table-column label="产品大类" prop="productCategory" show-overflow-tooltip /> |
| | | <el-table-column label="规格型号" prop="specificationModel" show-overflow-tooltip /> |
| | | <el-table-column label="单位" prop="unit" width="80" show-overflow-tooltip /> |
| | | <el-table-column label="已出库数量" prop="totalInboundNum" show-overflow-tooltip /> |
| | | <el-table-column label="剩余库存" prop="inboundNum0" show-overflow-tooltip /> |
| | | <el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" width="150"></el-table-column> |
| | | <el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" width="150"></el-table-column> |
| | | </el-table> |
| | | <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" :limit="page.size" @pagination="paginationChange" /> |
| | | </div> |
| | | <el-tab-pane label="原料库存" |
| | | name="purchase"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <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" /> |
| | | <span class="search_title ml10">产品大类:</span> |
| | | <el-input v-model="searchForm.productCategory" |
| | | style="width: 240px" |
| | | placeholder="请输入" |
| | | clearable /> |
| | | <el-button type="primary" |
| | | @click="handleQuery" |
| | | style="margin-left: 10px">搜索</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button @click="handleOut">导出</el-button> |
| | | <!-- <el-button type="danger" plain @click="handleDelete">删除</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="purchaseContractNumber" |
| | | width="180" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="产品大类" |
| | | prop="productCategory" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="规格型号" |
| | | prop="specificationModel" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="单位" |
| | | prop="unit" |
| | | width="80" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="已出库数量" |
| | | prop="totalInboundNum" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="剩余库存" |
| | | prop="inboundNum0" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="含税单价(元)" |
| | | prop="taxInclusiveUnitPrice" |
| | | width="150"></el-table-column> |
| | | <el-table-column label="含税总价(元)" |
| | | prop="taxInclusiveTotalPrice" |
| | | width="150"></el-table-column> |
| | | </el-table> |
| | | <pagination v-show="total > 0" |
| | | :total="total" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" |
| | | :limit="page.size" |
| | | @pagination="paginationChange" /> |
| | | </div> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | |
| | | <!-- 成品库存弹框 --> |
| | | <FormDiaProduction |
| | | v-model:dialogFormVisible="productionDialogVisible" |
| | | :operationType="operationType" |
| | | :formData="form" |
| | | @submit="submitForm" |
| | | @close="closeDia" |
| | | /> |
| | | |
| | | <FormDiaProduction v-model:dialogFormVisible="productionDialogVisible" |
| | | :operationType="operationType" |
| | | :formData="form" |
| | | @submit="submitForm" |
| | | @close="closeDia" /> |
| | | <!-- 原料库存弹框 --> |
| | | <FormDiaPurchase |
| | | v-model:dialogFormVisible="purchaseDialogVisible" |
| | | :operationType="operationType" |
| | | :formData="form" |
| | | @submit="submitForm" |
| | | @close="closeDia" |
| | | /> |
| | | <FormDiaPurchase v-model:dialogFormVisible="purchaseDialogVisible" |
| | | :operationType="operationType" |
| | | :formData="form" |
| | | @submit="submitForm" |
| | | @close="closeDia" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import pagination from '@/components/PIMTable/Pagination.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, |
| | | getStockManagePageByProduction, |
| | | delStockManage, |
| | | } from "@/api/inventoryManagement/stockManage.js"; |
| | | import { |
| | | updateManagement, updateManagementByCustom, updateStockIn |
| | | } from "@/api/inventoryManagement/stockIn.js"; |
| | | import pagination from "@/components/PIMTable/Pagination.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, |
| | | getStockManagePageByProduction, |
| | | delStockManage, |
| | | } from "@/api/inventoryManagement/stockManage.js"; |
| | | import { |
| | | updateManagement, |
| | | updateManagementByCustom, |
| | | updateStockIn, |
| | | } from "@/api/inventoryManagement/stockIn.js"; |
| | | |
| | | // 导入两个独立的弹框组件 |
| | | import FormDiaProduction from './components/FormDiaProduction.vue' |
| | | import FormDiaPurchase from './components/FormDiaPurchase.vue' |
| | | // 导入两个独立的弹框组件 |
| | | import FormDiaProduction from "./components/FormDiaProduction.vue"; |
| | | import FormDiaPurchase from "./components/FormDiaPurchase.vue"; |
| | | |
| | | const userStore = useUserStore() |
| | | const { proxy } = getCurrentInstance() |
| | | const tableData = ref([]) |
| | | const productData = ref([]) |
| | | const selectedRows = ref([]) |
| | | const userList = ref([]) |
| | | const productList = ref([]) |
| | | const productModelList = ref([]) |
| | | // const customerOption = ref([]) |
| | | const tableLoading = ref(false) |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | }) |
| | | const total = ref(0) |
| | | const fileList = ref([]) |
| | | const loading = ref(false); |
| | | // 用户信息表单弹框数据 |
| | | const operationType = ref('') |
| | | const activeTab = ref('production') |
| | | const userStore = useUserStore(); |
| | | const { proxy } = getCurrentInstance(); |
| | | const tableData = ref([]); |
| | | const productData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const userList = ref([]); |
| | | const productList = ref([]); |
| | | const productModelList = ref([]); |
| | | // const customerOption = ref([]) |
| | | const tableLoading = ref(false); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | }); |
| | | const total = ref(0); |
| | | const fileList = ref([]); |
| | | const loading = ref(false); |
| | | // 用户信息表单弹框数据 |
| | | const operationType = ref(""); |
| | | const activeTab = ref("production"); |
| | | |
| | | // 弹框显示状态 |
| | | const productionDialogVisible = ref(false) |
| | | const purchaseDialogVisible = ref(false) |
| | | // 弹框显示状态 |
| | | const productionDialogVisible = ref(false); |
| | | const purchaseDialogVisible = ref(false); |
| | | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | // supplierName: '', |
| | | productCategory:'', |
| | | customerName: '', |
| | | timeStr: '', |
| | | }, |
| | | form: { |
| | | supplierId: null, |
| | | // supplierName: '', |
| | | productId: null, |
| | | productName: '', |
| | | userId: userStore.userId, |
| | | nickName: '', |
| | | productModelId: null, |
| | | model: '', |
| | | unit: '', |
| | | productrecordId: null, |
| | | unitPrice: '', // 添加成品库存的单价字段 |
| | | taxInclusiveUnitPrice: '', |
| | | taxInclusiveTotalPrice: '', |
| | | taxRate: '', |
| | | taxExclusiveTotalPrice: '', |
| | | inboundTime: '', |
| | | inboundBatch: '', |
| | | stockQuantity: '', |
| | | boundTime: '', |
| | | warnNum: '', // 新增最低库存字段 |
| | | salesLedgerProductId: null, |
| | | }, |
| | | rules: { |
| | | // supplierName: [{ required: true, message: '请输入供应商名称', trigger: 'blur' }], |
| | | productCategory: [{ required: true, message: '请选择产品大类', trigger: 'change' }], |
| | | specificationModel: [{ required: true, message: '请输入规格型号', trigger: 'blur' }], |
| | | unit: [{ required: true, message: '请输入单位', trigger: 'blur' }], |
| | | stockQuantity: [{ required: true, message: '请输入出库数量', trigger: 'blur' }], |
| | | unitPrice: [{ required: true, message: '请输入单价', trigger: 'blur' }], // 添加成品库存单价的验证规则 |
| | | taxInclusiveUnitPrice: [{ required: true, message: '请输入含税单价', trigger: 'blur' }], |
| | | taxInclusiveTotalPrice: [{ required: true, message: '请输入含税总价', trigger: 'blur' }], |
| | | taxRate: [{ required: true, message: '请输入税率', trigger: 'blur' }], |
| | | taxExclusiveTotalPrice: [{ required: true, message: '请输入不含税总价', trigger: 'blur' }], |
| | | boundTime: [{ required: true, message: '请选择库存时间', trigger: 'change' }], |
| | | inboundTime: [{ required: true, message: '请选择入库时间', trigger: 'change' }], |
| | | inboundPerson: [{ required: true, message: '请选择出库人', trigger: 'change' }], |
| | | warnNum: [{ required: true, message: '请输入最低库存', trigger: 'blur' }], |
| | | } |
| | | }) |
| | | const { searchForm, form, rules } = toRefs(data) |
| | | const data = reactive({ |
| | | searchForm: { |
| | | // supplierName: '', |
| | | productCategory: "", |
| | | customerName: "", |
| | | timeStr: "", |
| | | }, |
| | | form: { |
| | | supplierId: null, |
| | | // supplierName: '', |
| | | productId: null, |
| | | productName: "", |
| | | userId: userStore.userId, |
| | | nickName: "", |
| | | productModelId: null, |
| | | model: "", |
| | | unit: "", |
| | | productrecordId: null, |
| | | unitPrice: "", // 添加成品库存的单价字段 |
| | | taxInclusiveUnitPrice: "", |
| | | taxInclusiveTotalPrice: "", |
| | | taxRate: "", |
| | | taxExclusiveTotalPrice: "", |
| | | inboundTime: "", |
| | | inboundBatch: "", |
| | | stockQuantity: "", |
| | | boundTime: "", |
| | | warnNum: "", // 新增最低库存字段 |
| | | salesLedgerProductId: null, |
| | | }, |
| | | rules: { |
| | | // supplierName: [{ required: true, message: '请输入供应商名称', trigger: 'blur' }], |
| | | productCategory: [ |
| | | { required: true, message: "请选择产品大类", trigger: "change" }, |
| | | ], |
| | | specificationModel: [ |
| | | { required: true, message: "请输入规格型号", trigger: "blur" }, |
| | | ], |
| | | unit: [{ required: true, message: "请输入单位", trigger: "blur" }], |
| | | stockQuantity: [ |
| | | { required: true, message: "请输入出库数量", trigger: "blur" }, |
| | | ], |
| | | unitPrice: [{ required: true, message: "请输入单价", trigger: "blur" }], // 添加成品库存单价的验证规则 |
| | | taxInclusiveUnitPrice: [ |
| | | { required: true, message: "请输入含税单价", trigger: "blur" }, |
| | | ], |
| | | taxInclusiveTotalPrice: [ |
| | | { required: true, message: "请输入含税总价", trigger: "blur" }, |
| | | ], |
| | | taxRate: [{ required: true, message: "请输入税率", trigger: "blur" }], |
| | | taxExclusiveTotalPrice: [ |
| | | { required: true, message: "请输入不含税总价", trigger: "blur" }, |
| | | ], |
| | | boundTime: [ |
| | | { required: true, message: "请选择库存时间", trigger: "change" }, |
| | | ], |
| | | inboundTime: [ |
| | | { required: true, message: "请选择入库时间", trigger: "change" }, |
| | | ], |
| | | inboundPerson: [ |
| | | { required: true, message: "请选择出库人", trigger: "change" }, |
| | | ], |
| | | warnNum: [{ required: true, message: "请输入最低库存", trigger: "blur" }], |
| | | }, |
| | | }); |
| | | const { searchForm, form, rules } = toRefs(data); |
| | | |
| | | // 查询列表 |
| | | /** 搜索按钮操作 */ |
| | | const handleQuery = () => { |
| | | page.current = 1 |
| | | getList() |
| | | } |
| | | const paginationChange = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList() |
| | | } |
| | | const buildQueryParams = () => { |
| | | const params = { |
| | | ...page, |
| | | timeStr: searchForm.value.timeStr, |
| | | } |
| | | params.productCategory = searchForm.value.productCategory |
| | | if (activeTab.value === 'production') { |
| | | params.customerName = searchForm.value.customerName |
| | | } else { |
| | | // params.supplierName = searchForm.value.supplierName |
| | | } |
| | | return params |
| | | } |
| | | |
| | | const getList = () => { |
| | | tableLoading.value = true |
| | | const params = buildQueryParams() |
| | | const apiCall = activeTab.value === 'production' |
| | | ? getStockManagePageByProduction(params) |
| | | : getStockManagePage(params) |
| | | apiCall.then(res => { |
| | | tableLoading.value = false |
| | | tableData.value = res.data.records |
| | | |
| | | // 为表格数据自动计算总价 |
| | | tableData.value = tableData.value.map(item => { |
| | | // 计算剩余库存 |
| | | const stockQuantity = parseFloat(item.inboundNum) || 0 |
| | | const outboundQuantity = parseFloat(item.totalInboundNum) || 0 |
| | | const remainingStock = Math.max(stockQuantity - outboundQuantity, 0) |
| | | |
| | | // 根据标签页类型计算总价 |
| | | if (activeTab.value === 'production') { |
| | | // 成品库存:总价 = 单价 × 剩余库存 |
| | | const unitPrice = parseFloat(item.unitPrice) || 0 |
| | | item.totalPrice = (unitPrice * remainingStock).toFixed(2) |
| | | } else if (activeTab.value === 'purchase') { |
| | | // 原料库存:含税总价 = 含税单价 × 剩余库存 |
| | | const taxInclusiveUnitPrice = parseFloat(item.taxInclusiveUnitPrice) || 0 |
| | | item.taxInclusiveTotalPrice = (taxInclusiveUnitPrice * remainingStock).toFixed(2) |
| | | } |
| | | |
| | | return item |
| | | }) |
| | | |
| | | total.value = res.data.total |
| | | // 数据加载完成后检查库存 |
| | | // checkStockAndCreatePurchase(); |
| | | }).catch(() => { |
| | | tableLoading.value = false |
| | | }) |
| | | } |
| | | |
| | | // 切换 tab |
| | | const handleTabChange = () => { |
| | | page.current = 1 |
| | | // searchForm.value.supplierName = '' |
| | | searchForm.value.customerName = '' |
| | | searchForm.value.timeStr = '' |
| | | selectedRows.value = [] |
| | | searchForm.value.productCategory = '' |
| | | getList() |
| | | } |
| | | |
| | | // 表格选择数据 |
| | | const handleSelectionChange = (selection) => { |
| | | |
| | | // 过滤掉子数据 |
| | | selectedRows.value = selection.filter(item => item.id); |
| | | console.log('selection', selectedRows.value) |
| | | } |
| | | const expandedRowKeys = ref([]) |
| | | |
| | | // 主表合计方法 |
| | | const summarizeMainTable = (param) => { |
| | | 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 |
| | | form.value = {} |
| | | productData.value = [] |
| | | let userLists = await userListNoPageByTenantId() |
| | | userList.value = userLists.data |
| | | if (type === 'edit') { |
| | | form.value = { ...row } |
| | | productTreeList().then(res =>{ |
| | | productList.value = res |
| | | productList.value.forEach(i =>{ |
| | | if (i.label === row.productCategory) { |
| | | modelList({ id: i.id }).then((res) => { |
| | | productModelList.value = res; |
| | | }); |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | form.value.entryDate = getCurrentDate() // 设置默认录入日期为当前日期 |
| | | |
| | | // 根据当前标签页显示对应的弹框 |
| | | if (activeTab.value === 'production') { |
| | | productionDialogVisible.value = true |
| | | } else if (activeTab.value === 'purchase') { |
| | | purchaseDialogVisible.value = true |
| | | } |
| | | } |
| | | |
| | | // 提交表单 |
| | | const submitForm = (submittedData) => { |
| | | console.log('子组件提交的数据:', submittedData) |
| | | |
| | | // 使用子组件提交的数据,而不是父组件的form对象 |
| | | const submitData = { ...submittedData } |
| | | |
| | | // 根据当前标签页移除对应的总价字段 |
| | | if (activeTab.value === 'production') { |
| | | // 成品库存:移除总价字段 |
| | | delete submitData.totalPrice |
| | | } else if (activeTab.value === 'purchase') { |
| | | // 原料库存:移除含税总价字段 |
| | | delete submitData.taxInclusiveTotalPrice |
| | | } |
| | | |
| | | // 移除其他可能的总价字段 |
| | | delete submitData.taxExclusiveTotalPrice |
| | | |
| | | console.log('提交给后端的数据(已移除总价字段):', submitData) |
| | | |
| | | // 根据当前标签页调用不同的提交接口 |
| | | let apiCall |
| | | if (activeTab.value === 'production') { |
| | | // 成品库存使用 updateManagement 接口 |
| | | apiCall = updateManagement(submitData) |
| | | } else { |
| | | // 原料库存使用 updateManagementByCustom 接口 |
| | | apiCall = updateManagementByCustom(submitData) |
| | | } |
| | | |
| | | apiCall.then(res => { |
| | | proxy.$modal.msgSuccess("提交成功") |
| | | closeDia() |
| | | getList() |
| | | // 提交后检查库存并尝试创建请购单 |
| | | // 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") |
| | | productionDialogVisible.value = false |
| | | purchaseDialogVisible.value = false |
| | | } |
| | | |
| | | // 导出 |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm( |
| | | '是否确认导出?', |
| | | '导出', { |
| | | confirmButtonText: '确认', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | } |
| | | ).then(() => { |
| | | const exportParams = buildQueryParams() |
| | | // 根据不同的 tab 类型调用不同的导出接口 |
| | | let exportUrl = "/stockin/exportCopy" |
| | | if (activeTab.value === 'production') { |
| | | exportUrl = "/stockin/exportCopyOne" |
| | | // 查询列表 |
| | | /** 搜索按钮操作 */ |
| | | const handleQuery = () => { |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | const paginationChange = obj => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | const buildQueryParams = () => { |
| | | const params = { |
| | | ...page, |
| | | timeStr: searchForm.value.timeStr, |
| | | }; |
| | | params.productCategory = searchForm.value.productCategory; |
| | | if (activeTab.value === "production") { |
| | | params.customerName = searchForm.value.customerName; |
| | | } else { |
| | | // params.supplierName = searchForm.value.supplierName |
| | | } |
| | | proxy.download(exportUrl, exportParams, '库存信息.xlsx') |
| | | }).catch(() => { |
| | | proxy.$modal.msg("已取消") |
| | | }) |
| | | } |
| | | // 删除 |
| | | const handleDelete = () => { |
| | | let ids = [] |
| | | if (selectedRows.value.length > 0) { |
| | | ids = selectedRows.value.map(item => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning('请选择数据') |
| | | return |
| | | } |
| | | ElMessageBox.confirm( |
| | | '选中的内容将被删除,是否确认删除?', |
| | | '导出', { |
| | | confirmButtonText: '确认', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | } |
| | | ).then(() => { |
| | | delStockManage({ids:ids}).then(res => { |
| | | proxy.$modal.msgSuccess("删除成功") |
| | | getList() |
| | | return params; |
| | | }; |
| | | |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | const params = buildQueryParams(); |
| | | const apiCall = |
| | | activeTab.value === "production" |
| | | ? getStockManagePageByProduction(params) |
| | | : getStockManagePage(params); |
| | | apiCall |
| | | .then(res => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records; |
| | | |
| | | // 为表格数据自动计算总价 |
| | | tableData.value = tableData.value.map(item => { |
| | | // 计算剩余库存 |
| | | const stockQuantity = parseFloat(item.inboundNum) || 0; |
| | | const outboundQuantity = parseFloat(item.totalInboundNum) || 0; |
| | | const remainingStock = Math.max(stockQuantity - outboundQuantity, 0); |
| | | |
| | | // 根据标签页类型计算总价 |
| | | if (activeTab.value === "production") { |
| | | // 成品库存:总价 = 单价 × 剩余库存 |
| | | const unitPrice = parseFloat(item.unitPrice) || 0; |
| | | item.totalPrice = (unitPrice * remainingStock).toFixed(2); |
| | | } else if (activeTab.value === "purchase") { |
| | | // 原料库存:含税总价 = 含税单价 × 剩余库存 |
| | | const taxInclusiveUnitPrice = |
| | | parseFloat(item.taxInclusiveUnitPrice) || 0; |
| | | item.taxInclusiveTotalPrice = ( |
| | | taxInclusiveUnitPrice * remainingStock |
| | | ).toFixed(2); |
| | | } |
| | | |
| | | return item; |
| | | }); |
| | | |
| | | total.value = res.data.total; |
| | | // 数据加载完成后检查库存 |
| | | // checkStockAndCreatePurchase(); |
| | | }) |
| | | .catch(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | // 切换 tab |
| | | const handleTabChange = () => { |
| | | page.current = 1; |
| | | // searchForm.value.supplierName = '' |
| | | searchForm.value.customerName = ""; |
| | | searchForm.value.timeStr = ""; |
| | | selectedRows.value = []; |
| | | searchForm.value.productCategory = ""; |
| | | getList(); |
| | | }; |
| | | |
| | | // 表格选择数据 |
| | | const handleSelectionChange = selection => { |
| | | // 过滤掉子数据 |
| | | selectedRows.value = selection.filter(item => item.id); |
| | | console.log("selection", selectedRows.value); |
| | | }; |
| | | const expandedRowKeys = ref([]); |
| | | |
| | | // 主表合计方法 |
| | | const summarizeMainTable = param => { |
| | | 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; |
| | | form.value = {}; |
| | | productData.value = []; |
| | | let userLists = await userListNoPageByTenantId(); |
| | | userList.value = userLists.data; |
| | | if (type === "edit") { |
| | | form.value = { ...row }; |
| | | productTreeList().then(res => { |
| | | productList.value = res; |
| | | productList.value.forEach(i => { |
| | | if (i.label === row.productCategory) { |
| | | modelList({ id: i.id }).then(res => { |
| | | productModelList.value = res; |
| | | }); |
| | | } |
| | | }); |
| | | }); |
| | | } |
| | | form.value.entryDate = getCurrentDate(); // 设置默认录入日期为当前日期 |
| | | |
| | | // 根据当前标签页显示对应的弹框 |
| | | if (activeTab.value === "production") { |
| | | productionDialogVisible.value = true; |
| | | } else if (activeTab.value === "purchase") { |
| | | purchaseDialogVisible.value = true; |
| | | } |
| | | }; |
| | | |
| | | // 提交表单 |
| | | const submitForm = submittedData => { |
| | | console.log("子组件提交的数据:", submittedData); |
| | | |
| | | // 使用子组件提交的数据,而不是父组件的form对象 |
| | | const submitData = { ...submittedData }; |
| | | |
| | | // 根据当前标签页移除对应的总价字段 |
| | | if (activeTab.value === "production") { |
| | | // 成品库存:移除总价字段 |
| | | delete submitData.totalPrice; |
| | | } else if (activeTab.value === "purchase") { |
| | | // 原料库存:移除含税总价字段 |
| | | delete submitData.taxInclusiveTotalPrice; |
| | | } |
| | | |
| | | // 移除其他可能的总价字段 |
| | | delete submitData.taxExclusiveTotalPrice; |
| | | |
| | | console.log("提交给后端的数据(已移除总价字段):", submitData); |
| | | |
| | | // 根据当前标签页调用不同的提交接口 |
| | | let apiCall; |
| | | if (activeTab.value === "production") { |
| | | // 成品库存使用 updateManagement 接口 |
| | | apiCall = updateManagement(submitData); |
| | | } else { |
| | | // 原料库存使用 updateManagementByCustom 接口 |
| | | apiCall = updateManagementByCustom(submitData); |
| | | } |
| | | |
| | | apiCall |
| | | .then(res => { |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | closeDia(); |
| | | getList(); |
| | | // 提交后检查库存并尝试创建请购单 |
| | | // 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"); |
| | | productionDialogVisible.value = false; |
| | | purchaseDialogVisible.value = false; |
| | | }; |
| | | |
| | | // 导出 |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("是否确认导出?", "导出", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "取消", |
| | | type: "warning", |
| | | }) |
| | | }).catch(() => { |
| | | proxy.$modal.msg("已取消") |
| | | }) |
| | | } |
| | | // 获取当前日期并格式化为 YYYY-MM-DD |
| | | function getCurrentDate() { |
| | | const today = new Date(); |
| | | const year = today.getFullYear(); |
| | | const month = String(today.getMonth() + 1).padStart(2, '0'); // 月份从0开始 |
| | | const day = String(today.getDate()).padStart(2, '0'); |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | onMounted(() => { |
| | | getList() |
| | | // checkStockAndCreatePurchase(); |
| | | .then(() => { |
| | | const exportParams = buildQueryParams(); |
| | | // 根据不同的 tab 类型调用不同的导出接口 |
| | | let exportUrl = "/stockin/exportCopy"; |
| | | if (activeTab.value === "production") { |
| | | exportUrl = "/stockin/exportCopyOne"; |
| | | } |
| | | proxy.download(exportUrl, exportParams, "库存信息.xlsx"); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已取消"); |
| | | }); |
| | | }; |
| | | // 删除 |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | ids = selectedRows.value.map(item => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("请选择数据"); |
| | | return; |
| | | } |
| | | ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "取消", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | delStockManage({ ids: ids }).then(res => { |
| | | proxy.$modal.msgSuccess("删除成功"); |
| | | getList(); |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已取消"); |
| | | }); |
| | | }; |
| | | // 获取当前日期并格式化为 YYYY-MM-DD |
| | | function getCurrentDate() { |
| | | const today = new Date(); |
| | | const year = today.getFullYear(); |
| | | const month = String(today.getMonth() + 1).padStart(2, "0"); // 月份从0开始 |
| | | const day = String(today.getDate()).padStart(2, "0"); |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | onMounted(() => { |
| | | getList(); |
| | | // checkStockAndCreatePurchase(); |
| | | // 每小时检查一次库存 |
| | | // const intervalId = setInterval(checkStockAndCreatePurchase, 60 * 60 * 1000); |
| | | |
| | | // onUnmounted(() => { |
| | | // // 组件卸载时清除定时器 |
| | | // clearInterval(intervalId); |
| | | // }); |
| | | }) |
| | | // onUnmounted(() => { |
| | | // // 组件卸载时清除定时器 |
| | | // clearInterval(intervalId); |
| | | // }); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | :deep(.row-low-stock td) { |
| | | background-color: #fde2e2; |
| | | color: #c45656; |
| | | } |
| | | :deep(.row-low-stock td) { |
| | | background-color: #fde2e2; |
| | | color: #c45656; |
| | | } |
| | | |
| | | :deep(.row-low-stock:hover > td) { |
| | | background-color: #fcd4d4; |
| | | } |
| | | :deep(.row-low-stock:hover > td) { |
| | | background-color: #fcd4d4; |
| | | } |
| | | </style> |