Переглянути джерело

添加状态及更新逻辑

qaz 4 днів тому
батько
коміт
b00d88b5f3

+ 61 - 18
src/views/system/borrow/component/CollectEquipment/index.vue

@@ -229,22 +229,29 @@
                             ></textarea>
                             <el-button type="primary" style="margin-left: 16px" @click="handleAdd">手动借用</el-button>
                         </div>
-                        <el-table :data="deviceList" border style="width: 100%">
+                        <el-table :data="sortedCollectDeviceList" border style="width: 100%">
                             <el-table-column type="index" label="序号" width="60" align="center" />
                             <el-table-column prop="device_code" label="设备编号" align="center" />
                             <el-table-column prop="device_type" label="设备分类" align="center" />
                             <el-table-column prop="device_name" label="设备名称" align="center" />
                             <el-table-column prop="borrow_count" label="借用数量" align="center" width="150">
                                 <template #default="{ row }">
-                                    <el-input-number v-model="row.borrow_count" :disabled="isView" :min="1" :max="row.available_quantity" size="small" />
+                                    <el-input-number
+                                        v-model="row.borrow_count"
+                                        :disabled="isView"
+                                        :min="1"
+                                        :max="row.available_quantity"
+                                        size="small"
+                                        @change="() => touchCollectRowOrder(row)"
+                                    />
                                 </template>
                             </el-table-column>
                             <el-table-column prop="brand" label="品牌" align="center" />
                             <el-table-column prop="device_specification" label="规格型号" align="center" />
                             <!-- <el-table-column prop="warehouse" label="存放仓库" align="center" /> -->
                             <el-table-column label="操作" width="80" align="center">
-                                <template #default="{ $index }">
-                                    <el-button type="text" style="color: red" :disabled="isView" @click="handleRemove($index)">移除</el-button>
+                                <template #default="{ row }">
+                                    <el-button type="text" style="color: red" :disabled="isView" @click="handleRemove(row)">移除</el-button>
                                 </template>
                             </el-table-column>
                         </el-table>
@@ -335,7 +342,7 @@
                             <el-table-column
                                 v-if="showUnreturnedReturnTableColumns"
                                 prop="borrow_count"
-                                label="归还数量"
+                                label="本次归还数量"
                                 align="center"
                                 width="150"
                             >
@@ -361,10 +368,7 @@
                             <!-- <el-table-column prop="warehouse" label="存放仓库" align="center" /> -->
                             <el-table-column prop="status" label="状态" align="center">
                                 <template #default="{ row }">
-                                  {{ row.return_status.label }}
-                                   <!--  <el-tag v-if="!isView" :type="row.status === '已归还' ? 'success' : 'warning'">{{ row.status }}</el-tag>
-                                    <el-tag v-else-if="['已领取', '已归还'].includes(form.status_label)">{{ form.status_label }}</el-tag> -->
-                                    <!-- <span v-else>{{ form.status_label }}</span> -->
+                                  {{ getDeviceReturnStatusDisplay(row) }}
                                 </template>
                             </el-table-column>
                             <el-table-column prop="status" label="归还时间" align="center">
