diff --git a/conf/config.go b/conf/config.go index 554c42b..42f0303 100644 --- a/conf/config.go +++ b/conf/config.go @@ -1,11 +1,13 @@ package conf import ( + "LAPP_SJA_ME/utils" + "github.com/spf13/viper" "gopkg.in/yaml.v2" "os" ) -var DbConfig *EnvConfig +var DbConfig EnvConfig type EnvConfig struct { DbType string `yaml:"dbtype"` @@ -18,6 +20,8 @@ type EnvConfig struct { TemplatePath string `yaml:"templatepath"` ReadTaskInterval int `yaml:"readtaskinterval"` PrinterType string `yaml:"printertype"` + Printnum int `yaml:"printnum"` + Msgtype string `yaml:"msgtype"` Finr int `yaml:"finr"` Inbox string `yaml:"inbox"` Outbox string `yaml:"outbox"` @@ -28,16 +32,62 @@ type EnvConfig struct { //read yaml config //注:path为yaml或yml文件的路径 -func ReadYamlConfig(path string) (*EnvConfig, error) { - DbConfig := &EnvConfig{} +func ReadYamlConfig() error { + path, err := utils.GetCurrentPath("conf/config.yaml") + if err != nil { + return err + } f, err := os.Open(path) if err != nil { - return nil, err + return err } else { - yaml.NewDecoder(f).Decode(DbConfig) + yaml.NewDecoder(f).Decode(&DbConfig) } defer f.Close() - return DbConfig, nil + return nil +} + +var AppInfo Config + +type Config struct { + *App `mapstructure:"app"` + *ETCD `mapstructure:"etcd"` +} + +type App struct { + Port int `yaml:"port"` + TaskNums int `yaml:"tasknums"` + ErrNums int `yaml:"errnums"` + ShellPath string `yaml:"shellpath"` + LocalAddr string `yaml:"localaddr"` + Mod string `yaml:"mod"` + Name string `yaml:"name"` + UseETCD bool `yaml:"useetcd"` +} + +type ETCD struct { + Addrs []string `yaml:"addrs"` + Timeout int `yaml:"timeout"` + LockLease int64 `yaml:"locklease"` + ServiceLease int64 `yaml:"servicelease"` +} + +func InitConfig() (err error) { + baseDir, err := utils.GetCurrentPath("conf") + if err != nil { + return + } + viper.SetConfigName("app_config") + viper.SetConfigType("yaml") + viper.AddConfigPath(baseDir) + + if err = viper.ReadInConfig(); err != nil { + return + } + if err = viper.Unmarshal(&AppInfo); err != nil { + return + } + return nil } diff --git a/main.go b/main.go index 8ee9f9a..7a8d4ec 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,6 @@ package main import ( "LAPP_SJA_ME/conf" "LAPP_SJA_ME/db" - Engine "LAPP_SJA_ME/engine" "LAPP_SJA_ME/etcd" "LAPP_SJA_ME/inits/parse" "LAPP_SJA_ME/lab" @@ -39,9 +38,9 @@ func (p *program) Stop(s service.Service) error { func main() { svcConfig := &service.Config{ - Name: "LeitServer", - DisplayName: "LeitServer", - Description: "this is LeitServer", + Name: "G38_LAPP_ME_WEB", + DisplayName: "G38_LAPP_ME_WEB", + Description: "this is G38_LAPP_ME_WEB", } prg := &program{} @@ -54,11 +53,19 @@ func main() { switch verb { case "install": s.Install() - log.Println("服务安装成功") + log.Println("Install success") return case "remove": s.Uninstall() - log.Println("服务卸载成功") + log.Println("remove success") + return + case "start": + s.Start() + log.Println("start server") + return + case "stop": + s.Stop() + log.Println("stop server") return } @@ -79,7 +86,10 @@ func imain() { defer glog.Flush() fmt.Println(baseDir) - baseDir = utils.EnsureDir(baseDir) + baseDir,err := utils.GetCurrentPath(baseDir) + if err != nil { + glog.InfoExtln("baseDir err :", err) + } fmt.Println(baseDir) pathLogDir := filepath.Join(baseDir, "glog") fmt.Println(pathLogDir) @@ -88,7 +98,7 @@ func imain() { glog.Infoln("启动日志", "InitDB return success") //初始化数据库 - err := db.InitDb() + err = db.InitDb() if err != nil { glog.InfoExtln("数据库加载失败", err) } @@ -96,7 +106,14 @@ func imain() { parse.AppOtherParse() //加载配置 - conf, err := conf.ReadYamlConfig(conf.Confurl) + err = conf.InitConfig() + if err != nil { + log.Printf("failed to read yaml config due to: %v", err) + return + } + + //加载配置 + err = conf.ReadYamlConfig() if err != nil { log.Printf("failed to read yaml config due to: %v", err) return @@ -111,19 +128,32 @@ func imain() { app.RegisterView(iris.HTML("./web/public", ".html")) // 设置静态资源 app.StaticWeb("/public", "./web/public") - //注册服务 - //go etcd.Etcdrun() - //检测 - //go func() { - // http.ListenAndServe("0.0.0.0:8899", nil) - //}() + //创建etcd连接 if err = etcd.InitJobLock(); err != nil { glog.Infoln("初始化EtCD连接", "InitJobLock return fail") return } + + //创建etcd监听连接 + if err = etcd.InitEtcdClient(); err != nil { + glog.Infoln("初始化EtCD连接", "InitJobLock return fail") + return + } + + // register app service to etcd + if conf.AppInfo.UseETCD { + CheckServiceDao := etcd.NewETCDServiceImplement(etcd.AppEtcdClient, conf.AppInfo.App.LocalAddr) + defer CheckServiceDao.RevokeLease() + err = CheckServiceDao.RegisterService(conf.AppInfo.App.Name) + if err != nil { + log.Fatal("register service to etcd failed, error:", err) + } + } + + //打印服务 - go Engine.RunEngine(conf) + //go Engine.RunEngine(config) //开启etl任务 go task.CreateCacheTask() @@ -133,5 +163,6 @@ func imain() { //启动监听端口 app.Run(iris.Addr(":8090"), iris.WithConfiguration(parse.C)) + //app.Run(iris.Addr(":9003"), iris.WithConfiguration(parse.C)) } diff --git a/task/func.go b/task/func.go index 50ebc22..6cfd11a 100644 --- a/task/func.go +++ b/task/func.go @@ -4,6 +4,7 @@ import ( "LAPP_SJA_ME/db" "LAPP_SJA_ME/etcd" "LAPP_SJA_ME/utils" + "LAPP_SJA_ME/web/middleware/glog" "LAPP_SJA_ME/web/models" "fmt" "time" @@ -24,7 +25,7 @@ LOOP: err := etcd.G_jobLock.TryLock("lock") if err != nil { fmt.Println("pln_workorder groutine lock fail!") - time.Sleep(5 * time.Millisecond) + time.Sleep(2 * time.Millisecond) goto LOOP } fmt.Println("pln_workorder groutine lock success!") @@ -38,35 +39,49 @@ LOOP: //判断传入状态 switch status { case 40: - //更新生产订单表 - _, err := session.Table("pln_workorder").Cols("status").Where("finr = ? and workordernr = ? and status <= ?", finr, workordernr, status).Update(&map[string]interface{}{"status": 40}) + glog.InfoExtln("UpdatePlnWorkorder", "workordernr:", workordernr, status, optime) + //查询生产订单对应的客户订单是否有小于80状态的订单 + var pln models.Pln_workorder + _, err = session.Table("pln_workorder").Where("finr = ? and workordernr = ?", finr, workordernr).Get(&pln) if err != nil { + glog.InfoExtln("UpdatePlnWorkorder", "err:", err) session.Rollback() session.Close() etcd.G_jobLock.UnLock() return err } - //查询生产订单对应的客户订单是否有小于80状态的订单 - var pln models.Pln_workorder - _, err = session.Table("pln_workorder").Where("finr = ? and workordernr = ?", finr, workordernr).Get(&pln) + if pln.Status > 40 { + glog.InfoExtln("UpdatePlnWorkorder", "err:", "订单状态大于40") + session.Rollback() + session.Close() + etcd.G_jobLock.UnLock() + return nil + } + //更新生产订单表 + _, err := session.Table("pln_workorder").Cols("status").Where("finr = ? and workordernr = ?", finr, workordernr).Update(&map[string]interface{}{"status": 40}) if err != nil { + glog.InfoExtln("UpdatePlnWorkorder", "err:", err) session.Rollback() session.Close() etcd.G_jobLock.UnLock() return err } + //更新客户订单 - _, err = session.Table("pln_custorder").Cols("status").Where("finr = ? and custordernr = ? and status <= ?", finr, pln.Custordernr, status).Update(&map[string]interface{}{"status": 40}) + _, err = session.Table("pln_custorder").Cols("status").Where("finr = ? and custordernr = ? ", finr, pln.Custordernr).Update(&map[string]interface{}{"status": 40}) if err != nil { + glog.InfoExtln("UpdatePlnWorkorder", "err:", err) session.Rollback() session.Close() etcd.G_jobLock.UnLock() return err } case 80: + glog.InfoExtln("UpdatePlnWorkorder", "workordernr:", workordernr, status, optime) //更新生产订单表 - _, err := session.Table("pln_workorder").Cols("status", "schedbegtime").Where("finr = ? and workordernr = ? and status <= ?", finr, workordernr, status).Update(&map[string]interface{}{"status": 80, "schedbegtime": optime}) + _, err := session.Table("pln_workorder").Cols("status", "schedbegtime").Where("finr = ? and workordernr = ?", finr, workordernr).Update(&map[string]interface{}{"status": 80, "schedbegtime": optime}) if err != nil { + glog.InfoExtln("UpdatePlnWorkorder", "err:", err) session.Rollback() session.Close() etcd.G_jobLock.UnLock() @@ -76,6 +91,7 @@ LOOP: var pln models.Pln_workorder _, err = session.Table("pln_workorder").Where("finr = ? and workordernr = ?", finr, workordernr).Get(&pln) if err != nil { + glog.InfoExtln("UpdatePlnWorkorder", "err:", err) session.Rollback() session.Close() etcd.G_jobLock.UnLock() @@ -84,6 +100,7 @@ LOOP: var plc models.Pln_workorder ok, err := session.Table("pln_workorder").Where("finr = ? and custordernr = ? and status < ?", finr, pln.Custordernr, status).Get(&plc) if err != nil { + glog.InfoExtln("UpdatePlnWorkorder", "err:", err) session.Rollback() session.Close() etcd.G_jobLock.UnLock() @@ -93,6 +110,7 @@ LOOP: //生产订单不存在小于80的状态,更新生产订单 _, err := session.Table("pln_custorder").Cols("status").Where("finr = ? and custordernr = ?", finr, pln.Custordernr).Update(&map[string]interface{}{"status": 80}) if err != nil { + glog.InfoExtln("UpdatePlnWorkorder", "err:", err) session.Rollback() session.Close() etcd.G_jobLock.UnLock() @@ -114,13 +132,13 @@ func UpdatePlnBatchorder(finr int, batchordernr string, status int, actqty int, switch status { case 40: //更新批次订单表 - _, err := engine.Table("pln_batchorder").Cols("status", "actqty", "actbegtime").Where("finr = ? and batchordernr = ? and status <= ?", finr, batchordernr, status).Update(&map[string]interface{}{"status": 40, "actqty": actqty, "actbegtime": optime}) + _, err := engine.Table("pln_batchorder").Cols("status", "actqty", "actbegtime").Where("finr = ? and batchordernr = ?", finr, batchordernr).Update(&map[string]interface{}{"status": 40, "actqty": actqty, "actbegtime": optime}) if err != nil { return err } case 80: //更新生产订单表 - _, err := engine.Table("pln_batchorder").Cols("status", "actqty", "actendtime").Where("finr = ? and batchordernr = ? and status <= ?", finr, batchordernr, status).Update(&map[string]interface{}{"status": 80, "actqty": actqty, "actendtime": optime}) + _, err := engine.Table("pln_batchorder").Cols("status", "actqty", "actendtime").Where("finr = ? and batchordernr = ?", finr, batchordernr).Update(&map[string]interface{}{"status": 80, "actqty": actqty, "actendtime": optime}) if err != nil { return err } diff --git a/task/task.go b/task/task.go index 431dc38..e5fbc2a 100644 --- a/task/task.go +++ b/task/task.go @@ -269,6 +269,7 @@ func ToLeadDataBase() { time.Sleep(1 * time.Second) continue } + glog.InfoExtln("UpdatePlnWorkorder", "len(data):", len(data)) //第二步:导入从库, for _, v := range data { //判断执行次数 @@ -280,22 +281,26 @@ func ToLeadDataBase() { //json解析 err := json.Unmarshal([]byte(v.Data), &tems) if err != nil { - glog.InfoExtln("etl导入从库", "Unmarshal err is :", err) + glog.InfoExtln("etl导入从库err", "Unmarshal err is :", err) continue } switch v.Funcspec { case "UpdatePlnWorkorder": finr := v.Finr workordernr := utils.ValueToString(tems["ordernr"], "") + glog.InfoExtln("UpdatePlnWorkorder", "workordernr task.go 295:", workordernr) status := utils.ValueToInt(tems["status"], 0) tem := utils.ValueToString(tems["optime"], "") - temtime, _ := time.Parse("2006-01-02T15:04:05Z07:00", tem) + temtime, err := time.Parse("2006-01-02T15:04:05Z07:00", tem) + if err != nil { + glog.InfoExtln("UpdatePlnWorkorder", "temtime err is :", err) + continue + } optime := temtime.Format("20060102150405") + glog.InfoExtln("UpdatePlnWorkorder", "workordernr task.go 295:", workordernr) err = UpdatePlnWorkorder(finr, workordernr, status, optime) if err != nil { - glog.InfoExtln("etl导入从库", "UpdatePlnWorkorder err is :", err) - glog.InfoExtln("etl导入从库", "ordernr is :", workordernr) - glog.InfoExtln("etl导入从库", "ordernr is :", status) + glog.InfoExtln("UpdatePlnWorkorder", "UpdatePlnWorkorder err is :", err) continue } //更新mongdb数据flag @@ -319,7 +324,7 @@ func ToLeadDataBase() { optime := temtime.Format("20060102150405") err = UpdatePlnBatchorder(finr, batchordernr, status, actqty, optime) if err != nil { - glog.InfoExtln("etl导入从库", "UpdatePlnBatchorder err is :", err) + glog.InfoExtln("UpdatePlnBatchorder", "UpdatePlnBatchorder err is :", err) continue } //更新mongdb数据flag diff --git a/utils/const.go b/utils/const.go index 9a31f21..3c42d2d 100644 --- a/utils/const.go +++ b/utils/const.go @@ -18,4 +18,12 @@ package utils * ******************************************************************************/ -const Finr = 100 \ No newline at end of file +const Finr = 100 + +// ETCD z状态 +const ( + // 任务状态 + SERVICE_STATUS_RUNNING = "RUNNING" + SERVICE_STATUS_STOP = "STOP" + SERVICE_STATUS_PAUSE = "PAUSE" +) \ No newline at end of file diff --git a/web/controllers/lab_controller.go b/web/controllers/lab_controller.go index 9be484d..b9e970b 100644 --- a/web/controllers/lab_controller.go +++ b/web/controllers/lab_controller.go @@ -56,7 +56,7 @@ func UploadLab(ctx iris.Context) { return } } - savePath = utils.EnsureDir(savePath) + savePath,_ = utils.GetCurrentPath(savePath) // 初始化 lab = &models.LAB{} if err = models.ParseLabEdi(savePath, lab); err != nil { diff --git a/web/middleware/casbins/casbins.go b/web/middleware/casbins/casbins.go index cec7df7..bd6e8fd 100644 --- a/web/middleware/casbins/casbins.go +++ b/web/middleware/casbins/casbins.go @@ -19,24 +19,27 @@ import ( // 获取Enforcer func NewCasbin() (*casbin.Enforcer, error) { - c := conf.MasterDbConfig driveSource := fmt.Sprintf("server=%s;database=%s;user id=%s;password=%s;port=%d;encrypt=disable", - c.Host, c.DbName, c.User, c.Pwd, c.Port) + conf.DbConfig.Server, conf.DbConfig.DbName, conf.DbConfig.User, conf.DbConfig.Password, conf.DbConfig.Port) a, err := xormadapter.NewAdapter(conf.DriverName, driveSource, true) if err != nil { log.Printf("连接数据库错误: %v", err) - return nil,err + return nil, err + } + savePath, err := utils.GetCurrentPath("conf/rbac_model.conf") + if err != nil { + log.Printf("savePath路径错误: %v", err) + return nil, err } - savePath := utils.EnsureDir("conf/rbac_model.conf") e, err := casbin.NewEnforcer(savePath, a) - if err !=nil{ + if err != nil { //日志 logs := new(models.LeitServerLog) logs.File = "/casbins.go" logs.Level = "debug" logs.Function = "CheckPermissions:NewCasbin()" - logs.Message ="conf/rbac_model.conf文件加载错误" + logs.Message = "conf/rbac_model.conf文件加载错误" logs.Operator = "debug" logs.TimeStamp = utils.TimeFormat(time.Now(), "yyyyMMddHHmmss") logs.InsertRecord() @@ -65,19 +68,19 @@ func CheckPermissions(ctx context.Context) bool { // 去除空格 //uid := strings.Replace(user.Userid, " ", "", -1) uid := strings.TrimSpace(user.Role) - e,err:=NewCasbin() - if err !=nil { + e, err := NewCasbin() + if err != nil { supports.Unauthorized(ctx, supports.PermissionsLess, nil) ctx.StopExecution() return false } - ok,err = e.Enforce(uid, ctx.Path(), ctx.Method()) + ok, err = e.Enforce(uid, ctx.Path(), ctx.Method()) log.Println("----------------", uid, ctx.Path(), ctx.Method()) log.Println(ok) - if err != nil{ + if err != nil { log.Printf("casbin权限控制错误: %v", err) } - if !ok{ + if !ok { supports.Unauthorized(ctx, supports.PermissionsLess, nil) ctx.StopExecution() return false diff --git a/web/models/buffer_model.go b/web/models/buffer_model.go index 758d185..e93dbf6 100644 --- a/web/models/buffer_model.go +++ b/web/models/buffer_model.go @@ -121,7 +121,7 @@ func (t *Buffer) FindData() []*Buffer { }, &options.FindOptions{ Skip: &skip, Limit: &limit, - Sort: bson.D{{"timestamp", -1}}, + Sort: bson.D{{"timestamp", 1}}, }) if err != nil { return nil @@ -178,37 +178,28 @@ func (t *Buffer) UpdateDataTimes() error { client := db.MgoDb() //2.选择数据库,数据表 collect := client.Database(conf.MongDbConfig.DbName).Collection("buffer") - if t.Times > 5 { - // 删除 - _, err := collect.DeleteOne(context.Background(), bson.M{"orderid": t.Orderid}) - if err != nil { - return err - } - return nil - } else { - new := &Buffer{ - Orderid: t.Orderid, - Eid: t.Eid, - Finr: t.Finr, - Data: t.Data, - TimeStamp: t.TimeStamp, - Todrivername: t.Todrivername, - Totable: t.Totable, - Todb: t.Todb, - Status: t.Status, - Message: t.Message, - Funcspec: t.Funcspec, - Dbtype: t.Dbtype, - Times: t.Times + 1, - Flag: 0, - } - update := bson.M{"$set": new} - _, err := collect.UpdateOne(context.Background(), bson.M{"orderid": new.Orderid}, update) - if err != nil { - return err - } - return nil + new := &Buffer{ + Orderid: t.Orderid, + Eid: t.Eid, + Finr: t.Finr, + Data: t.Data, + TimeStamp: utils.TimeFormat(time.Now(), "yyyyMMddHHmmss"), + Todrivername: t.Todrivername, + Totable: t.Totable, + Todb: t.Todb, + Status: t.Status, + Message: t.Message, + Funcspec: t.Funcspec, + Dbtype: t.Dbtype, + Times: t.Times + 1, + Flag: 0, } + update := bson.M{"$set": new} + _, err := collect.UpdateOne(context.Background(), bson.M{"orderid": new.Orderid}, update) + if err != nil { + return err + } + return nil } diff --git a/web/models/etltab_model.go b/web/models/etltab_model.go index db5d566..495bb96 100644 --- a/web/models/etltab_model.go +++ b/web/models/etltab_model.go @@ -3,6 +3,7 @@ package models import ( "LAPP_SJA_ME/db" "LAPP_SJA_ME/utils" + "LAPP_SJA_ME/web/middleware/glog" "errors" "github.com/go-xorm/xorm" "strings" @@ -221,6 +222,7 @@ func (t *Etltab) SelectArr() ([]Etltablst, error) { func (t *Etltab) SelectAll() ([]Etltab, error) { es := db.Eloquent.Slaves() e := es[0] + e.ShowSQL(true) data := make([]Etltab, 0) err := e.Table("etltab").Where("finr = ? and status != 1", t.Finr).Find(&data) if err != nil { @@ -234,7 +236,7 @@ func (t *Etltab) SelectAll() ([]Etltab, error) { } data[k].Valst = datalist } - + glog.InfoExtln("Etl","len(data) :",len(data)) return data, nil } diff --git a/web/models/me_attribute_model.go b/web/models/me_attribute_model.go index 68c9b1c..252499d 100644 --- a/web/models/me_attribute_model.go +++ b/web/models/me_attribute_model.go @@ -416,7 +416,7 @@ func (t *MeAttribute) ReadData() (string, string, error) { name := utils.MakeOrderSn("属性主数据") filename := name + ".xlsx" //文件名 - exceldir := utils.EnsureDir("web/public/uploadxlsx") // 目录+文件名 + exceldir,_ := utils.GetCurrentPath("web/public/uploadxlsx") // 目录+文件名 excelfile := exceldir + "/" + filename err = file.Save(excelfile) if err != nil { diff --git a/web/models/me_part_model.go b/web/models/me_part_model.go index a8e794a..3dcdffd 100644 --- a/web/models/me_part_model.go +++ b/web/models/me_part_model.go @@ -251,7 +251,7 @@ func (t *MePart) ReadData() (string, string, error) { name := utils.MakeOrderSn("零件主数据") filename := name + ".xlsx" //文件名 - exceldir := utils.EnsureDir("web/public/uploadxlsx") // 目录+文件名 + exceldir,_ := utils.GetCurrentPath("web/public/uploadxlsx") // 目录+文件名 excelfile := exceldir + "/" + filename err = file.Save(excelfile) if err != nil { diff --git a/web/models/me_partrule_model.go b/web/models/me_partrule_model.go index 17307cf..c152e91 100644 --- a/web/models/me_partrule_model.go +++ b/web/models/me_partrule_model.go @@ -319,7 +319,7 @@ func (t *MePartRule) ReadData() (string, string, error) { name := utils.MakeOrderSn("零件规则") filename := name + ".xlsx" //文件名 - exceldir := utils.EnsureDir("web/public/uploadxlsx") // 目录+文件名 + exceldir,_ := utils.GetCurrentPath("web/public/uploadxlsx") // 目录+文件名 excelfile := exceldir + "/" + filename err = file.Save(excelfile) if err != nil { diff --git a/web/models/pln_forecast_item_dailydemand_model.go b/web/models/pln_forecast_item_dailydemand_model.go index b4dca1a..3db50c5 100644 --- a/web/models/pln_forecast_item_dailydemand_model.go +++ b/web/models/pln_forecast_item_dailydemand_model.go @@ -892,7 +892,7 @@ func (t *PlnForecastItemDailydemand) ReadExcelMonthdemand(timedate string,articl name := utils.MakeOrderSn("月报") filename := name + ".xlsx" //文件名 - exceldir := utils.EnsureDir("web/public/uploadxlsx") // 目录+文件名 + exceldir,_ := utils.GetCurrentPath("web/public/uploadxlsx") // 目录+文件名 excelfile := exceldir + "/" + filename err = file.Save(excelfile) if err != nil { @@ -1068,7 +1068,7 @@ func (t *PlnForecastItemDailydemand) ReadExcelDaydemand(timedate string,articles name := utils.MakeOrderSn("日报") filename := name + ".xlsx" //文件名 - exceldir := utils.EnsureDir("web/public/uploadxlsx") // 目录+文件名 + exceldir,_ := utils.GetCurrentPath("web/public/uploadxlsx") // 目录+文件名 excelfile := exceldir + "/" + filename err = file.Save(excelfile) if err != nil { @@ -1245,7 +1245,7 @@ func (t *PlnForecastItemDailydemand) ReadExcelDemand(articles string) (string, s name := utils.MakeOrderSn("预测统计") filename := name + ".xlsx" //文件名 - exceldir := utils.EnsureDir("web/public/uploadxlsx") // 目录+文件名 + exceldir,_ := utils.GetCurrentPath("web/public/uploadxlsx") // 目录+文件名 excelfile := exceldir + "/" + filename err = file.Save(excelfile) if err != nil { @@ -2098,7 +2098,7 @@ func (t *PlnForecastItemDailydemand) ReadYearExcelDemand(timedate string,article name := utils.MakeOrderSn("预测统计") filename := name + ".xlsx" //文件名 - exceldir := utils.EnsureDir("web/public/uploadxlsx") // 目录+文件名 + exceldir,_ := utils.GetCurrentPath("web/public/uploadxlsx") // 目录+文件名 excelfile := exceldir + "/" + filename err = file.Save(excelfile) if err != nil {