From 7ab50761e7b6649fc30930cfd604d663b2ea4e00 Mon Sep 17 00:00:00 2001
From: tuqin <tuqin@tuqin.cn>
Date: 星期三, 21 十月 2026 15:16:10 +0800
Subject: [PATCH] feat(芯导): 仓储库存管理/协同审批会议提醒/采购付款查询导出/营销回款流水导出/生产设备补字段
---
src/views/inventoryManagement/issueManagement/index.vue | 355 +++++++++++++++++++++++++++++++---------------------------
1 files changed, 190 insertions(+), 165 deletions(-)
diff --git a/src/views/inventoryManagement/issueManagement/index.vue b/src/views/inventoryManagement/issueManagement/index.vue
index 50b44fd..9ec5730 100644
--- a/src/views/inventoryManagement/issueManagement/index.vue
+++ b/src/views/inventoryManagement/issueManagement/index.vue
@@ -1,56 +1,86 @@
<template>
<div class="app-container">
+ <el-tabs v-model="activeTab" @tab-change="handleTabChange" class="out-tabs">
+ <el-tab-pane label="鍙戞枡" name="issue" />
+ <el-tab-pane label="閿�鍞嚭搴�" name="sales" />
+ <el-tab-pane label="閫�璐у嚭搴�" name="purchaseReturn" />
+ </el-tabs>
<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-input
+ v-model="searchForm.productCategory"
+ style="width: 240px"
+ placeholder="璇疯緭鍏�"
+ clearable
+ @keyup.enter="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
+ :data="tableData"
+ border
+ v-loading="tableLoading"
+ @selection-change="handleSelectionChange"
+ :row-key="row => row.id"
+ show-summary
+ style="width: 100%"
+ :summary-method="summarizeMainTable"
+ height="calc(100vh - 21em)"
+ >
<el-table-column align="center" type="selection" width="55" />
<el-table-column align="center" label="搴忓彿" type="index" width="60" />
- <el-table-column label="鍏ュ簱鏃堕棿" prop="salesContractNo" width="100" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱鎵规" prop="customerContractNo" width="160" show-overflow-tooltip />
- <el-table-column label="渚涘簲鍟嗗悕绉�" prop="customerName" width="160" show-overflow-tooltip />
- <el-table-column label="浜у搧澶х被" prop="salesman" width="100" show-overflow-tooltip />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="projectName" width="160" show-overflow-tooltip />
- <el-table-column label="鍗曚綅" prop="contractAmount" width="70" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱鏁伴噺" prop="entryPersonName" width="90" show-overflow-tooltip />
- <el-table-column label="鍚◣鍗曚环" prop="entryDate" width="100" show-overflow-tooltip />
- <el-table-column label="鍚◣鎬讳环" prop="executionDate" width="100" show-overflow-tooltip />
- <el-table-column label="绋庣巼" prop="executionDate" width="80" show-overflow-tooltip />
- <el-table-column label="涓嶅惈绋庢�讳环" prop="executionDate" width="100" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱浜�" prop="executionDate" width="80" show-overflow-tooltip />
- <el-table-column fixed="right" label="鎿嶄綔" min-width="60" align="center">
+ <el-table-column label="鎵规鍙�" width="150" show-overflow-tooltip>
+ <template #default="scope">{{ scope.row.code || scope.row.inboundBatches }}</template>
+ </el-table-column>
+ <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 v-if="activeTab === 'issue'" label="鐗╁搧绫诲瀷" prop="itemType" show-overflow-tooltip />
+ <el-table-column v-if="activeTab === 'sales'" label="瀹㈡埛鍚嶇О" prop="customerName" show-overflow-tooltip />
+ <el-table-column v-if="activeTab === 'purchaseReturn'" label="渚涘簲鍟�" prop="supplierName" show-overflow-tooltip />
+ <el-table-column :label="cfg.availLabel" prop="inboundNum0" width="110" show-overflow-tooltip />
+ <el-table-column fixed="right" label="鎿嶄綔" width="110" align="center">
<template #default="scope">
- <el-button link type="primary" size="small" @click="openForm(scope.row);">鍑哄簱</el-button>
+ <el-button link type="primary" size="small" @click="openForm(scope.row)">{{ cfg.outLabel }}</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" />
+ <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="'鏂板鍑哄簱'" width="70%" @close="closeDia">
+ <el-dialog v-model="dialogFormVisible" :title="cfg.dialogTitle" width="40%" @close="closeDia" draggable>
<el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
- <el-form-item label="鍑哄簱鏁伴噺锛�" prop="salesContractNo">
- <el-input v-model="form.salesContractNo" placeholder="璇疯緭鍏�" clearable />
+ <div v-if="activeTab === 'purchaseReturn'" style="margin-bottom: 12px">
+ 渚涘簲鍟嗭細{{ currentRow.supplierName || '-' }}
+ </div>
+ <div>{{ cfg.availLabel }}锛歿{ currentRowNum }}</div>
+ <el-form-item :label="cfg.qtyLabel" prop="inboundQuantity">
+ <el-input-number :step="0.01" :min="0" :max="currentRowNum" style="width: 100%" v-model="form.inboundQuantity" placeholder="璇疯緭鍏�" clearable />
</el-form-item>
- <el-form-item label="鍑哄簱鏃ユ湡锛�" prop="projectName">
- <el-date-picker style="width: 100%" v-model="form.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
+ <el-form-item label="棰嗙敤鏁伴噺锛�">
+ <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="form.requisitionNum" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ <el-form-item :label="cfg.dateLabel" prop="inboundTime">
+ <el-date-picker style="width: 100%" v-model="form.inboundTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
type="date" placeholder="璇烽�夋嫨" clearable />
</el-form-item>
- <el-form-item label="鍑哄簱浜猴細" prop="entryPerson">
- <el-select v-model="form.entryPerson" placeholder="璇烽�夋嫨" clearable>
+ <el-form-item :label="cfg.personLabel" prop="nickName">
+ <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>
@@ -67,63 +97,92 @@
<script setup>
import pagination from '@/components/PIMTable/Pagination.vue'
-import { ref } from 'vue'
+import { ref, reactive, toRefs, onMounted, computed, getCurrentInstance } from 'vue'
import { ElMessageBox } from "element-plus";
-import useUserStore from '@/store/modules/user'
-import { userListNoPage } from "@/api/system/user.js";
+import { userListNoPageByTenantId } from "@/api/system/user.js";
import {
- ledgerListPage,
- customerList,
- addOrUpdateSalesLedger,
- getSalesLedgerWithProducts, delLedger
-} from "@/api/salesManagement/salesLedger.js";
-const userStore = useUserStore()
+ getInPageByCustom,
+ getStockInPage,
+ getStockInPageByProduction,
+} from "@/api/inventoryManagement/stockIn.js";
+import {
+ stockOut,
+} from "@/api/inventoryManagement/stockManage.js";
+import { getCurrentDate } from "@/utils/index.js";
+
const { proxy } = getCurrentInstance()
const tableData = ref([])
-const productData = ref([])
const selectedRows = ref([])
const userList = ref([])
-const customerOption = ref([])
const tableLoading = ref(false)
+const activeTab = ref('issue')
const page = reactive({
current: 1,
size: 100,
})
const total = ref(0)
-const fileList = ref([])
+
+// 涓夌鍑哄簱绫诲瀷閰嶇疆锛氬彂鏂�(type=3 鑷畾涔夊嚭搴�)銆侀攢鍞嚭搴�(type=2)銆侀��璐у嚭搴�(type=5 閲囪喘閫�璐у嚭搴�)
+const tabConfig = {
+ issue: {
+ type: 3,
+ outLabel: '鍙戞枡',
+ dialogTitle: '鏂板鍙戞枡',
+ availLabel: '鍙彂鏂欐暟閲�',
+ qtyLabel: '鍙戞枡鏁伴噺锛�',
+ dateLabel: '鍙戞枡鏃ユ湡锛�',
+ personLabel: '鍙戞枡浜猴細',
+ exportUrl: '/stockmanagement/exportTwo',
+ exportName: '鍙戞枡鍙拌处.xlsx',
+ },
+ sales: {
+ type: 2,
+ outLabel: '閿�鍞嚭搴�',
+ dialogTitle: '鏂板閿�鍞嚭搴�',
+ availLabel: '鍙嚭搴撴暟閲�',
+ qtyLabel: '鍑哄簱鏁伴噺锛�',
+ dateLabel: '鍑哄簱鏃ユ湡锛�',
+ personLabel: '缁忔墜浜猴細',
+ exportUrl: '/stockmanagement/exportOne',
+ exportName: '閿�鍞嚭搴撳彴璐�.xlsx',
+ },
+ purchaseReturn: {
+ type: 5,
+ outLabel: '閫�璐у嚭搴�',
+ dialogTitle: '鏂板閫�璐у嚭搴�',
+ availLabel: '鍙��璐ф暟閲�',
+ qtyLabel: '閫�璐ф暟閲忥細',
+ dateLabel: '閫�璐ф棩鏈燂細',
+ personLabel: '缁忔墜浜猴細',
+ exportUrl: '/stockmanagement/exportPurchaseReturn',
+ exportName: '閫�璐у嚭搴撳彴璐�.xlsx',
+ },
+}
+const cfg = computed(() => tabConfig[activeTab.value] || tabConfig.issue)
// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref('')
const dialogFormVisible = ref(false)
+const currentRow = ref({})
+const currentRowNum = ref(0)
const data = reactive({
searchForm: {
- customerName: '',
+ productCategory: '',
},
form: {
- salesContractNo: '',
- salesman: '',
- customerContractNo: '',
- customerId: '',
- projectName: '',
- entryPerson: '',
- entryDate: '',
- maintenanceTime: '',
- productData: [],
- executionDate: ''
+ productrecordId: '',
},
rules: {
- salesman: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- customerContractNo: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- customerId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- projectName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- entryPerson: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- entryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- executionDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ inboundTime: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ inboundQuantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ nickName: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }]
}
})
const { searchForm, form, rules } = toRefs(data)
-// 鏌ヨ鍒楄〃
+const handleTabChange = () => {
+ page.current = 1
+ getList()
+}
/** 鎼滅储鎸夐挳鎿嶄綔 */
const handleQuery = () => {
page.current = 1
@@ -134,98 +193,92 @@
page.size = obj.limit;
getList()
}
+// 鎸� tab 閫夋嫨"鍙嚭搴撳簱瀛�"鏉ユ簮锛氬彂鏂�=鑷畾涔夊叆搴擄紱閿�鍞嚭搴�=鐢熶骇鍏ュ簱锛涢��璐у嚭搴�=閲囪喘鍏ュ簱
+const fetchSource = (params) => {
+ if (activeTab.value === 'sales') return getStockInPageByProduction(params)
+ if (activeTab.value === 'purchaseReturn') return getStockInPage(params)
+ return getInPageByCustom(params)
+}
const getList = () => {
tableLoading.value = true
- ledgerListPage({ ...searchForm.value, ...page }).then(res => {
+ const params = { ...page }
+ params.productCategory = searchForm.value.productCategory
+ params.flag = true
+ fetchSource(params).then(res => {
tableLoading.value = false
- tableData.value = res.records
- tableData.value.map(item => {
- item.children = []
- })
- total.value = res.total
+ tableData.value = res.data.records || []
+ total.value = res.data.total
}).catch(() => {
tableLoading.value = false
})
}
-const findNodeById = (nodes, productId) => {
- for (let i = 0; i < nodes.length; i++) {
- if (nodes[i].value === productId) {
- return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣
- }
- if (nodes[i].children && nodes[i].children.length > 0) {
- const foundNode = findNodeById(nodes[i].children, productId);
- if (foundNode) {
- return foundNode.label; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝杩斿洖璇ヨ妭鐐�
- }
- }
- }
- return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
-};
+
// 琛ㄦ牸閫夋嫨鏁版嵁
const handleSelectionChange = (selection) => {
-
- // 杩囨护鎺夊瓙鏁版嵁
- selectedRows.value = selection.filter(item => item.children !== undefined);
- console.log('selection', selectedRows.value)
+ selectedRows.value = selection.filter(item => item.id);
}
-const expandedRowKeys = ref([])
// 涓昏〃鍚堣鏂规硶
const summarizeMainTable = (param) => {
- return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']);
-};
+ return proxy.summarizeTable(param, ['taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']);
+}
// 鎵撳紑寮规
const openForm = async (row) => {
- operationType.value = type
- form.value = {}
- productData.value = []
- let userLists = await userListNoPage()
- userList.value = userLists.data
- customerList().then(res => {
- customerOption.value = res
- })
- console.log('userStore.id', userStore.id)
- form.value.entryPerson = userStore.id
- if (type === 'edit') {
- currentId.value = row.id;
- getSalesLedgerWithProducts({ id: row.id, type: 1 }).then(res => {
- form.value = { ...res }
- form.value.entryPerson = Number(res.entryPerson)
- productData.value = form.value.productData
- fileList.value = form.value.salesLedgerFiles
- })
- }
- // let userAll = await userStore.getInfo()
- // userList.value.forEach(element => {
- // if(userAll.user.nickName === element.nickName && userAll.user.userName === element.userName) {
- // form.value.entryPerson = userAll.user.userId // 璁剧疆榛樿涓氬姟鍛樹负褰撳墠鐢ㄦ埛
- // }
- // });
- form.value.entryDate = getCurrentDate() // 璁剧疆榛樿褰曞叆鏃ユ湡涓哄綋鍓嶆棩鏈�
dialogFormVisible.value = true
+ currentRow.value = row || {}
+ currentRowNum.value = row ? row.inboundNum0 : 0
+ form.value = {}
+ // 鍔犺浇鐢ㄦ埛鍒楄〃
+ try {
+ const userLists = await userListNoPageByTenantId()
+ userList.value = userLists.data
+ // 鏉愭枡鍑哄簱榛樿鍙戞枡浜�
+ const defaultPersonName = '鍚寸帀姊�'
+ const defaultPerson = userList.value.find(user => user.nickName === defaultPersonName)
+ const defaultUserId = defaultPerson ? defaultPerson.userId : ''
+ form.value = {
+ productrecordId: '',
+ inboundQuantity: currentRowNum.value,
+ requisitionNum: 0,
+ inboundTime: getCurrentDate(),
+ nickName: defaultUserId,
+ }
+ } catch (error) {
+ form.value = {
+ productrecordId: '',
+ inboundQuantity: currentRowNum.value,
+ requisitionNum: 0,
+ inboundTime: getCurrentDate(),
+ nickName: '',
+ }
+ }
}
// 鎻愪氦琛ㄥ崟
const submitForm = () => {
+ let num = Number(form.value.inboundQuantity)
+ if (num <= 0 || num > currentRowNum.value) {
+ return proxy.$modal.msgWarning("璇峰~鍏ユ湁鏁堟暟瀛�")
+ }
proxy.$refs["formRef"].validate(valid => {
- if (valid) {
- if (productData.value.length > 0) {
- form.value.productData = proxy.HaveJson(productData.value)
- } else {
- proxy.$modal.msgWarning('璇锋坊鍔犱骇鍝佷俊鎭�')
- return
+ if (valid && currentRow.value && currentRow.value.id) {
+ const outData = {
+ id: currentRow.value.id, // 鏉ユ簮鍏ュ簱璁板綍ID
+ salesLedgerProductId: currentRow.value.salesLedgerProductId || 0,
+ quantity: form.value.inboundQuantity, // 鍑哄簱鏁伴噺
+ requisitionNum: form.value.requisitionNum, // 棰嗙敤鏁伴噺
+ time: form.value.inboundTime, // 鍑哄簱鏃堕棿
+ userId: form.value.nickName, // 缁忔墜浜�
+ type: cfg.value.type, // 鍑哄簱绫诲瀷锛�3鍙戞枡 / 2閿�鍞嚭搴� / 5閫�璐у嚭搴�
+ supplierName: currentRow.value.supplierName || '', // 閫�璐у嚭搴�-閫�鍥炰緵搴斿晢
}
- let tempFileIds = []
- if (fileList.value.length > 0) {
- tempFileIds = fileList.value.map(item => item.tempId)
- }
- form.value.tempFileIds = tempFileIds
- form.value.type = 1
- addOrUpdateSalesLedger(form.value).then(res => {
+ stockOut(outData).then(res => {
proxy.$modal.msgSuccess("鎻愪氦鎴愬姛")
closeDia()
getList()
+ }).catch(err => {
+ proxy.$modal.msgError("鍑哄簱澶辫触")
})
}
})
@@ -239,54 +292,26 @@
// 瀵煎嚭
const handleOut = () => {
ElMessageBox.confirm(
- '閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�',
+ '鏄惁纭瀵煎嚭锛�',
'瀵煎嚭', {
confirmButtonText: '纭',
cancelButtonText: '鍙栨秷',
type: 'warning',
}
).then(() => {
- proxy.download("/sales/ledger/export", {}, '鍏ュ簱鍙拌处.xlsx')
+ proxy.download(cfg.value.exportUrl, {}, cfg.value.exportName)
}).catch(() => {
proxy.$modal.msg("宸插彇娑�")
})
}
-// 鍒犻櫎
-const handleDelete = () => {
- let ids = []
- if (selectedRows.value.length > 0) {
- ids = selectedRows.value.map(item => item.id);
- } else {
- proxy.$modal.msgWarning('璇烽�夋嫨鏁版嵁')
- return
- }
- ElMessageBox.confirm(
- '閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�',
- '瀵煎嚭', {
- confirmButtonText: '纭',
- cancelButtonText: '鍙栨秷',
- type: 'warning',
- }
- ).then(() => {
- delLedger(ids).then(res => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛")
- getList()
- })
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�")
- })
-}
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, '0'); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, '0');
- return `${year}-${month}-${day}`;
-}
+
onMounted(() => {
getList()
})
</script>
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+.out-tabs {
+ margin-bottom: 6px;
+}
+</style>
--
Gitblit v1.9.3