@@ -597,6 +601,8 @@ interface DeviceListItem {
   line_update_at?: string;
   /** 本页对行做了归还/数量等操作时的排序时间戳,与 line_update_at 取较大者参与排序 */
   sort_touched_at?: number;
+  /** 领取设备清单行:加入列表时的时间序,用于倒序(最新添加在上) */
+  collect_order_ms?: number;
 }
 
 interface FormItem {
@@ -848,6 +854,21 @@ const returnSearchInputRef = ref<any>(null);
 // 借用列表相关数据
 const searchText = ref('');
 const deviceList = ref<DeviceListItem[]>([]);
+
+/** 领取态设备清单按加入时间倒序,保证「最新添加」始终在表格最上(不依赖 unshift/Map 遍历顺序) */
+const sortedCollectDeviceList = computed(() =>
+  [...deviceList.value].sort((a, b) => {
+    const tb = Number(b.collect_order_ms) || 0;
+    const ta = Number(a.collect_order_ms) || 0;
+    if (tb !== ta) return tb - ta;
+    return String(a.device_no ?? '').localeCompare(String(b.device_no ?? ''), 'en');
+  })
+);
+
+/** 修改借用数量后刷新排序键,使该行在列表中置顶 */
+function touchCollectRowOrder(row: DeviceListItem) {
+  row.collect_order_ms = Date.now();
+}
 const accessoryInfo = ref('');
 const remark = ref('');
 // 领取模式下的"实借配件信息"本地输入,不回显历史
@@ -997,6 +1018,16 @@ function isReturnLinePendingReturn(row: DeviceListItem) {
   return (Number(row.available_quantity) || 0) > 0;
 }
 
+/** 设备行状态:未归还>0 且 已归还数量≠0 时展示「部分归还」,否则用接口/明细上的 return_status */
+function getDeviceReturnStatusDisplay(row: DeviceListItem) {
+  const un = Number(row.available_quantity) || 0;
+  const ret = Number(row.returned_quantity) || 0;
+  if (un > 0 && ret !== 0) {
+    return '部分归还';
+  }
+  return row.return_status?.label ?? '—';
+}
+
 /**
  * 扫码命中列表中的设备时:归还数量 +1,不超过待归还数。
  * 成功返回 null;失败返回提示文案。不在此调用 ElMessage,由扫码/RFID 批处理处统一只弹一次。
@@ -1538,6 +1569,7 @@ const autoSubmitPendingCodes = async () => {
               continue;
             }
             existingDevice.borrow_count++;
+            touchCollectRowOrder(existingDevice);
             console.log(`设备 ${trimmedCode} 已存在,借用数量+1`);
           } else {
             // 如果不存在,添加到列表(unshift:最新添加的在表格最上方)
@@ -1551,7 +1583,8 @@ const autoSubmitPendingCodes = async () => {
               device_specification: device.specification,
               model: device.model || '',
               warehouse: device.warehouse,
-              available_quantity: avail
+              available_quantity: avail,
+              collect_order_ms: Date.now(),
             });
             console.log(`设备 ${trimmedCode} 已添加到列表`);
           }
@@ -2297,7 +2330,9 @@ const handleScanSearch = async (event?: Event) => {
         });
       }
       
-      // 统一处理设备添加,避免并发竞态条件
+      // 统一处理设备添加,避免并发竞态条件;同批多设备用微增量区分先后,倒序时「本轮最后一条」仍在上
+      const orderBase = Date.now();
+      let orderSeq = 0;
       deviceMap.forEach((deviceData, deviceId) => {
         const existingDevice = deviceList.value.find(d => d.device_no === deviceId);
         if (existingDevice) {
@@ -2311,9 +2346,13 @@ const handleScanSearch = async (event?: Event) => {
             return;
           }
           existingDevice.borrow_count++;
+          existingDevice.collect_order_ms = orderBase + orderSeq++;
           successCount++;
         } else {
-          deviceList.value.unshift(deviceData);
+          deviceList.value.unshift({
+            ...deviceData,
+            collect_order_ms: orderBase + orderSeq++,
+          });
           successCount++;
         }
       });
@@ -3244,8 +3283,9 @@ const handleAdd = () => {
   showSelectDeviceDialog.value = true;
 };
 
-const handleRemove = (index: number) => {
-  deviceList.value.splice(index, 1);
+const handleRemove = (row: DeviceListItem) => {
+  const i = deviceList.value.findIndex((d) => d.device_no === row.device_no);
+  if (i >= 0) deviceList.value.splice(i, 1);
 };
 const handleReturnRemove = (index: number) => {
   returnDeviceList.value.splice(index, 1);
@@ -3304,7 +3344,8 @@ function onDeviceSelected(devices: Device[]) {
       ElMessage.warning(`已过滤 ${devices.length - newDevices.length} 个重复的设备`);
     }
     
-    newDevices.forEach((d) => {
+    const pickOrderBase = Date.now();
+    newDevices.forEach((d, idx) => {
       deviceList.value.unshift({
         device_no: d.id,
         device_code: d.code,
@@ -3315,7 +3356,8 @@ function onDeviceSelected(devices: Device[]) {
         model: d.model,
         device_specification: d.specification,
         warehouse: d.warehouse,
-        available_quantity: d.available_quantity
+        available_quantity: d.available_quantity,
+        collect_order_ms: pickOrderBase + idx,
       });
     });
   }else if(activeName.value === 'third'){
@@ -3820,9 +3862,10 @@ function onSubmit() {
       return;
     }
 
+    const collectRowsOrdered = sortedCollectDeviceList.value;
     // 合并两个标签页的设备数据
     const allDevices = [
-      ...deviceList.value.map(item => ({
+      ...collectRowsOrdered.map(item => ({
         condition: remark.value,
         quantity: item.borrow_count,
         device_id: Number(item.device_no) || 0
@@ -3843,7 +3886,7 @@ function onSubmit() {
         // 准备结算单数据
         settlementData.value = {
           ...form.value,
-          items: deviceList.value.map(item => ({
+          items: collectRowsOrdered.map(item => ({
             ...item,
             device_category_name: item.device_type,
             device_name: item.device_name,