入库申请->入库审核流程:
提交按键定义位置:src\views\purchase\rurchase\RurchaseAdd.vue
<a-button @click="handleSubmit" type="primary" :loading="loading">确认物品已入库</a-button>
<template><a-drawertitle="采购单入库":maskClosable="false"placement="right":closable="false":visible="show":width="1200"@close="onClose"style="height: calc(100% - 55px);overflow: auto;padding-bottom: 53px;"><a-form :form="form" layout="vertical"><a-row :gutter="20"><a-col :span="12"><a-form-item label='采购单号' v-bind="formItemLayout"><a-input v-model="rurchaseData.num" disabled/></a-form-item></a-col><a-col :span="12"><a-form-item label='申请人' v-bind="formItemLayout"><a-input v-model="rurchaseData.applicant" disabled/></a-form-item></a-col><a-col :span="12"><a-form-item label='申请时间' v-bind="formItemLayout"><a-input v-model="rurchaseData.createDate" disabled/></a-form-item></a-col><a-col :span="12"><a-form-item label='备注消息' v-bind="formItemLayout"><a-input v-model="rurchaseData.content" disabled/></a-form-item></a-col><a-col :span="12"><a-form-item label='保管人' v-bind="formItemLayout"><a-input v-decorator="['custodian',{ rules: [{ required: true, message: '请输入保管人!' }] }]"/></a-form-item></a-col><a-col :span="12"><a-form-item label='入库人' v-bind="formItemLayout"><a-input v-decorator="['putUser',{ rules: [{ required: true, message: '请输入入库人!' }] }]"/></a-form-item></a-col><a-col :span="24"><a-form-item label='备注消息' v-bind="formItemLayout"><a-textarea :rows="4" v-decorator="['rurchaseContent',{ rules: [{ required: true, message: '请输入名称!' }] }]"/></a-form-item></a-col><a-col :span="24"><a-table :columns="columns" :data-source="dataList"><template slot="nameShow" slot-scope="text, record"><a-input v-model="record.name"></a-input></template><template slot="typeShow" slot-scope="text, record"><a-input v-model="record.type"></a-input></template><template slot="typeIdShow" slot-scope="text, record"><a-select v-model="record.typeId" style="width: 100%"><a-select-option v-for="(item, index) in consumableType" :value="item.id" :key="index">{{ item.name }}</a-select-option></a-select></template><template slot="unitShow" slot-scope="text, record"><a-input v-model="record.unit"></a-input></template><template slot="amountShow" slot-scope="text, record"><a-input-number v-model="record.amount" :min="1" :step="1"/></template><template slot="priceShow" slot-scope="text, record"><a-input-number v-model="record.price" :min="1"/></template></a-table><a-button @click="dataAdd" type="primary" ghost size="large" style="margin-top: 10px;width: 100%">新增物品</a-button></a-col></a-row></a-form><div class="drawer-bootom-button"><a-popconfirm title="确定放弃编辑?" @confirm="onClose" okText="确定" cancelText="取消"><a-button style="margin-right: .8rem">取消</a-button></a-popconfirm><a-button @click="handleSubmit" type="primary" :loading="loading">确认物品已入库RurchaseAdd</a-button></div></a-drawer>
</template><script>
import {mapState} from 'vuex'
const formItemLayout = {labelCol: { span: 24 },wrapperCol: { span: 24 }
}
export default {name: 'RurchaseAdd',props: {rurchaseAddVisiable: {default: false},rurchaseData: {type: Object}},computed: {...mapState({currentUser: state => state.account.user}),show: {get: function () {return this.rurchaseAddVisiable},set: function () {}},columns () {return [{title: '物品名称',dataIndex: 'name',scopedSlots: {customRender: 'nameShow'}}, {title: '型号',dataIndex: 'type',scopedSlots: {customRender: 'typeShow'}}, {title: '数量',dataIndex: 'amount',scopedSlots: {customRender: 'amountShow'}}, {title: '所属类型',dataIndex: 'typeId',width: 200,scopedSlots: {customRender: 'typeIdShow'}}, {title: '单位',dataIndex: 'unit',scopedSlots: {customRender: 'unitShow'}}, {title: '单价',dataIndex: 'price',scopedSlots: {customRender: 'priceShow'}}]}},data () {return {formItemLayout,form: this.$form.createForm(this),loading: false,dataList: [],consumableType: []}},mounted () {this.getConsumableType()this.getGoodsByNum(this.rurchaseData.num)},methods: {getGoodsByNum (num) {this.$get('/cos/goods-belong/getGoodsByNum', { num }).then((r) => {this.dataList = r.data.data})},getConsumableType () {this.$get('/cos/consumable-type/list').then((r) => {this.consumableType = r.data.data})},dataAdd () {this.dataList.push({name: '', type: '', typeId: '', unit: '', amount: '', price: ''})},reset () {this.loading = falsethis.form.resetFields()},onClose () {this.reset()this.$emit('close')},handleSubmit () {let price = 0this.dataList.forEach(item => {price += item.price * item.amount})this.form.validateFields((err, values) => {if (!err) {values.price = pricevalues.goods = JSON.stringify(this.dataList)values.id = this.rurchaseData.idthis.loading = truethis.$post('/cos/rurchase-request/rurchasePut ', {...values}).then((r) => {this.reset()this.$emit('success')}).catch(() => {this.loading = false})}})}}
}
</script><style scoped></style>
后台API地址:/cos/rurchase-request/rurchasePut
后台服务方法名:cc.mrbird.febs.cos.service.impl.RurchaseRequestServiceImpl#rurchasePut
后台java文件路径:D:\code\javaspringboot\dinningroomsupply\SuppliesManagementSystem\backend\src\main\java\cc\mrbird\febs\cos\service\impl\RurchaseRequestServiceImpl.java
存在的bug:80~82行,更新 stock_info表的当前物品库存总数,条件为限定is_in=0,导致is_in=1(入库)和is_in=2(出库)的历史出入库数据都被修改
stockInfoService.update(Wrappers.<StockInfo>lambdaUpdate()
.set(StockInfo::getAmount, stockInfo.getAmount()+item.getAmount())
.set(StockInfo::getPrice, stockInfo.getPrice())
.eq(StockInfo::getName, stockInfo.getName())); //注意,这里更新条件用的是name不是id
从控制台打印的sql语句可以看出,更新语句的条件有误:
2023-11-22 16:26:31 | INFO | http-nio-9527-exec-10 | p6spy | 2023-11-22 16:26:31 | 耗时 8 ms | SQL 语句: UPDATE stock_info SET amount=14,price=11.00 WHERE name = 'test';
package cc.mrbird.febs.cos.service.impl;import cc.mrbird.febs.cos.entity.GoodsBelong;
import cc.mrbird.febs.cos.entity.RurchaseRequest;
import cc.mrbird.febs.cos.dao.RurchaseRequestMapper;
import cc.mrbird.febs.cos.entity.StockInfo;
import cc.mrbird.febs.cos.entity.StockPut;
import cc.mrbird.febs.cos.service.IGoodsBelongService;
import cc.mrbird.febs.cos.service.IRurchaseRequestService;
import cc.mrbird.febs.cos.service.IStockInfoService;
import cc.mrbird.febs.cos.service.IStockPutService;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;/*** @author FanK*/
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class RurchaseRequestServiceImpl extends ServiceImpl<RurchaseRequestMapper, RurchaseRequest> implements IRurchaseRequestService {private final IGoodsBelongService goodsBelongService;private final IStockPutService stockPutService;private final IStockInfoService stockInfoService;@Overridepublic IPage<LinkedHashMap<String, Object>> rurchaseRequestByPage(Page page, RurchaseRequest rurchaseRequest) {return baseMapper.rurchaseRequestByPage(page, rurchaseRequest);}@Overridepublic Boolean rurchaseRequestAdd(RurchaseRequest rurchaseRequest) {rurchaseRequest.setNum("RUR-"+new Date().getTime());JSONArray array = JSONUtil.parseArray(rurchaseRequest.getGoods());List<GoodsBelong> goodsBelongList = JSONUtil.toList(array, GoodsBelong.class);rurchaseRequest.setStep(0);this.save(rurchaseRequest);goodsBelongList.forEach(item -> {item.setCreateDate(DateUtil.formatDateTime(new Date()));item.setNum(rurchaseRequest.getNum());});return goodsBelongService.saveBatch(goodsBelongList);}@Overridepublic Boolean rurchasePut(RurchaseRequest rurchaseRequest) {JSONArray array = JSONUtil.parseArray(rurchaseRequest.getGoods());List<GoodsBelong> goodsBelongList = JSONUtil.toList(array, GoodsBelong.class);// 添加入库单StockPut stockPut = new StockPut();stockPut.setContent(rurchaseRequest.getRurchaseContent());stockPut.setCreateDate(DateUtil.formatDateTime(new Date()));stockPut.setCustodian(rurchaseRequest.getCustodian());stockPut.setPutUser(rurchaseRequest.getPutUser());stockPut.setPrice(rurchaseRequest.getPrice());stockPut.setNum("PUT-"+new Date().getTime());stockPutService.save(stockPut);goodsBelongList.forEach(item -> {item.setCreateDate(DateUtil.formatDateTime(new Date()));item.setNum(stockPut.getNum());// 判断库房物品是否存在StockInfo stockInfo = stockInfoService.getOne(Wrappers.<StockInfo>lambdaQuery().eq(StockInfo::getName, item.getName()).eq(StockInfo::getTypeId, item.getTypeId()).eq(StockInfo::getIsIn, 0));if (stockInfo != null) {// 更改库房数据 这句话有bug,没有限定is_in=0stockInfoService.update(Wrappers.<StockInfo>lambdaUpdate().set(StockInfo::getAmount, stockInfo.getAmount()+item.getAmount()).set(StockInfo::getPrice, stockInfo.getPrice()).eq(StockInfo::getName, stockInfo.getName())); // 更新条件应该用id} else {// 重新添加库房数据StockInfo stock = new StockInfo();stock.setName(item.getName());stock.setAmount(item.getAmount());stock.setCreateDate(DateUtil.formatDateTime(new Date()));stock.setType(item.getType());stock.setTypeId(item.getTypeId());stock.setUnit(item.getUnit());stock.setPrice(item.getPrice());stock.setIsIn(0);stockInfo = stock;stockInfoService.save(stock);}// 添加入库记录StockInfo stockInfoPut = new StockInfo();stockInfoPut.setParentId(stockInfo.getId());stockInfoPut.setName(item.getName());stockInfoPut.setAmount(item.getAmount());stockInfoPut.setCreateDate(DateUtil.formatDateTime(new Date()));stockInfoPut.setType(item.getType());stockInfoPut.setTypeId(item.getTypeId());stockInfoPut.setUnit(item.getUnit());stockInfoPut.setPrice(item.getPrice());stockInfoPut.setIsIn(1);stockInfoService.save(stockInfoPut);// 添加所属信息GoodsBelong goodsBelong = new GoodsBelong();goodsBelong.setNum(stockPut.getNum());goodsBelong.setCreateDate(DateUtil.formatDateTime(new Date()));goodsBelong.setAmount(item.getAmount());goodsBelong.setName(item.getName());goodsBelong.setPrice(item.getPrice());goodsBelong.setType(item.getType());goodsBelong.setTypeId(item.getTypeId());goodsBelong.setUnit(item.getUnit());goodsBelongService.save(goodsBelong);});// 修改状态this.update(Wrappers.<RurchaseRequest>lambdaUpdate().set(RurchaseRequest::getStep, 1).eq(RurchaseRequest::getId, rurchaseRequest.getId()));return true;}
}
直接入库流程: 前台代码定义位置:src\views\purchase\request\RequestAdd.vue
<a-button @click="handleSubmit" type="primary" :loading="loading">提交</a-button>
后台API地址:/cos/stock-info/put
后台服务方法名:cc.mrbird.febs.cos.service.impl.StockInfoServiceImpl#stockPut
后台java文件路径:D:\code\javaspringboot\dinningroomsupply\SuppliesManagementSystem\backend\src\main\java\cc\mrbird\febs\cos\service\impl\StockInfoServiceImpl.java
// 判断库房物品是否存在 StockInfo stockInfo = this.getOne(Wrappers.<StockInfo>lambdaQuery().eq(StockInfo::getName, item.getName()).eq(StockInfo::getTypeId, item.getTypeId()).eq(StockInfo::getIsIn, 0));
if (stockInfo != null) { // 更改库房数据
this.update(Wrappers.<StockInfo>lambdaUpdate()
.set(StockInfo::getAmount, stockInfo.getAmount()+item.getAmount()) .set(StockInfo::getPrice, stockInfo.getPrice())
.eq(StockInfo::getId, stockInfo.getId())); //注意,这里更新条件用的是id
package cc.mrbird.febs.cos.service.impl;import cc.mrbird.febs.cos.entity.GoodsBelong;
import cc.mrbird.febs.cos.entity.StockInfo;
import cc.mrbird.febs.cos.dao.StockInfoMapper;
import cc.mrbird.febs.cos.entity.StockPut;
import cc.mrbird.febs.cos.entity.StudentInfo;
import cc.mrbird.febs.cos.service.*;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.math.BigDecimal;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;/*** @author FanK*/
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class StockInfoServiceImpl extends ServiceImpl<StockInfoMapper, StockInfo> implements IStockInfoService {private final IStockPutService stockPutService;private final IGoodsBelongService goodsBelongService;private final IBulletinInfoService bulletinInfoService;private final IStudentInfoService studentInfoService;@Overridepublic IPage<LinkedHashMap<String, Object>> stockInfoByPage(Page page, StockInfo stockInfo) {return baseMapper.stockInfoByPage(page, stockInfo);}@Overridepublic Boolean stockPut(String goods, String custodian, String putUser, String content, BigDecimal price) {// 添加入库单StockPut stockPut = new StockPut();stockPut.setContent(content);stockPut.setCreateDate(DateUtil.formatDateTime(new Date()));stockPut.setCustodian(custodian);stockPut.setPutUser(putUser);stockPut.setPrice(price);stockPut.setNum("PUT-"+new Date().getTime());stockPutService.save(stockPut);// 添加入库JSONArray array = JSONUtil.parseArray(goods);List<GoodsBelong> goodsBelongList = JSONUtil.toList(array, GoodsBelong.class);goodsBelongList.forEach(item -> {item.setCreateDate(DateUtil.formatDateTime(new Date()));item.setNum(stockPut.getNum());// 判断库房物品是否存在StockInfo stockInfo = this.getOne(Wrappers.<StockInfo>lambdaQuery().eq(StockInfo::getName, item.getName()).eq(StockInfo::getTypeId, item.getTypeId()).eq(StockInfo::getIsIn, 0));if (stockInfo != null) {// 更改库房数据this.update(Wrappers.<StockInfo>lambdaUpdate().set(StockInfo::getAmount, stockInfo.getAmount()+item.getAmount()).set(StockInfo::getPrice, stockInfo.getPrice()).eq(StockInfo::getId, stockInfo.getId())); // 这里用的id就不会出现误修改} else {// 重新添加库房数据StockInfo stock = new StockInfo();stock.setName(item.getName());stock.setAmount(item.getAmount());stock.setCreateDate(DateUtil.formatDateTime(new Date()));stock.setType(item.getType());stock.setTypeId(item.getTypeId());stock.setUnit(item.getUnit());stock.setPrice(item.getPrice());stock.setIsIn(0);stockInfo = stock;this.save(stock);}// 添加入库记录StockInfo stockInfoPut = new StockInfo();stockInfoPut.setParentId(stockInfo.getId());stockInfoPut.setName(item.getName());stockInfoPut.setAmount(item.getAmount());stockInfoPut.setCreateDate(DateUtil.formatDateTime(new Date()));stockInfoPut.setType(item.getType());stockInfoPut.setTypeId(item.getTypeId());stockInfoPut.setUnit(item.getUnit());stockInfoPut.setPrice(item.getPrice());stockInfoPut.setIsIn(1);this.save(stockInfoPut);// 添加所属信息GoodsBelong goodsBelong = new GoodsBelong();goodsBelong.setNum(stockPut.getNum());goodsBelong.setCreateDate(DateUtil.formatDateTime(new Date()));goodsBelong.setAmount(item.getAmount());goodsBelong.setName(item.getName());goodsBelong.setPrice(item.getPrice());goodsBelong.setType(item.getType());goodsBelong.setTypeId(item.getTypeId());goodsBelong.setUnit(item.getUnit());goodsBelongService.save(goodsBelong);});return true;}@Overridepublic IPage<LinkedHashMap<String, Object>> stockInfoDetailPage(Page page, StockInfo stockInfo) {return baseMapper.stockInfoDetailPage(page, stockInfo);}@Overridepublic IPage<LinkedHashMap<String, Object>> getGoodsPutByUserId(Page page, StockInfo stockInfo) {return baseMapper.getGoodsPutByUserId(page, stockInfo);}@Overridepublic LinkedHashMap<String, Object> home(Integer type, Integer userId) {LinkedHashMap<String, Object> result = new LinkedHashMap<>();result.put("bulletinList", bulletinInfoService.list());if (type == 74) {result.put("studentInfo", studentInfoService.getOne(Wrappers.<StudentInfo>lambdaQuery().eq(StudentInfo::getUserId, userId)));}result.put("stockPutRate", baseMapper.stockPutRate());result.put("stockPutTypeRate", baseMapper.stockPutTypeRate());result.put("stockOutRate", baseMapper.stockOutRate());result.put("stockOutTypeRate", baseMapper.stockOutTypeRate());result.put("stockInfo", baseMapper.stockInfoByMonth());return result;}
}
修复bug后,数据库查询正常了