Commit 563b3de0 by zhangtw

统计页面优化

parent 45790555
......@@ -39,8 +39,6 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="仓库" prop="warehouseId">
<el-input
v-model="queryWarehouseName"
......@@ -75,16 +73,6 @@
</template>
</el-input>
</el-form-item>
<!-- <el-form-item label="标签颜色" prop="labelColor">
<el-select v-model="queryParams.labelColor" placeholder="请选择标签颜色" clearable>
<el-option
v-for="dict in dict.type.label_color"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item> -->
</page-wrapper-search>
<!-- 表格区域 -->
......@@ -104,9 +92,10 @@
<el-table-column label="危险类别" align="center" prop="hazardId" width="120">
<template slot-scope="scope">
<el-tag
:type="getDictListClass('danger_type',scope.row.hazardId)"
size="small">
{{ getDictLabel('danger_type',scope.row.hazardId) }}
:type="getDictTagType('danger_type', scope.row.hazardId)"
size="small"
>
{{ getDictLabel('danger_type', scope.row.hazardId) }}
</el-tag>
</template>
</el-table-column>
......@@ -114,14 +103,14 @@
<el-table-column label="计量单位" align="center" prop="materialUnit" width="120" />
<el-table-column label="单位重量" align="center" prop="unitWeight" width="120" >
<template slot-scope="scope">
{{ formatAmount(scope.row.unitWeight || 0) }}
{{ formatNumber(scope.row.unitWeight) }}
</template>
</el-table-column>
<el-table-column label="计划数量" align="center" prop="plannedQuantity" width="100" />
<el-table-column label="实际数量" align="center" prop="actualQuantity" width="100" />
<el-table-column label="总额" align="center" prop="totalPrice" width="100" >
<template slot-scope="scope">
{{ formatAmount(scope.row.totalPrice || 0) }}
{{ formatNumber(scope.row.totalPrice) }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="100" fixed="right">
......@@ -136,19 +125,27 @@
</el-table-column>
</el-table>
</div>
<!-- 详情弹窗 -->
<el-dialog
title="出库物料详情"
v-model="detailDialogVisible"
:visible.sync="detailDialogVisible"
width="1400px"
append-to-body
:close-on-click-modal="false"
>
<el-form :model="detailQueryParams" ref="detailQueryForm" size="small" :inline="true" label-width="100px" style="margin-bottom: 15px;">
<el-form
:model="detailQueryParams"
ref="detailQueryForm"
size="small"
inline
label-width="100px"
class="detail-search-form"
>
<el-form-item label="入库日期" prop="inboundDateRange">
<el-date-picker
v-model="inboundDateRange"
v-model="detailDateRange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
......@@ -160,48 +157,48 @@
</el-form-item>
<el-form-item label="关联入库单号" prop="orderId">
<el-input
v-model="queryParams.orderId"
v-model="detailQueryParams.orderId"
placeholder="请输入入库单号"
clearable
/>
</el-form-item>
<el-form-item label="批次" prop="batchId">
<el-input
v-model="queryParams.batchId"
v-model="detailQueryParams.batchId"
placeholder="请输入批次"
clearable
/>
</el-form-item>
<el-form-item label="仓库" prop="warehouseId">
<el-input
v-model="queryWarehouseName"
v-model="detailWarehouseName"
placeholder="请选择仓库"
readonly
@focus="openWarehouseSelector"
@focus="openDetailWarehouseSelector"
:suffix-icon="''"
>
<template v-if="queryWarehouseName" #suffix>
<template v-if="detailWarehouseName" #suffix>
<i
class="el-icon-circle-close el-input__icon"
style="cursor: pointer;"
@click.stop="clearQueryWarehouse"
@click.stop="clearDetailWarehouse"
></i>
</template>
</el-input>
</el-form-item>
<el-form-item label="库位" prop="locationId">
<el-input
v-model="queryLocationName"
v-model="detailLocationName"
placeholder="请选择库位"
readonly
@focus="openLocationSelector"
@focus="openDetailLocationSelector"
:suffix-icon="''"
>
<template v-if="queryLocationName" #suffix>
<template v-if="detailLocationName" #suffix>
<i
class="el-icon-circle-close el-input__icon"
style="cursor: pointer;"
@click.stop="clearQueryLocation"
@click.stop="clearDetailLocation"
></i>
</template>
</el-input>
......@@ -211,7 +208,8 @@
<el-button icon="el-icon-refresh" size="mini" @click="resetDetailQuery">重置</el-button>
</el-form-item>
</el-form>
<div style="max-height: 600px; overflow: auto;">
<div class="detail-table-container">
<el-table
v-loading="detailLoading"
:data="detailList"
......@@ -220,7 +218,7 @@
>
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column label="物料名称" align="center" prop="materialName" min-width="150" show-overflow-tooltip />
<el-table-column label="关联订单号" align="center" prop="orderId" width="150" />
<el-table-column label="关联入库单号" align="center" prop="orderId" width="180" />
<el-table-column label="批次" align="center" prop="batchId" width="120" />
<el-table-column label="仓库" align="center" prop="warehousesName" width="120" />
<el-table-column label="库位" align="center" prop="locationName" width="120" />
......@@ -228,54 +226,63 @@
<el-table-column label="实际数量" align="center" prop="actualQuantity" width="100" />
<el-table-column label="入库日期" align="center" prop="inboundDate" width="120">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.inboundDate,'{y}-{m}-{d}') }}</span>
{{ parseTime(scope.row.inboundDate, '{y}-{m}-{d}') }}
</template>
</el-table-column>
<el-table-column label="单价" align="center" prop="unitPrice" width="100">
<template slot-scope="scope">
{{ formatAmount(scope.row.unitPrice || 0) }}
{{ formatNumber(scope.row.unitPrice) }}
</template>
</el-table-column>
<el-table-column label="金额" align="center" prop="totalPrice" width="120">
<template slot-scope="scope">
{{ formatAmount(scope.row.totalPrice || (scope.row.actualQuantity || 0) * (scope.row.unitPrice || 0)) }}
{{ formatNumber((scope.row.actualQuantity || 0) * (scope.row.unitPrice || 0)) }}
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" min-width="150" show-overflow-tooltip />
</el-table>
</div>
<pagination
v-show="detailTotal > 0"
:total="detailTotal"
:page.sync="detailQueryParams.pageNum"
:limit.sync="detailQueryParams.pageSize"
@pagination="getDetailList"
style="margin-top: 15px;"
class="detail-pagination"
/>
<div slot="footer" class="dialog-footer">
<el-button @click="detailDialogVisible = false"> </el-button>
</div>
</el-dialog>
<!-- 分页组件 -->
<pagination
v-show="total>0"
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 仓库选择组件 -->
<!-- 仓库/库位选择组件 -->
<WarehouseSelector
v-model="warehouseSelectorVisible"
@selected="handleWarehouseSelected"
/>
<!-- 库位选择组件 -->
<LocationSelector
v-model="locationSelectorVisible"
@selected="handleLocationSelected"
/>
<WarehouseSelector
v-model="detailWarehouseSelectorVisible"
@selected="handleDetailWarehouseSelected"
/>
<LocationSelector
v-model="detailLocationSelectorVisible"
@selected="handleDetailLocationSelected"
/>
</div>
</div>
</template>
......@@ -289,7 +296,7 @@ import LocationSelector from "@/views/compononents/LocationSelector.vue"
export default {
name: "InboundDetails",
dicts: ['label_color','danger_type'],
dicts: ['label_color', 'danger_type'],
components: {
PageTitle,
PageWrapperSearch,
......@@ -298,246 +305,315 @@ export default {
},
data() {
return {
// 入库日期选择数组
inboundDateRange: null,
// 仓库选择相关
// 主页面状态
loading: true,
total: 0,
inboundList: [],
warehouseSelectorVisible: false,
queryWarehouseName: null,
// 库位选择相关
locationSelectorVisible: false,
queryLocationName: null,
// 遮罩层
loading: true,
queryWarehouseName: '',
queryLocationName: '',
// 详情弹窗状态
detailDialogVisible: false,
detailLoading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
detailTotal: 0,
// 入库表格数据
inboundList: [],
// 查询参数
detailList: [],
detailWarehouseSelectorVisible: false,
detailLocationSelectorVisible: false,
detailWarehouseName: '',
detailLocationName: '',
detailDateRange: null, // 独立的详情日期范围,避免和主页面冲突
// 查询参数(规范化命名 + 初始值统一)
queryParams: {
pageNum: 1,
pageSize: 10,
sapNo: null,
materialName: null,
warehouseId: null,
locationId: null,
labelColor: null,
sapNo: '',
materialName: '',
warehouseId: '',
locationId: '',
labelColor: '',
inboundDateStart: '',
inboundDateEnd: ''
},
detailDialogVisible: false,
detailList: [],
detailQueryParams: {
pageNum: 1,
pageSize: 10,
orderId: null,
materialId: null,
warehouseId: null,
locationId: null,
batchId: null,
inboundDateStart: null,
inboundDateEnd: null
materialId: '',
orderId: '',
batchId: '',
warehouseId: '',
locationId: '',
inboundDateStart: '',
inboundDateEnd: ''
},
// 多选相关(仅声明必要变量)
ids: [],
single: true,
multiple: true
}
},
created() {
this.getList()
},
methods: {
// 封装字典取值方法
/**
* 获取字典标签(通用方法)
* @param {string} dictType 字典类型
* @param {*} value 字典值
* @returns {string} 字典标签
*/
getDictLabel(dictType, value) {
if (!value || !this.dict?.type?.[dictType]) return '-';
const dictItem = this.dict.type[dictType].find(item => item.value === value);
return dictItem?.label || '-';
},
getDictListClass(dictType, value) {
if (!value || !this.dict?.type?.[dictType]) return '-';
/**
* 获取字典标签样式(语义化命名)
* @param {string} dictType 字典类型
* @param {*} value 字典值
* @returns {string} 样式类名
*/
getDictTagType(dictType, value) {
if (!value || !this.dict?.type?.[dictType]) return '';
const dictItem = this.dict.type[dictType].find(item => item.value === value);
return dictItem?.raw?.listClass || '';
},
/** 查询入库列表 */
getList() {
this.loading = true
inbound_details(this.queryParams).then(response => {
this.inboundList = response.rows
this.total = response.total
this.loading = false
}).catch(() => {
this.loading = false
})
/**
* 数字格式化(通用方法,替代原formatAmount)
* @param {number} num 待格式化数字
* @returns {string} 保留两位小数的字符串
*/
formatNumber(num) {
const number = Number(num);
return isNaN(number) ? '0.00' : number.toFixed(2);
},
/**
* 查询主列表数据
*/
async getList() {
try {
this.loading = true;
const response = await inbound_details(this.queryParams);
this.inboundList = response.rows || [];
this.total = response.total || 0;
} catch (error) {
this.$message.error('查询入库列表失败:' + error.message);
} finally {
this.loading = false;
}
},
/** 搜索按钮操作 */
/**
* 主页面搜索
*/
handleQuery() {
this.queryParams.pageNum = 1
if (Array.isArray(this.inboundDateRange) && this.inboundDateRange.length === 2) {
this.queryParams.inboundDateStart = this.inboundDateRange[0];
this.queryParams.inboundDateEnd = this.inboundDateRange[1];
this.queryParams.pageNum = 1;
// 处理日期范围(原代码错误绑定到全局inboundDateRange,已修正)
if (Array.isArray(this.detailDateRange) && this.detailDateRange.length === 2) {
this.queryParams.inboundDateStart = this.detailDateRange[0];
this.queryParams.inboundDateEnd = this.detailDateRange[1];
} else {
// 清空开始/结束日期(避免残留旧值)
this.queryParams.inboundDateStart = "";
this.queryParams.inboundDateEnd = "";
this.queryParams.inboundDateStart = '';
this.queryParams.inboundDateEnd = '';
}
this.getList()
this.getList();
},
/** 重置按钮操作 */
/**
* 重置主页面查询条件
*/
resetQuery() {
this.queryParams = {
pageNum: 1,
pageSize: 10,
sapNo: null,
materialName: null,
orderId: null,
batchId: null,
warehouseId: null,
locationId: null,
labelColor: null,
inboundDateStart: null,
inboundDateStart: null
}
this.queryWarehouseName = null
this.queryLocationName = null
this.inboundDateRange = null
this.handleQuery()
sapNo: '',
materialName: '',
warehouseId: '',
locationId: '',
labelColor: '',
inboundDateStart: '',
inboundDateEnd: ''
};
this.queryWarehouseName = '';
this.queryLocationName = '';
this.detailDateRange = null;
this.getList();
},
/**
* 打开详情弹窗
* @param {object} row 选中的行数据
*/
handleViewDetail(row) {
this.currentDetailRow = row
this.detailDialogVisible = true
this.detailDialogVisible = true;
// 初始化详情查询参数
this.detailQueryParams = {
pageNum: 1,
pageSize: 10,
orderId: null,
materialId: row.materialId,
warehouseId: null,
warehousesCode: null,
locationId: null,
batchId: null,
inboundDateStart: null,
inboundDateStart: null
}
this.detailWarehouseName = null
this.detailLocationName = null
this.detailList = []
this.detailTotal = 0
this.getDetailList()
orderId: '',
batchId: '',
warehouseId: this.queryParams.warehouseId, // 继承主页面仓库筛选
locationId: this.queryParams.locationId, // 继承主页面库位筛选
inboundDateStart: '',
inboundDateEnd: ''
};
this.detailWarehouseName = this.queryWarehouseName;
this.detailLocationName = this.queryLocationName;
this.detailDateRange = null;
this.getDetailList();
},
getDetailList() {
this.detailLoading = true
const params = { ...this.detailQueryParams }
params.warehouseId = params.warehouseId || this.queryParams.warehouseId
params.locationId = params.locationId || this.queryParams.locationId
details_information(params).then(response => {
this.detailList = response.rows || []
this.detailTotal = response.total || 0
this.detailLoading = false
}).catch(() => {
this.detailLoading = false
})
/**
* 查询详情列表数据
*/
async getDetailList() {
try {
this.detailLoading = true;
// 处理详情日期范围
if (Array.isArray(this.detailDateRange) && this.detailDateRange.length === 2) {
this.detailQueryParams.inboundDateStart = this.detailDateRange[0];
this.detailQueryParams.inboundDateEnd = this.detailDateRange[1];
}
const response = await details_information(this.detailQueryParams);
this.detailList = response.rows || [];
this.detailTotal = response.total || 0;
} catch (error) {
this.$message.error('查询物料详情失败:' + error.message);
} finally {
this.detailLoading = false;
}
},
/**
* 详情弹窗搜索
*/
handleDetailQuery() {
this.detailQueryParams.pageNum = 1
this.getDetailList()
this.detailQueryParams.pageNum = 1;
this.getDetailList();
},
/**
* 重置详情弹窗查询条件
*/
resetDetailQuery() {
const materialId = this.detailQueryParams.materialId; // 保留物料ID
this.detailQueryParams = {
pageNum: 1,
pageSize: 10,
orderId: null,
materialId: row.materialId,
warehouseId: null,
locationId: null,
batchId: null,
inboundDateStart: null,
inboundDateStart: null
}
this.inboundDateRange = null
this.detailQueryParams.pageNum = 1
this.getDetailList()
},
formatAmount(amount) {
if (amount === null || amount === undefined || isNaN(amount)) {
return '0.00'
}
return parseFloat(amount).toFixed(2)
materialId,
orderId: '',
batchId: '',
warehouseId: '',
locationId: '',
inboundDateStart: '',
inboundDateEnd: ''
};
this.detailDateRange = null;
this.detailWarehouseName = '';
this.detailLocationName = '';
this.getDetailList();
},
/** 多选框选中数据 */
/**
* 多选框选中事件
* @param {array} selection 选中的行
*/
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
this.ids = selection.map(item => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 打开仓库选择器 */
// ========== 仓库/库位选择器相关方法(通用封装) ==========
openWarehouseSelector() {
this.warehouseSelectorVisible = true
this.warehouseSelectorVisible = true;
},
/** 仓库选择回调 */
handleWarehouseSelected(warehouse) {
if (!warehouse) return
this.queryParams.warehouseId = warehouse.warehouseId
this.queryWarehouseName = warehouse.warehousesName || warehouse.warehousesCode
// 仓库选择后,清空库位信息
// this.queryLocationName = null
// this.queryParams.locationId = null
this.handleQuery()
if (!warehouse) return;
this.queryParams.warehouseId = warehouse.warehouseId;
this.queryWarehouseName = warehouse.warehousesName || warehouse.warehousesCode;
this.handleQuery();
},
/** 清空仓库选择 */
clearQueryWarehouse() {
this.queryWarehouseName = null
this.queryParams.warehouseId = null
// 清空仓库时,同时清空库位
// this.queryLocationName = null
// this.queryParams.locationId = null
this.handleQuery()
this.queryWarehouseName = '';
this.queryParams.warehouseId = '';
this.handleQuery();
},
/** 打开库位选择器 */
openLocationSelector() {
// if (!this.queryParams.warehouseId) {
// this.$message.warning("请先选择仓库")
// return
// }
this.locationSelectorVisible = true
this.locationSelectorVisible = true;
},
/** 库位选择回调 */
handleLocationSelected(location) {
if (!location) return
this.queryParams.locationId = location.locationId || location.id
this.queryLocationName = location.locationName || location.locationCode
this.handleQuery()
if (!location) return;
this.queryParams.locationId = location.locationId || location.id;
this.queryLocationName = location.locationName || location.locationCode;
this.handleQuery();
},
/** 清空库位选择 */
clearQueryLocation() {
this.queryLocationName = null
this.queryParams.locationId = null
this.handleQuery()
this.queryLocationName = '';
this.queryParams.locationId = '';
this.handleQuery();
},
openDetailWarehouseSelector() {
this.detailWarehouseSelectorVisible = true;
},
handleDetailWarehouseSelected(warehouse) {
if (!warehouse) return;
this.detailQueryParams.warehouseId = warehouse.warehouseId;
this.detailWarehouseName = warehouse.warehousesName || warehouse.warehousesCode;
this.detailLocationName = '';
this.detailQueryParams.locationId = '';
},
clearDetailWarehouse() {
this.detailWarehouseName = '';
this.detailQueryParams.warehouseId = '';
this.detailLocationName = '';
this.detailQueryParams.locationId = '';
},
openDetailLocationSelector() {
this.detailLocationSelectorVisible = true;
},
handleDetailLocationSelected(location) {
if (!location) return;
this.detailQueryParams.locationId = location.locationId || location.id;
this.detailLocationName = location.locationName || location.locationCode;
},
clearDetailLocation() {
this.detailLocationName = '';
this.detailQueryParams.locationId = '';
},
/** 导出按钮操作 */
/**
* 导出数据
*/
handleExport() {
this.download('/inventory/inbound_items/exportDetails', {
...this.queryParams
}, `inbound_${new Date().getTime()}.xlsx`)
this.download(
'/inventory/inbound_items/exportDetails',
{ ...this.queryParams },
`inbound_details_${new Date().getTime()}.xlsx`
);
}
}
}
</script>
<style scoped>
/* 核心样式保留,冗余样式删除 */
.page-container {
padding: 16px;
background: #fff;
......@@ -548,4 +624,25 @@ export default {
.table-container {
margin-top: 16px;
}
/* 详情弹窗样式优化 */
.detail-search-form {
margin-bottom: 16px;
}
.detail-table-container {
max-height: 600px;
overflow: auto;
margin-bottom: 16px;
}
.detail-pagination {
margin-top: 10px;
text-align: right;
}
/* 修复弹窗内分页样式 */
:deep(.el-pagination) {
margin-top: 10px;
}
</style>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论