From f8b148c77b41b6dca8f469d4c37df2d6410360ee Mon Sep 17 00:00:00 2001
From: tuqin <tuqin@tuqin.cn>
Date: 星期四, 08 十月 2026 16:58:31 +0800
Subject: [PATCH] feat(芯导): 仓储物流出库管理 / 人力资源(离职/在职台账/合同/薪资) 前端

---
 src/views/inventoryManagement/issueManagement/index.vue |  232 +++++++++++++++++++++++++--------------------------------
 1 files changed, 103 insertions(+), 129 deletions(-)

diff --git a/src/views/inventoryManagement/issueManagement/index.vue b/src/views/inventoryManagement/issueManagement/index.vue
index 92d6073..c5a1236 100644
--- a/src/views/inventoryManagement/issueManagement/index.vue
+++ b/src/views/inventoryManagement/issueManagement/index.vue
@@ -1,5 +1,10 @@
 <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 ml10">浜у搧澶х被锛�</span>
@@ -8,6 +13,7 @@
           style="width: 240px"
           placeholder="璇疯緭鍏�"
           clearable
+          @keyup.enter="handleQuery"
         />
         <el-button type="primary" @click="handleQuery" style="margin-left: 10px">鎼滅储</el-button>
       </div>
@@ -21,24 +27,27 @@
         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)"
+        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="code" width="130" show-overflow-tooltip />
+        <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 label="鐗╁搧绫诲瀷" prop="itemType" show-overflow-tooltip />
-        <el-table-column label="鍓╀綑搴撳瓨" prop="inboundNum0" width="90" show-overflow-tooltip />
-        <el-table-column fixed="right" label="鎿嶄綔" width="100" align="center">
+        <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>
@@ -51,17 +60,20 @@
         @pagination="paginationChange"
       />
     </div>
-    <el-dialog v-model="dialogFormVisible" :title="getDialogTitle()" width="40%" @close="closeDia" draggable>
+    <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">
-			<div>{{getAvailableQuantityText()}}:{{currentRowNum}}</div>
-        <el-form-item :label="getQuantityLabel()" prop="inboundQuantity">
+        <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="getDateLabel()" prop="inboundTime">
+        <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="getPersonLabel()" prop="nickName">
+        <el-form-item :label="cfg.personLabel" prop="nickName">
           <el-select v-model="form.nickName"
 										 filterable
                      default-first-option
@@ -82,42 +94,76 @@
 
 <script setup>
 import pagination from '@/components/PIMTable/Pagination.vue'
-import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue'
+import { ref, reactive, toRefs, onMounted, computed, getCurrentInstance } from 'vue'
 import { ElMessageBox } from "element-plus";
-import useUserStore from '@/store/modules/user'
 import { userListNoPageByTenantId } from "@/api/system/user.js";
 import {
-	getInPageByCustom
+  getInPageByCustom,
+  getStockInPage,
+  getStockInPageByProduction,
 } from "@/api/inventoryManagement/stockIn.js";
 import {
-    delStockManage,
-    stockOut,
+  stockOut,
 } from "@/api/inventoryManagement/stockManage.js";
 import { getCurrentDate } from "@/utils/index.js";
 
-const userStore = useUserStore()
 const { proxy } = getCurrentInstance()
 const tableData = ref([])
 const selectedRows = ref([])
 const userList = 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 dialogFormVisible = ref(false)
