网站首页 > 技术文章 正文
一、前言
工厂订单及出入库业务的趋势是客户要求越来越高,客户需要快捷、方便、简单、一站式的出入库手续。因此,货物出入库管理信息系统要简化出入库手续,减轻人员作业量,提高工作效率,助力企业数字信息化转型。
之前整理过该系统的完整解决方案,有兴趣的参考文章:《工厂订单出入库信息管理系统》完整解决方案(含演示账号)
二、整体架构设计
开发语言:
- 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 controllers
import (
"fmt"
"github.com/astaxie/beego"
"github.com/robfig/cron"
"os"
"os/exec"
"productManage/common"
writelog "productManage/log"
"strconv"
"strings"
"time"
"productManage/models"
)
// SystemController operations for System
type SystemController struct {
BaseController
}
var GDatabaseBackupTime string //数据库自动备份时间,例如20:15:16
var GDatabaseBackupPath string //备份路径
func CronDbBackup() {
go func() {
time.Sleep(time.Second*10000)//启动的时候数据库还没连接,这里等一下
crontab := cron.New()
task := func() {
s, err := models.GetSystem()
if err != nil{
writelog.WriteDebug("GetSystem DB Error")
return
}
GDatabaseBackupTime = s.DatabaseBackupTime
GDatabaseBackupPath = s.DatabaseBackupPath
os.MkdirAll(GDatabaseBackupPath, os.ModePerm)
ss := strings.Split(GDatabaseBackupTime, ":")
if len(ss)<3 {
writelog.WriteDebug("DatabaseBackupTime Error")
return
}
hour, _ := strconv.Atoi(ss[0])
minute, _ := strconv.Atoi(ss[1])
second, _ := strconv.Atoi(ss[2])
//writelog.WriteDebug("%d %d %d", hour, minute, second)
now := time.Now()
//writelog.WriteDebug("%d, %d, %d", now.Hour(), now.Minute(), now.Second())
if now.Hour() == hour && now.Minute() == minute && now.Second() == second {
writelog.WriteDebug("DatabaseBackupTime------------------------------------------")
dbname :=beego.AppConfig.String("db::dbname")
dbuser :=beego.AppConfig.String("db::dbuser")
dbpassword :=beego.AppConfig.String("db::dbpassword")
dbhost :=beego.AppConfig.String("db::dbhost")
host := strings.Split(dbhost, ":")
exec.Command("./dbbackup.sh", GDatabaseBackupPath, dbname, dbuser, dbpassword, host[0], "&").Start() //不用等待执行完毕
//./dbbackup.sh /home/sql_bak jld root jld_db 192.168.1.230
//mysqldump -uroot -pjld_db -h192.168.1.230 jld --skip-lock-tables -q| sed -e '/SESSION.SQL_LOG_BIN/d' > temp.sql
}
}
crontab.AddFunc("*/1 * * * *", task) //每秒一次
crontab.Start()
select {}
}()
}
// URLMapping ...
func (c *SystemController) URLMapping() {
c.Mapping("Post", c.Post)
}
// Post ...
// @Title Post
// @Description create System
// @Param body body models.System true "body for System content"
// @Success 201 {int} models.System
// @Failure 403 body is empty
// @router / [post]
func (c *SystemController) Post() {
if c.CheckToken() < 0 {
return
}
act := c.GetString("Act")
ret := common.RetOK
if act == common.ActGetSystem {
s, err := models.GetSystem()
if err != nil {
ret = common.RetErrorActGetSystem
c.jsonStandardResult(ret, common.GetErrMsg(ret), err.Error())
return
} else {
c.jsonStandardResult(ret, common.GetErrMsg(ret), s)
}
return
}
if act == common.ActSetSystem {
DatabaseBackupPath := c.GetString("DatabaseBackupPath")
DatabaseBackupTime := c.GetString("DatabaseBackupTime")
LogAutocleanCycle, _ := c.GetInt("LogAutocleanCycle")
err := models.EditSystem(DatabaseBackupPath, DatabaseBackupTime, LogAutocleanCycle)
if err != nil {
ret = common.RetErrorActSetSystem
c.jsonStandardResult(ret, common.GetErrMsg(ret), err.Error())
return
}
GDatabaseBackupTime = DatabaseBackupTime//赋值给全局变量,立即生效
GDatabaseBackupPath = DatabaseBackupPath
c.jsonStandardResult(ret, common.GetErrMsg(ret), "")
models.AddSystemLogByToken(c.GetString("Token"), common.LogType_Update, fmt.Sprintf("设置系统参数,DatabaseBackupPath=%s,DatabaseBackupTime=%s,LogAutocleanCycle=%d",
DatabaseBackupPath, DatabaseBackupTime, LogAutocleanCycle))
return
}
}
3、vue代码
<template>
<el-form label-position="right">
<div class="">
<div class="form-group flex">
<div class="label">每日自动备份时间</div>
<el-input v-model="backupTime" @blur="changeBackupTime"></el-input>
</div>
<div class="error" v-if="timeError">时间格式不正确,正确格式为00:00:00</div>
</div>
<div class="" style="text-align: left;">
<div class="form-group flex">
<div class="label">自动备份路径</div>
<el-input v-model="backupPath"></el-input>
</div>
<div class="meta">备份文件以日期命名,格式:20200419.bak</div>
</div>
<div class="form-group flex">
<div class="label">定期删除日志</div>
<el-input v-model="logClearTime" style="width:80%"></el-input>
<span class="unit">单位:天</span>
</div>
<div class="operates">
<el-button type="primary" @click="confirmClick">确定</el-button>
<el-button @click="cancelClick">取消</el-button>
</div>
</el-form>
</template>
<script>
import {SYSTEM_API_PATH} from "../../service/api"
export default{
data(){
return{
timeError:false,
backupTime:"",
backupPath:"",
logClearTime:""
}
},
created(){
this.getSystemInfo()
},
methods:{
changeBackupTime(){
var reg = /^(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d$/; //时间格式的正则表达式
if (!reg.test(this.backupTime)) {
this.timeError = true
}else{
this.timeError = false
}
},
getSystemInfo(){
let formData = new FormData()
formData.append("Token",sessionStorage.getItem("token"))
formData.append("Act","GetSystem")
this.$axios.post(SYSTEM_API_PATH,formData).then(res=>{
if(res.data.Ret == 0){
this.backupPath = res.data.Data.DatabaseBackupPath
this.backupTime = res.data.Data.DatabaseBackupTime
this.logClearTime = res.data.Data.LogAutocleanCycle
}else{
this.$message({
message:res.data.Msg,
type:"error",
duration:3000
});
}
})
},
confirmClick(){
this.changeBackupTime()
if(this.timeError){
return
}
let formData = new FormData()
formData.append("Token",sessionStorage.getItem("token"))
formData.append("Act","SetSystem")
formData.append("DatabaseBackupPath",this.backupPath)
formData.append("DatabaseBackupTime",this.backupTime)
formData.append("LogAutocleanCycle",this.logClearTime)
this.$axios.post(SYSTEM_API_PATH,formData).then(res=>{
if(res.data.Ret == 0){
this.$message({
message:"系统设置成功",
type:"success",
duration:3000
})
}else{
this.$message({
message:res.data.Msg,
type:"error",
duration:3000
});
}
})
},
cancelClick(){
}
}
}
</script>
<style scoped="script">
.el-form-item{
text-align:left;
margin-top: 30px;
}
.error{
position: relative;
left:0px;
color:red;
top: 100%;
margin-top: 10px;
text-align: left;
}
.unit{
flex-shrink: 0;
}
</style>
四、结语
本次分享结束,欢迎来撩!
完整方案介绍:《工厂订单出入库信息管理系统》完整解决方案(含演示账号)
系统演示网址:factory http://47.113.115.218:81 演示密码:123456
?
- 上一篇: Java 字符串转日期或日期转字符串
- 下一篇: 学长半夜手把手教你调优(怎么搞定学长)
猜你喜欢
- 2024-09-20 非常详细!如何理解表格存储的多版本、生命周期和有效版本偏差
- 2024-09-20 6种快速统计代码执行时间的方法,真香
- 2024-09-20 Java 开发者最困惑的四件事(java开发遇到问题如何解决)
- 2024-09-20 【Java多线程】定时器Timer(java定时器线程池)
- 2024-09-20 还在用new Date计算任务执行时间?强烈建议使用这个API
- 2024-09-20 “抄”代码,再也不用上谷歌复制粘贴了
- 2024-09-20 java获取当前时间的四种方法代码实例
- 2024-09-20 撸完这篇线程池,我快咳血了(线程池有什么用)
- 2024-09-20 JAVA轮询遍历两个数组进行比较(遍历数组 java)
- 2024-09-20 蒙圈了?System.currentTimeMillis()存在性能问题
- 1514℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 563℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 508℃MySQL service启动脚本浅析(r12笔记第59天)
- 486℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 485℃启用MySQL查询缓存(mysql8.0查询缓存)
- 465℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 445℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 442℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- c语言min函数头文件 (68)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)