|
|
@@ -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,
|