一、前言

工厂订单及出入库业务的趋势是客户要求越来越高,客户需要快捷、方便、简单、一站式的出入库手续。因此,货物出入库管理信息系统要简化出入库手续,减轻人员作业量,提高工作效率,助力企业数字信息化转型

之前整理过该系统的完整解决方案,有兴趣的参考文章:https://blog.csdn.net/lildkdkdkjf/article/details/117841646

二、整体架构设计

开发语言:

  • Golang:Go 极其地快。其性能与 Java 或 C++相似。在我们的使用中,Go 一般比 Python 要快 30 倍。
  • Vue: 轻量级框架, 大小只有几十kb, 国人开发,中文文档,不存在语言障碍,易于理解和学习。运行速度更快,相比较与react而言,同样都是操作虚拟dom,就性能而言,vue存在很大的优势。

部署方式:

  • 服务器系统:基于免安装可执行程序:支持Windows、Linux,Centos,Ubuntu操作系统
  • 数据库类型:目前已支持PostgreSQL、MySQL、Oracle、Microsoft SQL Server、SQLite等,还可以定制其它类型数据库
  • 热数据缓存服务:基于Key-Value 的Redis 数据库,关键热活数据存储在Redis服务中,提高响应速率。
  • 主备双活服务器:确保稳定性,如果主服务器故障,自动切换到备服务器。热数据
  • 数据库备份:定时增量备份,定期全量备份。

三、编码实现 (基于篇幅及可读性考虑,此处展示部分关键代码)

1、模块截图

2、Go 关键代码

