查看操作历史
This commit is contained in:
@@ -1,6 +1,58 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-table :data="stockList" style="width: 100%" v-loading="loading">
|
<el-table
|
||||||
|
:data="stockList"
|
||||||
|
style="width: 100%"
|
||||||
|
v-loading="loading"
|
||||||
|
row-key="raw_material_id"
|
||||||
|
@expand-change="handleExpandChange"
|
||||||
|
@row-click="handleRowClick"
|
||||||
|
>
|
||||||
|
<el-table-column type="expand">
|
||||||
|
<template #default="props">
|
||||||
|
<div style="padding: 10px 20px;">
|
||||||
|
<h4 style="margin-bottom: 16px;">历史操作记录 ({{ props.row.raw_material_name }})</h4>
|
||||||
|
<el-table :data="props.row.stock_logs" border v-loading="props.row.stock_log_loading">
|
||||||
|
<el-table-column prop="happened_at" label="操作时间" width="180">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ formatRFC3339(scope.row.happened_at) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="source_type" label="操作类型" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ getStockLogSourceTypeLabel(scope.row.source_type) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="change_amount" label="变动数量" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ formatChangeAmount(scope.row.change_amount) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="before_quantity" label="变动前库存" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ formatWeight(scope.row.before_quantity) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="after_quantity" label="变动后库存" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ formatWeight(scope.row.after_quantity) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="remarks" label="备注"></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination
|
||||||
|
v-if="props.row.stock_log_pagination && props.row.stock_log_pagination.total > 0"
|
||||||
|
style="margin-top: 20px;"
|
||||||
|
:current-page="props.row.stock_log_pagination.page"
|
||||||
|
:page-size="props.row.stock_log_pagination.page_size"
|
||||||
|
:total="props.row.stock_log_pagination.total"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@size-change="(size) => handleStockLogSizeChange(props.row, size)"
|
||||||
|
@current-change="(page) => handleStockLogCurrentChange(props.row, page)"
|
||||||
|
></el-pagination>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column prop="raw_material_name" label="原料名称"></el-table-column>
|
<el-table-column prop="raw_material_name" label="原料名称"></el-table-column>
|
||||||
<el-table-column prop="stock" label="当前库存">
|
<el-table-column prop="stock" label="当前库存">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
@@ -36,10 +88,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, onMounted, watch } from 'vue';
|
import { ref, onMounted, watch, nextTick } from 'vue';
|
||||||
import { InventoryApi } from '../../api/inventory';
|
import { InventoryApi } from '../../api/inventory';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import { formatRFC3339, formatWeight } from '../../utils/format';
|
import { formatRFC3339, formatWeight, formatChangeAmount } from '../../utils/format'; // 导入 formatChangeAmount
|
||||||
import { getStockLogSourceTypeLabel } from '../../enums'; // 导入 getStockLogSourceTypeLabel
|
import { getStockLogSourceTypeLabel } from '../../enums'; // 导入 getStockLogSourceTypeLabel
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -64,6 +116,9 @@ export default {
|
|||||||
total: 0,
|
total: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// el-table 的引用,用于控制行的展开/折叠
|
||||||
|
const mainTable = ref(null);
|
||||||
|
|
||||||
const fetchStockList = async (filter = props.stockFilter, rawMaterialName = props.searchRawMaterialName) => {
|
const fetchStockList = async (filter = props.stockFilter, rawMaterialName = props.searchRawMaterialName) => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
@@ -78,7 +133,17 @@ export default {
|
|||||||
params.raw_material_name = rawMaterialName;
|
params.raw_material_name = rawMaterialName;
|
||||||
}
|
}
|
||||||
const res = await InventoryApi.getCurrentStockList(params);
|
const res = await InventoryApi.getCurrentStockList(params);
|
||||||
stockList.value = res.data.list;
|
// 初始化 stock_logs 和 stock_log_pagination
|
||||||
|
stockList.value = res.data.list.map(item => ({
|
||||||
|
...item,
|
||||||
|
stock_logs: [], // 存储历史操作记录
|
||||||
|
stock_log_loading: false, // 历史操作记录的加载状态
|
||||||
|
stock_log_pagination: { // 历史操作记录的分页信息
|
||||||
|
page: 1,
|
||||||
|
page_size: 10,
|
||||||
|
total: 0,
|
||||||
|
},
|
||||||
|
}));
|
||||||
pagination.value.total = res.data.pagination.total;
|
pagination.value.total = res.data.pagination.total;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('获取库存列表失败');
|
ElMessage.error('获取库存列表失败');
|
||||||
@@ -102,6 +167,78 @@ export default {
|
|||||||
emit('adjust-stock', row); // 只传递行数据
|
emit('adjust-stock', row); // 只传递行数据
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理行展开/折叠事件
|
||||||
|
* @param {object} row - 当前行数据
|
||||||
|
* @param {Array<object>} expandedRows - 所有已展开的行数据
|
||||||
|
*/
|
||||||
|
const handleExpandChange = async (row, expandedRows) => {
|
||||||
|
const isExpanded = expandedRows.some(r => r.raw_material_id === row.raw_material_id);
|
||||||
|
// 仅在展开时且数据未加载时才请求
|
||||||
|
if (isExpanded) {
|
||||||
|
// 确保每次展开都重新加载第一页数据,或者根据当前分页状态加载
|
||||||
|
// 如果是第一次展开,或者用户手动切换了分页,则需要重新获取
|
||||||
|
await fetchStockLogs(row);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定原料的历史操作记录
|
||||||
|
* @param {object} row - 当前原料行数据
|
||||||
|
*/
|
||||||
|
const fetchStockLogs = async (row) => {
|
||||||
|
row.stock_log_loading = true;
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
raw_material_id: row.raw_material_id,
|
||||||
|
page: row.stock_log_pagination.page,
|
||||||
|
page_size: row.stock_log_pagination.page_size,
|
||||||
|
order_by: 'happened_at DESC', // 按时间倒序
|
||||||
|
};
|
||||||
|
const res = await InventoryApi.getStockLogList(params);
|
||||||
|
if (res.data) {
|
||||||
|
row.stock_logs = res.data.list;
|
||||||
|
row.stock_log_pagination.total = res.data.pagination.total;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取库存历史操作记录失败:', error);
|
||||||
|
ElMessage.error('获取库存历史操作记录失败');
|
||||||
|
} finally {
|
||||||
|
row.stock_log_loading = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理历史操作记录分页的每页大小变化
|
||||||
|
* @param {object} row - 当前原料行数据
|
||||||
|
* @param {number} size - 新的每页大小
|
||||||
|
*/
|
||||||
|
const handleStockLogSizeChange = async (row, size) => {
|
||||||
|
row.stock_log_pagination.page_size = size;
|
||||||
|
row.stock_log_pagination.page = 1; // 重置页码到第一页
|
||||||
|
await fetchStockLogs(row);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理历史操作记录分页的当前页码变化
|
||||||
|
* @param {object} row - 当前原料行数据
|
||||||
|
* @param {number} page - 新的页码
|
||||||
|
*/
|
||||||
|
const handleStockLogCurrentChange = async (row, page) => {
|
||||||
|
row.stock_log_pagination.page = page;
|
||||||
|
await fetchStockLogs(row);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理行点击事件,用于切换行的展开状态
|
||||||
|
const handleRowClick = (row, column) => {
|
||||||
|
// 如果点击的是操作列,则不执行任何操作
|
||||||
|
if (column && column.label === '操作') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 否则,切换行的展开状态
|
||||||
|
mainTable.value.toggleRowExpansion(row);
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchStockList();
|
fetchStockList();
|
||||||
});
|
});
|
||||||
@@ -125,12 +262,18 @@ export default {
|
|||||||
stockList,
|
stockList,
|
||||||
loading,
|
loading,
|
||||||
pagination,
|
pagination,
|
||||||
|
mainTable, // 暴露 mainTable ref
|
||||||
handleSizeChange,
|
handleSizeChange,
|
||||||
handleCurrentChange,
|
handleCurrentChange,
|
||||||
formatRFC3339,
|
formatRFC3339,
|
||||||
formatWeight,
|
formatWeight,
|
||||||
|
formatChangeAmount, // 暴露 formatChangeAmount
|
||||||
handleAdjust,
|
handleAdjust,
|
||||||
getStockLogSourceTypeLabel, // 暴露辅助函数给模板
|
getStockLogSourceTypeLabel,
|
||||||
|
handleExpandChange,
|
||||||
|
handleStockLogSizeChange,
|
||||||
|
handleStockLogCurrentChange,
|
||||||
|
handleRowClick,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -34,5 +34,25 @@ export function formatWeight(grams) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化库存变动数量,显示正负号和单位 (kg 或 g)
|
||||||
|
* @param {number} changeAmount - 变动数量,单位为克 (正数入库,负数出库)
|
||||||
|
* @returns {string} - 格式化后的变动数量字符串 (例如 "+1.5 kg", "-500 g")
|
||||||
|
*/
|
||||||
|
export function formatChangeAmount(changeAmount) {
|
||||||
|
if (typeof changeAmount !== 'number' || isNaN(changeAmount)) {
|
||||||
|
return '--';
|
||||||
|
}
|
||||||
|
|
||||||
|
const sign = changeAmount > 0 ? '+' : '';
|
||||||
|
const absoluteAmount = Math.abs(changeAmount);
|
||||||
|
|
||||||
|
if (absoluteAmount >= 1000) {
|
||||||
|
return sign + (absoluteAmount / 1000).toFixed(2) + ' kg';
|
||||||
|
} else {
|
||||||
|
return sign + absoluteAmount + ' g';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 你未来还可以添加其他全局格式化函数
|
// 你未来还可以添加其他全局格式化函数
|
||||||
// export function formatCurrency(number) { ... }
|
// export function formatCurrency(number) { ... }
|
||||||
Reference in New Issue
Block a user