Commit cc0a0402 by wangchunyang

出入库统计增加数量来源查询

parent 676587af
...@@ -18,3 +18,20 @@ export function exportInboundOutboundStatistics(query) { ...@@ -18,3 +18,20 @@ export function exportInboundOutboundStatistics(query) {
}) })
} }
// 查询出入库统计列表
export function listInboundDetails(query) {
return request({
url: '/inventory/statistics/listInboundDetails',
method: 'get',
params: query
})
}
// 查询出入库统计列表
export function listOutboundDetails(query) {
return request({
url: '/inventory/statistics/listOutboundDetails',
method: 'get',
params: query
})
}
...@@ -87,12 +87,30 @@ ...@@ -87,12 +87,30 @@
<el-table-column label="出库次数" align="center" prop="outboundCount" min-width="100" /> <el-table-column label="出库次数" align="center" prop="outboundCount" min-width="100" />
<el-table-column label="入库数量" align="center" prop="inboundQuantity" min-width="120"> <el-table-column label="入库数量" align="center" prop="inboundQuantity" min-width="120">
<template slot-scope="scope"> <template slot-scope="scope">
{{ formatNumber(scope.row.inboundQuantity) }} <span
v-if="Number(scope.row.inboundQuantity || 0) > 0"
class="link-number"
@click="openDetailDialog('inbound', scope.row)"
>
{{ formatNumber(scope.row.inboundQuantity) }}
</span>
<span v-else>
{{ formatNumber(scope.row.inboundQuantity) }}
</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="出库数量" align="center" prop="outboundQuantity" min-width="120"> <el-table-column label="出库数量" align="center" prop="outboundQuantity" min-width="120">
<template slot-scope="scope"> <template slot-scope="scope">
{{ formatNumber(scope.row.outboundQuantity) }} <span
v-if="Number(scope.row.outboundQuantity || 0) > 0"
class="link-number"
@click="openDetailDialog('outbound', scope.row)"
>
{{ formatNumber(scope.row.outboundQuantity) }}
</span>
<span v-else>
{{ formatNumber(scope.row.outboundQuantity) }}
</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="入库总额" align="center" prop="inboundAmount" min-width="120"> <el-table-column label="入库总额" align="center" prop="inboundAmount" min-width="120">
...@@ -136,11 +154,43 @@ ...@@ -136,11 +154,43 @@
:warehousesId="queryParams.warehouseId" :warehousesId="queryParams.warehouseId"
@selected="handleLocationSelected" @selected="handleLocationSelected"
/> />
<!-- 出入库明细弹窗 -->
<el-dialog
:title="detailTitle"
:visible.sync="detailDialogVisible"
width="800px"
append-to-body
:close-on-click-modal="false"
>
<el-table
v-loading="detailLoading"
:data="detailList"
border
style="width: 100%"
max-height="500"
>
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column label="物料名称" prop="materialName" align="center" min-width="180" />
<el-table-column :label="detailType === 'inbound' ? '入库单号' : '出库单号'" prop="orderId" align="center" min-width="100" />
<el-table-column label="批次号" prop="batchNo" align="center" min-width="100" />
<el-table-column :label="detailType === 'inbound' ? '入库数量' : '出库数量'" prop="quantity" align="center" min-width="100" />
<el-table-column label="当前库存数量" v-if="detailType === 'inbound'" prop="inventoryQuantity" align="center" min-width="120" />
</el-table>
<div slot="footer" class="dialog-footer">
<el-button @click="detailDialogVisible = false">关闭</el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { listInboundOutboundStatistics, exportInboundOutboundStatistics } from "@/api/inventory/inventory_statistics" import {
listInboundOutboundStatistics,
exportInboundOutboundStatistics,
listInboundDetails,
listOutboundDetails
} from "@/api/inventory/inventory_statistics"
import RightToolbar from "@/components/RightToolbar" import RightToolbar from "@/components/RightToolbar"
import PageTitle from "@/components/PageTitle" import PageTitle from "@/components/PageTitle"
import WarehouseSelector from "@/views/compononents/WarehouseSelector.vue" import WarehouseSelector from "@/views/compononents/WarehouseSelector.vue"
...@@ -181,7 +231,13 @@ export default { ...@@ -181,7 +231,13 @@ export default {
queryWarehouseName: null, queryWarehouseName: null,
// 库位选择相关 // 库位选择相关
locationSelectorVisible: false, locationSelectorVisible: false,
queryLocationName: null queryLocationName: null,
// 明细弹窗相关
detailDialogVisible: false,
detailLoading: false,
detailType: '',
detailTitle: '',
detailList: []
} }
}, },
created() { created() {
...@@ -269,6 +325,41 @@ export default { ...@@ -269,6 +325,41 @@ export default {
this.queryParams.locationId = null this.queryParams.locationId = null
this.handleQuery() this.handleQuery()
}, },
/** 打开明细弹窗 */
openDetailDialog(type, row) {
this.detailType = type
this.detailTitle = type === 'inbound'
? `入库明细 - ${row.materialName || ''}`
: `出库明细 - ${row.materialName || ''}`
this.detailDialogVisible = true
this.fetchDetailList(row)
},
/** 查询明细列表 */
fetchDetailList(row) {
this.detailLoading = true
const params = { ...this.queryParams }
// 处理时间范围
if (params.dateRange && params.dateRange.length === 2) {
params.startDate = params.dateRange[0]
params.endDate = params.dateRange[1]
}
delete params.dateRange
// 当前行物料ID
params.materialId = row.materialId
const api = this.detailType === 'inbound' ? listInboundDetails : listOutboundDetails
api(params)
.then(res => {
this.detailList = res.rows || []
this.detailLoading = false
})
.catch(() => {
this.detailLoading = false
})
},
/** 格式化金额,保留2位小数 */ /** 格式化金额,保留2位小数 */
formatAmount(amount) { formatAmount(amount) {
if (amount === null || amount === undefined || isNaN(amount)) { if (amount === null || amount === undefined || isNaN(amount)) {
...@@ -327,5 +418,15 @@ export default { ...@@ -327,5 +418,15 @@ export default {
.mb8 { .mb8 {
margin-bottom: 8px; margin-bottom: 8px;
} }
.link-number {
color: #409EFF;
cursor: pointer;
text-decoration: underline;
}
.link-number:hover {
color: #66b1ff;
}
</style> </style>
...@@ -54,7 +54,7 @@ spring: ...@@ -54,7 +54,7 @@ spring:
allow: allow:
url-pattern: /druid/* url-pattern: /druid/*
# 控制台管理用户名和密码 # 控制台管理用户名和密码
login-username: ruoyi login-username: inventory
login-password: 123456 login-password: 123456
filter: filter:
stat: stat:
......
...@@ -7,6 +7,9 @@ ruoyi: ...@@ -7,6 +7,9 @@ ruoyi:
# 版权年份 # 版权年份
copyrightYear: 2025 copyrightYear: 2025
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
# 生产
# profile: /home/springboot/uploadPath
# 测试
profile: D:/ruoyi/uploadPath profile: D:/ruoyi/uploadPath
# 获取ip地址开关 # 获取ip地址开关
addressEnabled: false addressEnabled: false
......
...@@ -6,6 +6,7 @@ import com.ruoyi.common.core.domain.AjaxResult; ...@@ -6,6 +6,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.inventory.domain.vo.InboundOutboundDetailVO;
import com.ruoyi.inventory.domain.vo.InboundOutboundStatisticsVO; import com.ruoyi.inventory.domain.vo.InboundOutboundStatisticsVO;
import com.ruoyi.inventory.service.IInventoryStatisticsService; import com.ruoyi.inventory.service.IInventoryStatisticsService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -50,5 +51,25 @@ public class InventoryStatisticsController extends BaseController { ...@@ -50,5 +51,25 @@ public class InventoryStatisticsController extends BaseController {
ExcelUtil<InboundOutboundStatisticsVO> util = new ExcelUtil<>(InboundOutboundStatisticsVO.class); ExcelUtil<InboundOutboundStatisticsVO> util = new ExcelUtil<>(InboundOutboundStatisticsVO.class);
util.exportExcel(response, list, "出入库统计数据"); util.exportExcel(response, list, "出入库统计数据");
} }
/**
* 出库统计明细
*/
@GetMapping("/listOutboundDetails")
public TableDataInfo listOutboundDetails(InboundOutboundStatisticsVO query) {
startPage();
List<InboundOutboundDetailVO> list = inventoryStatisticsService.selectInboundDetails(query);
return getDataTable(list);
}
/**
* 入库统计明细
*/
@GetMapping("/listInboundDetails")
public TableDataInfo listInboundDetails(InboundOutboundStatisticsVO query) {
startPage();
List<InboundOutboundDetailVO> list = inventoryStatisticsService.selectInboundDetails(query);
return getDataTable(list);
}
} }
package com.ruoyi.inventory.domain.vo;
import lombok.Data;
/**
* 出入库明细视图对象(用于统计详情弹窗)
*/
@Data
public class InboundOutboundDetailVO {
/** 物料ID */
private String materialId;
/** 物料名称 */
private String materialName;
/** 批次号(入库批次/出库批次) */
private String batchNo;
/** 单号 */
private String orderId;
/** 出入库数量 */
private Long quantity;
/** 当前库存数量 */
private Long inventoryQuantity;
}
package com.ruoyi.inventory.mapper; package com.ruoyi.inventory.mapper;
import com.ruoyi.inventory.domain.vo.InboundOutboundDetailVO;
import com.ruoyi.inventory.domain.vo.InboundOutboundStatisticsVO; import com.ruoyi.inventory.domain.vo.InboundOutboundStatisticsVO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
...@@ -18,5 +19,15 @@ public interface InventoryStatisticsMapper { ...@@ -18,5 +19,15 @@ public interface InventoryStatisticsMapper {
* @return 汇总结果 * @return 汇总结果
*/ */
List<InboundOutboundStatisticsVO> selectInboundOutboundStatistics(InboundOutboundStatisticsVO query); List<InboundOutboundStatisticsVO> selectInboundOutboundStatistics(InboundOutboundStatisticsVO query);
/**
* 入库明细(按物料+批次)
*/
List<InboundOutboundDetailVO> selectInboundDetails(InboundOutboundStatisticsVO query);
/**
* 出库明细(按物料+批次)
*/
List<InboundOutboundDetailVO> selectOutboundDetails(InboundOutboundStatisticsVO query);
} }
package com.ruoyi.inventory.service; package com.ruoyi.inventory.service;
import com.ruoyi.inventory.domain.vo.InboundOutboundDetailVO;
import com.ruoyi.inventory.domain.vo.InboundOutboundStatisticsVO; import com.ruoyi.inventory.domain.vo.InboundOutboundStatisticsVO;
import java.util.List; import java.util.List;
...@@ -16,5 +17,15 @@ public interface IInventoryStatisticsService { ...@@ -16,5 +17,15 @@ public interface IInventoryStatisticsService {
* @return 统计列表 * @return 统计列表
*/ */
List<InboundOutboundStatisticsVO> selectInboundOutboundStatistics(InboundOutboundStatisticsVO query); List<InboundOutboundStatisticsVO> selectInboundOutboundStatistics(InboundOutboundStatisticsVO query);
/**
* 入库明细
*/
List<InboundOutboundDetailVO> selectInboundDetails(InboundOutboundStatisticsVO query);
/**
* 出库明细
*/
List<InboundOutboundDetailVO> selectOutboundDetails(InboundOutboundStatisticsVO query);
} }
package com.ruoyi.inventory.service.impl; package com.ruoyi.inventory.service.impl;
import com.ruoyi.inventory.domain.vo.InboundOutboundDetailVO;
import com.ruoyi.inventory.domain.vo.InboundOutboundStatisticsVO; import com.ruoyi.inventory.domain.vo.InboundOutboundStatisticsVO;
import com.ruoyi.inventory.mapper.InventoryStatisticsMapper; import com.ruoyi.inventory.mapper.InventoryStatisticsMapper;
import com.ruoyi.inventory.service.IInventoryStatisticsService; import com.ruoyi.inventory.service.IInventoryStatisticsService;
...@@ -21,5 +22,15 @@ public class InventoryStatisticsServiceImpl implements IInventoryStatisticsServi ...@@ -21,5 +22,15 @@ public class InventoryStatisticsServiceImpl implements IInventoryStatisticsServi
public List<InboundOutboundStatisticsVO> selectInboundOutboundStatistics(InboundOutboundStatisticsVO query) { public List<InboundOutboundStatisticsVO> selectInboundOutboundStatistics(InboundOutboundStatisticsVO query) {
return inventoryStatisticsMapper.selectInboundOutboundStatistics(query); return inventoryStatisticsMapper.selectInboundOutboundStatistics(query);
} }
@Override
public List<InboundOutboundDetailVO> selectInboundDetails(InboundOutboundStatisticsVO query) {
return inventoryStatisticsMapper.selectInboundDetails(query);
}
@Override
public List<InboundOutboundDetailVO> selectOutboundDetails(InboundOutboundStatisticsVO query) {
return inventoryStatisticsMapper.selectOutboundDetails(query);
}
} }
...@@ -108,5 +108,91 @@ ...@@ -108,5 +108,91 @@
GROUP BY t.material_id, m.material_name GROUP BY t.material_id, m.material_name
ORDER BY m.material_name ASC ORDER BY m.material_name ASC
</select> </select>
<!-- 出入库统计相关明细-->
<resultMap id="InOutDetailVO" type="com.ruoyi.inventory.domain.vo.InboundOutboundDetailVO">
<result column="material_id" property="materialId"/>
<result column="material_name" property="materialName"/>
<result column="batchNo" property="batchNo"/>
<result column="order_id" property="orderId"/>
<result column="quantity" property="quantity"/>
<result column="inventoryQuantity" property="inventoryQuantity"/>
</resultMap>
<select id="selectInboundDetails"
parameterType="com.ruoyi.inventory.domain.vo.InboundOutboundStatisticsVO"
resultMap="InOutDetailVO">
SELECT
i.material_id,
m1.material_name,
o.order_id,
o.batch_id as batchNo,
i.actual_quantity as quantity,
i.location_id,
inv.quantity as inventoryQuantity
FROM inbound_order_items i
LEFT JOIN inbound_orders o ON i.inbound_order_id = o.id
LEFT JOIN materials m1 ON m1.id = i.material_id
LEFT JOIN warehouses w ON w.id = i.warehouse_id
LEFT JOIN inventory inv ON inv.material_id = i.material_id and inv.order_id=i.order_id and inv.batch_id=i.batch_id and i.location_id = inv.location_id
<where>
and i.is_used = 1
<if test="warehouseId != null and warehouseId != ''">
AND i.warehouse_id = #{warehouseId}
</if>
<if test="locationId != null and locationId != ''">
AND i.location_id = #{locationId}
</if>
<if test="materialId != null and materialId != ''">
AND i.material_id = #{materialId}
</if>
<if test="warehousesCode != null and warehousesCode != ''">
AND w.warehouses_code LIKE CONCAT('%', #{warehousesCode}, '%')
</if>
<if test="startDate != null">
AND o.inbound_date &gt;= #{startDate}
</if>
<if test="endDate != null">
AND o.inbound_date &lt; DATE_ADD(#{endDate}, INTERVAL 1 DAY)
</if>
</where>
order by o.inbound_date asc
</select>
<select id="selectOutboundDetails"
parameterType="com.ruoyi.inventory.domain.vo.InboundOutboundStatisticsVO"
resultMap="InOutDetailVO">
SELECT
i.material_id,
m1.material_name,
o.order_id,
o.batch_code as batchNo,
i.actual_quantity as quantity
FROM outbound_order_items i
LEFT JOIN outbound_orders o ON i.outbound_order_id = o.id
LEFT JOIN materials m1 ON m1.id = i.material_id
LEFT JOIN warehouses w ON w.id = i.warehouse_id
<where>
i.is_used = 1
<if test="warehouseId != null and warehouseId != ''">
AND i.warehouse_id = #{warehouseId}
</if>
<if test="locationId != null and locationId != ''">
AND i.location_id = #{locationId}
</if>
<if test="materialId != null and materialId != ''">
AND i.material_id = #{materialId}
</if>
<if test="warehousesCode != null and warehousesCode != ''">
AND w.warehouses_code LIKE CONCAT('%', #{warehousesCode}, '%')
</if>
<if test="startDate != null">
AND o.inbound_date &gt;= #{startDate}
</if>
<if test="endDate != null">
AND o.inbound_date &lt; DATE_ADD(#{endDate}, INTERVAL 1 DAY)
</if>
</where>
order by i.shipped_at asc
</select>
</mapper> </mapper>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论