package controllersimport ("encoding/json""fmt""productManage/common"writelog "productManage/log""productManage/models"
)// LogController operations for Log
type BoxController struct {BaseController
}// URLMapping ...
func (c *BoxController) URLMapping() {c.Mapping("Post", c.Post)
}func (c *BoxController) Post() {if c.CheckToken() < 0 {return}ret := common.RetOKact := c.GetString("Act")writelog.WriteDebug("||||||||||||||||||||||||||||||-----------> %+v ", act)if act == common.ActAddBox {SnStart := c.GetString("SnStart")SnEnd := c.GetString("SnEnd")BoxNum, _ := c.GetInt("BoxNum")BoxTotal, _ := c.GetInt("BoxTotal")OrderID := c.GetString("OrderID")DistributeID, _ := c.GetInt64("DistributeID")RecipientID, _ := c.GetInt64("RecipientID")var m models.Boxm.SnStart = SnStartm.SnEnd = SnEndm.BoxNum = BoxNumm.BoxTotal = BoxTotalm.OrderID = OrderIDm.DistributeID = DistributeIDm.RecipientID = RecipientIDid, _ := models.AddBox(&m)c.jsonStandardResult(ret, "OK", id)return}if act == common.ActGetBoxBySnStart {SnStart := c.GetString("SnStart")SnStart,_, SnType := models.GetSnBySnOrKsn(SnStart)//如果输入的是Ksn,这里会转成真正的Snv, err := models.GetBoxBySnStart(SnStart)if err != nil {ret = common.RetErrorBoxEmptyc.jsonStandardResult(ret, "", "")return}writelog.WriteDebug("%+v", v)type rsp struct {SnStart stringSnEnd   stringBox     stringStatusBox   int8SnList  []string}var r rspwritelog.WriteDebug("snType %s", SnType)if SnType == "sn"  {  // snr.Box = fmt.Sprintf("%d/%d", v.BoxNum, v.BoxTotal)r.SnStart = v.SnStartr.SnEnd = v.SnEnd_, SnList, _, _ := models.GetSnListByOrderIDAndBoxNum(v.OrderID, v.BoxNum)for _, v := range SnList {r.SnList = append(r.SnList, v.Sn)}}else {  // ksnr.Box = fmt.Sprintf("%d/%d", v.BoxNum, v.BoxTotal)sStart, _ := models.GetKsnBySn(v.SnStart)r.SnStart = sStart.KsnsEnd, _ := models.GetKsnBySn(v.SnEnd)r.SnEnd = sEnd.Ksn_, SnList, _, _ := models.GetSnListByOrderIDAndBoxNum(v.OrderID, v.BoxNum)for _, v := range SnList {r.SnList = append(r.SnList, v.Ksn)}}r.StatusBox = v.StatusBoxc.jsonStandardResult(ret, "", r)return}if act == common.ActGetBoxList {StartTime, _ := c.GetInt64("StartTime")EndTime, _ := c.GetInt64("EndTime")OrderID := c.GetString("OrderID")Box := c.GetString("Box")BoxNum, BoxTotal := common.SplitBoxNumAndTotal(Box)StatusBox, _ := c.GetInt("StatusBox")Page, _ := c.GetInt("Page")RowNum, _ := c.GetInt("RowNum")recordcount, b, err := models.GetBoxList(StartTime, EndTime, StatusBox, BoxNum, BoxTotal, OrderID, Page, RowNum)if err != nil {ret = common.RetErrorBoxEmptyc.jsonStandardResult(ret, "", err.Error())return}writelog.WriteDebug("%+v", b)type rsp struct {SnStart    stringSnEnd      stringBox        stringStatusBox  int8StatusBoxOkNum  stringOrderID    stringCreateTime int64}var rList []rspvar r rspfor _, v := range b {r.Box = fmt.Sprintf("%d/%d", v.BoxNum, v.BoxTotal)r.StatusBox = v.StatusBoxr.SnEnd = v.SnEndr.SnStart = v.SnStartr.CreateTime = v.CreateTimer.OrderID = v.OrderIDo, _ := models.GetOrderById(v.OrderID)OkNum,_ := models.CountSnByStatusBox( v.BoxNum, v.OrderID, common.StatusOk)r.StatusBoxOkNum = common.MergeBoxNumAndTotal(OkNum, o.NumberPerBox)rList = append(rList, r)}//c.jsonStandardResult(ret, "", rList)c.Data["json"] = struct {Ret         intMsg         stringRecordcount int64Data        interface{}}{Ret:         common.RetOK,Msg:         common.GetErrMsg(common.RetOK),Recordcount: recordcount,Data:        rList,}c.ServeJSON()return}if act == common.ActSetStatusBox {SnStart := c.GetString("SnStart")SnEnd := c.GetString("SnEnd")SnStart,_, _type := models.GetSnBySnOrKsn(SnStart)//如果输入的是Ksn,这里会转成真正的Sn//SnEnd,_, _type = models.GetSnBySnOrKsn(SnEnd)Box := c.GetString("Box")SnOkList := c.GetString("SnOkList")var OkList []stringerr := json.Unmarshal([]byte(SnOkList), &OkList)if err != nil {c.jsonStandardResult(common.RetErrorBoxSetStatusBoxParseJsonData, "", "")return}go setBoxStatusExt(c.GetString("Token"), _type, SnStart, SnEnd , Box, OkList)c.jsonStandardResult(ret, "", 0)//log := fmt.Sprintf("扫描装箱: 箱号[%s] %s起止[%s-%s] 数量[%d]", Box, _type, SnStart, SnEnd, len(OkList))//models.AddSystemLogByToken(c.GetString("Token"), common.LogType_Update, log)return}if act == common.ActSetStatusBoxBySn {Sn := c.GetString("Sn")SnStart := c.GetString("SnStart")SnEnd := c.GetString("SnEnd")Sn,_, _ = models.GetSnBySnOrKsn(Sn)SnStart,_, _ = models.GetSnBySnOrKsn(SnStart)SnEnd,_, _ = models.GetSnBySnOrKsn(SnEnd)Box := c.GetString("Box")//判断sn是否为该箱if (len(Sn) <= 0) || (Sn > SnEnd) || (Sn < SnStart){ret = common.RetErrorSnNotInBoxc.jsonStandardResult(ret, "", "")return}//1. 更新sn表状态,根据箱号BoxNum和订单号OrderIDBoxNum, _ := common.SplitBoxNumAndTotal(Box)// 获取订单号v, err := models.GetBoxBySnStart(SnStart)if err != nil {ret = common.RetErrorBoxEmptyc.jsonStandardResult(ret, "", "")return}OrderID := v.OrderIDRecipientID := v.RecipientIDmodels.UpdateSnBoxStatusBySn(BoxNum, OrderID, Sn, common.StatusOk)//2. 更新box表状态, 获取每箱的产品数 NumberPerBoxBoxStatusBox := getBoxStatusBox(BoxNum, OrderID)models.UpdateBoxStatusBoxBySnStart(SnStart, BoxStatusBox)//3. 更新Recipient表状态: 判断 RecipientID 对应的StatusBox是否均为okRecipientStatusBox := getRecipientStatusBox(RecipientID)_, err = models.EditRecipientStatusBox(RecipientID, RecipientStatusBox)if err != nil {ret = common.RetErrorEditRecipientStatusBoxc.jsonStandardResult(ret, "", "")return}//4. 更新Distribute表状态//5. 更新Order表状态OrderStatusBox := getOrderStatusBox(OrderID)_, err = models.UpdateOrderStatusBox(OrderID, OrderStatusBox)if err != nil {ret = common.RetErrorUpdateOrderStatusBoxc.jsonStandardResult(ret, "", "")return}//提示正确多少sn,总共多少snsnTotalOk ,_ :=models.CountSnByStatusBox(BoxNum, OrderID, common.StatusOk)snTotal ,_ := models.CountSnByBoxNumAndOrderID(BoxStatusBox, OrderID)msg:=""if snTotalOk < snTotal{msg = fmt.Sprintf("总SN数[%d], 装箱正确的SN数[%d], 待处理的SN数[%d]", snTotal, snTotalOk, snTotal - snTotalOk)c.jsonStandardResult(common.RetErrorBoxSetStatusBoxOKAlertMsg, msg, 0)}else{c.jsonStandardResult(ret, "", 0)}log := fmt.Sprintf("扫描装箱->维修SN: 箱号[%s] SN起止[%s-%s] SN[%s] %s", Box, SnStart, SnEnd, Sn, msg)models.AddSystemLogByToken(c.GetString("Token"), common.LogType_Update, log)return}c.jsonStandardResult(common.RetErrorAct, "", nil)return
}func getBoxStatusBox(BoxNum int, OrderID string) (BoxStatus int){//orderV, err := models.GetOrderById(OrderID)//if err != nil {// writelog.WriteDebug("%+v" , err.Error())// return common.StatusError//}//NumberPerBox := orderV.NumberPerBox 可能存在散箱,所以不能这么判断,需要用实际的SN个数判断//Box 只有正确或异常状态StatusBoxAllNum, _ := models.CountSnByBoxNumAndOrderID(BoxNum, OrderID)StatusBoxOkNum, _ := models.CountSnByStatusBox(BoxNum, OrderID, common.StatusOk)if StatusBoxOkNum == StatusBoxAllNum {return common.StatusOk}return common.StatusException//StatusBoxExceptionNum, _ := models.CountSnByStatusBox(BoxNum, OrderID, common.StatusException)//if StatusBoxExceptionNum > 0 {//  return common.StatusException//}////return common.StatusDoing
}func getRecipientStatusBox(RecipientID int64) (BoxStatus int) {if RecipientID == 0{return common.StatusAll}BoxTotal, _ := models.CountBoxByRecipientID(RecipientID)StatusBoxOkNum, _ := models.CountBoxByStatusBox(RecipientID, common.StatusOk)if StatusBoxOkNum == BoxTotal {return common.StatusOk}StatusBoxExceptionNum, _ := models.CountBoxByStatusBox(RecipientID, common.StatusException)if StatusBoxExceptionNum > 0 {return common.StatusException}return common.StatusDoing
}func getOrderStatusBox(OrderID string) (StatusBox int) {// 1.获取收件人个数o, _ := models.GetOrderById(OrderID)RecipientTotal := o.RecipientTotal// 2.获取ok状态的个数StatusOkNum, _ := models.CountRecipientByStatusBox(OrderID, common.StatusOk)if StatusOkNum == RecipientTotal {return common.StatusOk}// 2.获取Exception状态的个数StatusExceptionNum, _ := models.CountRecipientByStatusBox(OrderID, common.StatusException)if StatusExceptionNum > 0 {return common.StatusException}return common.StatusDoing
}func setBoxStatusExt(token string, _type string, SnStart string, SnEnd string, Box string, OkList []string) (ret int){if _type == "ksn" {for i, v := range OkList{OkList[i], _, _ = models.GetSnByKsn(v)}SnEnd,_, _ = models.GetSnByKsn(SnEnd)}//1. 更新sn表状态,根据箱号BoxNum和订单号OrderIDBoxNum, _ := common.SplitBoxNumAndTotal(Box)// 获取订单号v, err := models.GetBoxBySnStart(SnStart)if err != nil {//ret = common.RetErrorBoxEmpty//c.jsonStandardResult(ret, "", "")return common.RetErrorBoxEmpty}OrderID := v.OrderIDRecipientID := v.RecipientIDmodels.UpdateSnStatusBox(OkList, common.StatusOk)//2. 更新box表状态, 获取每箱的产品数 NumberPerBoxBoxStatusBox := getBoxStatusBox(BoxNum, OrderID)_, err = models.UpdateBoxStatusBoxBySnStart(SnStart, BoxStatusBox)if err != nil  {log := fmt.Sprintf("扫描装箱错误(%v): 箱号[%s] %s起止[%s-%s] 数量[%d]", common.RetErrorBoxUpdateBoxStatus, Box, _type, SnStart, SnEnd, len(OkList))models.AddSystemLogByToken(token, common.LogType_Update, log)return common.RetErrorBoxUpdateBoxStatus}//3. 更新Recipient表状态: 判断 RecipientID 对应的StatusBox是否均为okif RecipientID >0{RecipientStatusBox := getRecipientStatusBox(RecipientID)_, err = models.EditRecipientStatusBox(RecipientID, RecipientStatusBox)if err != nil {//ret = common.RetErrorEditRecipientStatusBox//c.jsonStandardResult(ret, "", "")log := fmt.Sprintf("扫描装箱错误(%v): 箱号[%s] %s起止[%s-%s] 数量[%d]", common.RetErrorEditRecipientStatusBox, Box, _type, SnStart, SnEnd, len(OkList))models.AddSystemLogByToken(token, common.LogType_Update, log)return common.RetErrorEditRecipientStatusBox}}//4. 更新Distribute表状态//5. 更新Order表状态OrderStatusBox := getOrderStatusBox(OrderID)_, err = models.UpdateOrderStatusBox(OrderID, OrderStatusBox)if err != nil {//ret = common.RetErrorUpdateOrderStatusBox//c.jsonStandardResult(ret, "", "")log := fmt.Sprintf("扫描装箱错误(%v): 箱号[%s] %s起止[%s-%s] 数量[%d]", common.RetErrorUpdateOrderStatusBox, Box, _type, SnStart, SnEnd, len(OkList))models.AddSystemLogByToken(token, common.LogType_Update, log)return common.RetErrorUpdateOrderStatusBox}log := fmt.Sprintf("扫描装箱正确: 箱号[%s] %s起止[%s-%s] 数量[%d]", Box, _type, SnStart, SnEnd, len(OkList))models.AddSystemLogByToken(token, common.LogType_Update, log)return common.RetOK}

3、vue代码 

<template><div class="page-container"><div class="el-form"><div style="margin-bottom: 20px;">第{{ currentNum }}/{{ totalNum }}箱</div><div class="form-group"><div class="flex"><div class="label">快运单号</div><el-input v-model="formData.expressId" ref="expressIdRef" placeholder="请扫描快运单号" @input="changeInput" @focus="focusInput('expressId')"></el-input></div></div><div class="form-group"><div class="flex"><div class="label">SN号起始</div><el-input v-model="formData.snStart" ref="snStartRef" placeholder="请扫描SN号起始" @input="changeInput"  @focus="focusInput('snStart')"></el-input></div></div><div class="form-group"><div class="flex"><div class="label">SN号终止</div><el-input v-model="formData.snEnd" ref="snEndRef" @input="changeInput" placeholder="请扫描SN号终止" @focus="focusInput('snEnd')"></el-input></div></div><div class="form-group"><div class="flex"><div class="label">箱号</div><el-input v-model="formData.boxNum" ref="boxNumRef" placeholder="请扫描箱号" @input="changeInput" @focus="focusInput('boxNum')"></el-input><div class="box-right" src="../../assets/right.png" v-if="boxChecked && boxRight"></div><div class="box-error" src="../../assets/error.png" v-if="boxChecked && !boxRight"></div></div><div class="error" v-if="boxChecked && !boxRight">快运单号 {{ formData.expressId }} 和箱号 {{ box }} 不匹配</div></div><div class="operates"><el-button type="primary" style="margin-top:50px;" @click="confirmTypeByScan">强制确认</el-button></div></div></div>
</template>
<script>
import { RECIPIENT_API_PATH } from '../../service/api';
import Vue from 'vue';
Vue.directive('paste', {// 因为一个元素只有插入dom之后,才能获取焦点updated: function(el) {alert(el.value);}
});export default {data() {return {path: '',focus: 'expressId',totalNum: 0,currentNum: 0,boxChecked: false,boxRight: true,hasError: false,snList: [], //从后台获取的每箱数据ksnList: [],errorBoxList: [],snOkList: [],ksnOkList: [],box:"",hasEnter:false,formData: {boxNum: '',snStart: '',snEnd: '',expressId: ''}};},mounted() {this.path = this.$route.query.type;console.log('path=' + this.path);document.body.onkeydown = e => {if (e.keyCode == 13) {this.enterInput()} else if (e.keyCode == 86) {}};this.$nextTick(() => {this.$refs.expressIdRef.focus();});},methods: {changeInput(){this.hasEnter = falseconsole.log("ctrl+v")setTimeout(()=>{if(!this.hasEnter){console.log("程序自动enter")this.enterInput()}},1000)},enterInput(){this.hasEnter = trueif (this.focus == 'expressId') {this.focus = 'snStart';this.$refs.snStartRef.focus();this.getBoxListByExpressID(this.snStart);} else if (this.focus == 'snStart') {this.checkSnStart();this.focus = 'snEnd';this.$refs.snEndRef.focus();this.boxChecked = false;} else if (this.focus == 'snEnd') {this.checkSnEnd();this.focus = 'boxNum';this.$refs.boxNumRef.focus();} else if (this.focus == 'boxNum') {this.checkBox();console.log('currentNum=' + this.currentNum);if (this.currentNum < this.totalNum) {this.focus = 'snStart';this.$refs.snStartRef.focus();this.formData.snStart = '';this.formData.snEnd = '';this.formData.boxNum = '';} else {this.confirmTypeByScan();}}},focusInput(str) {this.focus = str;},checkBox() {this.boxChecked = true;this.box = this.formData.boxNumif (this.snList.find(v => v.Box == this.formData.boxNum)) {this.boxRight = true;if (this.snOkList[this.currentNum]) {Object.assign(this.snOkList[this.currentNum], {Box: this.formData.boxNum});} else {this.snOkList[this.currentNum] = {Box: this.formData.boxNum};}this.currentNum = this.snOkList.length;return true;} else {if (this.ksnList.find(v => v.Box == this.formData.boxNum)) {this.boxRight = true;if (this.ksnOkList[this.currentNum]) {Object.assign(this.ksnOkList[this.currentNum], {Box: this.formData.boxNum});} else {this.ksnOkList[this.currentNum] = {Box: this.formData.boxNum};}this.currentNum = this.ksnOkList.length;return true;} else {this.boxRight = false;this.errorBoxList.push(this.formData.boxNum);if (this.snOkList[this.currentNum]) {this.snOkList.splice(this.currentNum, 1);}if (this.ksnOkList[this.currentNum]) {this.ksnOkList.splice(this.currentNum, 1);}return false;}}},checkSnStart() {if (this.snList.find(v => v.SnStart == this.formData.snStart)) {if (this.snOkList[this.currentNum]) {Object.assign(this.snOkList[this.currentNum], {SnStart: this.formData.snStart});} else {this.snOkList[this.currentNum] = {SnStart: this.formData.snStart};}return true;} else {if (this.ksnList.find(v => v.SnStart == this.formData.snStart)) {if (this.ksnOkList[this.currentNum]) {Object.assign(this.ksnOkList[this.currentNum], {SnStart: this.formData.snStart});} else {this.ksnOkList[this.currentNum] = {SnStart: this.formData.snStart};}return true;} else {this.hasError = true;this.$message({type:'error',message:'Sn号起始与快运单号不匹配'});if (this.snOkList[this.currentNum]) {this.snOkList.splice(this.currentNum, 1);}if (this.ksnOkList[this.currentNum]) {this.ksnOkList.splice(this.currentNum, 1);}return false;}return false;}},checkSnEnd() {if (this.snList.find(v => v.SnEnd == this.formData.snEnd)) {if (this.snOkList[this.currentNum]) {Object.assign(this.snOkList[this.currentNum], {SnEnd: this.formData.snEnd});} else {this.snOkList[this.currentNum] = {SnEnd: this.formData.snEnd};}return true;} else {if (this.ksnList.find(v => v.SnEnd == this.formData.snEnd)) {if (this.ksnOkList[this.currentNum]) {Object.assign(this.ksnOkList[this.currentNum], {SnEnd: this.formData.snEnd});} else {this.ksnOkList[this.currentNum] = {SnEnd: this.formData.snEnd};}return true;} else {this.hasError = true;this.$message({message:'Sn号终止与快运单号不匹配',type:"error"});if (this.snOkList[this.currentNum]) {this.snOkList.splice(this.currentNum, 1);}if (this.ksnOkList[this.currentNum]) {this.ksnOkList.splice(this.currentNum, 1);}return false;}}},confirmTypeByScan() {if (!this.hasError && this.errorBoxList.length <= 0) {let formData = new FormData();formData.append('Token', sessionStorage.getItem('token'));formData.append('ExpressID', this.formData.expressId);if (this.path == 'choice') {formData.append('Act', 'SetStatusPrepareByExpressID');//formData.append("StatusPrepare",item.StatusPrepare)} else {formData.append('Act', 'SetStatusQcByExpressID');//formData.append("StatusQc",item.StatusQc)}formData.append('ConfirmType', 2);this.$axios.post(RECIPIENT_API_PATH, formData).then(res => {if (res.data.Ret == 0) {this.$message({type:"success",message:"整单正确",duration:3000})} else {this.$message({message:res.data.Msg,type:"error",duration:3000});}}).finally(() => {this.focus = 'expressId';this.$refs.expressIdRef.focus();this.formData = {boxNum: '',snStart: '',snEnd: '',expressId: ''};this.box = ""this.totalNum = 0;this.currentNum = 0;this.boxChecked = false;});} else {let formData = new FormData();formData.append('Token', sessionStorage.getItem('token'));formData.append('ExpressID', this.formData.expressId);if (this.path == 'choice') {formData.append('Act', 'SetStatusPrepare');} else {formData.append('Act', 'SetStatusQc');}this.snOkList = this.snOkList.filter(v => {return v && v.SnStart && v.SnEnd && v.Box;});this.ksnOkList = this.ksnOkList.filter(v => {return v && v.SnStart && v.SnEnd && v.Box;});formData.append('SnOkList', JSON.stringify(this.snOkList));formData.append('KsnOkList', JSON.stringify(this.ksnOkList));this.$axios.post(RECIPIENT_API_PATH, formData).then(res => {if (res.data.Ret == 0) {} else {this.$message({type:"error",message:res.data.Msg});}}).finally(()=>{this.focus = 'expressId';this.$refs.expressIdRef.focus();this.formData = {boxNum: '',snStart: '',snEnd: '',expressId: ''};this.totalNum = 0;this.currentNum = 0;this.boxChecked = false;});}},getBoxListByExpressID() {let formData = new FormData();formData.append('Act', 'GetBoxListByExpressID');formData.append('Token', sessionStorage.getItem('token'));formData.append('ExpressID', this.formData.expressId);this.$axios.post(RECIPIENT_API_PATH, formData).then(res => {if (res.data.Ret == 0) {this.snList = res.data.Data && res.data.Data.SnList ? res.data.Data.SnList : [];this.ksnList = res.data.Data && res.data.Data.KsnList ? res.data.Data.KsnList : [];this.totalNum = res.data.Data&& res.data.Data.SnList?res.data.Data.SnList.length:0console.log("snList="+JSON.stringify(this.snList))console.log("ksnList="+JSON.stringify(this.ksnList))}else{this.$message({message:res.data.Msg,type:"error"})}});},pasteSn(e) {console.log(e.target.value);this.formData.boxNum = e.target.value;}}
};
</script><style scoped="scoped">
.div {position: relative;
}
.label{width: 150px;text-align: right;
}
.error {padding-right: 160px;left: 0px;color: red;top: 100%;margin-top: 10px;
}
.el-icon-check,
.el-icon-close {position: absolute;left: 100%;margin-left: 10px;top: 50%;transform: translateY(-50%);
}
.box-right,
.box-error {position: absolute;width: 50px;height: 50px;left: 100%;margin-left: 10px;top: 0px;
}
.box-right {background: url(../../assets/right.png) no-repeat center;background-size: contain;
}
.box-error {background: url(../../assets/error.png) no-repeat center;background-size: contain;
}
.el-form {width: 90%;
}
.el-button{width: 100%;
}
.el-table,.div__label,.div__content,.error,.el-menu-item,.el-submenu__title,.el-message__content,div{font-size:28px;
}
</style>

四、结语

本次分享结束,欢迎来撩!

完整方案介绍:https://blog.csdn.net/lildkdkdkjf/article/details/117841646

系统演示网址:http://47.113.115.218:81 演示密码:123456

微信:6550523 

《工厂订单出入库信息管理系统》模块5 -- 扫码装箱相关推荐

  1. 《工厂订单出入库信息管理系统》完整案例详解(含演示网址账号)(GoVue源码MysqlRedis数据库)

    近期开发了一套工厂订单及出入库信息管理系统,现在系统已经正式上线,我也抽出时间对之前的工作了进行了二次整理,在总结的过程中继续完善. 系统演示网址:出入库系统   演示账号:admin 密码:1234 ...

  2. 《工厂订单出入库信息管理系统》模块3 -- 收货信息管理

    一.前言 工厂订单及出入库业务的趋势是客户要求越来越高,客户需要快捷.方便.简单.一站式的出入库手续.因此,货物出入库管理信息系统要简化出入库手续,减轻人员作业量,提高工作效率,助力企业数字信息化转型 ...

  3. 《工厂订单出入库信息管理系统》模块1 -- 订单管理

    一.前言 工厂订单及出入库业务的趋势是客户要求越来越高,客户需要快捷.方便.简单.一站式的出入库手续.因此,货物出入库管理信息系统要简化出入库手续,减轻人员作业量,提高工作效率,助力企业数字信息化转型 ...

  4. 《工厂订单出入库信息管理系统》- 用户操作手册

    一 PMC 1.1 添加订单 1.2导入数据 1.2.1导入<SN> 1.2.2导入<发货申请单> 1.2.3导出<跨越物流的发货信息> 根据开始时间,结束时间导出 ...

  5. 达梦两个表模糊查询_Excel出入库管理查询工具,支持出入库信息一键查询,快捷可套用...

    最近得了一套出入库查询管理工具,一共五张表,前期设置好出入库参数,后期再繁琐的出入库信息都能一键查询,简直太省事了,话不多说,分享给大家. 出入库管理查询工具共有:参数设置表.入库明细表.出库明细表. ...

  6. springboot+mysql+基于java的员工信息管理系统 毕业设计-附源码201524

    Springboot员工信息管理系统 摘 要 由于数据库和数据仓库技术的快速发展,企业员工信管理建设越来越向模块化.智能化.自我服务和管理科学化的方向发展.员工信息管理对处理对象和服务对象,自身的系统 ...

  7. springboot+人事信息管理系统 毕业设计-附源码221507

    Springboot人事信息管理系统 摘 要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以 ...

  8. Springboot人事信息管理系统毕业设计-附源码221507

    摘 要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题.针对人事信息管理系统等问题 ...

  9. 基于JAVA游泳馆信息管理系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署

    基于JAVA游泳馆信息管理系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署 基于JAVA游泳馆信息管理系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署 本源码技术栈: 项目 ...

最新文章

  1. 预告 | AIS (ACL, IJCAI, SIGIR) 2019 论文报告会日程安排
  2. 欢迎参加天津PDC Party的活动
  3. 线性表之顺序表与单链表的区别及优缺点
  4. 容器编排技术 -- Kubernetes kubectl create 命令详解
  5. java只有值传递_为什么说java中只有值传递
  6. java备份mysql的单个表_MySQL 使用java备份某张表的操作
  7. bootstrap-table为空_JS组件Bootstrap Table使用方法详解
  8. c++线程间通信的几种方法_JAVA并发之线程amp;进程
  9. CentOS 6.6安装配置LAMP服务器(Apache+PHP5+MySQL)
  10. cs231n_2020 作业knn笔记
  11. 在linux中PHP的集成环境吗,linux有php集成环境吗
  12. edcoder数据结构第1关:基于BF算法的病毒感染监测
  13. 传感器实训心得体会_传感器实训心得体会
  14. AppStore上线规则
  15. OpenGL ES —— PBO 使用
  16. Python 文件目录操作
  17. 2011年5月51CTO壁纸点评活动获奖名单【已结束】
  18. Informatica基础系列(一)——Helloworld
  19. 英语基础语法(十二)-虚拟语气
  20. python计算灰色关联度

热门文章

  1. 实用的SEO必用的3款关键词查询工具
  2. 珠海先达MES系统在电镀车间的应用
  3. java/php/net/python果蔬在线销售和配送系统设计
  4. JRA7xx M4 抓log
  5. 前OPPO高管王腾,担任小米中国区销售运营一部负责人
  6. 服务器没问题 网站确打不开,域名和国外高防服务器都没问题,网站为何打不...
  7. 突发!Facebook一员工在公司总部跳楼身亡,传是程序员;微软开源新字体Cascadia Code;华为下一个研究前沿是AI...
  8. 构造/析构/赋值运算--龙之介《Effective C++》实验室
  9. 如何在Controll 获取数据库数据
  10. APP注册通用用户协议