+const currentRow = ref({})
+const currentRowNum = ref(0)
 const data = reactive({
   searchForm: {
-    inboundQuantity:'',
-    inboundTime:'',
-    nickName: '',
-    userId: '',
-    productCategory:'',
-    // timeStr: getCurrentDate(),
+    productCategory: '',
   },
   form: {
     productrecordId: '',
@@ -130,7 +176,10 @@
 })
 const { searchForm, form, rules } = toRefs(data)
 
-// 鏌ヨ鍒楄〃
+const handleTabChange = () => {
+  page.current = 1
+  getList()
+}
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
   page.current = 1
@@ -141,81 +190,57 @@
   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
   const params = { ...page }
   params.productCategory = searchForm.value.productCategory
   params.flag = true
-  const apiCall = getInPageByCustom(params)
-  apiCall.then(res => {
+  fetchSource(params).then(res => {
     tableLoading.value = false
-    tableData.value = res.data.records
+    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.id);
-  console.log('selection', selectedRows.value)
 }
-const expandedRowKeys = ref([])
 
 // 涓昏〃鍚堣鏂规硶
 const summarizeMainTable = (param) => {
-  return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']);
-};
-const currentRowId = ref(null) // 鏂板锛氬瓨鍌ㄥ綋鍓嶆搷浣滅殑琛孖D
-
-const currentRowNum = ref(0)
-const salesLedgerProductId = ref(null);
+  return proxy.summarizeTable(param, ['taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']);
+}
 
 // 鎵撳紑寮规
 const openForm = async (row) => {
   dialogFormVisible.value = true
-  currentRowId.value = row.id
-  currentRowNum.value = row.inboundNum0
-  salesLedgerProductId.value = row.salesLedgerProductId
+  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, // 浣跨敤currentRowNum浣滀负榛樿鍊�
-      inboundTime: getCurrentDate(), // 榛樿褰撳墠鏃ユ湡
-      nickName: defaultUserId, // 鏍规嵁tab绫诲瀷璁剧疆榛樿鍙戣揣浜�
+      inboundQuantity: currentRowNum.value,
+      inboundTime: getCurrentDate(),
+      nickName: defaultUserId,
     }
-    console.log('form',form.value)
   } catch (error) {
-    console.error('鍔犺浇鐢ㄦ埛鍒楄〃澶辫触:', error)
-    // 濡傛灉鍔犺浇澶辫触锛屼娇鐢ㄧ┖鍊煎垵濮嬪寲
     form.value = {
       productrecordId: '',
       inboundQuantity: currentRowNum.value,
@@ -228,21 +253,20 @@
 // 鎻愪氦琛ㄥ崟
 const submitForm = () => {
   let num = Number(form.value.inboundQuantity)
-  if(num <= 0 || num > currentRowNum.value){
+  if (num <= 0 || num > currentRowNum.value) {
     return proxy.$modal.msgWarning("璇峰~鍏ユ湁鏁堟暟瀛�")
   }
   proxy.$refs["formRef"].validate(valid => {
-    if (valid && currentRowId.value) {
+    if (valid && currentRow.value && currentRow.value.id) {
       const outData = {
-        id: currentRowId.value, // 鍘熷璁板綍ID
-        salesLedgerProductId: 0,
+        id: currentRow.value.id, // 鏉ユ簮鍏ュ簱璁板綍ID
+        salesLedgerProductId: currentRow.value.salesLedgerProductId || 0,
         quantity: form.value.inboundQuantity, // 鍑哄簱鏁伴噺
         time: form.value.inboundTime, // 鍑哄簱鏃堕棿
-        userId: form.value.nickName, // 鎿嶄綔浜�
-        type: 3 // 鍑哄簱绫诲瀷锛氳嚜瀹氫箟/鏉愭枡
+        userId: form.value.nickName, // 缁忔墜浜�
+        type: cfg.value.type, // 鍑哄簱绫诲瀷锛�3鍙戞枡 / 2閿�鍞嚭搴� / 5閫�璐у嚭搴�
+        supplierName: currentRow.value.supplierName || '', // 閫�璐у嚭搴�-閫�鍥炰緵搴斿晢
       }
-      console.log(outData)
-
       stockOut(outData).then(res => {
         proxy.$modal.msgSuccess("鎻愪氦鎴愬姛")
         closeDia()
@@ -269,69 +293,19 @@
     type: 'warning',
   }
   ).then(() => {
-    const exportUrl = "/stockin/exportTwo"
-    proxy.download(exportUrl, {}, '鍑哄簱鍙拌处.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(() => {
-    delStockManage(ids).then(res => {
-      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛")
-      getList()
-    })
-  }).catch(() => {
-    proxy.$modal.msg("宸插彇娑�")
-  })
-}
-
-// 鏍规嵁tab绫诲瀷鑾峰彇寮规鏍囬
-const getDialogTitle = () => {
-  return '鏂板鍙戞枡';
-};
-
-// 鏍规嵁tab绫诲瀷鑾峰彇鍙嚭搴撴暟閲忔枃鏈�
-const getAvailableQuantityText = () => {
-  return '鍙彂鏂欐暟閲�';
-};
-
-// 鏍规嵁tab绫诲瀷鑾峰彇鏁伴噺瀛楁鏍囩
-const getQuantityLabel = () => {
-  return '鍙戞枡鏁伴噺锛�';
-};
-
-// 鏍规嵁tab绫诲瀷鑾峰彇鏃ユ湡瀛楁鏍囩
-const getDateLabel = () => {
-  return '鍙戞枡鏃ユ湡锛�';
-};
-
-// 鏍规嵁tab绫诲瀷鑾峰彇浜哄憳瀛楁鏍囩
-const getPersonLabel = () => {
-  return '鍙戞枡浜猴細';
-};
 
 onMounted(() => {
   getList()
 })
 </script>
 
-<style scoped lang="scss"></style>
-
-
-
+<style scoped lang="scss">
+.out-tabs {
+  margin-bottom: 6px;
+}
+</style>

--
Gitblit v1.9.3