Commit 5a9423a2 by zhangtw

入库明细统计修改

parent b5531cfe
...@@ -51,9 +51,10 @@ export function delInbound_items(id) { ...@@ -51,9 +51,10 @@ export function delInbound_items(id) {
} }
// 统计入库单明细 // 统计入库单明细
export function inbound_details(){ export function inbound_details(query){
return request({ return request({
url: '/inventory/inbound_items/details', url: '/inventory/inbound_items/details',
method: 'get' method: 'get',
params: query
}) })
} }
...@@ -23,9 +23,9 @@ ...@@ -23,9 +23,9 @@
@search="handleQuery" @search="handleQuery"
@reset="resetQuery" @reset="resetQuery"
> >
<el-form-item label="物料SAPNO" prop="sapNo"> <el-form-item label="物料SAPNO" prop="materialId">
<el-input <el-input
v-model="queryParams.sapNo" v-model="queryParams.materialId"
placeholder="请输入物料SAPNO" placeholder="请输入物料SAPNO"
clearable clearable
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
...@@ -56,39 +56,48 @@ ...@@ -56,39 +56,48 @@
/> />
</el-form-item> </el-form-item>
<el-form-item label="所在仓库" prop="warehouseId"> <el-form-item label="仓库" prop="warehouseId">
<el-select v-model="queryParams.warehouseId" placeholder="请选择仓库" clearable <el-input
@change="handleQuery" v-model="queryWarehouseName"
filterable placeholder="请选择仓库"
> readonly
<el-option @focus="openWarehouseSelector"
v-for="item in warehouseOptions" :suffix-icon="''"
:key="item.value" >
:label="item.label" <template v-if="queryWarehouseName" #suffix>
:value="item.value" <i
/> class="el-icon-circle-close el-input__icon"
</el-select> style="cursor: pointer;"
</el-form-item> @click.stop="clearQueryWarehouse"
></i>
<!-- 库位ID下拉框:修正数据源 + 唯一key --> </template>
<el-form-item label="库位ID" prop="locationId"> </el-input>
<el-select v-model="queryParams.locationId" placeholder="请选择库位ID" clearable> </el-form-item>
<!-- 替换为库位专属数据源(需补充 locationOptions 定义) --> <el-form-item label="库位" prop="locationId">
<el-option <el-input
v-for="item in locationOptions" v-model="queryLocationName"
:key="item.locationId" placeholder="请选择库位"
:label="item.locationName" readonly
:value="item.locationId" @focus="openLocationSelector"
/> :suffix-icon="''"
</el-select> :disabled="!queryParams.warehouseId"
</el-form-item> >
<template v-if="queryLocationName" #suffix>
<i
class="el-icon-circle-close el-input__icon"
style="cursor: pointer;"
@click.stop="clearQueryLocation"
></i>
</template>
</el-input>
</el-form-item>
<el-form-item label="标签颜色" prop="labelColor"> <el-form-item label="标签颜色" prop="labelColor">
<el-select v-model="queryParams.locationId" placeholder="请选择标签颜色" clearable> <el-select v-model="queryParams.labelColor" placeholder="请选择标签颜色" clearable>
<el-option <el-option
v-for="item in orderTypeOptions" v-for="dict in dict.type.label_color"
:key="item.orderType" :key="dict.value"
:label="item.orderTypeName" :label="dict.label"
:value="item.orderType" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
...@@ -113,11 +122,20 @@ ...@@ -113,11 +122,20 @@
<el-table-column label="件数" align="center" prop="actualPackages" width="200"/> <el-table-column label="件数" align="center" prop="actualPackages" width="200"/>
<el-table-column label="单价" align="center" prop="unitPrice" width="200"/> <el-table-column label="单价" align="center" prop="unitPrice" width="200"/>
<el-table-column label="入库批次物料总价" align="center" prop="totalPrice" width="200"/> <el-table-column label="入库批次物料总价" align="center" prop="totalPrice" width="200"/>
<el-table-column label="标签颜色" align="center" prop="labelColor" width="200"/> <el-table-column label="标签颜色" align="center" prop="labelColor" width="200">
<template slot-scope="scope">
<el-tag
:type="getDictListClass('label_color', scope.row.labelColor)"
size="small"
>
{{ getDictLabel('label_color', scope.row.labelColor) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" width="200"/> <el-table-column label="备注" align="center" prop="remark" width="200"/>
<el-table-column label="入库时间" align="center" prop="inboundDate" width="200"> <el-table-column label="入库时间" align="center" prop="inboundDate" width="200">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.inboundDate) }}</span> <span>{{ parseTime(scope.row.inboundDate, '{y}-{m}-{d}') }}</span>
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column <!-- <el-table-column
...@@ -148,6 +166,17 @@ ...@@ -148,6 +166,17 @@
:limit.sync="queryParams.pageSize" :limit.sync="queryParams.pageSize"
@pagination="getList" @pagination="getList"
/> />
<!-- 仓库选择组件 -->
<WarehouseSelector
v-model="warehouseSelectorVisible"
@selected="handleWarehouseSelected"
/>
<!-- 库位选择组件 -->
<LocationSelector
v-model="locationSelectorVisible"
:warehousesId="queryParams.warehouseId"
@selected="handleLocationSelected"
/>
</div> </div>
<!-- 入库单详情弹窗 --> <!-- 入库单详情弹窗 -->
...@@ -214,34 +243,39 @@ import InboundItems from "@/views/inventory/inbound_items/index.vue" ...@@ -214,34 +243,39 @@ import InboundItems from "@/views/inventory/inbound_items/index.vue"
import PageTitle from "@/components/PageTitle" // 引入字典页面的标题组件 import PageTitle from "@/components/PageTitle" // 引入字典页面的标题组件
import PageWrapperSearch from "@/components/Search/PageWrapperSearch" // 引入搜索包装组件 import PageWrapperSearch from "@/components/Search/PageWrapperSearch" // 引入搜索包装组件
import { listWarehouses } from "@/api/inventory/warehouses" import { listWarehouses } from "@/api/inventory/warehouses"
import WarehouseSelector from "@/views/compononents/WarehouseSelector.vue"
import LocationSelector from "@/views/compononents/LocationSelector.vue"
export default { export default {
name: "Inbound", name: "Inbound",
dicts: ['label_color'],
filters: {
dictFilter(value, dictType) {
if (!value || !this.dict[dictType]) return '-';
return this.dict.type[dictType][value] || '-';
}
},
components: { components: {
InboundItems, InboundItems,
PageTitle, PageTitle,
PageWrapperSearch PageWrapperSearch,
WarehouseSelector,
LocationSelector
}, },
data() { data() {
return { return {
inBoundTypeOptions: [ labelColorOptions: [],
{ orderTypeId: '1', orderTypeName: '入库类型1' },
{ orderTypeId: '2', orderTypeName: '入库类型2' }
],
inBoundStatusOptions: [
{ orderStatus: 1, orderStatusName: '草稿', type: 'info' },
{ orderStatus: 2, orderStatusName: '已完成', type: 'success' },
{ orderStatus: 3, orderStatusName: '已取消', type: 'danger' }
],
orderTypeOptions: [
{ orderType: '1', orderTypeName: '订单类型1' },
{ orderType: '2', orderTypeName: '订单类型2' }
],
// 仓库列表 // 仓库列表
warehouseOptions: [], warehouseOptions: [],
// 库位列表 // 库位列表
locationOptions: [], locationOptions: [],
loadingWarehouse: false, loadingWarehouse: false,
// 仓库选择相关
warehouseSelectorVisible: false,
queryWarehouseName: null,
// 库位选择相关
locationSelectorVisible: false,
queryLocationName: null,
// 可编辑状态 // 可编辑状态
isEditable: true, isEditable: true,
// 物料组件显示 // 物料组件显示
...@@ -278,6 +312,7 @@ export default { ...@@ -278,6 +312,7 @@ export default {
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
materialId: null,
orderId: null, orderId: null,
orderTypeId: null, orderTypeId: null,
systemNo: null, systemNo: null,
...@@ -312,56 +347,37 @@ export default { ...@@ -312,56 +347,37 @@ export default {
updateUserCode: null, updateUserCode: null,
// 明细列表 // 明细列表
inboundOrderItemsList: [] inboundOrderItemsList: []
},
// 表单校验
rules: {
orderId: [
{ required: true, message: "入库单号不能为空", trigger: "blur" }
],
orderTypeId: [
{ required: true, message: "入库类型不能为空", trigger: "blur" }
],
systemNo: [
{ required: true, message: "系统编号不能为空", trigger: "blur" }
],
batchId: [
{ required: true, message: "批次ID不能为空", trigger: "blur" }
]
} }
} }
}, },
mounted(){
console.log("标签颜色字典数据:", this.dict.type.label_color);
},
created() { created() {
this.getList() this.getList()
// 初始化仓库信息 // 初始化标签颜色下拉选项
this.getWarehouseOptions()
}, },
methods: { methods: {
//初始化仓库信息 // 封装字典取值方法
getWarehouseOptions() { getDictLabel(dictType, value) {
this.loadingWarehouse = true // 1. 空值/字典不存在时返回默认值
listWarehouses({ pageNum: 1, pageSize: 100 }).then(response => { if (!value || !this.dict?.type?.[dictType]) return '-';
const rows = response.rows || [] // 2. 从字典数组中匹配 value 对应的 label
this.warehouseOptions = rows.map(item => ({ const dictItem = this.dict.type[dictType].find(item => item.value === value);
label: `${item.warehousesName || item.name || '未命名仓库'} (${item.warehouseCode || item.code || item.warehousesCode || ''})`, return dictItem?.label || '-';
// 用仓库ID + 编码作为唯一key,避免空值重复
value: item.id || item.warehouseCode || item.code,
key: item.id || item.warehouseCode || Date.now() + Math.random()
})).filter(option => option.value)
this.loadingWarehouse = false
}).catch(error => {
console.error('获取仓库列表失败:', error)
this.warehouseOptions = []
this.loadingWarehouse = false
})
}, },
getWarehouseName(warehouseId) { getDictListClass(dictType, value){
if (!warehouseId) return '' // 1. 空值/字典不存在时返回默认值
const warehouse = this.warehouseOptions.find(item => item.value === warehouseId) if (!value || !this.dict?.type?.[dictType]) return '-';
return warehouse ? warehouse.label : warehouseId // 2. 从字典数组中匹配 value 对应的 label
const dictItem = this.dict.type[dictType].find(item => item.value === value);
return dictItem?.raw?.listClass || '';
}, },
/** 查询入库列表 */ /** 查询入库列表 */
getList() { getList() {
this.loading = true this.loading = true
console.log(this.queryParams)
inbound_details(this.queryParams).then(response => { inbound_details(this.queryParams).then(response => {
this.inboundList = response.rows this.inboundList = response.rows
this.total = response.total this.total = response.total
...@@ -370,26 +386,6 @@ export default { ...@@ -370,26 +386,6 @@ export default {
this.loading = false this.loading = false
}) })
}, },
/** 获取状态样式类型 */
getStatusType(status) {
const item = this.inBoundStatusOptions.find(item => item.orderStatus === status)
return item ? item.type : 'info'
},
/** 获取状态类型名称 */
getStatusName(status) {
const item = this.inBoundStatusOptions.find(item => item.orderStatus === status)
return item ? item.orderStatusName : status
},
getInBoundTypeName(typeId) {
if (!typeId) return '未知类型'
const item = this.inBoundTypeOptions.find(item => item.orderTypeId === typeId)
return item ? item.orderTypeName : '未知类型'
},
getOrderTypeName(type) {
if (!type) return '未知类型'
const item = this.orderTypeOptions.find(item => item.orderType === type)
return item ? item.orderTypeName : '未知类型'
},
/** 搜索按钮操作 */ /** 搜索按钮操作 */
handleQuery() { handleQuery() {
this.queryParams.pageNum = 1 this.queryParams.pageNum = 1
...@@ -455,6 +451,52 @@ export default { ...@@ -455,6 +451,52 @@ export default {
this.detailOpen = true this.detailOpen = true
}) })
}, },
/** 打开仓库选择器 */
openWarehouseSelector() {
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()
console.log('selected warehouse', warehouse);
},
/** 清空仓库选择 */
clearQueryWarehouse() {
this.queryWarehouseName = null
this.queryParams.warehouseId = null
this.queryParams.warehousesCode = null
// 清空仓库时,同时清空库位
this.queryLocationName = null
this.queryParams.locationId = null
this.handleQuery()
},
/** 打开库位选择器 */
openLocationSelector() {
if (!this.queryParams.warehouseId) {
this.$message.warning("请先选择仓库")
return
}
this.locationSelectorVisible = true
},
/** 库位选择回调 */
handleLocationSelected(location) {
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()
},
// 打开物料选择弹窗 // 打开物料选择弹窗
showMaterials(status) { showMaterials(status) {
this.materialSelectOpen = status; this.materialSelectOpen = status;
......
...@@ -468,11 +468,11 @@ export default { ...@@ -468,11 +468,11 @@ export default {
// 根据字典类型和值,获取对应的listClass(标签样式) // 根据字典类型和值,获取对应的listClass(标签样式)
getDictListClass(dictType, value) { getDictListClass(dictType, value) {
const dictList = this.dict.type[dictType] || [] const dictList = this.dict.type[dictType] || []
if (!value) return 'info' if (!value) return ''
const dictItem = dictList.find(item => item.value === value+"") const dictItem = dictList.find(item => item.value === value+"")
// 兼容raw和直接属性两种写法 // 兼容raw和直接属性两种写法
return dictItem?.raw?.listClass || 'info' return dictItem?.raw?.listClass
}, },
// 根据字典类型和值,获取对应的显示标签 // 根据字典类型和值,获取对应的显示标签
......
...@@ -141,7 +141,8 @@ public class InboundOrderItemsController extends BaseController ...@@ -141,7 +141,8 @@ public class InboundOrderItemsController extends BaseController
public TableDataInfo itemDetails(InboundDetailsVO inboundDetailsVO) throws Exception public TableDataInfo itemDetails(InboundDetailsVO inboundDetailsVO) throws Exception
{ {
startPage(); startPage();
List<InboundDetailsVO> list = inboundOrderItemsService.selectInboundDetailsVOBySapNo(); System.out.println(inboundDetailsVO);
List<InboundDetailsVO> list = inboundOrderItemsService.selectInboundDetailsVOBySapNo(inboundDetailsVO);
return getDataTable(list); return getDataTable(list);
} }
} }
...@@ -72,5 +72,5 @@ public interface InboundOrderItemsMapper ...@@ -72,5 +72,5 @@ public interface InboundOrderItemsMapper
* 统计入库单明细 * 统计入库单明细
* @return 结果 * @return 结果
*/ */
public List<InboundDetailsVO> selectInboundDetailsVOBySapNo(); public List<InboundDetailsVO> selectInboundDetailsVOBySapNo(InboundDetailsVO inboundDetailsVO);
} }
...@@ -74,5 +74,5 @@ public interface IInboundOrderItemsService ...@@ -74,5 +74,5 @@ public interface IInboundOrderItemsService
* 统计入库单明细 * 统计入库单明细
* @return 结果 * @return 结果
*/ */
public List<InboundDetailsVO> selectInboundDetailsVOBySapNo(); public List<InboundDetailsVO> selectInboundDetailsVOBySapNo(InboundDetailsVO inboundDetailsVO);
} }
...@@ -176,7 +176,7 @@ public class InboundOrderItemsServiceImpl implements IInboundOrderItemsService ...@@ -176,7 +176,7 @@ public class InboundOrderItemsServiceImpl implements IInboundOrderItemsService
} }
@Override @Override
public List<InboundDetailsVO> selectInboundDetailsVOBySapNo() { public List<InboundDetailsVO> selectInboundDetailsVOBySapNo(InboundDetailsVO inboundDetailsVO) {
return inboundOrderItemsMapper.selectInboundDetailsVOBySapNo(); return inboundOrderItemsMapper.selectInboundDetailsVOBySapNo(inboundDetailsVO);
} }
} }
...@@ -336,7 +336,7 @@ ...@@ -336,7 +336,7 @@
<result column="inbound_date" property="inboundDate"/> <result column="inbound_date" property="inboundDate"/>
</resultMap> </resultMap>
<select id="selectInboundDetailsVOBySapNo" resultMap="InboundDetailsResultMap"> <select id="selectInboundDetailsVOBySapNo" resultMap="InboundDetailsResultMap" parameterType="com.ruoyi.inventory.domain.vo.InboundDetailsVO">
SELECT SELECT
ioi.material_id, ioi.material_id,
ms.material_name, ms.material_name,
...@@ -358,7 +358,30 @@ ...@@ -358,7 +358,30 @@
INNER JOIN materials ms ON ms.sap_no = ioi.material_id INNER JOIN materials ms ON ms.sap_no = ioi.material_id
inner join warehouses w on ioi.warehouse_id = w.id inner join warehouses w on ioi.warehouse_id = w.id
inner join storage_locations sl on ioi.location_id = sl.id inner join storage_locations sl on ioi.location_id = sl.id
WHERE io.order_status = 2 <where>
io.order_status = 2
<if test="materialId != null and materialId != ''">
AND ioi.material_id = #{materialId}
</if>
<if test="materialName != null and materialName != ''">
AND ms.material_name LIKE CONCAT('%', #{materialName}, '%')
</if>
<if test="orderId != null and orderId != ''">
AND ioi.order_id = #{orderId}
</if>
<if test="batchId != null and batchId != ''">
AND ioi.batch_id = #{batchId}
</if>
<if test="warehouseId != null and warehouseId != ''">
AND ioi.warehouse_id = #{warehouseId}
</if>
<if test="locationId != null and locationId != ''">
AND ioi.location_id = #{locationId}
</if>
<if test="labelColor != null and labelColor != ''">
AND ioi.label_color = #{labelColor}
</if>
</where>
GROUP BY GROUP BY
ioi.material_id, ioi.material_id,
ioi.batch_id, ioi.batch_id,
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论