cmvr-wms/ruoyi-ui/src/views/warehouse/inRecord/index.vue
lixiaolong d872e3e235 feat(warehouse): 优化智能代理功能和库存管理
- 修改默认出库类型从销售出库改为生产出库
- 添加产品类别自动推断功能,支持基于历史数据和关键词的智能分类
- 实现库存查询结果显示和选择功能,优化用户体验
- 增强代理计划的消息提示和错误处理机制
- 添加现有产品类别的获取和展示功能
- 优化库存不足和产品未找到的提示信息
- 修复前端表单默认值设置问题
2026-07-17 09:17:42 +08:00

266 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-form ref="queryForm" :model="queryParams" size="small" :inline="true" v-show="showSearch" label-width="80px">
<el-form-item label="库区" prop="areaId">
<el-select v-model="queryParams.areaId" placeholder="请选择库区" clearable filterable>
<el-option v-for="item in areaOptions" :key="item.id" :label="areaLabel(item)" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="产品名称" prop="productName">
<el-input v-model="queryParams.productName" placeholder="请输入产品名称" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="品牌" prop="brand">
<el-select v-model="queryParams.brand" placeholder="请选择品牌" clearable filterable>
<el-option v-for="item in brandOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
<el-form-item label="类别" prop="category">
<el-select v-model="queryParams.category" placeholder="请选择类别" clearable filterable>
<el-option v-for="item in categoryOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
<el-form-item label="规格" prop="spec">
<el-input v-model="queryParams.spec" placeholder="请输入规格" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="入库人" prop="inOperator">
<el-select v-model="queryParams.inOperator" placeholder="请选择入库人" clearable filterable>
<el-option v-for="item in userOptions" :key="item.userId" :label="userLabel(item)" :value="userValue(item)" />
</el-select>
</el-form-item>
<el-form-item label="状态" prop="inStatus">
<el-select v-model="queryParams.inStatus" placeholder="请选择状态" clearable>
<el-option v-for="dict in dict.type.wms_in_status" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5"><el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['warehouse:in:add']">新增</el-button></el-col>
<el-col :span="1.5"><el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate" v-hasPermi="['warehouse:in:edit']">修改</el-button></el-col>
<el-col :span="1.5"><el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete" v-hasPermi="['warehouse:in:remove']">删除</el-button></el-col>
<el-col :span="1.5"><el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['warehouse:in:export']">导出</el-button></el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" />
</el-row>
<el-table v-loading="loading" :data="recordList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="入库单号" align="center" prop="inNo" min-width="150" />
<el-table-column label="库区" align="center" prop="areaName" min-width="110" />
<el-table-column label="产品信息" min-width="280">
<template slot-scope="scope">
<div class="product-name">{{ scope.row.productName || '-' }}</div>
<div class="product-meta">
<span v-if="scope.row.brand">品牌:{{ scope.row.brand }}</span>
<span v-if="scope.row.category">类别:{{ scope.row.category }}</span>
<span v-if="scope.row.spec">规格:{{ scope.row.spec }}</span>
<span v-if="scope.row.unit">单位:{{ scope.row.unit }}</span>
</div>
</template>
</el-table-column>
<el-table-column label="入库类型" align="center" prop="inType">
<template slot-scope="scope"><dict-tag :options="dict.type.wms_in_type" :value="scope.row.inType" /></template>
</el-table-column>
<el-table-column label="数量" align="right" prop="inNum" />
<el-table-column label="状态" align="center" prop="inStatus">
<template slot-scope="scope"><dict-tag :options="dict.type.wms_in_status" :value="scope.row.inStatus" /></template>
</el-table-column>
<el-table-column label="系统操作人" align="center" prop="operator" />
<el-table-column label="入库人" align="center" prop="inOperator" />
<el-table-column label="确认时间" align="center" prop="confirmTime" width="180">
<template slot-scope="scope">{{ parseTime(scope.row.confirmTime) }}</template>
</el-table-column>
<el-table-column label="操作" align="center" width="210" fixed="right">
<template slot-scope="scope">
<el-button v-if="scope.row.inStatus === 0" size="mini" type="text" icon="el-icon-check" @click="handleConfirm(scope.row)" v-hasPermi="['warehouse:in:confirm']">入库</el-button>
<el-button v-if="scope.row.inStatus === 0" size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['warehouse:in:edit']">修改</el-button>
<el-button v-if="scope.row.inStatus === 0" size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['warehouse:in:remove']">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
<el-dialog :title="title" :visible.sync="open" width="620px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="入库单号" prop="inNo"><el-input v-model="form.inNo" placeholder="不填则自动生成" /></el-form-item>
<el-form-item label="库区" prop="areaId">
<el-select v-model="form.areaId" placeholder="请选择库区" filterable>
<el-option v-for="item in areaOptions" :key="item.id" :label="areaLabel(item)" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="产品" prop="productId">
<el-select v-model="form.productId" placeholder="请选择产品" filterable>
<el-option v-for="item in productOptions" :key="item.id" :label="productLabel(item)" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="入库人" prop="inOperator">
<el-select v-model="form.inOperator" placeholder="请选择入库人" filterable>
<el-option v-for="item in userOptions" :key="item.userId" :label="userLabel(item)" :value="userValue(item)" />
</el-select>
</el-form-item>
<el-form-item label="入库类型" prop="inType">
<el-select v-model="form.inType" placeholder="请选择入库类型">
<el-option v-for="dict in dict.type.wms_in_type" :key="dict.value" :label="dict.label" :value="Number(dict.value)" />
</el-select>
</el-form-item>
<el-form-item label="入库数量" prop="inNum"><el-input-number v-model="form.inNum" :min="0.001" :precision="3" :step="1" controls-position="right" /></el-form-item>
<el-form-item label="备注" prop="remark"><el-input v-model="form.remark" type="textarea" placeholder="请输入备注" /></el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listInRecord, getInRecord, delInRecord, addInRecord, updateInRecord, confirmInRecord } from '@/api/warehouse/inRecord'
import { optionselectArea } from '@/api/warehouse/area'
import { optionselectProduct } from '@/api/warehouse/product'
import { optionselectUser } from '@/api/warehouse/user'
export default {
name: 'InRecord',
dicts: ['wms_in_type', 'wms_in_status'],
data() {
return {
loading: true,
ids: [],
single: true,
multiple: true,
showSearch: true,
total: 0,
recordList: [],
areaOptions: [],
productOptions: [],
userOptions: [],
title: '',
open: false,
queryParams: { pageNum: 1, pageSize: 10, areaId: undefined, productName: undefined, brand: undefined, category: undefined, spec: undefined, inOperator: undefined, inType: undefined, inStatus: undefined },
form: {},
rules: {
areaId: [{ required: true, message: '库区不能为空', trigger: 'change' }],
productId: [{ required: true, message: '产品不能为空', trigger: 'change' }],
inOperator: [{ required: true, message: '入库人不能为空', trigger: 'change' }],
inType: [{ required: true, message: '入库类型不能为空', trigger: 'change' }],
inNum: [{ required: true, message: '入库数量不能为空', trigger: 'blur' }]
}
}
},
computed: {
brandOptions() {
return this.getDistinctOptions('brand')
},
categoryOptions() {
return this.getDistinctOptions('category')
}
},
created() {
this.getOptions()
this.getList()
},
methods: {
userLabel(user) {
return user.nickName || user.userName
},
userValue(user) {
return user.nickName || user.userName
},
areaLabel(area) {
return area.areaName || area.areaCode
},
productLabel(product) {
const name = product.productName || product.productCode || '-'
const details = [product.brand, product.category, product.spec, product.unit].filter(item => item)
return details.length ? name + '' + details.join(' / ') + '' : name
},
getDistinctOptions(field) {
const values = this.productOptions.map(item => item[field]).filter(item => item !== undefined && item !== null && item !== '')
return Array.from(new Set(values))
},
getOptions() {
optionselectArea().then(res => { this.areaOptions = res.data })
optionselectProduct().then(res => { this.productOptions = res.data })
optionselectUser().then(res => { this.userOptions = res.data })
},
getList() {
this.loading = true
listInRecord(this.queryParams).then(response => {
this.recordList = response.rows
this.total = response.total
this.loading = false
})
},
cancel() { this.open = false; this.reset() },
reset() {
this.form = { id: undefined, inNo: undefined, areaId: undefined, productId: undefined, inOperator: undefined, inType: 2, inNum: undefined, remark: undefined }
this.resetForm('form')
},
handleQuery() { this.queryParams.pageNum = 1; this.getList() },
resetQuery() { this.resetForm('queryForm'); this.handleQuery() },
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
handleAdd() { this.reset(); this.open = true; this.title = '新增入库记录' },
handleUpdate(row) {
this.reset()
const id = row.id || this.ids
getInRecord(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改入库记录'
})
},
submitForm() {
this.$refs.form.validate(valid => {
if (!valid) return
const request = this.form.id ? updateInRecord(this.form) : addInRecord(this.form)
request.then(() => {
this.$modal.msgSuccess(this.form.id ? '修改成功' : '新增成功')
this.open = false
this.getList()
})
})
},
handleConfirm(row) {
this.$modal.confirm('是否确认入库单号为"' + row.inNo + '"的记录?').then(() => confirmInRecord(row.id)).then(() => {
this.getList()
this.$modal.msgSuccess('入库成功')
}).catch(() => {})
},
handleDelete(row) {
const ids = row.id || this.ids
this.$modal.confirm('是否确认删除入库编号为"' + ids + '"的数据项?').then(() => delInRecord(ids)).then(() => {
this.getList()
this.$modal.msgSuccess('删除成功')
}).catch(() => {})
},
handleExport() {
this.download('warehouse/in/export', { ...this.queryParams }, `in_record_${new Date().getTime()}.xlsx`)
}
}
}
</script>
<style scoped>
.product-name {
line-height: 20px;
font-weight: 600;
}
.product-meta {
color: #909399;
line-height: 18px;
}
.product-meta span {
margin-right: 12px;
white-space: nowrap;
}
</style>