From a88e8243f12915445671da7ce211e2d54c2c918f Mon Sep 17 00:00:00 2001
From: 周宾 <2802492122@qq.com>
Date: 星期一, 22 十二月 2025 17:16:37 +0800
Subject: [PATCH] 双奇点-替换仓储物流
---
src/api/inventoryManagement/stockManage.js | 20
src/views/inventoryManagement/stockManagement/components/FormDiaPurchase.vue | 147 ++
src/views/inventoryManagement/receiptManagement/index.vue | 918 ++++++-------
src/views/inventoryManagement/issueManagement/index.vue | 287 +++
src/views/inventoryManagement/stockManagement/index.vue | 544 +++++--
src/api/inventoryManagement/stockIn.js | 78 +
src/views/inventoryManagement/receiptManagement/components/formDiaManual.vue | 386 ++++++
src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue | 302 ++++
src/views/inventoryManagement/receiptManagement/components/formDia.vue | 399 ++++++
src/views/inventoryManagement/dispatchLog/index.vue | 420 ++++--
src/views/inventoryManagement/stockManagement/components/FormDiaManual.vue | 154 ++
src/views/inventoryManagement/stockManagement/components/FormDiaProduction.vue | 147 ++
12 files changed, 2,910 insertions(+), 892 deletions(-)
diff --git a/src/api/inventoryManagement/stockIn.js b/src/api/inventoryManagement/stockIn.js
index 5e104f7..70f07a7 100644
--- a/src/api/inventoryManagement/stockIn.js
+++ b/src/api/inventoryManagement/stockIn.js
@@ -9,6 +9,41 @@
});
};
+// 鏌ヨ鐢熶骇鍏ュ簱淇℃伅鍒楄〃
+export const getStockInPageByProduction = (params) => {
+ return request({
+ url: "/stockin/listPageByProduction",
+ method: "get",
+ params,
+ });
+};
+
+// 鍑哄簱鍙拌处-鏌ヨ鑷畾涔夊叆搴撲俊鎭垪琛�
+export const getStockInPageByCustom = (params) => {
+ return request({
+ url: "/stockmanagement/listPageByCustom",
+ method: "get",
+ params,
+ });
+};
+// 鍏ュ簱绠$悊-鏌ヨ鑷畾涔夊叆搴撲俊鎭垪琛�
+export const getInPageByCustom = (params) => {
+ return request({
+ url: "/stockin/listPageByCustom",
+ method: "get",
+ params,
+ });
+};
+
+// 鍑哄簱鍙拌处-鏌ヨ鐢熶骇鍑哄簱淇℃伅鍒楄〃
+export const getStockInPageByProduct = (params) => {
+ return request({
+ url: "/stockmanagement/listPageByProduct",
+ method: "get",
+ params,
+ });
+};
+
// 淇敼鍏ュ簱瀛樹俊鎭�
export const updateStockIn = (data) => {
return request({
@@ -26,6 +61,14 @@
data,
});
};
+// 淇敼鏉愭枡搴撳瓨淇℃伅
+export const updateManagementByCustom = (data) => {
+ return request({
+ url: "/stockin/updateManagementByCustom ",
+ method: "post",
+ data,
+ });
+};
// 鏂板鍟嗗搧鍏ュ簱淇℃伅
export function addSutockIn(data) {
@@ -36,6 +79,32 @@
})
}
+// 鏂板鑷畾涔夊叆搴撲俊鎭�
+export function addStockInCustom(data) {
+ return request({
+ url: '/stockin/addCustom',
+ method: 'post',
+ data: data
+ })
+}
+
+// 缂栬緫鑷畾涔夊叆搴撲俊鎭�
+export function updateStockInCustom(data) {
+ return request({
+ url: '/stockin/updateCustom',
+ method: 'post',
+ data: data
+ })
+}
+// 缂栬緫鎴愬搧鍏ュ簱淇℃伅
+export function updateProduct(data) {
+ return request({
+ url: '/stockin/update',
+ method: 'post',
+ data: data
+ })
+}
+
// 鍒犻櫎鍏ュ簱淇℃伅
export function delStockIn(ids) {
return request({
@@ -45,6 +114,15 @@
})
}
+// 鍒犻櫎鑷畾涔夊叆搴撲俊鎭�
+export function delStockInCustom(ids) {
+ return request({
+ url: '/stockin/delteCustom',
+ method: 'post',
+ data: ids
+ })
+}
+
// 瀵煎嚭鍏ュ簱淇℃伅
export function exportStockIn(query) {
return request({
diff --git a/src/api/inventoryManagement/stockManage.js b/src/api/inventoryManagement/stockManage.js
index bb2081b..4f5d957 100644
--- a/src/api/inventoryManagement/stockManage.js
+++ b/src/api/inventoryManagement/stockManage.js
@@ -9,6 +9,24 @@
});
};
+// 鏌ヨ鐢熶骇鍏ュ簱搴撳瓨淇℃伅鍒楄〃
+export const getStockManagePageByProduction = (params) => {
+ return request({
+ url: "/stockin/listPageCopyByProduction",
+ method: "get",
+ params,
+ });
+};
+
+// 鏌ヨ鑷畾涔夊叆搴撳簱瀛樹俊鎭垪琛�
+export const getStockManagePageByCustom = (params) => {
+ return request({
+ url: "/stockin/listPageCopyByCustom",
+ method: "get",
+ params,
+ });
+};
+
// 淇敼搴撳瓨淇℃伅
export const updateStockManage = (data) => {
@@ -38,7 +56,7 @@
})
}
-//鍑哄簱鎺ュ彛
+// 鍑哄簱绠$悊-棰嗙敤鎺ュ彛
export const stockOut = (data) => {
return request({
url: '/stockmanagement/stockout',
diff --git a/src/views/inventoryManagement/dispatchLog/index.vue b/src/views/inventoryManagement/dispatchLog/index.vue
index 3eb5758..2370655 100644
--- a/src/views/inventoryManagement/dispatchLog/index.vue
+++ b/src/views/inventoryManagement/dispatchLog/index.vue
@@ -1,144 +1,224 @@
<template>
<div class="app-container">
- <div class="search_form">
- <div>
- <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>
- <!-- <el-button type="primary" @click="openForm('add')">鏂板</el-button> -->
- <el-button @click="handleOut">瀵煎嚭</el-button>
- <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
- <el-button type="primary" plain @click="handlePrint">鎵撳嵃</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%"
- :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"
- min-width="250"
- show-overflow-tooltip
- />
- <el-table-column
- label="渚涘簲鍟嗗悕绉�"
- prop="supplierName"
- width="250"
- show-overflow-tooltip
- />
- <el-table-column
- label="浜у搧澶х被"
- prop="productCategory"
- width="100"
- show-overflow-tooltip
- />
- <el-table-column
- label="瑙勬牸鍨嬪彿"
- prop="specificationModel"
- width="100"
- show-overflow-tooltip
- />
- <el-table-column
- label="鍗曚綅"
- prop="unit"
- width="80"
- show-overflow-tooltip
- />
- <el-table-column
- label="鍑哄簱鏁伴噺"
- prop="inboundNum"
- width="100"
- 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-table-column
- label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- width="180"
- show-overflow-tooltip
- />
- <el-table-column
- label="鍑哄簱浜�"
- prop="createBy"
- width="80"
- show-overflow-tooltip
- />
- <!-- <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>
- <pagination
- v-show="total > 0"
- :total="total"
- layout="total, sizes, prev, pager, next, jumper"
- :page="page.current"
- :limit="page.size"
- @pagination="paginationChange"
- />
- </div>
+ <el-tabs v-model="activeTab" @tab-change="handleTabChange">
+ <el-tab-pane label="閲囪喘鍑哄簱" name="production">
+ <div class="search_form">
+ <div>
+<!-- <span class="search_title">瀹㈡埛鍚嶇О锛�</span>-->
+<!-- <el-input-->
+<!-- v-model="searchForm.customerName"-->
+<!-- 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"
+ />
+ <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="primary" plain @click="handlePrint">鎵撳嵃</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%"
+ :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" min-width="120" show-overflow-tooltip />
+<!-- <el-table-column label="瀹㈡埛鍚嶇О" prop="customerName" width="250" 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="inboundNum" 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 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-table-column label="涓嶅惈绋庢�讳环(鍏�)" prop="taxExclusiveTotalPrice" width="180" show-overflow-tooltip />-->
+ <el-table-column label="鍑哄簱浜�" prop="createBy" width="80" show-overflow-tooltip />
+ </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-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>
+ <el-button type="primary" plain @click="handlePrint">鎵撳嵃</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%"
+ :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" min-width="120" 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="inboundNum" width="100" 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-column label="鍑哄簱浜�" prop="createBy" width="80" show-overflow-tooltip />
+ </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-tab-pane label="鎴愬搧鍑哄簱" name="manual">
+ <div class="search_form">
+ <div>
+<!-- <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"
+ />
+ <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="primary" plain @click="handlePrint">鎵撳嵃</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%"
+ :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" show-overflow-tooltip />
+ <!-- <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" width="250" 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" show-overflow-tooltip />
+ <el-table-column label="鐗╁搧绫诲瀷" prop="itemType" show-overflow-tooltip />
+ <el-table-column label="鍑哄簱鏁伴噺" prop="inboundNum" 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-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-table-column label="涓嶅惈绋庢�讳环(鍏�)" prop="taxExclusiveTotalPrice" width="180" show-overflow-tooltip />-->
+ <el-table-column label="鍑哄簱浜�" prop="createBy" show-overflow-tooltip />
+ </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>
<!-- 鎵撳嵃棰勮寮圭獥 -->
<el-dialog
@@ -258,17 +338,22 @@
<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 {
getStockOutPage,
delStockOut,
} from "@/api/inventoryManagement/stockOut.js";
+import {
+ getStockInPageByProduct,
+ getStockInPageByCustom,
+} from "@/api/inventoryManagement/stockIn.js";
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
const tableData = ref([]);
+const activeTab = ref('production');
const selectedRows = ref([]);
const tableLoading = ref(false);
const page = reactive({
@@ -285,7 +370,9 @@
const data = reactive({
searchForm: {
supplierName: "",
- timeStr: "",
+ customerName: "",
+ productCategory:'',
+ timeStr: getCurrentDate(),
},
form: {
supplierId: null,
@@ -322,18 +409,56 @@
};
const getList = () => {
tableLoading.value = true;
- getStockOutPage({ ...searchForm.value, ...page })
+ const params = { ...page }
+ if (activeTab.value === 'production') {
+ params.customerName = searchForm.value.customerName
+ params.timeStr = searchForm.value.timeStr
+ } else {
+ params.supplierName = searchForm.value.supplierName
+ params.timeStr = searchForm.value.timeStr
+ }
+ params.productCategory = searchForm.value.productCategory
+
+ // 鏍规嵁涓嶅悓鐨� tab 绫诲瀷璋冪敤涓嶅悓鐨勬帴鍙�
+ const apiCall = activeTab.value === 'production'
+ ? getStockInPageByProduct(params)
+ : activeTab.value === 'manual'
+ ? getStockInPageByCustom(params)
+ : getStockOutPage(params)
+
+ apiCall
.then((res) => {
tableLoading.value = false;
tableData.value = res.data.records;
tableData.value.map((item) => {
item.children = [];
+ // 鍓嶇璁$畻鎬讳环
+ const inboundNum = Number(item.inboundNum) || 0;
+ if (activeTab.value === 'production') {
+ // 鎴愬搧鍑哄簱锛氭�讳环 = unitPrice 脳 inboundNum
+ const unitPrice = Number(item.unitPrice) || 0;
+ item.totalPrice = (unitPrice * inboundNum).toFixed(2);
+ } else {
+ // 鍘熸枡鍜屾潗鏂欏嚭搴擄細鎬讳环 = taxInclusiveUnitPrice 脳 inboundNum
+ const taxInclusiveUnitPrice = Number(item.taxInclusiveUnitPrice) || 0;
+ item.taxInclusiveTotalPrice = (taxInclusiveUnitPrice * inboundNum).toFixed(2);
+ }
});
total.value = res.data.total;
})
.catch(() => {
tableLoading.value = false;
});
+};
+
+const handleTabChange = () => {
+ page.current = 1
+ searchForm.value.supplierName = ''
+ searchForm.value.customerName = ''
+ searchForm.value.timeStr = ''
+ selectedRows.value = []
+ searchForm.value.productCategory = ''
+ getList()
};
// 琛ㄦ牸閫夋嫨鏁版嵁
@@ -361,7 +486,14 @@
type: "warning",
})
.then(() => {
- proxy.download("/stockmanagement/export", {}, "鍑哄簱鍙拌处.xlsx");
+ // 鏍规嵁涓嶅悓鐨� tab 绫诲瀷璋冪敤涓嶅悓鐨勫鍑烘帴鍙�
+ let exportUrl = "/stockmanagement/export"
+ if (activeTab.value === 'production') {
+ exportUrl = "/stockmanagement/exportone"
+ } else if (activeTab.value === 'manual') {
+ exportUrl = "/stockmanagement/exportTwo"
+ }
+ proxy.download(exportUrl, {}, "鍑哄簱鍙拌处.xlsx");
})
.catch(() => {
proxy.$modal.msg("宸插彇娑�");
@@ -863,3 +995,5 @@
}
}
</style>
+
+
diff --git a/src/views/inventoryManagement/issueManagement/index.vue b/src/views/inventoryManagement/issueManagement/index.vue
index d8ce8f8..cbaf637 100644
--- a/src/views/inventoryManagement/issueManagement/index.vue
+++ b/src/views/inventoryManagement/issueManagement/index.vue
@@ -1,58 +1,183 @@
<template>
<div class="app-container">
- <div class="search_form">
- <div>
- <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>
- <!-- <el-button type="primary" @click="openForm('add')">鏂板鍑哄簱</el-button> -->
- <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%"
- :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="inboundBatches" width="160" 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="70" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="90" show-overflow-tooltip />
- <el-table-column label="搴撳瓨鏁伴噺" prop="inboundNum0" width="90" 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="80" show-overflow-tooltip />
- <el-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱浜�" prop="createBy" width="80" show-overflow-tooltip />
- <el-table-column fixed="right" label="鎿嶄綔" min-width="60" align="center">
- <template #default="scope">
- <el-button link type="primary" size="small" @click="openForm(scope.row);">棰嗙敤</el-button>
- </template>
- </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-tabs v-model="activeTab" @tab-change="handleTabChange">
+ <el-tab-pane label="鎴愬搧鍑哄簱" name="production">
+ <div class="search_form">
+ <div>
+<!-- <span class="search_title">瀹㈡埛鍚嶇О锛�</span>-->
+<!-- <el-input v-model="searchForm.customerName" 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"
+ />
+ <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>
+ </div>
+ </div>
+ <div class="table_list">
+ <el-table :data="tableData" border v-loading="tableLoading"
+ :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%"
+ :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)">
+ <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="inboundBatches" width="160" show-overflow-tooltip /> -->
+<!-- <el-table-column label="瀹㈡埛鍚嶇О" prop="customerName" width="240" 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="70" show-overflow-tooltip />
+ <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="90" show-overflow-tooltip />
+ <el-table-column label="鍓╀綑搴撳瓨" prop="inboundNum0" width="90" 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="80" show-overflow-tooltip />-->
+<!-- <el-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />-->
+ <!-- <el-table-column label="鍏ュ簱浜�" prop="createBy" width="80" show-overflow-tooltip /> -->
+ <el-table-column fixed="right" label="鎿嶄綔" min-width="60" align="center">
+ <template #default="scope">
+ <el-button link type="primary" size="small" @click="openForm(scope.row);">棰嗙敤</el-button>
+ </template>
+ </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-tab-pane label="鍘熸枡鍑哄簱" name="purchase">
+ <div class="search_form">
+ <div>
+<!-- <!– <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"
+ />
+ <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>
+ </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%"
+ :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="inboundBatches" width="160" show-overflow-tooltip /> -->
+<!--<el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" width="240" 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="70" show-overflow-tooltip />
+ <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="90" show-overflow-tooltip />
+ <el-table-column label="鍓╀綑搴撳瓨" prop="inboundNum0" width="90" 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-column fixed="right" label="鎿嶄綔" min-width="60" align="center">
+ <template #default="scope">
+ <el-button link type="primary" size="small" @click="openForm(scope.row);">棰嗙敤</el-button>
+ </template>
+ </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-tab-pane label="鏉愭枡鍑哄簱" name="manual">
+ <div class="search_form">
+ <div>
+<!-- <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"
+ />
+ <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>
+ </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%"
+ :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="inboundDate" width="100" show-overflow-tooltip />
+ <!-- <el-table-column label="鍏ュ簱鎵规" prop="inboundBatches" width="160" show-overflow-tooltip /> -->
+<!-- <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" width="240" 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="70" show-overflow-tooltip />
+ <el-table-column label="鐗╁搧绫诲瀷" prop="itemType" show-overflow-tooltip />
+ <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" show-overflow-tooltip />
+ <el-table-column label="鍓╀綑搴撳瓨" prop="inboundNum0" width="90" 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="80" show-overflow-tooltip />-->
+<!-- <el-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />-->
+ <!-- <el-table-column label="鍏ュ簱浜�" prop="createBy" show-overflow-tooltip /> -->
+ <el-table-column fixed="right" label="鎿嶄綔" width="100" align="center">
+ <template #default="scope">
+ <el-button link type="primary" size="small" @click="openForm(scope.row);">棰嗙敤</el-button>
+ </template>
+ </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>
<el-dialog v-model="dialogFormVisible" :title="'鏂板鍑哄簱'" width="40%" @close="closeDia">
<el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+ <div>鍙嚭搴撴暟閲�:{{currentRowNum}}</div>
<el-form-item label="鍑哄簱鏁伴噺锛�" prop="salesContractNo">
<el-input-number :step="0.01" :min="0" style="width: 100%" v-model="form.inboundQuantity" placeholder="璇疯緭鍏�" clearable />
</el-form-item>
@@ -61,7 +186,9 @@
type="date" placeholder="璇烽�夋嫨" clearable />
</el-form-item>
<el-form-item label="鍑哄簱浜猴細" prop="entryPerson">
- <el-select v-model="form.nickName" placeholder="璇烽�夋嫨" clearable>
+ <el-select v-model="form.nickName" filterable
+ default-first-option
+ :reserve-keyword="false" placeholder="璇烽�夋嫨" clearable>
<el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
</el-select>
</el-form-item>
@@ -78,12 +205,14 @@
<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 {
- getStockInPage
+ getStockInPage,
+ getStockInPageByProduction,
+ getStockInPageByCustom, getInPageByCustom
} from "@/api/inventoryManagement/stockIn.js";
import {
getStockManagePage,
@@ -106,14 +235,17 @@
// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
const dialogFormVisible = ref(false)
+const activeTab = ref('production')
const data = reactive({
searchForm: {
supplierName: '',
+ customerName: '',
inboundQuantity:'',
inboundTime:'',
nickName: '',
userId: '',
- timeStr: '',
+ productCategory:'',
+ timeStr: getCurrentDate(),
},
form: {
productrecordId: '',
@@ -139,14 +271,40 @@
}
const getList = () => {
tableLoading.value = true
- getStockInPage({ ...searchForm.value, ...page }).then(res => {
+ const params = { ...page }
+ if (activeTab.value === 'production') {
+ params.customerName = searchForm.value.customerName
+ params.timeStr = searchForm.value.timeStr
+ } else {
+ params.supplierName = searchForm.value.supplierName
+ params.timeStr = searchForm.value.timeStr
+ }
+ params.productCategory = searchForm.value.productCategory
+ let apiCall
+ if (activeTab.value === 'production') {
+ apiCall = getStockInPageByProduction(params)
+ } else if (activeTab.value === 'manual') {
+ apiCall = getInPageByCustom(params)
+ } else {
+ apiCall = getStockInPage(params)
+ }
+ apiCall.then(res => {
tableLoading.value = false
tableData.value = res.data.records
total.value = res.data.total
- console.log('res', res.data.records)
}).catch(() => {
tableLoading.value = false
})
+}
+
+const handleTabChange = () => {
+ page.current = 1
+ searchForm.value.supplierName = ''
+ searchForm.value.customerName = ''
+ searchForm.value.timeStr = ''
+ selectedRows.value = []
+ searchForm.value.productCategory = ''
+ getList()
}
const findNodeById = (nodes, productId) => {
@@ -212,12 +370,14 @@
}
proxy.$refs["formRef"].validate(valid => {
if (valid && currentRowId.value) {
+ const typeMap = { production: 2, purchase: 1, manual: 3 }
const outData = {
id: currentRowId.value, // 鍘熷璁板綍ID
- salesLedgerProductId: salesLedgerProductId.value,
+ salesLedgerProductId: activeTab.value === 'manual' ? 0 : salesLedgerProductId.value,
quantity: form.value.inboundQuantity, // 鍑哄簱鏁伴噺
time: form.value.inboundTime, // 鍑哄簱鏃堕棿
- userId: form.value.nickName // 鎿嶄綔浜�
+ userId: form.value.nickName, // 鎿嶄綔浜�
+ type: typeMap[activeTab.value] // 鍑哄簱绫诲瀷锛氶噰璐�1锛岀敓浜�2锛岃嚜瀹氫箟3
}
console.log(outData)
@@ -247,7 +407,14 @@
type: 'warning',
}
).then(() => {
- proxy.download("/stockin/export", {}, '鍏ュ簱鍙拌处.xlsx')
+ // 鏍规嵁涓嶅悓鐨� tab 绫诲瀷璋冪敤涓嶅悓鐨勫鍑烘帴鍙�
+ let exportUrl = "/stockin/export"
+ if (activeTab.value === 'production') {
+ exportUrl = "/stockin/exportOne"
+ } else if (activeTab.value === 'manual') {
+ exportUrl = "/stockin/exportTwo"
+ }
+ proxy.download(exportUrl, {}, '鍏ュ簱鍙拌处.xlsx')
}).catch(() => {
proxy.$modal.msg("宸插彇娑�")
})
diff --git a/src/views/inventoryManagement/receiptManagement/components/formDia.vue b/src/views/inventoryManagement/receiptManagement/components/formDia.vue
new file mode 100644
index 0000000..3bd3390
--- /dev/null
+++ b/src/views/inventoryManagement/receiptManagement/components/formDia.vue
@@ -0,0 +1,399 @@
+<template>
+ <el-dialog v-model="dialogFormVisible" :title="getDialogTitle()" width="70%"
+ @close="closeDia">
+ <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+ <el-form-item label="閲囪喘璁㈠崟鍙�" prop="purchaseContractNumber">
+ <el-select
+ v-model="form.purchaseContractNumber"
+ placeholder="璇烽�夋嫨閲囪喘璁㈠崟鍙�"
+ clearable
+ filterable
+ :loading="loadingPurchaseOptions"
+ @change="handlePurchaseChange"
+ :disabled="operationType === 'edit'"
+ style="width: 100%"
+ >
+ <el-option
+ v-for="item in purchaseOptions"
+ :key="item.purchaseContractNumber"
+ :label="formatPurchaseOption(item)"
+ :value="item.purchaseContractNumber"
+ />
+ </el-select>
+ </el-form-item>
+ <el-table
+ :data="productList"
+ border
+ v-loading="loadingProducts"
+ @selection-change="handleSelectionChange"
+ >
+ <el-table-column align="center" type="selection" width="55" />
+ <el-table-column
+ align="center"
+ label="搴忓彿"
+ type="index"
+ width="60"
+ />
+ <el-table-column label="浜у搧澶х被" prop="productCategory" />
+ <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
+ <el-table-column label="鍗曚綅" prop="unit" width="70" />
+ <!-- <el-table-column label="渚涘簲鍟�" prop="supplierName" width="100" /> -->
+ <el-table-column label="閲囪喘鏁伴噺" prop="quantity" width="100" />
+ <el-table-column label="寰呭叆搴撴暟閲�" prop="quantity0" width="100" />
+ <el-table-column label="鏈鍏ュ簱鏁伴噺" prop="quantityStock" width="150">
+ <template #default="scope">
+ <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.quantityStock" @change="() => calculateTotalPrice(scope.row)" />
+ </template>
+ </el-table-column>
+ <el-table-column label="绋庣巼(%)" prop="taxRate" width="120" />
+ <el-table-column label="鍗曚环(鍏�)" prop="taxInclusiveUnitPrice" width="150">
+ <template #default="scope">
+ <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.taxInclusiveUnitPrice" @change="() => calculateTotalPrice(scope.row)" :disabled="operationType === 'edit'"/>
+ </template>
+ </el-table-column>
+ <el-table-column
+ label="鎬讳环(鍏�)"
+ :formatter="formattedNumber"
+ prop="taxInclusiveTotalPrice"
+ width="150"
+ >
+ </el-table-column>
+ </el-table>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button @click="closeDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, getCurrentInstance } from 'vue'
+import useUserStore from '@/store/modules/user'
+import {
+ updateStockIn,
+ addSutockIn,
+ selectProductRecordListByPuechaserId
+} from "@/api/inventoryManagement/stockIn.js";
+import { purchaseListPage } from "@/api/procurementManagement/procurementLedger.js";
+
+const userStore = useUserStore()
+const { proxy } = getCurrentInstance()
+const emit = defineEmits(['close', 'success'])
+
+const operationType = ref('')// 鎿嶄綔绫诲瀷: 'add' 鎴� 'edit'
+const dialogFormVisible = ref(false)// 寮规鏄剧ず鐘舵��
+const productList = ref([]);// 浜у搧鍒楄〃鏁版嵁
+const loadingProducts = ref(false);// 浜у搧鍔犺浇鐘舵��
+const selectedRows = ref([]) // 浜у搧琛ㄦ牸閫変腑琛�
+const purchaseOptions = ref([])
+const loadingPurchaseOptions = ref(false)
+const loading = ref(false);
+
+const data = reactive({
+ form: {
+ id: null,
+ purchaseContractNumber: '', // 閲囪喘璁㈠崟鍙�
+ supplierId: null, // 渚涘簲鍟咺D
+ supplierName: '', // 渚涘簲鍟嗗悕绉�
+ inboundTime: '', // 鍏ュ簱鏃堕棿
+ inboundBatch: '', // 鍏ュ簱鎵规
+ recorderId: userStore.userId, // 褰曞叆浜篒D
+ recorderName: userStore.name, // 褰曞叆浜哄鍚�
+ entryDate: getCurrentDate(), // 褰曞叆鏃ユ湡
+ remark: '', // 澶囨敞
+ },
+ rules: {
+ purchaseContractNumber: [{ required: true, message: "璇疯緭鍏ラ噰璐悎鍚屽彿", trigger: "blur" }],
+ supplierId: [{ required: true, message: "璇烽�夋嫨渚涘簲鍟�", trigger: "change" }],
+ inboundTime: [{ required: true, message: "璇烽�夋嫨鍏ュ簱鏃堕棿", trigger: "change" }],
+ inboundBatch: [{ required: true, message: "璇疯緭鍏ュ叆搴撴壒娆�", trigger: "blur" }]
+ }
+})
+const { form, rules } = toRefs(data)
+
+// 鍔ㄦ�佽绠楀璇濇鏍囬
+const getDialogTitle = () => {
+ return operationType.value === 'add' ? '鏂板鍏ュ簱' : '缂栬緫鍏ュ簱'
+}
+
+const formatPurchaseOption = (item = {}) => {
+ const contract = item.purchaseContractNumber || '--';
+ const supplier = item.supplierName ? ` 路 ${item.supplierName}` : '';
+ return `${contract}${supplier}`;
+};
+
+const loadPurchaseOptions = async (keyword = '') => {
+ try {
+ loadingPurchaseOptions.value = true;
+ const res = await purchaseListPage({
+ current: -1,
+ size: -1,
+ purchaseContractNumber: keyword,
+ });
+ const records = res.data?.records || [];
+ purchaseOptions.value = records;
+ if (
+ form.value.purchaseContractNumber &&
+ !purchaseOptions.value.find(
+ (item) => item.purchaseContractNumber === form.value.purchaseContractNumber
+ )
+ ) {
+ purchaseOptions.value.push({
+ purchaseContractNumber: form.value.purchaseContractNumber,
+ supplierName: form.value.supplierName,
+ supplierId: form.value.supplierId,
+ });
+ }
+ } finally {
+ loadingPurchaseOptions.value = false;
+ }
+};
+
+const handlePurchaseChange = (value) => {
+ form.value.purchaseContractNumber = value || '';
+ const matched = purchaseOptions.value.find(
+ (item) => item.purchaseContractNumber === value
+ );
+ if (matched) {
+ form.value.supplierName = matched.supplierName || form.value.supplierName;
+ form.value.supplierId = matched.supplierId || form.value.supplierId;
+ }
+ if (!value) {
+ productList.value = [];
+ return;
+ }
+ fetchProductsByContract();
+};
+
+const exceedsAddLimit = (product) => {
+ const stock = Number(product?.quantityStock ?? 0);
+ const waiting = Number(product?.quantity0 ?? 0);
+ if (!Number.isFinite(stock) || !Number.isFinite(waiting)) {
+ return false;
+ }
+ return stock > waiting;
+};
+
+const exceedsEditLimit = (product) => {
+ const stock = Number(product?.quantityStock ?? 0);
+ const waiting = Number(product?.quantity0 ?? 0);
+ const original = Number(product?.originalQuantityStock ?? 0);
+ if (!Number.isFinite(stock) || !Number.isFinite(waiting) || !Number.isFinite(original)) {
+ return false;
+ }
+ return stock > waiting + original;
+};
+
+const formattedNumber = (row, column, cellValue) => {
+ return parseFloat(cellValue).toFixed(2);
+};
+
+// 璁$畻鎬讳环
+const calculateTotalPrice = (row) => {
+ const quantityStock = Number(row?.quantityStock ?? 0);
+ const taxInclusiveUnitPrice = Number(row?.taxInclusiveUnitPrice ?? 0);
+
+ if (Number.isFinite(quantityStock) && Number.isFinite(taxInclusiveUnitPrice)) {
+ row.taxInclusiveTotalPrice = quantityStock * taxInclusiveUnitPrice;
+ } else {
+ row.taxInclusiveTotalPrice = 0;
+ }
+};
+
+const fetchProductsByContract = async () => {
+ if (!form.value.purchaseContractNumber) {
+ proxy.$modal.msgWarning('璇烽�夋嫨鍚堝悓鍙�')
+ return
+ }
+ try {
+ loadingProducts.value = true
+ const productRes = await selectProductRecordListByPuechaserId({
+ purchaseContractNumber: form.value.purchaseContractNumber
+ });
+ if (!productRes.data || productRes.data.length === 0) {
+ proxy.$modal.msgWarning('璇ュ悎鍚屼笅娌℃湁浜у搧璁板綍')
+ productList.value = [];
+ return
+ }
+ productList.value = productRes.data.map(item => ({
+ ...item,
+ quantityStock: 0,
+ taxInclusiveUnitPrice: Number(item?.taxInclusiveUnitPrice ?? 0),
+ taxInclusiveTotalPrice: 0,
+ originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? 0),
+ }))
+ } catch (error) {
+ console.error('鏌ヨ浜у搧璁板綍澶辫触:', error)
+ proxy.$modal.msgError('鏌ヨ浜у搧璁板綍澶辫触')
+ productList.value = [];
+ } finally {
+ loadingProducts.value = false
+ }
+}
+
+const updatePro = async () => {
+ if (selectedRows.value.length === 0) {
+ proxy.$modal.msgWarning('璇峰厛閫夋嫨浜у搧');
+ return;
+ }
+ const target = selectedRows.value[0];
+ const stock = Number(target?.quantityStock ?? 0);
+ if (!Number.isFinite(stock) || stock <= 0) {
+ proxy.$modal.msgWarning('璇峰~鍐欐湁鏁堢殑鍏ュ簱鏁伴噺');
+ return;
+ }
+ if (exceedsEditLimit(target)) {
+ proxy.$modal.msgError('鏈鍏ュ簱鏁伴噺涓嶈兘瓒呰繃鍘熷叆搴撴暟閲忎笌寰呭叆搴撴暟閲忎箣鍜�');
+ return;
+ }
+ const stockInData = {
+ id: selectedRows.value[0].recordId,
+ quantityStock: Number(selectedRows.value[0].quantityStock),
+ };
+ await updateStockIn(stockInData)
+ proxy.$modal.msgSuccess('淇敼鍏ュ簱鎴愬姛')
+ closeDia()
+ emit('success')
+}
+
+const submitForm = async () => {
+ if (selectedRows.value.length === 0) {
+ proxy.$modal.msgWarning('璇峰厛閫夋嫨閲囪喘鍚堝悓骞堕�夋嫨浜у搧')
+ return
+ }
+ if(operationType.value !== 'add'){
+ await updatePro()
+ return
+ }
+ try {
+ await proxy.$refs.formRef.validate()
+ const invalidProducts = selectedRows.value.filter((product) => {
+ const stock = Number(product?.quantityStock ?? 0);
+ if (!Number.isFinite(stock) || stock <= 0) {
+ return true;
+ }
+ return exceedsAddLimit(product);
+ })
+
+ if (invalidProducts.length > 0) {
+ proxy.$modal.msgError('鏈鍏ュ簱鏁伴噺闇�澶т簬0锛屼笖涓嶈兘瓒呰繃寰呭叆搴撴暟閲�')
+ return
+ }
+
+ const stockInData = {
+ ...form.value,
+ inboundTime: formatDateTime(form.value.inboundTime),
+ nickName: userStore.nickName,
+ details: selectedRows.value.map(product => ({
+ id: product.id,
+ inboundQuantity: Number(product.quantityStock),
+ taxInclusiveUnitPrice: Number(product.taxInclusiveUnitPrice),
+ taxInclusiveTotalPrice: Number(product.taxInclusiveTotalPrice)
+ })),
+ };
+ loading.value = true
+ await addSutockIn(stockInData)
+
+ proxy.$modal.msgSuccess('鏂板鍏ュ簱鎴愬姛')
+ closeDia()
+ emit('success')
+
+ } catch (error) {
+ console.error('鎻愪氦澶辫触:', error)
+ if (!error.errors) {
+ proxy.$modal.msgError('鎿嶄綔澶辫触锛岃閲嶈瘯')
+ }
+ } finally {
+ loading.value = false
+ }
+}
+
+const closeDia = () => {
+ proxy.$refs.formRef.resetFields()
+ dialogFormVisible.value = false
+ emit('close')
+}
+
+const handleSelectionChange = (selection) => {
+ selectedRows.value = selection.filter(item => item.id);
+}
+
+function formatDateTime(date = new Date(), includeTime = true) {
+ const d = new Date(date);
+ const year = d.getFullYear();
+ const month = String(d.getMonth() + 1).padStart(2, '0');
+ const day = String(d.getDate()).padStart(2, '0');
+
+ if (!includeTime) {
+ return `${year}-${month}-${day}`;
+ }
+
+ const hours = String(d.getHours()).padStart(2, '0');
+ const minutes = String(d.getMinutes()).padStart(2, '0');
+ const seconds = String(d.getSeconds()).padStart(2, '0');
+
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+}
+
+function getCurrentDate() {
+ return formatDateTime(new Date(), false);
+}
+
+const openDialog = async (type, row) => {
+ operationType.value = type
+ dialogFormVisible.value = true
+ selectedRows.value = []
+ await loadPurchaseOptions();
+
+ if (type === 'add') {
+ form.value = {
+ id: null,
+ purchaseContractNumber: '',
+ supplierId: null,
+ supplierName: '',
+ inboundTime: '',
+ inboundBatch: '',
+ recorderId: userStore.userId,
+ recorderName: userStore.name,
+ entryDate: getCurrentDate(),
+ remark: ''
+ }
+ productList.value = []
+ } else {
+ form.value = JSON.parse(JSON.stringify(row))
+ try {
+ loadingProducts.value = true
+ const res = await selectProductRecordListByPuechaserId({
+ purchaseContractNumber: form.value.purchaseContractNumber,
+ id: row.id
+ });
+ productList.value = res.data.map(item => ({
+ ...item,
+ quantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0),
+ taxInclusiveUnitPrice: Number(item?.taxInclusiveUnitPrice ?? 0),
+ taxInclusiveTotalPrice: Number(item?.quantityStock ?? 0) * Number(item?.taxInclusiveUnitPrice ?? 0),
+ originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0),
+ }))
+ selectedRows.value = productList.value
+ } catch (error) {
+ console.error('鍔犺浇浜у搧澶辫触:', error)
+ proxy.$modal.msgError('鍔犺浇浜у搧澶辫触')
+ productList.value = []
+ } finally {
+ loadingProducts.value = false
+ }
+ }
+}
+
+defineExpose({
+ openDialog,
+})
+</script>
+
+<style scoped lang="scss"></style>
+
+
+
diff --git a/src/views/inventoryManagement/receiptManagement/components/formDiaManual.vue b/src/views/inventoryManagement/receiptManagement/components/formDiaManual.vue
new file mode 100644
index 0000000..6d2c07b
--- /dev/null
+++ b/src/views/inventoryManagement/receiptManagement/components/formDiaManual.vue
@@ -0,0 +1,386 @@
+<template>
+ <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '鏂板鑷畾涔夊叆搴�' : '缂栬緫鑷畾涔夊叆搴�'" width="70%"
+ @close="closeDia">
+ <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+ <div style="margin-bottom: 10px;" v-if="operationType === 'add'">
+ <el-button type="primary" @click="addProductRow">鏂板</el-button>
+ </div>
+ <el-table
+ :data="productList"
+ border
+ v-loading="loadingProducts"
+ >
+ <el-table-column
+ align="center"
+ label="搴忓彿"
+ type="index"
+ width="60"
+ />
+ <el-table-column label="浜у搧鍥剧墖" align="center" prop="productCategory" width="100">
+ <template #default="scope">
+ <el-upload
+ :action="uploadUrl"
+ :before-upload="handleBeforeUpload"
+ :on-success="(res,file)=>{handleUploadSuccess(res,file,scope.row)}"
+ :on-error="handleUploadError"
+ name="file"
+ :show-file-list="false"
+ :headers="headers"
+ accept="image/*"
+ :data="{ type: 9 }"
+ >
+ <img v-if="scope.row.url" :src="javaApiUrl+scope.row.url"></img>
+ <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
+ </el-upload>
+ </template>
+ </el-table-column>
+ <el-table-column label="浜у搧澶х被" prop="productCategory" width="200">
+ <template #default="scope">
+ <el-input v-model="scope.row.productCategory" placeholder="璇疯緭鍏ヤ骇鍝佸ぇ绫�" />
+ </template>
+ </el-table-column>
+ <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="200">
+ <template #default="scope">
+ <el-input v-model="scope.row.specificationModel" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
+ </template>
+ </el-table-column>
+ <el-table-column label="鍗曚綅" prop="unit" width="100">
+ <template #default="scope">
+ <el-input v-model="scope.row.unit" placeholder="璇疯緭鍏ュ崟浣�" />
+ </template>
+ </el-table-column>
+ <el-table-column label="渚涘簲鍟�" prop="supplierName" width="200">
+ <template #default="scope">
+ <el-input v-model="scope.row.supplierName" placeholder="璇疯緭鍏ヤ緵搴斿晢" />
+ </template>
+ </el-table-column>
+ <el-table-column label="鐗╁搧绫诲瀷" prop="itemType" width="150">
+ <template #default="scope">
+ <el-select v-model="scope.row.itemType" filterable allow-create placeholder="璇烽�夋嫨鐗╁搧绫诲瀷" style="width: 100%">
+ <el-option
+ v-for="item in itemTypeOptions"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value"
+ />
+ </el-select>
+ </template>
+ </el-table-column>
+ <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="150">
+ <template #default="scope">
+ <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.inboundNum" @change="() => calculateTotalPrice(scope.row)" />
+ </template>
+ </el-table-column>
+ <el-table-column label="鍏ュ簱鏃ユ湡" prop="inboundDate" width="180">
+ <template #default="scope">
+ <el-date-picker
+ v-model="scope.row.inboundDate"
+ type="date"
+ placeholder="璇烽�夋嫨鍏ュ簱鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ style="width: 100%"
+ />
+ </template>
+ </el-table-column>
+<!-- <el-table-column label="鏁伴噺" prop="quantityStock" width="150">-->
+<!-- <template #default="scope">-->
+<!-- <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.quantityStock" @change="() => calculateTotalPrice(scope.row)" />-->
+<!-- </template>-->
+<!-- </el-table-column>-->
+<!-- <el-table-column label="鍗曚环(鍏�)" prop="taxInclusiveUnitPrice" width="150">-->
+<!-- <template #default="scope">-->
+<!-- <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.taxInclusiveUnitPrice" @change="() => calculateTotalPrice(scope.row)" />-->
+<!-- </template>-->
+<!-- </el-table-column>-->
+<!-- <el-table-column -->
+<!-- label="鎬讳环(鍏�)" -->
+<!-- prop="taxInclusiveTotalPrice" -->
+<!-- width="150" -->
+<!-- >-->
+<!-- </el-table-column>-->
+ <el-table-column label="鎿嶄綔" width="80" v-if="operationType === 'add'">
+ <template #default="scope">
+ <el-button type="danger" size="small" @click="removeProductRow(scope.$index)">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button @click="closeDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, getCurrentInstance } from 'vue'
+import useUserStore from '@/store/modules/user'
+import {
+ addStockInCustom,
+ updateStockInCustom,
+} from "@/api/inventoryManagement/stockIn.js";
+import { getToken } from "@/utils/auth";
+const headers = ref({
+ Authorization: "Bearer " + getToken(),
+});
+
+const imeUrl = ref(import.meta.env.VITE_APP_ENV)
+console.log(import.meta)
+const javaApiUrl = __BASE_API__;
+console.log('Java API 鍦板潃:', javaApiUrl)
+
+const userStore = useUserStore()
+const { proxy } = getCurrentInstance()
+const emit = defineEmits(['close', 'success'])
+
+const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // 涓婁紶鐨勫浘鐗囨湇鍔″櫒鍦板潃
+
+const operationType = ref('')// 鎿嶄綔绫诲瀷: 'add' 鎴� 'edit'
+const dialogFormVisible = ref(false)// 寮规鏄剧ず鐘舵��
+const productList = ref([]);// 浜у搧鍒楄〃鏁版嵁
+const loadingProducts = ref(false);// 浜у搧鍔犺浇鐘舵��
+const loading = ref(false);
+
+function formatDateTime(date = new Date(), includeTime = true) {
+ const d = new Date(date);
+ const year = d.getFullYear();
+ const month = String(d.getMonth() + 1).padStart(2, '0');
+ const day = String(d.getDate()).padStart(2, '0');
+
+ if (!includeTime) {
+ return `${year}-${month}-${day}`;
+ }
+
+ const hours = String(d.getHours()).padStart(2, '0');
+ const minutes = String(d.getMinutes()).padStart(2, '0');
+ const seconds = String(d.getSeconds()).padStart(2, '0');
+
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+}
+
+function getCurrentDate() {
+ return formatDateTime(new Date(), false);
+}
+
+const itemTypeOptions = [
+ { label: '鐗╂枡', value: '鐗╂枡' },
+ { label: '鍘熸枡', value: '鍘熸枡' },
+ { label: '鎴愬搧', value: '鎴愬搧' },
+ { label: '鍏朵粬', value: '鍏朵粬' },
+]
+
+const taxRateOptions = [
+ { label: '1', value: 1 },
+ { label: '6', value: 6 },
+ { label: '13', value: 13 },
+]
+
+const data = reactive({
+ form: {
+ id: null,
+ supplierId: null, // 渚涘簲鍟咺D
+ supplierName: '', // 渚涘簲鍟嗗悕绉�
+ recorderId: userStore.userId, // 褰曞叆浜篒D
+ recorderName: userStore.name, // 褰曞叆浜哄鍚�
+ entryDate: getCurrentDate(), // 褰曞叆鏃ユ湡
+ remark: '', // 澶囨敞
+ },
+ rules: {
+ supplierName: [{ required: true, message: "璇疯緭鍏ヤ緵搴斿晢鍚嶇О", trigger: "blur" }]
+ }
+})
+const { form, rules } = toRefs(data)
+
+// 鏂板浜у搧琛�
+const addProductRow = () => {
+ productList.value.push({
+ id: null,
+ productCategory: '',
+ specificationModel: '',
+ unit: '',
+ supplierName: form.value.supplierName || '',
+ itemType: '',
+ inboundNum: 0,
+ inboundDate: '',
+ quantityStock: 0,
+ taxInclusiveUnitPrice: 0,
+ taxInclusiveTotalPrice: 0,
+ taxRate: null,
+ taxExclusiveTotalPrice: 0,
+ });
+};
+
+// 鍒犻櫎浜у搧琛�
+const removeProductRow = (index) => {
+ productList.value.splice(index, 1);
+};
+
+// 璁$畻鎬讳环锛堟牴鎹暟閲忋�佸崟浠峰拰鍚◣鍗曚环锛�
+const calculateTotalPrice = (row) => {
+ // 璁$畻鏅�氭�讳环锛歲uantityStock * taxInclusiveUnitPrice
+ const quantity = Number(row.quantityStock || 0);
+ const taxInclusiveUnitPrice = Number(row.taxInclusiveUnitPrice || 0);
+ row.taxInclusiveTotalPrice = quantity * taxInclusiveUnitPrice;
+ calculateExclusivePrice(row);
+};
+
+// 璁$畻涓嶅惈绋庢�讳环锛堟牴鎹惈绋庢�讳环鍜岀◣鐜囷級
+const calculateExclusivePrice = (row) => {
+ const taxInclusiveTotalPrice = Number(row.taxInclusiveTotalPrice || 0);
+ const taxRate = Number(row.taxRate || 0);
+ row.taxExclusiveTotalPrice = taxInclusiveTotalPrice / (1 + taxRate / 100);
+};
+
+const submitForm = async () => {
+ try {
+ await proxy.$refs.formRef.validate()
+
+ if (!productList.value.length) {
+ proxy.$modal.msgError('璇疯嚦灏戞坊鍔犱竴鏉′骇鍝佹暟鎹�')
+ return
+ }
+
+ // 楠岃瘉鑷畾涔夋坊鍔犵殑鏁版嵁蹇呭~瀛楁
+ for (let i = 0; i < productList.value.length; i++) {
+ const product = productList.value[i];
+ if (!product.productCategory || !product.specificationModel || !product.unit) {
+ proxy.$modal.msgError(`绗�${i + 1}琛屼骇鍝佹暟鎹湭濉啓瀹屾暣锛堜骇鍝佸ぇ绫汇�佽鏍煎瀷鍙枫�佸崟浣嶄负蹇呭~锛塦)
+ return
+ }
+ if (!product.itemType) {
+ proxy.$modal.msgError(`绗�${i + 1}琛岃閫夋嫨鐗╁搧绫诲瀷`)
+ return
+ }
+ if (!product.inboundDate) {
+ proxy.$modal.msgError(`绗�${i + 1}琛岃閫夋嫨鍏ュ簱鏃ユ湡`)
+ return
+ }
+ const stock = Number(product?.inboundNum ?? 0);
+ if (!Number.isFinite(stock) || stock <= 0) {
+ proxy.$modal.msgError(`绗�${i + 1}琛屾湰娆″叆搴撴暟閲忛渶澶т簬0`)
+ return
+ }
+ }
+
+ const payloadList = productList.value.map(product => ({
+ id: product.id ?? null,
+ inboundNum: Number(product.inboundNum),
+ productCategory: product.productCategory,
+ specificationModel: product.specificationModel,
+ unit: product.unit,
+ supplierName: product.supplierName || form.value.supplierName,
+ itemType: product.itemType,
+ inboundDate: formatDateTime(product.inboundDate, false),
+ taxRate: Number(product.taxRate || 0),
+ taxExclusiveTotalPrice: Number(product.taxExclusiveTotalPrice || 0),
+ taxInclusiveUnitPrice: Number(product.taxInclusiveUnitPrice || 0),
+ taxInclusiveTotalPrice: Number(product.taxInclusiveTotalPrice || 0),
+ url: product.url,
+ }));
+ loading.value = true
+ if (operationType.value === 'edit') {
+ const editPayload = payloadList[0]
+ await updateStockInCustom(editPayload)
+ } else {
+ await addStockInCustom(payloadList)
+ }
+
+ proxy.$modal.msgSuccess(operationType.value === 'edit' ? '缂栬緫鑷畾涔夊叆搴撴垚鍔�' : '鏂板鑷畾涔夊叆搴撴垚鍔�')
+ closeDia()
+ emit('success')
+
+ } catch (error) {
+ console.error('鎻愪氦澶辫触:', error)
+ if (!error.errors) {
+ proxy.$modal.msgError('鎿嶄綔澶辫触锛岃閲嶈瘯')
+ }
+ } finally {
+ loading.value = false
+ }
+}
+
+const closeDia = () => {
+ proxy.$refs.formRef.resetFields()
+ dialogFormVisible.value = false
+ productList.value = []
+ emit('close')
+}
+
+// 涓婁紶鍓嶆牎妫�鏍煎紡鍜屽ぇ灏�
+function handleBeforeUpload(file) {
+ const type = ["image/jpeg", "image/jpg", "image/png", "image/svg"];
+ const isJPG = type.includes(file.type);
+ //妫�楠屾枃浠舵牸寮�
+ if (!isJPG) {
+ proxy.$modal.msgError(`鍥剧墖鏍煎紡閿欒!`);
+ return false;
+ }
+ return true;
+}
+const handleUploadSuccess = (res, file,item) => {
+ // 濡傛灉涓婁紶鎴愬姛
+ if (res.code == 200) {
+ item.url = res.data?.tempPath||''
+ } else {
+ proxy.$modal.msgError("鍥剧墖鎻掑叆澶辫触");
+ }
+}
+// 涓婁紶澶辫触澶勭悊
+function handleUploadError() {
+ proxy.$modal.msgError("鍥剧墖鎻掑叆澶辫触");
+}
+
+const openDialog = async (type, row) => {
+ operationType.value = type
+ dialogFormVisible.value = true
+
+ if (type === 'add') {
+ form.value = {
+ id: null,
+ supplierId: null,
+ supplierName: '',
+ recorderId: userStore.userId,
+ recorderName: userStore.name,
+ entryDate: getCurrentDate(),
+ remark: ''
+ }
+ productList.value = []
+ } else {
+ // 缂栬緫妯″紡锛氬皢琛屾暟鎹~鍏呭埌琛ㄦ牸涓互鏀寔淇敼
+ form.value = {
+ id: row?.id ?? null,
+ supplierId: row?.supplierId ?? null,
+ supplierName: row?.supplierName ?? '',
+ recorderId: userStore.userId,
+ recorderName: userStore.name,
+ entryDate: getCurrentDate(),
+ remark: row?.remark ?? ''
+ }
+ productList.value = [{
+ id: row?.id ?? null,
+ productCategory: row?.productCategory ?? '',
+ specificationModel: row?.specificationModel ?? '',
+ unit: row?.unit ?? '',
+ supplierName: row?.supplierName ?? '',
+ itemType: row?.itemType ?? '',
+ inboundNum: Number(row?.inboundNum ?? row?.inboundQuantity ?? 0),
+ inboundDate: row?.inboundDate ?? row?.createTime ?? '',
+ quantityStock: Number(row?.quantityStock ?? 0),
+ taxRate: Number(row?.taxRate ?? 0),
+ taxInclusiveUnitPrice: Number(row?.taxInclusiveUnitPrice ?? 0),
+ taxInclusiveTotalPrice: Number(row?.taxInclusiveTotalPrice ?? 0),
+ taxExclusiveTotalPrice: Number(row?.taxExclusiveTotalPrice ?? 0),
+ }]
+ }
+}
+
+defineExpose({
+ openDialog,
+})
+</script>
+
+<style scoped lang="scss"></style>
+
diff --git a/src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue b/src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue
new file mode 100644
index 0000000..6048e18
--- /dev/null
+++ b/src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue
@@ -0,0 +1,302 @@
+<template>
+ <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '鏂板鑷畾涔夊叆搴�' : '缂栬緫鑷畾涔夊叆搴�'" width="70%"
+ @close="closeDia">
+ <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+ <div style="margin-bottom: 10px;" v-if="operationType === 'add'">
+ <el-button type="primary" @click="addProductRow">鏂板</el-button>
+ </div>
+ <el-table
+ :data="productList"
+ border
+ v-loading="loadingProducts"
+ >
+ <el-table-column
+ align="center"
+ label="搴忓彿"
+ type="index"
+ width="60"
+ />
+ <el-table-column label="浜у搧澶х被" prop="productCategory" width="200">
+ <template #default="scope">
+ <el-input v-model="scope.row.productCategory" placeholder="璇疯緭鍏ヤ骇鍝佸ぇ绫�" />
+ </template>
+ </el-table-column>
+ <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="200">
+ <template #default="scope">
+ <el-input v-model="scope.row.specificationModel" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
+ </template>
+ </el-table-column>
+ <el-table-column label="鍗曚綅" prop="unit" width="100">
+ <template #default="scope">
+ <el-input v-model="scope.row.unit" placeholder="璇疯緭鍏ュ崟浣�" />
+ </template>
+ </el-table-column>
+ <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="150">
+ <template #default="scope">
+ <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.inboundNum" @change="() => calculateTotalPrice(scope.row)" />
+ </template>
+ </el-table-column>
+ <el-table-column label="鍏ュ簱鏃ユ湡" prop="inboundDate" width="180">
+ <template #default="scope">
+ <el-date-picker
+ v-model="scope.row.inboundDate"
+ type="date"
+ placeholder="璇烽�夋嫨鍏ュ簱鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ style="width: 100%"
+ />
+ </template>
+ </el-table-column>
+ <el-table-column label="鍗曚环(鍏�)" prop="unitPrice" width="150">
+ <template #default="scope">
+ <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.unitPrice" @change="() => calculateTotalPrice(scope.row)" />
+ </template>
+ </el-table-column>
+ <el-table-column
+ label="鎬讳环(鍏�)"
+ prop="totalPrice"
+ width="150"
+ >
+ </el-table-column>
+ <el-table-column label="鎿嶄綔" width="80" v-if="operationType === 'add'">
+ <template #default="scope">
+ <el-button type="danger" size="small" @click="removeProductRow(scope.$index)">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button @click="closeDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, getCurrentInstance } from 'vue'
+import useUserStore from '@/store/modules/user'
+import {
+ addStockInCustom, updateProduct
+} from "@/api/inventoryManagement/stockIn.js";
+
+const userStore = useUserStore()
+const { proxy } = getCurrentInstance()
+const emit = defineEmits(['close', 'success'])
+
+const operationType = ref('')// 鎿嶄綔绫诲瀷: 'add' 鎴� 'edit'
+const dialogFormVisible = ref(false)// 寮规鏄剧ず鐘舵��
+const productList = ref([]);// 浜у搧鍒楄〃鏁版嵁
+const loadingProducts = ref(false);// 浜у搧鍔犺浇鐘舵��
+const loading = ref(false);
+
+function formatDateTime(date = new Date(), includeTime = true) {
+ const d = new Date(date);
+ const year = d.getFullYear();
+ const month = String(d.getMonth() + 1).padStart(2, '0');
+ const day = String(d.getDate()).padStart(2, '0');
+
+ if (!includeTime) {
+ return `${year}-${month}-${day}`;
+ }
+
+ const hours = String(d.getHours()).padStart(2, '0');
+ const minutes = String(d.getMinutes()).padStart(2, '0');
+ const seconds = String(d.getSeconds()).padStart(2, '0');
+
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+}
+
+function getCurrentDate() {
+ return formatDateTime(new Date(), false);
+}
+
+const itemTypeOptions = [
+ { label: '鐗╂枡', value: '鐗╂枡' },
+ { label: '鍘熸枡', value: '鍘熸枡' },
+ { label: '鎴愬搧', value: '鎴愬搧' },
+ { label: '鍏朵粬', value: '鍏朵粬' },
+]
+
+const taxRateOptions = [
+ { label: '1', value: 1 },
+ { label: '6', value: 6 },
+ { label: '13', value: 13 },
+]
+
+const data = reactive({
+ form: {
+ id: null,
+ supplierId: null, // 渚涘簲鍟咺D
+ supplierName: '', // 渚涘簲鍟嗗悕绉�
+ recorderId: userStore.userId, // 褰曞叆浜篒D
+ recorderName: userStore.name, // 褰曞叆浜哄鍚�
+ entryDate: getCurrentDate(), // 褰曞叆鏃ユ湡
+ remark: '', // 澶囨敞
+ },
+ rules: {
+ supplierName: [{ required: true, message: "璇疯緭鍏ヤ緵搴斿晢鍚嶇О", trigger: "blur" }]
+ }
+})
+const { form, rules } = toRefs(data)
+
+// 鏂板浜у搧琛�
+const addProductRow = () => {
+ productList.value.push({
+ id: null,
+ productCategory: '',
+ specificationModel: '',
+ unit: '',
+ supplierName: form.value.supplierName || '',
+ itemType: '',
+ inboundNum: 0,
+ inboundDate: '',
+ quantityStock: 0,
+ unitPrice: 0,
+ totalPrice: 0,
+ taxRate: null,
+ taxExclusiveTotalPrice: 0,
+ });
+};
+
+// 鍒犻櫎浜у搧琛�
+const removeProductRow = (index) => {
+ productList.value.splice(index, 1);
+};
+
+// 璁$畻鎬讳环锛堟牴鎹暟閲忋�佸崟浠峰拰鍚◣鍗曚环锛�
+const calculateTotalPrice = (row) => {
+ // 璁$畻鏅�氭�讳环锛歩nboundNum * unitPrice
+ const quantity = Number(row.inboundNum || 0);
+ const unitPrice = Number(row.unitPrice || 0);
+ row.totalPrice = quantity * unitPrice;
+ calculateExclusivePrice(row);
+};
+
+// 璁$畻涓嶅惈绋庢�讳环锛堟牴鎹惈绋庢�讳环鍜岀◣鐜囷級
+const calculateExclusivePrice = (row) => {
+ const totalPrice = Number(row.totalPrice || 0);
+ const taxRate = Number(row.taxRate || 0);
+ row.taxExclusiveTotalPrice = totalPrice / (1 + taxRate / 100);
+};
+
+const submitForm = async () => {
+ try {
+ await proxy.$refs.formRef.validate()
+
+ if (!productList.value.length) {
+ proxy.$modal.msgError('璇疯嚦灏戞坊鍔犱竴鏉′骇鍝佹暟鎹�')
+ return
+ }
+
+ // 楠岃瘉鑷畾涔夋坊鍔犵殑鏁版嵁蹇呭~瀛楁
+ for (let i = 0; i < productList.value.length; i++) {
+ const product = productList.value[i];
+ if (!product.productCategory || !product.specificationModel || !product.unit) {
+ proxy.$modal.msgError(`绗�${i + 1}琛屼骇鍝佹暟鎹湭濉啓瀹屾暣锛堜骇鍝佸ぇ绫汇�佽鏍煎瀷鍙枫�佸崟浣嶄负蹇呭~锛塦)
+ return
+ }
+ if (!product.inboundDate) {
+ proxy.$modal.msgError(`绗�${i + 1}琛岃閫夋嫨鍏ュ簱鏃ユ湡`)
+ return
+ }
+ const stock = Number(product?.inboundNum ?? 0);
+ if (!Number.isFinite(stock) || stock <= 0) {
+ proxy.$modal.msgError(`绗�${i + 1}琛屾湰娆″叆搴撴暟閲忛渶澶т簬0`)
+ return
+ }
+ }
+
+ const payloadList = productList.value.map(product => ({
+ id: product.id ?? null,
+ inboundNum: Number(product.inboundNum),
+ productCategory: product.productCategory,
+ specificationModel: product.specificationModel,
+ unit: product.unit,
+ supplierName: product.supplierName || form.value.supplierName,
+ itemType: product.itemType,
+ inboundDate: formatDateTime(product.inboundDate, false),
+ taxRate: Number(product.taxRate || 0),
+ taxExclusiveTotalPrice: Number(product.taxExclusiveTotalPrice || 0),
+ unitPrice: Number(product.unitPrice || 0),
+ }));
+ loading.value = true
+ if (operationType.value === 'edit') {
+ const editPayload = payloadList[0]
+ await updateProduct(editPayload)
+ } else {
+ await addStockInCustom(payloadList)
+ }
+
+ proxy.$modal.msgSuccess(operationType.value === 'edit' ? '缂栬緫鑷畾涔夊叆搴撴垚鍔�' : '鏂板鑷畾涔夊叆搴撴垚鍔�')
+ closeDia()
+ emit('success')
+
+ } catch (error) {
+ console.error('鎻愪氦澶辫触:', error)
+ if (!error.errors) {
+ proxy.$modal.msgError('鎿嶄綔澶辫触锛岃閲嶈瘯')
+ }
+ } finally {
+ loading.value = false
+ }
+}
+
+const closeDia = () => {
+ proxy.$refs.formRef.resetFields()
+ dialogFormVisible.value = false
+ productList.value = []
+ emit('close')
+}
+
+const openDialog = async (type, row) => {
+ operationType.value = type
+ dialogFormVisible.value = true
+
+ if (type === 'add') {
+ form.value = {
+ id: null,
+ supplierId: null,
+ supplierName: '',
+ recorderId: userStore.userId,
+ recorderName: userStore.name,
+ entryDate: getCurrentDate(),
+ remark: ''
+ }
+ productList.value = []
+ } else {
+ // 缂栬緫妯″紡锛氬皢琛屾暟鎹~鍏呭埌琛ㄦ牸涓互鏀寔淇敼
+ form.value = {
+ id: row?.id ?? null,
+ supplierId: row?.supplierId ?? null,
+ supplierName: row?.supplierName ?? '',
+ recorderId: userStore.userId,
+ recorderName: userStore.name,
+ entryDate: getCurrentDate(),
+ remark: row?.remark ?? ''
+ }
+ productList.value = [{
+ id: row?.id ?? null,
+ productCategory: row?.productCategory ?? '',
+ specificationModel: row?.specificationModel ?? '',
+ unit: row?.unit ?? '',
+ supplierName: row?.supplierName ?? '',
+ itemType: row?.itemType ?? '',
+ inboundNum: Number(row?.inboundNum ?? row?.inboundQuantity ?? 0),
+ inboundDate: row?.inboundDate ?? row?.createTime ?? '',
+ taxRate: Number(row?.taxRate ?? 0),
+ unitPrice: Number(row?.unitPrice ?? 0),
+ taxExclusiveTotalPrice: Number(row?.taxExclusiveTotalPrice ?? 0),
+ }]
+ }
+}
+
+defineExpose({
+ openDialog,
+})
+</script>
+
+<style scoped lang="scss"></style>
+
diff --git a/src/views/inventoryManagement/receiptManagement/index.vue b/src/views/inventoryManagement/receiptManagement/index.vue
index 626a9ce..f07100f 100644
--- a/src/views/inventoryManagement/receiptManagement/index.vue
+++ b/src/views/inventoryManagement/receiptManagement/index.vue
@@ -1,140 +1,205 @@
<template>
<div class="app-container">
- <div class="search_form">
- <div>
- <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>
- <el-button type="primary" @click="openForm('add')">鏂板鍏ュ簱</el-button>
- <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%"
- :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="inboundBatches" width="160" 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="70" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="90" 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="80" show-overflow-tooltip />
- <el-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱浜�" prop="createBy" width="80" show-overflow-tooltip />
- <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);" :disabled="scope.row.createUser !== userStore.id">缂栬緫</el-button>
- <el-button
- link
- type="success"
- size="small"
- @click="showQRCode(scope.row)"
- >鐢熸垚鏉″舰鐮�</el-button
- >
- </template>
- </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-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '鏂板鍏ュ簱' : '缂栬緫鍏ュ簱'" width="70%"
- @close="closeDia">
- <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
- <el-form-item label="閲囪喘璁㈠崟鍙�" prop="purchaseContractNumber">
- <el-select
- v-model="form.purchaseContractNumber"
- placeholder="璇烽�夋嫨閲囪喘璁㈠崟鍙�"
- clearable
- filterable
- remote
- :remote-method="loadPurchaseOptions"
- :loading="loadingPurchaseOptions"
- @change="handlePurchaseChange"
- :disabled="operationType === 'edit'"
- style="width: 100%"
- >
- <el-option
- v-for="item in purchaseOptions"
- :key="item.purchaseContractNumber"
- :label="formatPurchaseOption(item)"
- :value="item.purchaseContractNumber"
- />
- </el-select>
- </el-form-item>
- <el-table
- :data="productList"
- border
- v-loading="loadingProducts"
- @selection-change="handleSelectionChange"
- >
- <el-table-column align="center" type="selection" width="55" />
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column label="浜у搧澶х被" prop="productCategory" />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
- <el-table-column label="鍗曚綅" prop="unit" width="70" />
- <el-table-column label="渚涘簲鍟�" prop="supplierName" width="100" />
- <el-table-column label="閲囪喘鏁伴噺" prop="quantity" width="100" />
- <el-table-column label="寰呭叆搴撴暟閲�" prop="quantity0" width="100" />
- <el-table-column label="鏈鍏ュ簱鏁伴噺" prop="quantityStock" width="150">
- <template #default="scope">
- <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.quantityStock" />
- </template>
- </el-table-column>
- <el-table-column label="绋庣巼(%)" prop="taxRate" width="120" />
- <el-table-column
- label="鍚◣鍗曚环(鍏�)"
- prop="taxInclusiveUnitPrice"
- :formatter="formattedNumber"
- width="150"
- />
- <el-table-column
- label="鍚◣鎬讳环(鍏�)"
- prop="taxInclusiveTotalPrice"
- :formatter="formattedNumber"
- width="150"
- />
- <el-table-column
- label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- :formatter="formattedNumber"
- width="150"
- />
- </el-table>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitForm">纭</el-button>
- <el-button @click="closeDia">鍙栨秷</el-button>
+ <el-tabs v-model="activeTab" @tab-change="handleTabChange">
+ <el-tab-pane label="鎴愬搧鍏ュ簱" name="production">
+ <div class="search_form">
+ <div>
+<!-- <span class="search_title">瀹㈡埛鍚嶇О锛�</span>-->
+<!-- <el-input v-model="searchForm.customerName" 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"
+ />
+ <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>
- </template>
- </el-dialog>
- <!-- 浜岀淮鐮佹樉绀哄璇濇 -->
+ <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%"
+ :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" show-overflow-tooltip />
+ <!-- <el-table-column label="鍏ュ簱鎵规" prop="inboundBatches" show-overflow-tooltip /> -->
+<!-- <el-table-column label="瀹㈡埛鍚嶇О" prop="customerName" width="240" 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="70" show-overflow-tooltip />
+ <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="100" show-overflow-tooltip />
+<!-- <el-table-column label="鍓╀綑搴撳瓨" prop="inboundNum0" 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 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="80" show-overflow-tooltip />-->
+<!-- <el-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />-->
+ <!-- <el-table-column label="鍏ュ簱浜�" prop="createBy" width="80" show-overflow-tooltip /> -->
+ <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, 'production');">缂栬緫</el-button>
+ <el-button link type="success" size="small" @click="showQRCode(scope.row)">鐢熸垚鏉″舰鐮�</el-button>
+ <el-button link type="success" size="small" @click="showERCode(scope.row)">鐢熸垚浜岀淮鐮�</el-button>
+ </template>
+ </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-tab-pane label="鍘熸枡鍏ュ簱" name="purchase">
+ <div class="search_form">
+ <div>
+<!--<!– <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"
+ />
+ <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 type="primary" @click="openForm('add', 'purchase')">鏂板鍏ュ簱</el-button>
+ <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%"
+ :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="inboundBatches" width="160" show-overflow-tooltip /> -->
+<el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" width="240" 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="70" show-overflow-tooltip />
+ <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="100" 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-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="80" show-overflow-tooltip />–>-->
+<!--<!– <el-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />–>-->
+ <el-table-column label="鍏ュ簱浜�" prop="createBy" width="80" show-overflow-tooltip />
+ <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, 'purchase');">缂栬緫</el-button>
+ <el-button link type="success" size="small" @click="showQRCode(scope.row)">鐢熸垚鏉″舰鐮�</el-button>
+ <el-button link type="success" size="small" @click="showERCode(scope.row)">鐢熸垚浜岀淮鐮�</el-button>
+ </template>
+ </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-tab-pane label="鏉愭枡鍏ュ簱" name="manual">
+ <div class="search_form">
+ <div>
+<!-- <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"
+ />
+ <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 type="primary" @click="openForm('add', 'manual')">鏂板鍏ュ簱</el-button>
+ <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%"
+ :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="inboundDate" width="100" show-overflow-tooltip />
+ <!-- <el-table-column label="鍏ュ簱鎵规" prop="inboundBatches" show-overflow-tooltip /> -->
+<!-- <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" width="240" 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="70" show-overflow-tooltip />
+ <el-table-column label="鐗╁搧绫诲瀷" prop="itemType" show-overflow-tooltip />
+ <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="100" 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-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="80" show-overflow-tooltip />-->
+<!-- <el-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />-->
+ <el-table-column label="鍏ュ簱浜�" prop="createBy" width="80" show-overflow-tooltip />
+ <el-table-column fixed="right" label="鎿嶄綔" width="100" align="center">
+ <template #default="scope">
+ <el-button link type="primary" size="small" @click="openForm('edit', scope.row, 'manual');">缂栬緫</el-button>
+ <el-button link type="success" size="small" @click="showQRCode(scope.row)">鐢熸垚鏉″舰鐮�</el-button>
+ <el-button link type="success" size="small" @click="showERCode(scope.row)">鐢熸垚浜岀淮鐮�</el-button>
+ </template>
+ </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>
+
+ <form-dia ref="formDia" @close="handleQuery" @success="handleQuery"></form-dia>
+ <form-dia-manual ref="formDiaManual" @close="handleQuery" @success="handleQuery"></form-dia-manual>
+ <form-dia-product ref="formDiaProduct" @close="handleQuery" @success="handleQuery"></form-dia-product>
<el-dialog
v-model="qrCodeDialogVisible"
title="鍟嗗搧鏉″舰鐮�"
@@ -145,7 +210,21 @@
<img id="barcode" style="width:200px;height: 50px;"/>
<!-- <img :src="qrCodeUrl" alt="浜岀淮鐮�" style="width:200px;height:200px;" /> -->
<div style="margin: 20px;">
- <el-button type="primary" @click="downloadQRCode">涓嬭浇浜屾潯褰㈢爜</el-button>
+ <el-button type="primary" @click="downloadQRCode">涓嬭浇鏉″舰鐮�</el-button>
+ </div>
+ </div>
+ </el-dialog>
+ <!-- 浜岀淮鐮佹樉绀哄璇濇 -->
+ <el-dialog
+ v-model="erCodeDialogVisible"
+ title="鍟嗗搧浜岀淮鐮�"
+ width="400px"
+ center
+ >
+ <div style="text-align: center;">
+ <img :src="erCodeUrl" alt="浜岀淮鐮�" style="width:200px;height:200px;" />
+ <div style="margin: 20px;">
+ <el-button type="primary" @click="downloadERCode">涓嬭浇浜岀淮鐮佸浘鐗�</el-button>
</div>
</div>
</el-dialog>
@@ -154,33 +233,36 @@
<script setup>
import pagination from '@/components/PIMTable/Pagination.vue'
-import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue'
+import { ref, reactive, toRefs, onMounted, getCurrentInstance, nextTick } from 'vue'
import { ElMessageBox } from "element-plus";
import useUserStore from '@/store/modules/user'
+import dayjs from 'dayjs'
+import {
+ getStockInPage,
+ getStockInPageByProduction,
+ delStockIn,
+ delStockInCustom, getInPageByCustom,
+} from "@/api/inventoryManagement/stockIn.js";
+import FormDia from './components/formDia.vue'
+import FormDiaManual from './components/formDiaManual.vue'
+import FormDiaProduct from './components/formDiaProduct.vue'
import QRCode from "qrcode";
import JsBarcode from "jsbarcode";
-import {
- getStockInPage,
- updateStockIn,
- addSutockIn,
- delStockIn,
- selectProductRecordListByPuechaserId
-} from "@/api/inventoryManagement/stockIn.js";
-import { purchaseListPage } from "@/api/procurementManagement/procurementLedger.js";
-const userStore = useUserStore()
+// 鑾峰彇褰撳墠鏃ユ湡
+function getCurrentDate() {
+ return dayjs().format('YYYY-MM-DD')
+}
+
const { proxy } = getCurrentInstance()
const tableData = ref([])
const selectedRows = ref([])
-const userList = ref([])
-
-const purchaseOptions = ref([])
-const loadingPurchaseOptions = ref(false)
-
-
-const loading = ref(false);
const tableLoading = ref(false)
+const formDia = ref()
+const formDiaManual = ref()
+const formDiaProduct = ref()
+const activeTab = ref('production') // 褰撳墠婵�娲荤殑 tab
const page = reactive({
current: 1,
@@ -188,107 +270,15 @@
})
const total = ref(0)
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref('')// 鎿嶄綔绫诲瀷: 'add' 鎴� 'edit'
-const dialogFormVisible = ref(false)// 寮规鏄剧ず鐘舵��
-const productList = ref([]);// 浜у搧鍒楄〃鏁版嵁
-const loadingProducts = ref(false);// 浜у搧鍔犺浇鐘舵��
-const productSelectedRows = ref([]) // 浜у搧琛ㄦ牸閫変腑琛�
const data = reactive({
searchForm: {
supplierName: '',
- timeStr: '',
+ customerName: '',
+ productCategory:'',
+ timeStr: getCurrentDate(),
},
- form: {
- id: null,
- purchaseContractNumber: '', // 閲囪喘璁㈠崟鍙�
- supplierId: null, // 渚涘簲鍟咺D
- supplierName: '', // 渚涘簲鍟嗗悕绉�
- inboundTime: '', // 鍏ュ簱鏃堕棿
- inboundBatch: '', // 鍏ュ簱鎵规
- recorderId: userStore.userId, // 褰曞叆浜篒D
- recorderName: userStore.name, // 褰曞叆浜哄鍚�
- entryDate: getCurrentDate(), // 褰曞叆鏃ユ湡
- remark: '', // 澶囨敞
- },
- rules: {
- purchaseContractNumber: [{ required: true, message: "璇疯緭鍏ラ噰璐悎鍚屽彿", trigger: "blur" }],
- supplierId: [{ required: true, message: "璇烽�夋嫨渚涘簲鍟�", trigger: "change" }],
- inboundTime: [{ required: true, message: "璇烽�夋嫨鍏ュ簱鏃堕棿", trigger: "change" }],
- inboundBatch: [{ required: true, message: "璇疯緭鍏ュ叆搴撴壒娆�", trigger: "blur" }]
- }
})
-const { searchForm, form, rules } = toRefs(data)
-
-const formatPurchaseOption = (item = {}) => {
- const contract = item.purchaseContractNumber || '--';
- const supplier = item.supplierName ? ` 路 ${item.supplierName}` : '';
- return `${contract}${supplier}`;
-};
-
-const loadPurchaseOptions = async (keyword = '') => {
- try {
- loadingPurchaseOptions.value = true;
- const res = await purchaseListPage({
- current: -1,
- size: -1,
- purchaseContractNumber: keyword,
- });
- const records = res.data?.records || [];
- purchaseOptions.value = records;
- if (
- form.value.purchaseContractNumber &&
- !purchaseOptions.value.find(
- (item) => item.purchaseContractNumber === form.value.purchaseContractNumber
- )
- ) {
- purchaseOptions.value.push({
- purchaseContractNumber: form.value.purchaseContractNumber,
- supplierName: form.value.supplierName,
- supplierId: form.value.supplierId,
- });
- }
- } finally {
- loadingPurchaseOptions.value = false;
- }
-};
-
-const handlePurchaseChange = (value) => {
- form.value.purchaseContractNumber = value || '';
- const matched = purchaseOptions.value.find(
- (item) => item.purchaseContractNumber === value
- );
- if (matched) {
- form.value.supplierName = matched.supplierName || form.value.supplierName;
- form.value.supplierId = matched.supplierId || form.value.supplierId;
- }
- if (!value) {
- productList.value = [];
- return;
- }
- fetchProductsByContract();
-};
-const exceedsAddLimit = (product) => {
- const stock = Number(product?.quantityStock ?? 0);
- const waiting = Number(product?.quantity0 ?? 0);
- if (!Number.isFinite(stock) || !Number.isFinite(waiting)) {
- return false;
- }
- return stock > waiting;
-};
-
-const exceedsEditLimit = (product) => {
- const stock = Number(product?.quantityStock ?? 0);
- const waiting = Number(product?.quantity0 ?? 0);
- const original = Number(product?.originalQuantityStock ?? 0);
- if (!Number.isFinite(stock) || !Number.isFinite(waiting) || !Number.isFinite(original)) {
- return false;
- }
- return stock > waiting + original;
-};
-const formattedNumber = (row, column, cellValue) => {
- return parseFloat(cellValue).toFixed(2);
-};
+const { searchForm } = toRefs(data)
// 鏌ヨ鍒楄〃
/** 鎼滅储鎸夐挳鎿嶄綔 */
const handleQuery = () => {
@@ -302,186 +292,156 @@
}
const getList = () => {
tableLoading.value = true
- getStockInPage({ ...searchForm.value, ...page }).then(res => {
+ const params = { ...page }
+
+ // 鏍规嵁涓嶅悓鐨� tab 绫诲瀷浼犻�掍笉鍚岀殑鏌ヨ鍙傛暟
+ if (activeTab.value === 'production') {
+ params.customerName = searchForm.value.customerName
+ params.timeStr = searchForm.value.timeStr
+ } else {
+ params.supplierName = searchForm.value.supplierName
+ params.timeStr = searchForm.value.timeStr
+ }
+ params.productCategory = searchForm.value.productCategory
+
+ // 鏍规嵁涓嶅悓鐨� tab 绫诲瀷璋冪敤涓嶅悓鐨勬帴鍙�
+ const apiCall = activeTab.value === 'production'
+ ? getStockInPageByProduction(params)
+ : activeTab.value === 'manual'
+ ? getInPageByCustom(params)
+ : getStockInPage(params)
+
+ apiCall.then(res => {
tableLoading.value = false
tableData.value = res.data.records
+
+ // 鍓嶇璁$畻鎬讳环锛氭�讳环 = unitPrice * inboundNum
+ tableData.value = tableData.value.map(item => {
+ // 浣跨敤鍏ュ簱鏁伴噺璁$畻鎬讳环
+ const inboundNum = Number(item.inboundNum) || 0
+ const unitPrice = Number(item.unitPrice) || 0
+ const taxInclusiveUnitPrice = Number(item.taxInclusiveUnitPrice) || 0
+
+ // 鏍规嵁鏍囩椤电被鍨嬭绠椾笉鍚岀殑鎬讳环
+ if (activeTab.value === 'production') {
+ // 鎴愬搧搴撳瓨锛氭�讳环 = unitPrice * 鍏ュ簱鏁伴噺
+ item.totalPrice = (unitPrice * inboundNum).toFixed(2)
+ } else {
+ // 鍘熸枡鍜屾潗鏂欏簱瀛橈細鍚◣鎬讳环 = taxInclusiveUnitPrice * 鍏ュ簱鏁伴噺
+ item.taxInclusiveTotalPrice = (taxInclusiveUnitPrice * inboundNum).toFixed(2)
+ }
+
+ return item
+ })
+
total.value = res.data.total
}).catch(() => {
tableLoading.value = false
})
}
-
-// 璋冪敤selectProductRecordListByPuechaserId杩欎釜鏂规硶鏍规嵁鍚堝悓鏌ヨ鍒癷d锛屽啀璋冪敤getProductRecordByhetong杩欎釜鏂规硶鏍规嵁id鏌ヨ鍒颁骇鍝佽鍗曡褰�
-// 鏂板鏍规嵁鍚堝悓鍙锋煡璇骇鍝佽褰曠殑鏂规硶
-const fetchProductsByContract = async () =>
-{
- if (!form.value.purchaseContractNumber) {
- proxy.$modal.msgWarning('璇烽�夋嫨鍚堝悓鍙�')
- return
- }
- try {
- loadingProducts.value = true
- // 鏍规嵁鍚堝悓鏌ヨ浜у搧璁板綍
- const productRes = await selectProductRecordListByPuechaserId({
- purchaseContractNumber: form.value.purchaseContractNumber
- });
- if (!productRes.data || productRes.data.length === 0) {
- proxy.$modal.msgWarning('璇ュ悎鍚屼笅娌℃湁浜у搧璁板綍')
- productList.value = [];
- return
- }
- // 澶勭悊浜у搧鏁版嵁锛屾坊鍔犳湰娆″叆搴撴暟閲忓瓧娈�
- productList.value = productRes.data.map(item => ({
- ...item,
- quantityStock: 0,
- originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? 0),
- }))
- } catch (error) {
- console.error('鏌ヨ浜у搧璁板綍澶辫触:', error)
- proxy.$modal.msgError('鏌ヨ浜у搧璁板綍澶辫触')
- productList.value = [];
- } finally {
- loadingProducts.value = false
- }
+// 鍒囨崲 tab
+const handleTabChange = (tabName) => {
+ page.current = 1
+ // 鍒囨崲 tab 鏃舵竻绌烘悳绱㈡潯浠�
+ searchForm.value.supplierName = ''
+ searchForm.value.customerName = ''
+ searchForm.value.timeStr = ''
+ searchForm.value.productCategory = ''
+ getList()
}
-
// 鎵撳紑寮规
- const openForm = async (type, row) => {
- operationType.value = type
- dialogFormVisible.value = true
- selectedRows.value = []
- await loadPurchaseOptions();
+const openForm = async (type, row, tabType) => {
+ const currentTab = tabType || activeTab.value
+ await nextTick(() => {
+ if (currentTab === 'manual') {
+ formDiaManual.value?.openDialog(type, row)
+ } else if (currentTab === 'production') {
+ formDiaProduct.value?.openDialog(type, row)
+ }else {
+ formDia.value?.openDialog(type, row)
+ }
+ })
+}
- if (type === 'add') {
- // 鏂板鏃跺垵濮嬪寲琛ㄥ崟
- form.value = {
- id: null,
- purchaseContractNumber: '',
- supplierId: null,
- supplierName: '',
- inboundTime: '',
- inboundBatch: '',
- recorderId: userStore.userId,
- recorderName: userStore.name,
- entryDate: getCurrentDate(),
- remark: ''
- }
- productList.value = [] // 娓呯┖浜у搧鍒楄〃
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+ selectedRows.value = selection.filter(item => item.id)
+}
+
+const expandedRowKeys = ref([])
+
+// 涓昏〃鍚堣鏂规硶
+const summarizeMainTable = (param) => {
+ return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice'])
+}
+
+// 瀵煎嚭
+const handleOut = () => {
+ ElMessageBox.confirm('鏄惁纭瀵煎嚭锛�', '瀵煎嚭', {
+ confirmButtonText: '纭',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning',
+ }).then(() => {
+ // 鏍规嵁涓嶅悓鐨� tab 绫诲瀷璋冪敤涓嶅悓鐨勫鍑烘帴鍙�
+ let exportUrl = "/stockin/export"
+ if (activeTab.value === 'production') {
+ exportUrl = "/stockin/exportOne"
+ } else if (activeTab.value === 'manual') {
+ exportUrl = "/stockin/exportTwo"
+ }
+ proxy.download(exportUrl, {}, '鍏ュ簱鍙拌处.xlsx')
+ }).catch(() => {
+ proxy.$modal.msg("宸插彇娑�")
+ })
+}
+
+// 鍒犻櫎
+const handleDelete = () => {
+ if (selectedRows.value.length === 0) {
+ proxy.$modal.msgWarning('璇烽�夋嫨鏁版嵁')
+ return
+ }
+ const ids = selectedRows.value.map(item => item.id)
+
+ ElMessageBox.confirm('閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�', '鍒犻櫎', {
+ confirmButtonText: '纭',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning',
+ }).then(() => {
+ // 鏍规嵁褰撳墠 tab 绫诲瀷閫夋嫨涓嶅悓鐨勫垹闄ゆ帴鍙e拰type鍙傛暟
+ let deleteApi, deleteParams
+
+ if (activeTab.value === 'production') {
+ // 鎴愬搧鍒犻櫎锛宼ype浼�2
+ deleteApi = delStockIn
+ deleteParams = { ids, type: 2 }
+ } else if (activeTab.value === 'purchase') {
+ // 鍘熸枡鍒犻櫎锛宼ype浼�1
+ deleteApi = delStockIn
+ deleteParams = { ids, type: 1 }
} else {
- form.value = JSON.parse(JSON.stringify(row))
- try {
- loadingProducts.value = true
- // 鏍规嵁鍚堝悓鍙峰姞杞藉搴旂殑浜у搧鍒楄〃锛堝亣璁� getProductByContract 鏄彲鐢ㄦ帴鍙o級
- const res = await selectProductRecordListByPuechaserId({
- purchaseContractNumber: form.value.purchaseContractNumber,
- id: row.id
- });
- productList.value = res.data.map(item => ({
- ...item,
- quantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0),
- originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0),
- }))
- selectedRows.value = productList.value
- } catch (error) {
- console.error('鍔犺浇浜у搧澶辫触:', error)
- proxy.$modal.msgError('鍔犺浇浜у搧澶辫触')
- productList.value = []
- } finally {
- loadingProducts.value = false
- }
+ // 鏉愭枡鍏ュ簱
+ deleteApi = delStockInCustom
+ deleteParams = { ids }
}
- }
+
+ deleteApi(deleteParams).then(() => {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛")
+ getList()
+ }).catch(() => {
+ proxy.$modal.msgError("鍒犻櫎澶辫触")
+ })
+ }).catch(() => {
+ proxy.$modal.msg("宸插彇娑�")
+ })
+}
- const updatePro = async () => {
- // 鍑嗗鎻愪氦鏁版嵁
- // 鍑嗗鎻愪氦鏁版嵁 - 淇敼涓哄悗绔渶瑕佺殑鏍煎紡
- if (selectedRows.value.length === 0) {
- proxy.$modal.msgWarning('璇峰厛閫夋嫨浜у搧');
- return;
- }
- const target = selectedRows.value[0];
- const stock = Number(target?.quantityStock ?? 0);
- if (!Number.isFinite(stock) || stock <= 0) {
- proxy.$modal.msgWarning('璇峰~鍐欐湁鏁堢殑鍏ュ簱鏁伴噺');
- return;
- }
- if (exceedsEditLimit(target)) {
- proxy.$modal.msgError('鏈鍏ュ簱鏁伴噺涓嶈兘瓒呰繃鍘熷叆搴撴暟閲忎笌寰呭叆搴撴暟閲忎箣鍜�');
- return;
- }
- const stockInData = {
- id: selectedRows.value[0].recordId,
- quantityStock: Number(selectedRows.value[0].quantityStock),// 浣跨敤鏂版牸寮忓寲鍑芥暟
- };
- await updateStockIn(stockInData)
- proxy.$modal.msgSuccess('淇敼鍏ュ簱鎴愬姛')
- closeDia()
- getList() // 鍒锋柊鍒楄〃
- }
-
-// 鎻愪氦琛ㄥ崟
- const submitForm = async () => {
- // 楠岃瘉鑷冲皯閫夋嫨浜嗕竴涓骇鍝�
- if (selectedRows.value.length === 0) {
- proxy.$modal.msgWarning('璇峰厛閫夋嫨閲囪喘鍚堝悓骞堕�夋嫨浜у搧')
- return
- }
- if(operationType.value !== 'add'){
- await updatePro()
- return
- }
- try {
- await proxy.$refs.formRef.validate()
- // 楠岃瘉鍏ュ簱鏁伴噺
- const invalidProducts = selectedRows.value.filter((product) => {
- const stock = Number(product?.quantityStock ?? 0);
- if (!Number.isFinite(stock) || stock <= 0) {
- return true;
- }
- return exceedsAddLimit(product);
- })
-
- if (invalidProducts.length > 0) {
- proxy.$modal.msgError('鏈鍏ュ簱鏁伴噺闇�澶т簬0锛屼笖涓嶈兘瓒呰繃寰呭叆搴撴暟閲�')
- return
- }
-
- // 鍑嗗鎻愪氦鏁版嵁 - 淇敼涓哄悗绔渶瑕佺殑鏍煎紡
- const stockInData = {
- // 鍏ュ簱鍗曞熀鏈俊鎭�
- ...form.value,
- inboundTime: formatDateTime(form.value.inboundTime),
- nickName: userStore.nickName,
- details: selectedRows.value.map(product => ({
- id: product.id,
- // id: product.salesLedgerProductId,
- inboundQuantity: Number(product.quantityStock)
- })),
- };
- // 璋冪敤API
- loading.value = true
- await addSutockIn(stockInData)
-
- proxy.$modal.msgSuccess('鏂板鍏ュ簱鎴愬姛')
- closeDia()
- getList() // 鍒锋柊鍒楄〃
-
- } catch (error) {
- console.error('鎻愪氦澶辫触:', error)
- if (!error.errors) {
- proxy.$modal.msgError('鎿嶄綔澶辫触锛岃閲嶈瘯')
- }
- } finally {
- loading.value = false
- }
- }
// 浜岀淮鐮佺浉鍏冲彉閲�
const qrCodeDialogVisible = ref(false);
const qrCodeUrl = ref("");
-// 鏄剧ず浜岀淮鐮�
const showQRCode = async (row) => {
try {
// 鏋勫缓浜岀淮鐮佸唴瀹癸紝鍙寘鍚噰璐悎鍚屽彿锛堢函鏂囨湰锛�
@@ -503,6 +463,31 @@
proxy.$modal.msgError("鐢熸垚鏉″舰鐮佸け璐ワ細" + error.message);
}
};
+
+const erCodeDialogVisible = ref(false);
+const erCodeUrl = ref("");
+const showERCode = async (row) => {
+ const qrContent = row.id || '';
+ // 妫�鏌ュ唴瀹规槸鍚︿负绌�
+ if (!qrContent) {
+ proxy.$modal.msgWarning("璇ヨ鍟嗗搧id锛屾棤娉曠敓鎴愪簩缁寸爜");
+ return;
+ }
+ try {
+ erCodeUrl.value = await QRCode.toDataURL(qrContent+'', {
+ width: 200,
+ margin: 2,
+ color: {
+ dark: '#000000',
+ light: '#FFFFFF'
+ }
+ });
+ erCodeDialogVisible.value = true;
+ } catch (error) {
+ console.error('鐢熸垚浜岀淮鐮佸け璐�:', error);
+ proxy.$modal.msgError("鐢熸垚浜岀淮鐮佸け璐ワ細" + error.message);
+ }
+};
const downloadQRCode = () => {
const imgSrc = document.getElementById('barcode').src
const a = document.createElement('a');
@@ -518,103 +503,28 @@
proxy.$modal.msgSuccess("涓嬭浇鎴愬姛");
};
-// 鍏抽棴寮规
- const closeDia = () => {
- proxy.$refs.formRef.resetFields()
- dialogFormVisible.value = false
-
+// 涓嬭浇浜岀淮鐮�
+const downloadERCode = () => {
+ if (!erCodeUrl.value) {
+ proxy.$modal.msgWarning("浜岀淮鐮佹湭鐢熸垚");
+ return;
}
-// 琛ㄦ牸閫夋嫨鏁版嵁
- const handleSelectionChange = (selection) => {
- // 杩囨护鎺夊瓙鏁版嵁
- selectedRows.value = selection.filter(item => item.id);
- }
+
+ const a = document.createElement('a');
+ a.href = erCodeUrl.value;
+ a.download = `鍟嗗搧浜岀淮鐮乢${new Date().getTime()}.png`;
+ document.body.appendChild(a);
+ a.click();
+ document.body.removeChild(a);
+ proxy.$modal.msgSuccess("涓嬭浇鎴愬姛");
+};
- const expandedRowKeys = ref([])
-
-// 涓昏〃鍚堣鏂规硶
- const summarizeMainTable = (param) => {
- return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']);
- };
-
-// 瀵煎嚭
- const handleOut = () => {
- ElMessageBox.confirm(
- '鏄惁纭瀵煎嚭锛�',
- '瀵煎嚭', {
- confirmButtonText: '纭',
- cancelButtonText: '鍙栨秷',
- type: 'warning',
- }
- ).then(() => {
- proxy.download("/stockin/export", {}, '鍏ュ簱鍙拌处.xlsx')
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�")
- })
- }
-// 鍒犻櫎
- const handleDelete = () => {
- let ids = []
- if (selectedRows.value.length > 0) {
- // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
- const unauthorizedData = selectedRows.value.filter(item => item.createUser !== userStore.id);
- if (unauthorizedData.length > 0) {
- proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
- return;
- }
- ids = selectedRows.value.map(item => item.id);
- } else {
- proxy.$modal.msgWarning('璇烽�夋嫨鏁版嵁')
- return
- }
- ElMessageBox.confirm(
- '閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�',
- '瀵煎嚭', {
- confirmButtonText: '纭',
- cancelButtonText: '鍙栨秷',
- type: 'warning',
- }
- ).then(() => {
- delStockIn({ids:ids}).then(res => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛")
- getList()
- })
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�")
- })
- }
-
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-// 淇敼涓烘洿閫氱敤鐨勬棩鏈熸椂闂存牸寮忓寲鍑芥暟
-function formatDateTime(date = new Date(), includeTime = true) {
- const d = new Date(date);
- const year = d.getFullYear();
- const month = String(d.getMonth() + 1).padStart(2, '0');
- const day = String(d.getDate()).padStart(2, '0');
-
- if (!includeTime) {
- return `${year}-${month}-${day}`; // 淇濇寔鍘熸湁 getCurrentDate 鍔熻兘
- }
-
- // 鏂板鏃堕棿閮ㄥ垎鏍煎紡鍖�
- const hours = String(d.getHours()).padStart(2, '0');
- const minutes = String(d.getMinutes()).padStart(2, '0');
- const seconds = String(d.getSeconds()).padStart(2, '0');
-
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
-}
-
-// 淇濇寔鍘熸湁 getCurrentDate 鐨勫吋瀹规��
-function getCurrentDate() {
- return formatDateTime(new Date(), false);
-}
-
-
-
-
- onMounted(() => {
- getList()
- })
+onMounted(() => {
+ getList()
+})
</script>
<style scoped lang="scss"></style>
+
+
+
diff --git a/src/views/inventoryManagement/stockManagement/components/FormDiaManual.vue b/src/views/inventoryManagement/stockManagement/components/FormDiaManual.vue
new file mode 100644
index 0000000..e65a487
--- /dev/null
+++ b/src/views/inventoryManagement/stockManagement/components/FormDiaManual.vue
@@ -0,0 +1,154 @@
+<template>
+ <el-dialog :model-value="dialogFormVisible" :title="operationType === 'add' ? '鏂板鏉愭枡搴撳瓨' : '缂栬緫鏉愭枡搴撳瓨'" width="70%"
+ @update:model-value="$emit('update:dialogFormVisible', $event)" @close="closeDia">
+ <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="浜у搧澶х被锛�" prop="productCategory">
+ <el-input disabled v-model="form.productCategory" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="specificationModel">
+ <el-input disabled v-model="form.specificationModel" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="鍗曚綅锛�" prop="unit">
+ <el-input disabled v-model="form.unit" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鐗╁搧绫诲瀷锛�" prop="itemType">
+ <el-input disabled v-model="form.itemType" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="鍏ュ簱鏃堕棿锛�" prop="createTime">
+ <el-date-picker style="width: 100%" v-model="form.createTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
+ type="date" placeholder="璇烽�夋嫨" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="搴撳瓨鏁伴噺锛�" prop="inboundNum">
+ <el-input v-model="form.inboundNum" placeholder="璇疯緭鍏�" clearable @input="calculateTotalPrice" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="宸插嚭搴撴暟閲忥細" prop="totalInboundNum">
+ <el-input disabled v-model="form.totalInboundNum" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="寰呭嚭搴撴暟閲忥細" prop="inboundNum0">
+ <el-input disabled v-model="form.inboundNum0" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+<!-- <el-row :gutter="30">-->
+<!-- <el-col :span="12">-->
+<!-- <el-form-item label="鍗曚环(鍏�)锛�" prop="taxInclusiveUnitPrice">-->
+<!-- <el-input v-model="form.taxInclusiveUnitPrice" placeholder="璇疯緭鍏�" clearable @input="calculateTotalPrice" />-->
+<!-- </el-form-item>-->
+<!-- </el-col>-->
+<!-- <el-col :span="12">-->
+<!-- <el-form-item label="鎬讳环(鍏�)锛�" prop="taxInclusiveTotalPrice">-->
+<!-- <el-input disabled v-model="form.taxInclusiveTotalPrice" placeholder="鑷姩璁$畻" clearable />-->
+<!-- </el-form-item>-->
+<!-- </el-col>-->
+<!-- </el-row>-->
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button @click="closeDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, watch } from 'vue'
+
+const props = defineProps({
+ dialogFormVisible: Boolean,
+ operationType: String,
+ formData: Object
+})
+
+const emit = defineEmits(['update:dialogFormVisible', 'submit', 'close'])
+
+const formRef = ref()
+
+const data = reactive({
+ form: {
+ productCategory: '',
+ specificationModel: '',
+ unit: '',
+ itemType: '',
+ createTime: '',
+ inboundNum: '',
+ totalInboundNum: '',
+ inboundNum0: '',
+ taxInclusiveUnitPrice: '',
+ taxInclusiveTotalPrice: ''
+ },
+ rules: {
+ productCategory: [{ required: true, message: '璇疯緭鍏ヤ骇鍝佸ぇ绫�', trigger: 'blur' }],
+ specificationModel: [{ required: true, message: '璇疯緭鍏ヨ鏍煎瀷鍙�', trigger: 'blur' }],
+ unit: [{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: 'blur' }],
+ itemType: [{ required: true, message: '璇疯緭鍏ョ墿鍝佺被鍨�', trigger: 'blur' }],
+ createTime: [{ required: true, message: '璇烽�夋嫨鍏ュ簱鏃堕棿', trigger: 'change' }],
+ inboundNum: [{ required: true, message: '璇疯緭鍏ュ簱瀛樻暟閲�', trigger: 'blur' }],
+ taxInclusiveUnitPrice: [{ required: true, message: '璇疯緭鍏ュ崟浠�', trigger: 'blur' }]
+ }
+})
+
+const { form, rules } = toRefs(data)
+
+// 璁$畻鎬讳环锛氭�讳环 = 鍗曚环 脳 鍓╀綑搴撳瓨
+const calculateTotalPrice = () => {
+ const unitPrice = parseFloat(form.value.taxInclusiveUnitPrice) || 0
+ const stockQuantity = parseFloat(form.value.inboundNum) || 0 // 搴撳瓨鏁伴噺
+ const outboundQuantity = parseFloat(form.value.totalInboundNum) || 0 // 宸插嚭搴撴暟閲�
+ const remainingStock = stockQuantity - outboundQuantity // 鍓╀綑搴撳瓨
+ form.value.taxInclusiveTotalPrice = (unitPrice * remainingStock).toFixed(2)
+}
+
+// 鐩戝惉formData鍙樺寲
+watch(() => props.formData, (newVal) => {
+ if (newVal) {
+ form.value = { ...newVal }
+ // 鏁版嵁鍙樺寲鍚庨噸鏂拌绠楁�讳环
+ calculateTotalPrice()
+ }
+}, { immediate: true })
+
+// 鎻愪氦琛ㄥ崟
+const submitForm = () => {
+ formRef.value.validate(valid => {
+ if (valid) {
+ emit('submit', form.value)
+ }
+ })
+}
+
+// 鍏抽棴寮规
+const closeDia = () => {
+ emit('close')
+ emit('update:dialogFormVisible', false)
+}
+
+</script>
+
+<style scoped lang="scss">
+.dialog-footer {
+ text-align: center;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/inventoryManagement/stockManagement/components/FormDiaProduction.vue b/src/views/inventoryManagement/stockManagement/components/FormDiaProduction.vue
new file mode 100644
index 0000000..1653307
--- /dev/null
+++ b/src/views/inventoryManagement/stockManagement/components/FormDiaProduction.vue
@@ -0,0 +1,147 @@
+<template>
+ <el-dialog :model-value="dialogFormVisible" :title="operationType === 'add' ? '鏂板鎴愬搧搴撳瓨' : '缂栬緫鎴愬搧搴撳瓨'" width="70%"
+ @update:model-value="$emit('update:dialogFormVisible', $event)" @close="closeDia">
+ <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="浜у搧澶х被锛�" prop="productCategory">
+ <el-input disabled v-model="form.productCategory" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="specificationModel">
+ <el-input disabled v-model="form.specificationModel" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="鍗曚綅锛�" prop="unit">
+ <el-input disabled v-model="form.unit" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍏ュ簱鏃堕棿锛�" prop="createTime">
+ <el-date-picker style="width: 100%" v-model="form.createTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
+ type="date" placeholder="璇烽�夋嫨" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="搴撳瓨鏁伴噺锛�" prop="inboundNum">
+ <el-input v-model="form.inboundNum" placeholder="璇疯緭鍏�" clearable @input="calculateTotalPrice" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="宸插嚭搴撴暟閲忥細" prop="totalInboundNum">
+ <el-input disabled v-model="form.totalInboundNum" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="寰呭嚭搴撴暟閲忥細" prop="inboundNum0">
+ <el-input disabled v-model="form.inboundNum0" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍗曚环(鍏�)锛�" prop="unitPrice">
+ <el-input v-model="form.unitPrice" placeholder="璇疯緭鍏�" clearable @input="calculateTotalPrice" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="鎬讳环(鍏�)锛�" prop="totalPrice">
+ <el-input disabled v-model="form.totalPrice" placeholder="鑷姩璁$畻" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button @click="closeDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, watch } from 'vue'
+
+const props = defineProps({
+ dialogFormVisible: Boolean,
+ operationType: String,
+ formData: Object
+})
+
+const emit = defineEmits(['update:dialogFormVisible', 'submit', 'close'])
+
+const formRef = ref()
+
+const data = reactive({
+ form: {
+ productCategory: '',
+ specificationModel: '',
+ unit: '',
+ createTime: '',
+ inboundNum: '',
+ totalInboundNum: '',
+ inboundNum0: '',
+ unitPrice: '',
+ totalPrice: ''
+ },
+ rules: {
+ productCategory: [{ required: true, message: '璇疯緭鍏ヤ骇鍝佸ぇ绫�', trigger: 'blur' }],
+ specificationModel: [{ required: true, message: '璇疯緭鍏ヨ鏍煎瀷鍙�', trigger: 'blur' }],
+ unit: [{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: 'blur' }],
+ createTime: [{ required: true, message: '璇烽�夋嫨鍏ュ簱鏃堕棿', trigger: 'change' }],
+ inboundNum: [{ required: true, message: '璇疯緭鍏ュ簱瀛樻暟閲�', trigger: 'blur' }],
+ unitPrice: [{ required: true, message: '璇疯緭鍏ュ崟浠�', trigger: 'blur' }]
+ }
+})
+
+const { form, rules } = toRefs(data)
+
+// 璁$畻鎬讳环锛氭�讳环 = 鍗曚环 脳 鍓╀綑搴撳瓨
+const calculateTotalPrice = () => {
+ const unitPrice = parseFloat(form.value.unitPrice) || 0
+ const stockQuantity = parseFloat(form.value.inboundNum) || 0 // 搴撳瓨鏁伴噺
+ const outboundQuantity = parseFloat(form.value.totalInboundNum) || 0 // 宸插嚭搴撴暟閲�
+ const remainingStock = stockQuantity - outboundQuantity // 鍓╀綑搴撳瓨
+ form.value.totalPrice = (unitPrice * remainingStock).toFixed(2)
+}
+
+// 鐩戝惉formData鍙樺寲
+watch(() => props.formData, (newVal) => {
+ if (newVal) {
+ form.value = { ...newVal }
+ // 鏁版嵁鍙樺寲鍚庨噸鏂拌绠楁�讳环
+ calculateTotalPrice()
+ }
+}, { immediate: true })
+
+// 鎻愪氦琛ㄥ崟
+const submitForm = () => {
+ formRef.value.validate(valid => {
+ if (valid) {
+ emit('submit', form.value)
+ }
+ })
+}
+
+// 鍏抽棴寮规
+const closeDia = () => {
+ emit('close')
+ emit('update:dialogFormVisible', false)
+}
+
+</script>
+
+<style scoped lang="scss">
+.dialog-footer {
+ text-align: center;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/inventoryManagement/stockManagement/components/FormDiaPurchase.vue b/src/views/inventoryManagement/stockManagement/components/FormDiaPurchase.vue
new file mode 100644
index 0000000..5da2eee
--- /dev/null
+++ b/src/views/inventoryManagement/stockManagement/components/FormDiaPurchase.vue
@@ -0,0 +1,147 @@
+<template>
+ <el-dialog :model-value="dialogFormVisible" :title="operationType === 'add' ? '鏂板鍘熸枡搴撳瓨' : '缂栬緫鍘熸枡搴撳瓨'" width="70%"
+ @update:model-value="$emit('update:dialogFormVisible', $event)" @close="closeDia">
+ <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="浜у搧澶х被锛�" prop="productCategory">
+ <el-input disabled v-model="form.productCategory" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="specificationModel">
+ <el-input disabled v-model="form.specificationModel" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="鍗曚綅锛�" prop="unit">
+ <el-input disabled v-model="form.unit" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍏ュ簱鏃堕棿锛�" prop="createTime">
+ <el-date-picker style="width: 100%" v-model="form.createTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
+ type="date" placeholder="璇烽�夋嫨" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="搴撳瓨鏁伴噺锛�" prop="inboundNum">
+ <el-input v-model="form.inboundNum" placeholder="璇疯緭鍏�" clearable @input="calculateTotalPrice" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="宸插嚭搴撴暟閲忥細" prop="totalInboundNum">
+ <el-input disabled v-model="form.totalInboundNum" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="寰呭嚭搴撴暟閲忥細" prop="inboundNum0">
+ <el-input disabled v-model="form.inboundNum0" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍚◣鍗曚环(鍏�)锛�" prop="taxInclusiveUnitPrice">
+ <el-input v-model="form.taxInclusiveUnitPrice" placeholder="璇疯緭鍏�" clearable @input="calculateTotalPrice" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="鍚◣鎬讳环(鍏�)锛�" prop="taxInclusiveTotalPrice">
+ <el-input disabled v-model="form.taxInclusiveTotalPrice" placeholder="鑷姩璁$畻" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button @click="closeDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, watch } from 'vue'
+
+const props = defineProps({
+ dialogFormVisible: Boolean,
+ operationType: String,
+ formData: Object
+})
+
+const emit = defineEmits(['update:dialogFormVisible', 'submit', 'close'])
+
+const formRef = ref()
+
+const data = reactive({
+ form: {
+ productCategory: '',
+ specificationModel: '',
+ unit: '',
+ createTime: '',
+ inboundNum: '',
+ totalInboundNum: '',
+ inboundNum0: '',
+ taxInclusiveUnitPrice: '',
+ taxInclusiveTotalPrice: ''
+ },
+ rules: {
+ productCategory: [{ required: true, message: '璇疯緭鍏ヤ骇鍝佸ぇ绫�', trigger: 'blur' }],
+ specificationModel: [{ required: true, message: '璇疯緭鍏ヨ鏍煎瀷鍙�', trigger: 'blur' }],
+ unit: [{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: 'blur' }],
+ createTime: [{ required: true, message: '璇烽�夋嫨鍏ュ簱鏃堕棿', trigger: 'change' }],
+ inboundNum: [{ required: true, message: '璇疯緭鍏ュ簱瀛樻暟閲�', trigger: 'blur' }],
+ taxInclusiveUnitPrice: [{ required: true, message: '璇疯緭鍏ュ惈绋庡崟浠�', trigger: 'blur' }]
+ }
+})
+
+const { form, rules } = toRefs(data)
+
+// 璁$畻鎬讳环锛氬惈绋庢�讳环 = 鍚◣鍗曚环 脳 鍓╀綑搴撳瓨
+const calculateTotalPrice = () => {
+ const unitPrice = parseFloat(form.value.taxInclusiveUnitPrice) || 0
+ const stockQuantity = parseFloat(form.value.inboundNum) || 0 // 搴撳瓨鏁伴噺
+ const outboundQuantity = parseFloat(form.value.totalInboundNum) || 0 // 宸插嚭搴撴暟閲�
+ const remainingStock = stockQuantity - outboundQuantity // 鍓╀綑搴撳瓨
+ form.value.taxInclusiveTotalPrice = (unitPrice * remainingStock).toFixed(2)
+}
+
+// 鐩戝惉formData鍙樺寲
+watch(() => props.formData, (newVal) => {
+ if (newVal) {
+ form.value = { ...newVal }
+ // 鏁版嵁鍙樺寲鍚庨噸鏂拌绠楁�讳环
+ calculateTotalPrice()
+ }
+}, { immediate: true })
+
+// 鎻愪氦琛ㄥ崟
+const submitForm = () => {
+ formRef.value.validate(valid => {
+ if (valid) {
+ emit('submit', form.value)
+ }
+ })
+}
+
+// 鍏抽棴寮规
+const closeDia = () => {
+ emit('close')
+ emit('update:dialogFormVisible', false)
+}
+
+</script>
+
+<style scoped lang="scss">
+.dialog-footer {
+ text-align: center;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/inventoryManagement/stockManagement/index.vue b/src/views/inventoryManagement/stockManagement/index.vue
index 8e2c805..16a865d 100644
--- a/src/views/inventoryManagement/stockManagement/index.vue
+++ b/src/views/inventoryManagement/stockManagement/index.vue
@@ -1,152 +1,211 @@
<template>
<div class="app-container">
- <div class="search_form">
- <div>
- <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>
- <!-- <el-button type="primary" @click="openForm('add')">鏂板</el-button> -->
- <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="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-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱浜�" prop="createBy" width="80" show-overflow-tooltip />
- <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);" :disabled="scope.row.createUser !== userStore.id">缂栬緫</el-button>
- </template>
- </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-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '鏂板搴撳瓨' : '缂栬緫搴撳瓨'" width="70%"
- @close="closeDia">
- <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierName">
- <el-input disabled v-model="form.supplierName" placeholder="璇疯緭鍏�" clearable />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="浜у搧澶х被锛�" prop="productId">
- <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-form-item>
- </el-col>
- </el-row>
- <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">
- <el-option v-for="item in productModelList" :key="item.id" :label="item.model"
- :value="item.id" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍗曚綅锛�" prop="customerId">
- <el-input disabled v-model="form.unit" placeholder="璇疯緭鍏�" clearable />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="搴撳瓨鏃堕棿锛�" prop="projectName">
- <el-date-picker style="width: 100%" v-model="form.updateTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
- type="date" placeholder="璇烽�夋嫨" clearable />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍏ュ簱鏃堕棿锛�" prop="projectName">
- <el-date-picker style="width: 100%" v-model="form.createTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
- type="date" placeholder="璇烽�夋嫨" clearable />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
-
- <el-col :span="12">
- <el-form-item label="鍚◣鍗曚环锛�" prop="customerId">
- <el-input disabled v-model="form.taxInclusiveUnitPrice" placeholder="璇疯緭鍏�" clearable />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍚◣鎬讳环锛�" prop="customerContractNo">
- <el-input disabled v-model="form.taxInclusiveTotalPrice" placeholder="璇疯緭鍏�" clearable />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
-
- <el-col :span="12">
- <el-form-item label="绋庣巼锛�" prop="customerId">
- <el-input disabled v-model="form.taxRate" placeholder="璇疯緭鍏�" clearable />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="涓嶅惈绋庢�讳环锛�" prop="entryDate">
- <el-input disabled v-model="form.taxExclusiveTotalPrice" placeholder="璇疯緭鍏�" clearable />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍑哄簱浜猴細" prop="entryPerson">
- <el-select v-model="form.createUser" placeholder="璇烽�夋嫨" clearable>
- <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
- </el-select>
- </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>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitForm">纭</el-button>
- <el-button @click="closeDia">鍙栨秷</el-button>
+ <el-tabs v-model="activeTab" @tab-change="handleTabChange">
+ <el-tab-pane label="鎴愬搧搴撳瓨" name="production">
+ <div class="search_form">
+ <div>
+<!-- <span class="search_title">瀹㈡埛鍚嶇О锛�</span>-->
+<!-- <el-input v-model="searchForm.customerName" 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"
+ />
+ <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>
- </template>
- </el-dialog>
- <el-dialog v-model="barcodeDia" title="浜у搧淇℃伅" width="70%" @close="closeBarcodeDia">
+ <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="customerName" width="240" 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="inboundNum" width="100" 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 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-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />-->
+ <!-- <el-table-column label="鍏ュ簱浜�" prop="createBy" width="80" show-overflow-tooltip /> -->
+ <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>
+ <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="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="inboundNum" width="100" 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-tab-pane label="鏉愭枡搴撳瓨" name="manual">
+ <div class="search_form">
+ <div>
+<!-- <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"
+ />
+ <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="supplierName" width="240" 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="itemType" width="120" show-overflow-tooltip />
+ <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="100" 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="taxInclusiveUnitPrice" width="150"></el-table-column>-->
+<!-- <el-table-column label="鎬讳环(鍏�)" prop="taxInclusiveTotalPrice" width="150"></el-table-column>-->
+<!-- <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-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />-->
+ <!-- <el-table-column label="鍏ュ簱浜�" prop="createBy" width="80" show-overflow-tooltip /> -->
+ <el-table-column fixed="right" label="鎿嶄綔" width="100" 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>
+ <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"
+ />
+
+ <!-- 鍘熸枡搴撳瓨寮规 -->
+ <FormDiaPurchase
+ v-model:dialogFormVisible="purchaseDialogVisible"
+ :operationType="operationType"
+ :formData="form"
+ @submit="submitForm"
+ @close="closeDia"
+ />
+
+ <!-- 鏉愭枡搴撳瓨寮规 -->
+ <FormDiaManual
+ v-model:dialogFormVisible="manualDialogVisible"
+ :operationType="operationType"
+ :formData="form"
+ @submit="submitForm"
+ @close="closeDia"
+ />
+ </div>
+ <el-dialog v-model="barcodeDia" title="浜у搧淇℃伅" width="70%" @close="closeBarcodeDia">
<div>
<el-row :gutter="30">
<el-col :span="12">
@@ -191,7 +250,6 @@
</div>
</template>
</el-dialog>
- </div>
</template>
<script setup>
@@ -203,13 +261,23 @@
import { productTreeList,modelList } from "@/api/basicData/product.js"
import {
getStockManagePage,
+ getStockManagePageByProduction,
+ getStockManagePageByCustom,
delStockManage,
} from "@/api/inventoryManagement/stockManage.js";
import {
- updateManagement,updateStockIn
+ updateManagement, updateManagementByCustom, updateStockIn
} from "@/api/inventoryManagement/stockIn.js";
+// 瀵煎叆涓変釜鐙珛鐨勫脊妗嗙粍浠�
+import FormDiaProduction from './components/FormDiaProduction.vue'
+import FormDiaPurchase from './components/FormDiaPurchase.vue'
+import FormDiaManual from './components/FormDiaManual.vue'
+//鎵爜鐩稿叧鍙傛暟
+const barcodeDia = ref(false);
+const scanBarcodeInput = ref('');
+const barcodeDetail = ref({})
const userStore = useUserStore()
const { proxy } = getCurrentInstance()
@@ -230,16 +298,23 @@
const loading = ref(false);
// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
const operationType = ref('')
-const dialogFormVisible = ref(false)
-const barcodeDia = ref(false)
+const activeTab = ref('production')
+
+// 涓変釜鐙珛鐨勫脊妗嗘樉绀虹姸鎬�
+const productionDialogVisible = ref(false)
+const purchaseDialogVisible = ref(false)
+const manualDialogVisible = ref(false)
+
const data = reactive({
searchForm: {
- supplierName: '',
- timeStr: '',
+ // supplierName: '',
+ productCategory:'',
+ customerName: '',
+ timeStr: getCurrentDate(),
},
form: {
supplierId: null,
- supplierName: '',
+ // supplierName: '',
productId: null,
productName: '',
userId: userStore.userId,
@@ -248,6 +323,7 @@
model: '',
unit: '',
productrecordId: null,
+ unitPrice: '', // 娣诲姞鎴愬搧搴撳瓨鐨勫崟浠峰瓧娈�
taxInclusiveUnitPrice: '',
taxInclusiveTotalPrice: '',
taxRate: '',
@@ -260,11 +336,12 @@
salesLedgerProductId: null,
},
rules: {
- supplierName: [{ required: true, message: '璇疯緭鍏ヤ緵搴斿晢鍚嶇О', trigger: 'blur' }],
+ // 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' }],
@@ -288,17 +365,77 @@
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
- getStockManagePage({ ...searchForm.value, ...page }).then(res => {
+ const params = buildQueryParams()
+ let apiCall
+ if (activeTab.value === 'production') {
+ apiCall = getStockManagePageByProduction(params)
+ } else if (activeTab.value === 'manual') {
+ apiCall = getStockManagePageByCustom(params)
+ } else {
+ apiCall = 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)
+ } else if (activeTab.value === 'manual') {
+ // 鏉愭枡搴撳瓨锛氬惈绋庢�讳环 = 鍚◣鍗曚环 脳 鍓╀綑搴撳瓨
+ 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()
}
// 琛ㄦ牸閫夋嫨鏁版嵁
@@ -327,7 +464,6 @@
// 鎵撳紑寮规
const openForm = async (type, row) => {
- console.log('openForm',type,row)
operationType.value = type
form.value = {}
productData.value = []
@@ -347,23 +483,63 @@
})
}
form.value.entryDate = getCurrentDate() // 璁剧疆榛樿褰曞叆鏃ユ湡涓哄綋鍓嶆棩鏈�
- dialogFormVisible.value = true
+
+ // 鏍规嵁褰撳墠鏍囩椤垫樉绀哄搴旂殑寮规
+ if (activeTab.value === 'production') {
+ productionDialogVisible.value = true
+ } else if (activeTab.value === 'purchase') {
+ purchaseDialogVisible.value = true
+ } else if (activeTab.value === 'manual') {
+ manualDialogVisible.value = true
+ }
}
// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- console.log(form.value)
- proxy.$refs["formRef"].validate(valid => {
- if (valid) {
-
- updateManagement(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛")
- closeDia()
- getList()
- // 鎻愪氦鍚庢鏌ュ簱瀛樺苟灏濊瘯鍒涘缓璇疯喘鍗�
- // checkStockAndCreatePurchase();
- })
- }
+const submitForm = (submittedData) => {
+ console.log('瀛愮粍浠舵彁浜ょ殑鏁版嵁:', submittedData)
+
+ // 浣跨敤瀛愮粍浠舵彁浜ょ殑鏁版嵁锛岃�屼笉鏄埗缁勪欢鐨刦orm瀵硅薄
+ const submitData = { ...submittedData }
+
+ // 鏍规嵁褰撳墠鏍囩椤电Щ闄ゅ搴旂殑鎬讳环瀛楁
+ if (activeTab.value === 'production') {
+ // 鎴愬搧搴撳瓨锛氱Щ闄ゆ�讳环瀛楁
+ delete submitData.totalPrice
+ } else if (activeTab.value === 'purchase') {
+ // 鍘熸枡搴撳瓨锛氱Щ闄ゅ惈绋庢�讳环瀛楁
+ delete submitData.taxInclusiveTotalPrice
+ } else if (activeTab.value === 'manual') {
+ // 鏉愭枡搴撳瓨锛氱Щ闄ゅ惈绋庢�讳环瀛楁
+ delete submitData.taxInclusiveTotalPrice
+ }
+
+ // 绉婚櫎鍏朵粬鍙兘鐨勬�讳环瀛楁
+ delete submitData.taxExclusiveTotalPrice
+
+ console.log('鎻愪氦缁欏悗绔殑鏁版嵁锛堝凡绉婚櫎鎬讳环瀛楁锛�:', submitData)
+
+ // 鏍规嵁褰撳墠鏍囩椤佃皟鐢ㄤ笉鍚岀殑鎻愪氦鎺ュ彛
+ let apiCall
+ if (activeTab.value === 'production') {
+ // 鎴愬搧搴撳瓨浣跨敤 updateManagement 鎺ュ彛
+ apiCall = updateManagement(submitData)
+ } else if (activeTab.value === 'manual') {
+ // 鏉愭枡搴撳瓨浣跨敤 updateManagementByCustom 鎺ュ彛
+ apiCall = updateManagementByCustom(submitData)
+ } else {
+ // 鍘熸枡搴撳瓨浣跨敤 updateManagementByCustom 鎺ュ彛
+ apiCall = updateManagementByCustom(submitData)
+ }
+
+ apiCall.then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛")
+ closeDia()
+ getList()
+ // 鎻愪氦鍚庢鏌ュ簱瀛樺苟灏濊瘯鍒涘缓璇疯喘鍗�
+ // checkStockAndCreatePurchase();
+ }).catch(error => {
+ console.error('鎻愪氦澶辫触:', error)
+ proxy.$modal.msgError("鎻愪氦澶辫触锛岃閲嶈瘯")
})
}
// 妫�鏌ュ簱瀛樺苟鍒涘缓璇疯喘鍗�
@@ -391,7 +567,9 @@
// 鍏抽棴寮规
const closeDia = () => {
proxy.resetForm("formRef")
- dialogFormVisible.value = false
+ productionDialogVisible.value = false
+ purchaseDialogVisible.value = false
+ manualDialogVisible.value = false
}
// 瀵煎嚭
@@ -404,7 +582,15 @@
type: 'warning',
}
).then(() => {
- proxy.download("/stockin/exportCopy", {}, '搴撳瓨淇℃伅.xlsx')
+ const exportParams = buildQueryParams()
+ // 鏍规嵁涓嶅悓鐨� tab 绫诲瀷璋冪敤涓嶅悓鐨勫鍑烘帴鍙�
+ let exportUrl = "/stockin/exportCopy"
+ if (activeTab.value === 'production') {
+ exportUrl = "/stockin/exportCopyOne"
+ } else if (activeTab.value === 'manual') {
+ exportUrl = "/stockin/exportCopyTwo"
+ }
+ proxy.download(exportUrl, exportParams, '搴撳瓨淇℃伅.xlsx')
}).catch(() => {
proxy.$modal.msg("宸插彇娑�")
})
@@ -413,12 +599,6 @@
const handleDelete = () => {
let ids = []
if (selectedRows.value.length > 0) {
- // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
- const unauthorizedData = selectedRows.value.filter(item => item.createUser !== userStore.id);
- if (unauthorizedData.length > 0) {
- proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
- return;
- }
ids = selectedRows.value.map(item => item.id);
} else {
proxy.$modal.msgWarning('璇烽�夋嫨鏁版嵁')
@@ -448,8 +628,7 @@
const day = String(today.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
-
-let scanBarcodeInput = ref('')
+// 鎵爜鍑芥暟
const scanBarcode = (e) => {
if(!e||!e.target||!e.target.tagName){
return;
@@ -465,8 +644,6 @@
scanBarcodeInput.value += e.key
}
}
-
-const barcodeDetail = ref({})
const getDetail = (barcode)=>{
barcodeDetail.value = {
barcode:barcode
@@ -477,7 +654,6 @@
const closeBarcodeDia = () => {
barcodeDia.value = false
}
-
onMounted(() => {
// 娣诲姞鎵爜鏋洃鍚簨浠�
document.addEventListener('keypress', scanBarcode)
@@ -512,4 +688,4 @@
justify-content: space-between;
padding: 5px 0;
}
-</style>
+</style>
\ No newline at end of file
--
Gitblit v1.9.3