Browse Source

新版本伊起牛

baishaojie 1 year ago
commit
0f58516b5e

+ 0 - 0
1a 伊启牛.txt


BIN
KPTAdmin32.exe


BIN
PrconsoleV2.4.exe


BIN
PrconsoleV2.4.zip


+ 10 - 0
app.ini

@@ -0,0 +1,10 @@
+
+
+[database]
+Type = mysql
+User = root
+Password = root
+Host = localhost
+Name = tmrwatch
+TablePrefix =
+FarmCode = 221141

BIN
go_build_translate_.exe


+ 3 - 0
linux64.bat

@@ -0,0 +1,3 @@
+set GOARCH=amd64
+set GOOS=linux
+go build -o tmrgo

+ 1055 - 0
main.go

@@ -0,0 +1,1055 @@
+package main
+
+import (
+	"encoding/json"
+	"encoding/xml"
+	"fmt"
+	"os"
+	"strconv"
+	"strings"
+	"time"
+
+	"./models"
+	"./pkg/setting"
+	"github.com/astaxie/beego/logs"
+	"github.com/pkg/errors"
+	//"unsafe"
+)
+
+var (
+	strMethod      string // 输入的方法名称
+	strOutFilePath string //保存路径
+	strDate        string // 操作日期
+	FarmCode       string // 牧场编号
+)
+
+type DataXML struct {
+	XMLName xml.Name    `xml:"DataXML"`
+	Head    XMLHead     `xml:"Head"`
+	Record  []XMLRecord `xml:"Record"`
+}
+type DataXMLMix struct {
+	XMLName xml.Name       `xml:"DataXML"`
+	Head    XMLHead        `xml:"Head"`
+	Record  []XMLRecordMix `xml:"Record"`
+}
+type DataXMLResi struct {
+	XMLName xml.Name        `xml:"DataXML"`
+	Head    XMLHead         `xml:"Head"`
+	Record  []XMLRecordResi `xml:"Record"`
+}
+type XMLHead struct {
+	SystemCode string `xml:"SystemCode"`
+	MappingID  string `xml:"MappingID"`
+	Type       string `xml:"Type"`
+	FarmCode   string `xml:"FarmCode"`
+	DataNum    string `xml:"DataNum"`
+	Version    string `xml:"Version"`
+}
+type XMLRecord struct {
+	FeedCode            string
+	FeedName            string
+	FarmCode            string
+	FeedDate            string
+	Banci               string
+	BarName             string
+	GroupTypeCode       string
+	GroupTypeName       string
+	CowAmount           string
+	PCows               string
+	RecipeCode          string
+	RecipeName          string
+	MixBatch            string
+	BarStartTime        string
+	BarEndTime          string
+	BarRecipePlanWeight string
+	BarRecipeRealWeight string
+	BarFeedPlanWeight   string
+	BarFeedRealWeight   string
+	FDate               string
+	DStatus             string
+	UserName            string
+	UserTrueName        string
+}
+type XMLRecordMix struct {
+	FarmCode        string
+	MixDate         string
+	RecipeCode      string
+	RecipeName      string
+	FeedCode        string
+	FeedName        string
+	GroupTypeCode   string
+	GroupTypeName   string
+	Banci           string
+	MixBatch        string
+	MixStartTime    string
+	MixEndTime      string
+	MixRound        string
+	OutFeedTime     string
+	FeedWeightTotal string
+	FeedOrder       string
+	FeedDryMatter   string
+	FeedAddTime     string
+	RecipeWeight    string
+	SystemWeight    string
+	FDate           string
+	DStatus         string
+	UserName        string
+	UserTrueName    string
+}
+type XMLRecordResi struct {
+	FarmCode          string
+	FeedDate          string
+	ResiDate          string
+	BarName           string
+	GroupTypeCode     string
+	GroupTypeName     string
+	ResiWeight        string
+	ResiGroupTypeCode string
+	ResiGroupTypeName string
+	FDate             string
+	DStatus           string
+	UserName          string
+	UserTrueName      string
+}
+type Senddatarecipe struct {
+	XMLName xml.Name             `xml:"DataXML"`
+	Head    XMLHead              `xml:"Head"`
+	Record  []Xnr_senddatarecipe `xml:"Record"`
+}
+type Senddatafeed struct {
+	XMLName xml.Name           `xml:"DataXML"`
+	Head    XMLHead            `xml:"Head"`
+	Record  []Xnr_senddatafeed `xml:"Record"`
+}
+type Feedgdailycost struct {
+	XMLName xml.Name             `xml:"DataXML"`
+	Head    XMLHead              `xml:"Head"`
+	Record  []Xnr_feedgdailycost `xml:"Record"`
+}
+type Xnr_senddatarecipe struct {
+	getDate        string
+	getTime        string
+	FarmCode       string
+	RecipeCode     string
+	RecipeName     string
+	RecipeVersion  string
+	GroupTypeCode  string
+	GroupTypeName  string
+	RecipeType     string
+	FeedCode       string
+	FeedName       string
+	DryMatter      string
+	JiaobanOrder   string
+	JiaobanTime    string
+	BDWeight       string
+	BDTime         string
+	FeedWeight     string
+	FeedWeightRate string
+	StartDate      string
+	LastAdjDate    string
+	FDate          string
+	DStatus        string
+	UserName       string
+	UserTrueName   string
+}
+type Xnr_senddatafeed struct {
+	getDate      string
+	getTime      string
+	FarmCode     string
+	FeedCode     string
+	FeedName     string
+	Goods_Spec   string
+	Goods_Unit   string
+	Class2_Name  string
+	FDate        string
+	DStatus      string
+	UserName     string
+	UserTrueName string
+}
+type Xnr_feedgdailycost struct {
+	GDailyCostListID   string
+	getDate            string
+	getTime            string
+	FarmCode           string
+	FeedName           string
+	FeedTMR_Date       string
+	DeptGroupType_Code string
+	DeptGroupType_Name string
+	Group_Name         string
+	RealCowAmount      string
+	PCows              string
+	FeedCowAmount      string
+	FeedRecipe_Code    string
+	FeedRecipe_Verson  string
+	FeedRecipe_Name    string
+	FeedWeight         string
+	AverageDMIasRecipe string
+	FeedBanciPlan      string
+	Banci1Rate         string
+	Banci2Rate         string
+	Banci3Rate         string
+	Banci4Rate         string
+	StatusID           string
+	StatusText         string
+	OrderNum           string
+	Remark             string
+	Creator            string
+	CreateDate         string
+}
+
+func main() {
+	if len(os.Args) < 2 {
+		logs.Error("参数输入错误:例 : " + `PrconsoleV2.4.exe -a getData -p d:\202101011getData.txt -d 2021-01-01`)
+		return
+	}
+	paraMap := make(map[string]string, 0)
+
+	for i := 1; i < len(os.Args); i++ {
+		if len(os.Args) > i+1 {
+			paraMap[strings.ToLower(os.Args[i])] = strings.Trim(strings.ToLower(os.Args[i+1]), " ")
+		} else {
+			paraMap[strings.ToLower(os.Args[i])] = ""
+		}
+	}
+	strMethod = paraMap["-a"]
+	strDate = paraMap["-d"]
+	err := checkDate()
+	if err != nil {
+		logs.Error("日期格式错误 例 : 2021-01-01")
+		return
+	}
+	strOutFilePath = strings.ToLower(paraMap["-p"])
+
+	FarmCode = setting.DatabaseSetting.FarmCode
+	setting.Setup("")
+	models.Setup()
+	FarmCode = setting.DatabaseSetting.FarmCode
+	//logs.Error(strMethod,strOutFilePath,strDate,FarmCode)
+	SelectApi()
+
+}
+
+func SelectApi() {
+	var err error
+	switch strMethod {
+	case "getstate":
+		err = getstate()
+	case "getdatamix":
+		err = checkpathCreat()
+		if err != nil {
+			return
+		}
+		err = getDataMix()
+	case "getdata":
+		err = checkpathCreat()
+		if err != nil {
+			return
+		}
+		err = getData()
+	case "getdataresi":
+		err = checkpathCreat()
+		if err != nil {
+			return
+		}
+		err = getDataResi()
+	case "senddatarecipe":
+		err = checkpathExist()
+		if err != nil {
+			return
+		}
+		err = sendDataRecipe()
+	case "senddatafeed":
+		err = checkpathExist()
+		if err != nil {
+			return
+		}
+		err = sendDataFeed()
+	case "feedgdailycost":
+		err = checkpathExist()
+		if err != nil {
+			return
+		}
+		err = feedGDailyCost()
+	default:
+		fmt.Println("1")
+		//logs.Info("1")
+	}
+
+	if err == nil {
+		fmt.Println("1")
+		//logs.Info("1")
+	} else {
+		logs.Error("fail", err)
+	}
+
+}
+func getstate() error {
+	tx := models.Engine.NewSession()
+	err := tx.Begin()
+	defer func() {
+		switch {
+		case err != nil:
+			//logs.Error("__error:", err)
+			if tx != nil {
+				tx.Rollback()
+			}
+		default:
+			if tx != nil {
+				err = tx.Commit()
+			}
+		}
+		if tx != nil {
+			tx.Close()
+		}
+	}()
+	//  修改栏舍配方
+	sqlstr := `
+	ALTER TABLE feed ADD COLUMN xnrFeedName VARCHAR(50) DEFAULT NULL COMMENT '伊启牛饲料名称'
+`
+
+	_, err = tx.Exec(sqlstr)
+	if err != nil {
+		// logs.Error("err", err, )
+	}
+	sqlstr = `
+	ALTER TABLE feedp ADD COLUMN xnrFeedpName VARCHAR(50) DEFAULT NULL COMMENT '伊启牛栏舍名称'
+`
+	_, err = tx.Exec(sqlstr)
+	if err != nil {
+		// logs.Error("err", err, )
+	}
+	sqlstr = `
+	ALTER TABLE feedtemplet ADD COLUMN feedtempletCode VARCHAR(50) DEFAULT NULL COMMENT '伊启牛配方模板编码'
+`
+	_, err = tx.Exec(sqlstr)
+	if err != nil {
+		// logs.Error("err", err, )
+	}
+	sqlstr = `
+	ALTER TABLE feedtemplet ADD COLUMN xnrFeedtempletName VARCHAR(50) DEFAULT NULL COMMENT '伊启牛配方模板名称'
+`
+	_, err = tx.Exec(sqlstr)
+	if err != nil {
+		//logs.Error("err", err, )
+	}
+
+	return nil
+
+}
+func getDataMix() error {
+	sqlstr := `SELECT ? AS FarmCode, DATE_FORMAT(MixDate,'%Y-%m-%d') MixDate,RecipeCode,RecipeName,GroupTypeCode,GroupTypeName,Banci,MixBatch,
+	DATE_FORMAT(MixStartTime,'%Y-%m-%d %H:%i:%s')MixStartTime, DATE_FORMAT(MixEndTime,'%Y-%m-%d %H:%i:%s') MixEndTime,MixRound, DATE_FORMAT(OutFeedTime,'%Y-%m-%d %H:%i:%s') OutFeedTime,
+	SUM(FeedWeightTotal) AS FeedWeightTotal,FeedOrder,FeedCode,FeedName,
+	   FeedDryMatter, DATE_FORMAT(FeedAddTime,'%Y-%m-%d %H:%i:%s') FeedAddTime ,SUM(RecipeWeight) AS RecipeWeight,SUM(SystemWeight) AS SystemWeight, DATE_FORMAT(FDate,'%Y-%m-%d %H:%i:%s') FDate,DStatus,UserName,UserTrueName 
+	   
+	   FROM(
+		 SELECT d.Mydate AS MixDate, 
+		IFNULL((SELECT feedtempletCode FROM feedtemplet WHERE id = d2.feedtempletId),'') AS RecipeCode, 
+		d2.feedtempletName  AS RecipeName,        
+	  (SELECT GroupTypeCode FROM xnr_senddatarecipe WHERE RecipeName=d2.feedtempletName ORDER BY id DESC LIMIT 1) AS GroupTypeCode, 
+		   (SELECT GroupTypeName FROM xnr_senddatarecipe WHERE RecipeName=d2.feedtempletName ORDER BY id DESC LIMIT 1) AS GroupTypeName,
+		CASE WHEN (d.Times = 1) OR (d.Times = 2) THEN 1 WHEN (d.Times = 3) OR (d.Times = 4) THEN 2 WHEN (d.Times = 5) OR (d.Times = 6) THEN 3 END AS Banci,
+		CEIL(SUBSTRING_INDEX(d.ProjName,'.', -1)) AS MixBatch,   
+		   (SELECT MIN(downloadplandtl1_exec.InTime) FROM downloadplandtl1_exec WHERE downloadplandtl1_exec.PID = d.id GROUP BY d.id) AS MixStartTime,        
+		   (SELECT MAX(downloadplandtl1_exec.InTime) FROM downloadplandtl1_exec WHERE downloadplandtl1_exec.PID = d.id GROUP BY d.id) AS MixEndTime,'' AS MixRound, 
+			d1exe.InTime AS OutFeedTime,
+		   (SELECT SUM(downloadplandtl1.ActualWeightMinus) FROM downloadplandtl1 WHERE downloadplandtl1.PID = d.id GROUP BY d.id) AS FeedWeightTotal,d1exe.sort AS FeedOrder,
+		 feed.feedcode AS FeedCode,d1.Fname AS FeedName,feed.dry AS FeedDryMatter, 
+		 IFNULL(DATE_SUB(d1exe.Intime, INTERVAL d1exe.processTime HOUR_SECOND),d1exe.Intime) AS FeedAddTime,d1.LWEIGHT AS RecipeWeight,
+		  d1.ActualWeightMinus AS SystemWeight,NOW() AS FDate,1 AS DStatus,driver.ID AS UserName,driver.drivername AS UserTrueName  
+		   FROM downloadplandtl1 d1 LEFT JOIN downloadedplan d ON d.id = d1.PID LEFT JOIN downloadplandtl1_exec d1exe ON d1.PID = d1exe.PID AND d1.SORT=d1exe.SORT  
+			LEFT JOIN driver ON d.DriverID = driver.ID 
+		LEFT JOIN feed ON d1.FID = feed.ID  
+		LEFT JOIN (SELECT downloadplandtl2.* FROM downloadplandtl2 JOIN downloadedplan ON downloadplandtl2.pid=downloadedplan.id
+		   WHERE downloadedplan.lpplanType!=1 AND downloadedplan.Mydate= ?
+			GROUP BY pid) d2 ON d2.pid=d.id    
+		   WHERE d.Mydate = ?   AND d.IsCompleted = 1 
+			) a
+		   
+	WHERE FeedName != '需加料'  GROUP BY RecipeName,Banci,MixBatch,feedname
+		UNION ALL 
+		SELECT ? AS FarmCode,  DATE_FORMAT(MixDate,'%Y-%m-%d') MixDate,RecipeCode,RecipeName,GroupTypeCode,GroupTypeName,Banci,MixBatch,
+		 DATE_FORMAT(MixStartTime,'%Y-%m-%d %H:%i:%s')MixStartTime,  DATE_FORMAT(MixEndTime,'%Y-%m-%d %H:%i:%s') MixEndTime,MixRound, DATE_FORMAT(OutFeedTime,'%Y-%m-%d %H:%i:%s') OutFeedTime,
+		 SUM(FeedWeightTotal) AS FeedWeightTotal,FeedOrder,FeedCode,FeedName,
+	   FeedDryMatter, DATE_FORMAT(FeedAddTime,'%Y-%m-%d %H:%i:%s') FeedAddTime ,SUM(RecipeWeight) AS RecipeWeight,SUM(SystemWeight) AS SystemWeight, DATE_FORMAT(FDate,'%Y-%m-%d %H:%i:%s') FDate,DStatus,UserName,UserTrueName FROM(
+		 SELECT  d.Mydate AS MixDate, 
+	   IFNULL((SELECT feedtempletCode FROM feedtemplet WHERE id = d2.feedtempletId),'') AS RecipeCode, 
+		d2.feedtempletName  AS RecipeName,        
+	  (SELECT GroupTypeCode FROM xnr_senddatarecipe WHERE RecipeName=d2.feedtempletName ORDER BY id DESC LIMIT 1) AS GroupTypeCode, 
+		   (SELECT GroupTypeName FROM xnr_senddatarecipe WHERE RecipeName=d2.feedtempletName ORDER BY id DESC LIMIT 1) AS GroupTypeName,
+		CASE WHEN (d.Times = 1) OR (d.Times = 2) THEN 1 WHEN (d.Times = 3) OR (d.Times = 4) THEN 2 WHEN (d.Times = 5) OR (d.Times = 6) THEN 3 END AS Banci,
+		CEIL(SUBSTRING_INDEX(d.ProjName, '.', -1)) AS MixBatch,   
+		   (SELECT MIN(downloadplandtl1_exec.InTime) FROM downloadplandtl1_exec WHERE downloadplandtl1_exec.PID = d.id GROUP BY d.id) AS MixStartTime,        
+		   (SELECT MAX(downloadplandtl1_exec.InTime) FROM downloadplandtl1_exec WHERE downloadplandtl1_exec.PID = d.id GROUP BY d.id) AS MixEndTime, ''AS MixRound, 
+			d1exe.InTime AS OutFeedTime,
+		   (SELECT SUM(downloadplandtl1.ActualWeightMinus) FROM downloadplandtl1 WHERE downloadplandtl1.PID = d.id GROUP BY d.id) AS FeedWeightTotal,d1exe.sort AS FeedOrder,
+		 feed.feedcode AS FeedCode,d1.Fname AS FeedName,feed.dry AS FeedDryMatter, 
+		 IFNULL(DATE_SUB(d1exe.Intime, INTERVAL d1exe.processTime HOUR_SECOND),d1exe.Intime) AS FeedAddTime,d1.LWEIGHT AS RecipeWeight,
+		  d1.ActualWeightMinus AS SystemWeight,NOW() AS FDate,1 AS DStatus,driver.ID AS UserName,driver.drivername AS UserTrueName  
+		   FROM downloadplandtl1 d1 LEFT JOIN downloadedplan d ON d.id = d1.PID LEFT JOIN downloadplandtl1_exec d1exe ON d1.PID = d1exe.PID AND d1.SORT=d1exe.SORT  
+			LEFT JOIN driver ON d.DriverID = driver.ID 
+		LEFT JOIN feed ON d1.FID = feed.ID  
+		LEFT JOIN (SELECT downloadplandtl2.* FROM downloadplandtl2 JOIN downloadedplan ON downloadplandtl2.pid=downloadedplan.id
+		   WHERE downloadedplan.lpplanType!=1 AND downloadedplan.Mydate= ?
+			GROUP BY pid) d2 ON d2.flpid=d.id    
+		   WHERE d.Mydate = ?  AND d.IsCompleted = 1 AND d2.FLPID IS NOT NULL 
+			
+			   ) a  GROUP BY RecipeName,Banci,MixBatch,feedname`
+	valuesMap, err := models.Engine.SQL(sqlstr, FarmCode, strDate, strDate, FarmCode, strDate, strDate).QueryString()
+
+	if err != nil {
+		logs.Error("err", err, len(valuesMap))
+		return err
+	}
+
+	W := DataXMLMix{}
+	W.Head = XMLHead{
+		SystemCode: "TMR",
+		MappingID:  FarmCode,
+		Type:       "TMRDataMix",
+		FarmCode:   FarmCode,
+		DataNum:    strconv.Itoa(len(valuesMap)),
+		Version:    "3",
+	}
+	var records []XMLRecordMix
+	strtem, err := json.Marshal(valuesMap)
+	if err != nil {
+		logs.Error("json.Marshal err", err)
+	}
+	err = json.Unmarshal(strtem, &records)
+	if err != nil {
+		logs.Error("json.Unmarshal err", err)
+	}
+	W.Record = append(W.Record, records...)
+
+	output1, _ := xml.MarshalIndent(W, "  ", "    ")
+
+	f, err := os.Create(strOutFilePath)
+	if err != nil {
+		logs.Error("os.Open err", err)
+		return err
+	}
+	output1 = append([]byte(xml.Header), output1...)
+	_, err = f.Write(output1)
+	if err != nil {
+		logs.Error("f.Write err", err)
+		return err
+	}
+	f.Close()
+	return nil
+}
+
+func getData() error {
+	sqlstr := `	SELECT ? AS FarmCode,id,DATE_FORMAT(FeedDate,'%Y-%m-%d') AS FeedDate,Banci,BarName,GroupTypeCode,GroupTypeName,CowAmount,  
+	PCows,RecipeCode,RecipeName,MixBatch,                                                   
+	DATE_FORMAT(BarStartTime,'%Y-%m-%d %H:%i:%s') BarStartTime,DATE_FORMAT(BarEndTime,'%Y-%m-%d %H:%i:%s') BarEndTime,                                                                 
+	SUM(BarRecipePlanWeight) AS BarRecipePlanWeight,
+SUM(BarRecipeRealWeight) AS BarRecipeRealWeight,                                                 
+	FeedCode,FeedName,                                                                        
+	SUM(ROUND(BarFeedPlanWeight / CCountRatio * BarRecipePlanWeight,2)) AS BarFeedPlanWeight,      
+	SUM(ROUND(BarFeedRealWeight / aCCountRatio * BarRecipeRealWeight,2)) AS BarFeedRealWeight,      
+	DATE_FORMAT(FDate,'%Y-%m-%d %H:%i:%s') FDate,IF(d1fname <> 0,d1fname,IF(ismodify=0,1,3)) DStatus,UserName,UserTrueName                                                          
+FROM ( 
+SELECT d.id,d.Mydate AS FeedDate,
+ 
+IF(
+(SELECT COUNT(*) FROM  recweight r WHERE  d2.Intime = r.MTime AND r.Weight = d2.ActualWeight )>0,
+IF((SELECT COUNT(*) FROM  recweight r WHERE   r.MTime = (SELECT dee.intime FROM downloadplandtl1_exec dee WHERE dee.pid = d1.pid AND dee.sort= d1.sort) 
+AND r.Weight = (SELECT dee.ActualWeight FROM downloadplandtl1_exec dee WHERE dee.pid = d1.pid AND dee.sort= d1.sort) ) >0,0,3),3) ismodify, 
+
+IF(ABS((SELECT SUM(ActualWeightMinus) FROM  downloadplandtl1_exec de WHERE  de.PID = d1.PID AND de.sort = d1.sort ) -
+(SELECT SUM(ActualWeightMinus) FROM  downloadplandtl1 de WHERE  de.PID = d1.PID AND de.sort = d1.sort ))<1,0,2 ) d1fname,   
+
+
+CASE WHEN (d.Times = 1) OR (d.Times = 2) THEN 1 WHEN (d.Times = 3) OR (d.Times = 4) THEN 2 WHEN (d.Times = 5) OR (d.Times = 6) THEN 3 END AS Banci,
+d2.Fname AS BarName,
+IFNULL((SELECT DeptGroupType_Code FROM xnr_feedgdailycost WHERE Group_Name=d2.Fname ORDER BY id DESC LIMIT 1),
+(SELECT GroupTypeCode FROM xnr_senddatarecipe WHERE RecipeName =d2.feedtempletName ORDER BY id DESC LIMIT 1)
+) AS GroupTypeCode,
+IFNULL( (SELECT DeptGroupType_Name FROM xnr_feedgdailycost WHERE Group_Name=d2.Fname ORDER BY id DESC LIMIT 1),
+(SELECT GroupTypeName FROM xnr_senddatarecipe WHERE RecipeName =d2.feedtempletName ORDER BY id DESC LIMIT 1)
+) AS GroupTypeName,
+d2.cowcount AS CowAmount,
+d2.cowcount*CCountRatio/100 AS PCows,
+(SELECT feedtempletCode FROM feedtemplet WHERE id = d2.feedtempletId) AS RecipeCode,
+d2.feedtempletName  AS RecipeName,
+CEIL(SUBSTRING_INDEX(d.ProjName, '.', -1)) AS MixBatch,                                      
+IFNULL(DATE_SUB(d2.Intime, INTERVAL d2.processTime HOUR_SECOND),d2.intime) AS BarStartTime,d2.Intime AS BarEndTime,                                                                  
+d2.LWEIGHT AS BarRecipePlanWeight,d2.ActualWeightMinus AS BarRecipeRealWeight,feed.feedcode AS FeedCode,d1.Fname AS FeedName,                                      
+d1.LWEIGHT AS BarFeedPlanWeight,d1.ActualWeightMinus AS BarFeedRealWeight,NOW() AS FDate,1 AS DStatus,driver.ID AS UserName,driver.drivername AS UserTrueName,    
+(SELECT SUM(dd1.lweight) FROM downloadplandtl1 dd1 INNER JOIN downloadedplan dd ON dd1.PID = dd.id WHERE dd1.PID = d.ID AND dd.IsCompleted = 1) AS CCountRatio,                                                                                  
+(SELECT SUM(ActualWeightMinus) FROM downloadplandtl1 dd1 INNER JOIN downloadedplan dd ON dd1.PID = dd.id WHERE dd1.PID = d.ID AND dd.IsCompleted = 1) AS aCCountRatio                                                                        
+FROM downloadedplan d INNER JOIN downloadplandtl1 d1 ON d.id = d1.PID                                                                                 
+INNER JOIN  downloadplandtl2  d2 ON d.id = d2.PID INNER JOIN feed  ON d1.FID=feed.id                                                                                                                       
+left JOIN driver ON d.DriverID = driver.ID    
+																									   
+WHERE d.Mydate = ? AND d.IsCompleted = 1   
+
+) a  GROUP BY BarName,FeedName,banci
+UNION ALL 
+SELECT ? AS FarmCode,id,DATE_FORMAT(FeedDate,'%Y-%m-%d') FeedDate,Banci,BarName,GroupTypeCode,GroupTypeName,CowAmount,  
+	PCows,RecipeCode,RecipeName,MixBatch,                                                   
+   DATE_FORMAT(BarStartTime,'%Y-%m-%d %H:%i:%s') BarStartTime,DATE_FORMAT(BarEndTime,'%Y-%m-%d %H:%i:%s')BarEndTime,                                                                 
+	SUM(BarRecipePlanWeight) AS BarRecipePlanWeight,
+SUM(BarRecipeRealWeight) AS BarRecipeRealWeight,                                                 
+	FeedCode,FeedName,                                                                        
+	SUM(ROUND(BarFeedPlanWeight / CCountRatio * BarRecipePlanWeight,2)) AS BarFeedPlanWeight,      
+	SUM(ROUND(BarFeedRealWeight / aCCountRatio * BarRecipeRealWeight,2)) AS BarFeedRealWeight,      
+	DATE_FORMAT(FDate,'%Y-%m-%d %H:%i:%s') FDate, IF(d1fname <> 0,d1fname,IF(ismodify=0,1,3)) DStatus,UserName,UserTrueName                                                          
+FROM ( 
+SELECT d.id,d.Mydate AS FeedDate,
+IF(
+(SELECT COUNT(*) FROM  recweight r WHERE  d2.Intime = r.MTime AND r.Weight = d2.ActualWeight )>0,
+IF((SELECT COUNT(*) FROM  recweight r WHERE   r.MTime = (SELECT dee.intime FROM downloadplandtl1_exec dee WHERE dee.pid = d1.pid AND dee.sort= d1.sort) 
+AND r.Weight = (SELECT dee.ActualWeight FROM downloadplandtl1_exec dee WHERE dee.pid = d1.pid AND dee.sort= d1.sort) ) >0,0,3),3) ismodify, 
+
+IF((SELECT SUM(ActualWeightMinus) FROM  downloadplandtl1_exec de WHERE  de.PID = d1.PID AND de.sort = d1.sort ) =
+(SELECT SUM(ActualWeightMinus) FROM  downloadplandtl1 de WHERE  de.PID = d1.PID AND de.sort = d1.sort ),0,2 ) d1fname,  
+
+CASE WHEN (d.Times = 1) OR (d.Times = 2) THEN 1 WHEN (d.Times = 3) OR (d.Times = 4) THEN 2 WHEN (d.Times = 5) OR (d.Times = 6) THEN 3 END AS Banci,
+d2.Fname AS BarName,
+IFNULL((SELECT DeptGroupType_Code FROM xnr_feedgdailycost WHERE Group_Name=d2.Fname ORDER BY id DESC LIMIT 1),
+(SELECT GroupTypeCode FROM xnr_senddatarecipe WHERE RecipeName =d2.Fname ORDER BY id DESC LIMIT 1)
+) AS GroupTypeCode,
+IFNULL( (SELECT DeptGroupType_Name FROM xnr_feedgdailycost WHERE Group_Name=d2.Fname ORDER BY id DESC LIMIT 1),
+(SELECT GroupTypeCode FROM xnr_senddatarecipe WHERE RecipeName =d2.Fname ORDER BY id DESC LIMIT 1)
+) AS GroupTypeName,
+d2.cowcount AS CowAmount,
+d2.cowcount*CCountRatio/100 AS PCows,
+(SELECT feedtempletCode FROM feedtemplet WHERE id = d2.feedtempletId) AS RecipeCode,
+d2.feedtempletName  AS RecipeName,
+CEIL(SUBSTRING_INDEX(d.ProjName, '.', -1)) AS MixBatch,                                      
+IFNULL(DATE_SUB(d2.Intime, INTERVAL d2.processTime HOUR_SECOND),d2.intime) AS BarStartTime,d2.Intime AS BarEndTime,                                                                  
+d2.LWEIGHT AS BarRecipePlanWeight,d2.ActualWeightMinus AS BarRecipeRealWeight,feed.feedcode AS FeedCode,d1.Fname AS FeedName,                                      
+d1.LWEIGHT AS BarFeedPlanWeight,d1.ActualWeightMinus AS BarFeedRealWeight,NOW() AS FDate,1 AS DStatus,driver.ID AS UserName,driver.drivername AS UserTrueName,    
+(SELECT SUM(dd1.lweight) FROM downloadplandtl1 dd1 INNER JOIN downloadedplan dd ON dd1.PID = dd.id WHERE dd1.PID = d.ID AND dd.IsCompleted = 1) AS CCountRatio,                                                                                  
+(SELECT SUM(ActualWeightMinus) FROM downloadplandtl1 dd1 INNER JOIN downloadedplan dd ON dd1.PID = dd.id WHERE dd1.PID = d.ID AND dd.IsCompleted = 1) AS aCCountRatio                                                                        
+FROM downloadedplan d INNER JOIN downloadplandtl1 d1 ON d.id = d1.PID                                                                                 
+INNER JOIN downloadplandtl2  d2 ON d.id = d2.FLPID INNER JOIN feed  ON d1.FID=feed.id                                                                                                                       
+left JOIN driver ON d.DriverID = driver.ID                                                                                                                          
+WHERE d.Mydate = ? AND d.IsCompleted = 1 AND d2.FLPID IS NOT NULL         
+) a  GROUP BY BarName,FeedName,banci   `
+
+	valuesMap, err := models.Engine.SQL(sqlstr, FarmCode, strDate, FarmCode, strDate).QueryString()
+	//valuesMap, err := models.Engine.SQL(sqlstr).QueryString()
+
+	if err != nil {
+		logs.Error("err", err, len(valuesMap))
+		logs.Error("err", err, len(valuesMap))
+		return err
+	}
+
+	W := DataXML{}
+	W.Head = XMLHead{
+		SystemCode: "TMR",
+		MappingID:  FarmCode,
+		Type:       "TMRData",
+		FarmCode:   FarmCode,
+		DataNum:    strconv.Itoa(len(valuesMap)),
+		Version:    "3",
+	}
+	var records []XMLRecord
+	strtem, err := json.Marshal(valuesMap)
+	if err != nil {
+		logs.Error("json.Marshal err", err)
+		logs.Error("json.Marshal err", err)
+	}
+	err = json.Unmarshal(strtem, &records)
+	if err != nil {
+		logs.Error("json.Unmarshal err", err)
+		logs.Error("json.Unmarshal err", err)
+	}
+	W.Record = append(W.Record, records...)
+
+	output1, _ := xml.MarshalIndent(W, "  ", "    ")
+
+	f, err := os.Create(strOutFilePath)
+	if err != nil {
+		logs.Error("os.Open err", err)
+		logs.Error("os.Open err", err)
+		return err
+	}
+	output1 = append([]byte(xml.Header), output1...)
+	_, err = f.Write(output1)
+	if err != nil {
+		logs.Error("f.Write err", err)
+		return err
+	}
+	f.Close()
+	return nil
+
+}
+
+func getDataResi() error {
+
+	sqlstr := `   SELECT ? AS FarmCode, DATE_FORMAT(DATE_SUB(d.Mydate, INTERVAL 1 DAY),'%Y-%m-%d')  AS FeedDate,DATE_FORMAT(d.Mydate,'%Y-%m-%d') AS ResiDate,d2.Fname AS BarName,      
+	'' AS GroupTypeCode,d2.cowclassname AS GroupTypeName,barfeedremain.Remain AS ResiWeight,'' AS ResiGroupTypeCode,bar.class AS ResiGroupTypeName,    
+ DATE_FORMAT(NOW(),'%Y-%m-%d %H:%i:%s') AS FDate,1 AS DStatus,driver.ID AS UserName,driver.drivername AS UserTrueName                                                                               
+	FROM downloadedplan d INNER JOIN downloadplandtl2 d2 ON d.id = d2.PID                                                                                        
+	 JOIN barfeedremain ON d2.FBarID = barfeedremain.barid                                                                                                 
+  AND DATE_ADD(d.Mydate,INTERVAL -1 DAY) = barfeedremain.RemainDate 
+	LEFT JOIN feedp ON feedp.barid = barfeedremain.barid                                                                                                        
+	LEFT JOIN bar  ON feedp.barid = bar.id                                                                                                             
+	left JOIN driver ON d.DriverID = driver.ID                                                                                                                  
+	WHERE d.Mydate = ? AND d.IsCompleted = 1  `
+	valuesMap, err := models.Engine.SQL(sqlstr, FarmCode, strDate).QueryString()
+
+	if err != nil {
+		logs.Error("select downloadedplan err", err, len(valuesMap))
+		return err
+	}
+
+	W := DataXMLResi{}
+	W.Head = XMLHead{
+		SystemCode: "TMR",
+		MappingID:  FarmCode,
+		Type:       "TMRDataResi",
+		FarmCode:   FarmCode,
+		DataNum:    strconv.Itoa(len(valuesMap)),
+		Version:    "3",
+	}
+	var records []XMLRecordResi
+	strtem, err := json.Marshal(valuesMap)
+	if err != nil {
+		logs.Error("json.Marshal err", err)
+	}
+	err = json.Unmarshal(strtem, &records)
+	if err != nil {
+		logs.Error("json.Unmarshal err", err)
+	}
+	W.Record = append(W.Record, records...)
+
+	output1, _ := xml.MarshalIndent(W, "  ", "    ")
+
+	f, err := os.Create(strOutFilePath)
+	if err != nil {
+		logs.Error("os.Open err", err)
+		return err
+	}
+	output1 = append([]byte(xml.Header), output1...)
+	_, err = f.Write(output1)
+	if err != nil {
+		logs.Error("f.Write err", err)
+		return err
+	}
+	f.Close()
+	return nil
+}
+
+// 判断集合是否包含某个字符串
+func contains(slice []string, str string) bool {
+	for _, s := range slice {
+		if s == str {
+			return true
+		}
+	}
+	return false
+}
+func sendDataRecipe() error {
+	tx := models.Engine.NewSession()
+	err := tx.Begin()
+	defer func() {
+		switch {
+		case err != nil:
+			logs.Error("__error:", err)
+			if tx != nil {
+				tx.Rollback()
+			}
+		default:
+			if tx != nil {
+				err = tx.Commit()
+			}
+		}
+		if tx != nil {
+			tx.Close()
+		}
+	}()
+	_, err = tx.Exec("delete from xnr_senddatarecipe where getDate = ?", strDate)
+	if err != nil {
+		logs.Error("delete xnr_senddatarecipe err", err)
+	}
+
+	f, err := os.Open(strOutFilePath)
+	if err != nil {
+		logs.Error("os.Open err", err)
+	}
+	input := make([]byte, 100000)
+	_, err = f.Read(input)
+
+	if err != nil {
+		logs.Error("f.Read err", err)
+	}
+
+	W := Senddatarecipe{}
+
+	err = xml.Unmarshal(input, &W)
+	if err != nil {
+		//logs.Error("xml.Unmarshal err", err,W)
+	}
+	sqlstr := `INSERT INTO xnr_senddatarecipe (
+  getDate,getTime,FarmCode,RecipeCode,RecipeName,RecipeVersion,GroupTypeCode,GroupTypeName,RecipeType,FeedCode,FeedName,DryMatter,JiaobanTime,JiaobanOrder,BDWeight,BDTime,FeedWeight,FeedWeightRate,StartDate,LastAdjDate,FDate,DStatus,UserName,UserTrueName
+ ) VALUES ( ?,NOW(),?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ) `
+
+	// 新增新的明细
+	for _, v := range W.Record {
+		_, err = tx.Exec(sqlstr, strDate, v.FarmCode, v.RecipeCode, v.RecipeName, transtr(v.RecipeVersion), v.GroupTypeCode, v.GroupTypeName,
+			transtr(v.RecipeVersion), v.FeedCode, v.FeedName, transtr(v.DryMatter), transtr(v.JiaobanTime), transtr(v.JiaobanOrder), transtr(v.BDWeight),
+			transtr(v.BDTime), transtr(v.FeedWeight), transtr(v.FeedWeightRate), trandate(v.StartDate), trandate(v.LastAdjDate), trandate(v.FDate), v.DStatus, v.UserName, v.UserTrueName)
+		if err != nil {
+			logs.Error("insert xnr_senddatarecipe err"+sqlstr, err)
+		}
+	}
+
+	// 修改饲料
+	sqlstr = `
+		UPDATE feedtemplet SET TNAME=CONCAT(LEFT(TNAME,4),'_del'),
+	feedtempletCode=NULL,xnrFeedtempletName=NULL WHERE isDelete=1
+`
+	_, _ = tx.Exec(sqlstr)
+
+	// 修改饲料
+	sqlstr = `
+	UPDATE feed 
+	JOIN xnr_senddatarecipe xf ON feed.feedCode = xf.FeedCode
+	SET 
+	feed.xnrFeedName=xf.FeedName,feed.ENABLE=1 
+	WHERE  xf.getDate=? `
+	_, err = tx.Exec(sqlstr, strDate)
+	if err != nil {
+		logs.Error("UPDATE feed1 err", err)
+	}
+	// 修改饲料
+	//	sqlstr = `
+	//	UPDATE feed
+	//	JOIN xnr_senddatarecipe xf ON feed.xnrFeedName = xf.FeedName OR feed.FNAME = xf.FeedName
+	//	SET
+	//	feed.xnrFeedName=xf.FeedName,feed.feedCode=xf.FeedCode,feed.ENABLE=1
+	//	WHERE  xf.getDate=?
+	//`
+	//	_, err =tx.Exec(sqlstr,strDate)
+	//	if err != nil {
+	//		logs.Error(" update feed2 err", err)
+	//	}
+	//新增饲料
+	sqlstr = `
+	INSERT INTO feed(feedcode,FNAME,xnrFeedName,FCLASS,ENABLE) 
+	
+	SELECT xf.FeedCode,xf.FeedName,xf.FeedName,
+	IFNULL((SELECT ID FROM feedclass WHERE FCNAME='其它' OR FCNAME='其他' LIMIT 1),0)ww,1
+	FROM xnr_senddatarecipe xf
+	WHERE xf.getDate=?  AND (SELECT COUNT(*) FROM feed WHERE  feed.feedCode = xf.FeedCode) = 0
+	GROUP BY xf.FeedCode `
+
+	_, err = tx.Exec(sqlstr, strDate)
+	if err != nil {
+		logs.Error(" INSERT feed  err", err)
+	}
+	// 修改饲料干物质
+	sqlstr = `
+	UPDATE feed 
+	JOIN xnr_senddatarecipe xf ON feed.feedCode = xf.FeedCode
+	SET 
+	feed.dry=ROUND(xf.DryMatter/100,4)
+	WHERE  xf.getDate=? AND xf.DryMatter IS NOT NULL
+`
+	_, err = tx.Exec(sqlstr, strDate)
+	if err != nil {
+		logs.Error("update feed3 err", err)
+	}
+	// 修改配方模板
+	sqlstr = `
+	 UPDATE feedtemplet ft
+	JOIN xnr_senddatarecipe xf ON ft.feedtempletCode = xf.RecipeCode OR ft.xnrFeedtempletName =  xf.RecipeName
+	OR ft.TNAME = xf.RecipeName
+	SET 
+	ft.TNAME=xf.RecipeName,ft.feedtempletCode=xf.RecipeCode,
+	ft.xnrFeedtempletName=xf.RecipeName,
+	ft.OWNER = xf.UserTrueName,
+	ft.REMARK = '伊启牛配方',
+	ft.CCID = IFNULL((SELECT id FROM cowclass WHERE CLASSNAME= xf.GroupTypeName LIMIT 1),3)
+	WHERE  xf.getDate=? `
+	_, err = tx.Exec(sqlstr, strDate)
+	if err != nil {
+		logs.Error(" update feedtemplet1 err", err)
+	}
+	//新增配方模板
+	sqlstr = `
+	INSERT INTO feedtemplet(TNAME,feedtempletCode,xnrFeedtempletName,OWNER,CCID,REMARK)
+	SELECT xf.RecipeName,xf.RecipeCode,xf.RecipeName,xf.UserTrueName,
+	IFNULL((SELECT id FROM cowclass WHERE CLASSNAME= xf.GroupTypeName LIMIT 1),3),'伊启牛配方'
+	 FROM xnr_senddatarecipe xf
+	LEFT JOIN feedtemplet ft  ON ft.feedtempletCode = xf.RecipeCode OR ft.xnrFeedtempletName =  xf.RecipeName
+	OR ft.TNAME = xf.RecipeName
+	WHERE  xf.getDate=? AND ft.id IS NULL GROUP BY xf.RecipeCode
+	
+`
+	_, err = tx.Exec(sqlstr, strDate)
+	if err != nil {
+		logs.Error(" INSERT feedtemplet2 err", err)
+	}
+	//修改配方模板子表
+	sqlstr = ` DELETE ftdetail
+	FROM feedtemplet 
+	JOIN ftdetail  ON ftdetail.FTID = feedtemplet.id 
+	WHERE feedtemplet.feedtempletCode IN(
+	SELECT RecipeCode FROM xnr_senddatarecipe WHERE  getDate=? GROUP BY RecipeCode
+	)	`
+	_, err = tx.Exec(sqlstr, strDate)
+	if err != nil {
+		logs.Error("UPDATE ftdetail err", err)
+	}
+
+	//新增配方模板子表
+	// 	sqlstr = `
+	// 	DELETE ftd
+	// FROM ftdetail ftd
+	// LEFT JOIN feed ON feed.id = ftd.FID
+	// LEFT JOIN feedtemplet ft ON  ftd.FTID = ft.id
+
+	// LEFT JOIN xnr_senddatarecipe xf
+	// ON ft.feedtempletCode = xf.RecipeCode  AND feed.feedCode = xf.FeedCode
+	// AND xf.getDate = ?
+	// WHERE xf.id IS NULL AND ft.feedtempletCode IN(SELECT RecipeCode FROM  xnr_senddatarecipe xf1 WHERE xf1.getDate = ?  GROUP BY RecipeCode)
+
+	// `
+
+	// 	_, err = tx.Exec(sqlstr, strDate, strDate)
+	// 	if err != nil {
+	// 		logs.Error("delete ftdetail err", err)
+	// 	}
+
+	//新增配方模板子表
+
+	sqlstr = `
+	INSERT INTO ftdetail(FTID,FID,FWEIGHT,packageSumWeight,sort,autosecond,autosecondname,feedgroup,fname)
+	SELECT ft.id,(SELECT id FROM feed WHERE feed.feedCode = xf.FeedCode LIMIT 1) feedcode,xf.FeedWeight,0,xf.JiaobanOrder,0,'禁用',
+	IF((SELECT COUNT(1) FROM ftdetail WHERE ftid = ft.id AND sort = xf.JiaobanOrder ) > 0 ,
+	(SELECT feedgroup FROM ftdetail WHERE ftid = ft.id AND sort = xf.JiaobanOrder ) ,
+	(SELECT fname FROM feed WHERE feed.feedCode =xf.FeedCode LIMIT 1)),
+	(SELECT fname FROM feed WHERE feed.feedCode =xf.FeedCode LIMIT 1)
+	FROM xnr_senddatarecipe xf 
+	LEFT JOIN feedtemplet ft ON ft.feedtempletCode =xf.RecipeCode OR ft.xnrFeedtempletName = xf.RecipeName OR ft.TNAME = xf.RecipeName
+	WHERE xf.getDate=? GROUP BY ft.id,feedcode`
+	_, err = tx.Exec(sqlstr, strDate)
+	if err != nil {
+		logs.Error(" INSERT ftdetail err", err)
+	}
+
+	return nil
+}
+
+func sendDataFeed() error {
+	tx := models.Engine.NewSession()
+	err := tx.Begin()
+	defer func() {
+		switch {
+		case err != nil:
+			logs.Error("__error:", err)
+			if tx != nil {
+				tx.Rollback()
+			}
+		default:
+			if tx != nil {
+				err = tx.Commit()
+			}
+		}
+		if tx != nil {
+			tx.Close()
+		}
+	}()
+	_, err = tx.Exec("delete from xnr_senddatafeed where getDate = ?", strDate)
+	if err != nil {
+		logs.Error("delete err", err)
+	}
+
+	f, err := os.Open(strOutFilePath)
+	if err != nil {
+		logs.Error("os.Open err", err)
+	}
+	input := make([]byte, 100000)
+	_, err = f.Read(input)
+
+	if err != nil {
+		logs.Error("f.Read err", err)
+	}
+
+	W := Senddatafeed{}
+
+	err = xml.Unmarshal(input, &W)
+	if err != nil {
+		//logs.Error("xml.Unmarshal err", err,W)
+	}
+
+	sqlstr := `INSERT INTO xnr_senddatafeed (
+    getDate,getTime,FarmCode,FeedCode,FeedName,Goods_Spec,Goods_Unit,Class2_Name,FDate,DStatus,UserName,UserTrueName
+ )
+VALUES
+  (
+   ?,NOW(),?,?,?,?,?,?,?,?,?,?
+  )
+`
+	for _, v := range W.Record {
+		_, err = tx.Exec(sqlstr, strDate, v.FarmCode, v.FeedCode, v.FeedName, v.Goods_Spec, v.Goods_Unit, v.Class2_Name, trandate(v.FDate), transtr(v.DStatus), v.UserName, v.UserTrueName)
+		if err != nil {
+			logs.Error("insert err", err)
+		}
+	}
+	_, err = tx.Exec("call xnr_synfeeddata(?)", strDate)
+	if err != nil {
+		logs.Error("call xnr_synfeeddata err", err)
+	}
+
+	return nil
+}
+
+func feedGDailyCost() error {
+	tx := models.Engine.NewSession()
+	err := tx.Begin()
+	defer func() {
+		//switch {
+		//case err != nil:
+		//	logs.Error("__error:", err)
+		//	if tx != nil {
+		//		tx.Rollback()
+		//	}
+		//default:
+		//	if tx != nil {
+		//		err = tx.Commit()
+		//	}
+		//}
+		err = tx.Commit()
+		if tx != nil {
+			tx.Close()
+		}
+	}()
+
+	_, err = tx.Exec("delete from xnr_feedgdailycost where getDate = ?", strDate)
+	if err != nil {
+		logs.Error("delete err", err)
+	}
+
+	f, err := os.Open(strOutFilePath)
+	if err != nil {
+		logs.Error("os.Open err", err)
+	}
+	input := make([]byte, 100000)
+	_, err = f.Read(input)
+
+	if err != nil {
+		logs.Error("f.Read err", err)
+	}
+
+	W := Feedgdailycost{}
+
+	err = xml.Unmarshal(input, &W)
+	if err != nil {
+		logs.Error("xml.Unmarshal err", err, W)
+	}
+
+	sqlstr := `INSERT INTO xnr_feedgdailycost (
+   getDate,getTime,FarmCode,GDailyCostListID,FeedName,FeedTMR_Date,DeptGroupType_Code,DeptGroupType_Name,Group_Name,RealCowAmount,
+    PCows,FeedCowAmount,FeedRecipe_Code,FeedRecipe_Verson,FeedRecipe_Name,FeedWeight,AverageDMIasRecipe,
+    FeedBanciPlan,Banci1Rate,Banci2Rate,Banci3Rate,Banci4Rate,StatusID,StatusText,OrderNum,Remark,Creator,CreateDate
+ )
+VALUES
+  (
+   ?,NOW(),?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
+  )
+`
+	for _, v := range W.Record {
+		_, err = tx.Exec(sqlstr, strDate, v.FarmCode, transtr(v.GDailyCostListID), v.FeedName, trandate(v.FeedTMR_Date),
+			v.DeptGroupType_Code, v.DeptGroupType_Name, v.Group_Name, transtr(v.RealCowAmount), transtr(v.PCows),
+			transtr(v.FeedCowAmount), v.FeedRecipe_Code, v.FeedRecipe_Verson, v.FeedRecipe_Name,
+			transtr(v.FeedWeight), transtr(v.AverageDMIasRecipe), transtr(v.FeedBanciPlan), transtr(v.Banci1Rate), transtr(v.Banci2Rate),
+			transtr(v.Banci3Rate), transtr(v.Banci4Rate), transtr(v.StatusID), v.StatusText, transtr(v.OrderNum), v.Remark, v.Creator, trandate(v.CreateDate))
+		if err != nil {
+			logs.Error("insert err", err)
+		}
+	}
+	//  修改栏舍配方
+	sqlstr = `
+	UPDATE feedp 
+	JOIN xnr_feedgdailycost xf ON feedp.xnrFeedpName = xf.Group_Name OR feedp.BNAME = xf.Group_Name
+	SET 
+	feedp.softCowCount=xf.RealCowAmount,feedp.xnrFeedpName= xf.Group_Name,feedp.ENABLE=1 
+	WHERE  xf.getDate=?
+`
+	_, err = tx.Exec(sqlstr, strDate)
+	if err != nil {
+		logs.Error(" update feedp err", err)
+	}
+	//新增栏舍配方
+	sqlstr = `
+	INSERT INTO feedp (BNAME,xnrFeedpName,softCowCount,ENABLE) 
+	SELECT xf.Group_Name,xf.Group_Name,xf.RealCowAmount,1
+	FROM xnr_feedgdailycost xf
+	LEFT JOIN feedp ON feedp.xnrFeedpName = xf.Group_Name OR feedp.BNAME = xf.Group_Name 
+	WHERE xf.getDate=? AND feedp.id IS NULL
+`
+	_, err = tx.Exec(sqlstr, strDate)
+	if err != nil {
+		logs.Error(" insert feedp err", err)
+	}
+
+	return nil
+}
+
+func transtr(str string) string {
+	if str == "" {
+		str = "0"
+	}
+	return str
+}
+
+func trandate(str string) string {
+	if str == "" {
+		str = time.Now().Format("2006-01-02 15:04:05")
+	}
+	return str
+}
+
+func checkpathCreat() error {
+	if strOutFilePath == "" {
+		strOutFilePath = setting.CurrentPath + strMethod + strDate
+	}
+	f, err := os.Create(strOutFilePath)
+	if err != nil {
+		logs.Error("输入的保存路径不存在,请核对", err.Error())
+		return err
+	}
+	f.Close()
+	return nil
+}
+
+func checkpathExist() error {
+	if strOutFilePath == "" {
+		logs.Error("输入的路径不存在")
+		return errors.New("输入的路径不存在")
+	}
+	f, err := os.Open(strOutFilePath)
+	if err != nil {
+		logs.Error("输入的保存路径不存在,请核对", err.Error())
+		return err
+	}
+	f.Close()
+	return nil
+}
+
+func checkDate() error {
+
+	if strDate == "" {
+		strDate = time.Now().Format("2006-01-02")
+		return nil
+	}
+	_, err := time.Parse("2006-01-02", strDate)
+
+	if err != nil {
+		_, err = time.Parse("2006/01/02", strDate)
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}

+ 43 - 0
models/models.go

@@ -0,0 +1,43 @@
+package models
+
+import (
+	"../pkg/setting"
+	"fmt"
+	_ "github.com/go-sql-driver/mysql"
+	"github.com/xormplus/xorm"
+	"log"
+)
+var Engine   *xorm.Engine
+func Setup() {
+	var err error
+
+	// restful  接口的 数据库初始化
+	if err := SQLInit("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local",
+		setting.DatabaseSetting.User,
+		setting.DatabaseSetting.Password,
+		setting.DatabaseSetting.Host,
+		setting.DatabaseSetting.Name), 1000, 10,setting.DatabaseSetting.ShowXormlog); err != nil {
+		log.Fatal(err.Error())
+		fmt.Println("dbs 数据库初始化失败 ")
+	}
+	if err != nil {
+		fmt.Println("dbs 数据库初始化失败 ")
+		log.Fatalf("models.Setup err: %v", err)
+	}
+}
+
+func SQLInit(driverName, dataSourceName string, maxOpenConns, maxIdleConns int, showlog bool) error {
+	if Engine == nil {
+		var err error
+		if Engine, err = xorm.NewEngine(driverName, dataSourceName); err != nil {
+			return err
+		}
+		if showlog {
+			Engine.ShowSQL(true)
+		}
+		Engine.SetMaxIdleConns(maxIdleConns)
+		Engine.SetMaxOpenConns(maxOpenConns)
+
+	}
+	return nil
+}

+ 15 - 0
pkg/app/request.go

@@ -0,0 +1,15 @@
+package app
+
+import (
+	"github.com/astaxie/beego/validation"
+
+	"../../pkg/logging"
+)
+
+func MarkErrors(errors []*validation.Error) {
+	for _, err := range errors {
+		logging.Info(err.Key, err.Message)
+	}
+
+	return
+}

+ 31 - 0
pkg/app/response.go

@@ -0,0 +1,31 @@
+package app
+
+import (
+	"github.com/gin-gonic/gin"
+	"../../pkg/e"
+)
+
+type Gin struct {
+	C *gin.Context
+}
+
+func (g *Gin) Response(httpCode, errCode int, data interface{}) {
+	g.C.JSON(httpCode, gin.H{
+		"code": httpCode,
+		"msg":  e.GetMsg(errCode),
+		"data": data,
+	})
+	return
+}
+
+func (g *Gin) ResponseEq(httpCode, errCode int, errorNo int, data interface{}) {
+	g.C.JSON(httpCode, gin.H{
+		"code": httpCode,
+		"message":  e.GetMsg(errCode),
+		"results": data,
+		"errorNo": errorNo,
+		"success": 1,
+	})
+	return
+}
+

+ 23 - 0
pkg/e/code.go

@@ -0,0 +1,23 @@
+package e
+
+const (
+	SUCCESS        = 200
+	ERROR          = 500
+	INVALID_PARAMS = 400
+
+	ERROR_EXIST       = 10001
+	ERROR_EXIST_FAIL  = 10002
+	ERROR_NOT_EXIST   = 10003
+	ERROR_GET_S_FAIL  = 10004
+	ERROR_COUNT_FAIL  = 10005
+	ERROR_ADD_FAIL    = 10006
+	ERROR_EDIT_FAIL   = 10007
+	ERROR_DELETE_FAIL = 10008
+	ERROR_EXPORT_FAIL = 10009
+	ERROR_IMPORT_FAIL = 10010
+
+	ERROR_AUTH_CHECK_TOKEN_FAIL    = 20001
+	ERROR_AUTH_CHECK_TOKEN_TIMEOUT = 20002
+	ERROR_AUTH_TOKEN               = 20003
+	ERROR_AUTH                     = 20004
+)

+ 32 - 0
pkg/e/msg.go

@@ -0,0 +1,32 @@
+package e
+
+var MsgFlags = map[int]string{
+	SUCCESS:        "ok",
+	ERROR:          "fail",
+	INVALID_PARAMS: "请求参数错误",
+
+	ERROR_EXIST:       "已存在该对象名称",
+	ERROR_EXIST_FAIL:  "获取已存在对象失败",
+	ERROR_NOT_EXIST:   "该对象不存在",
+	ERROR_GET_S_FAIL:  "获取所有对象失败",
+	ERROR_COUNT_FAIL:  "统计对象失败",
+	ERROR_ADD_FAIL:    "新增对象失败",
+	ERROR_EDIT_FAIL:   "修改对象失败",
+	ERROR_DELETE_FAIL: "删除对象失败",
+	ERROR_EXPORT_FAIL: "导出对象失败",
+	ERROR_IMPORT_FAIL: "导入对象失败",
+
+	ERROR_AUTH_CHECK_TOKEN_FAIL:    "Token鉴权失败",
+	ERROR_AUTH_CHECK_TOKEN_TIMEOUT: "Token已超时",
+	ERROR_AUTH_TOKEN:               "Token生成失败",
+	ERROR_AUTH:                     "Token错误",
+}
+
+func GetMsg(code int) string {
+	msg, ok := MsgFlags[code]
+	if ok {
+		return msg
+	}
+
+	return MsgFlags[ERROR]
+}

+ 85 - 0
pkg/file/file.go

@@ -0,0 +1,85 @@
+package file
+
+import (
+	"fmt"
+	"io/ioutil"
+	"mime/multipart"
+	"os"
+	"path"
+)
+
+func GetSize(f multipart.File) (int, error) {
+	content, err := ioutil.ReadAll(f)
+
+	return len(content), err
+}
+
+func GetExt(fileName string) string {
+	return path.Ext(fileName)
+}
+
+func CheckNotExist(src string) bool {
+	_, err := os.Stat(src)
+
+	return os.IsNotExist(err)
+}
+
+func CheckPermission(src string) bool {
+	_, err := os.Stat(src)
+
+	return os.IsPermission(err)
+}
+
+func IsNotExistMkDir(src string) error {
+	if notExist := CheckNotExist(src); notExist == true {
+		if err := MkDir(src); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func MkDir(src string) error {
+	err := os.MkdirAll(src, os.ModePerm)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func Open(name string, flag int, perm os.FileMode) (*os.File, error) {
+	f, err := os.OpenFile(name, flag, perm)
+	if err != nil {
+		return nil, err
+	}
+
+	return f, nil
+}
+
+func MustOpen(fileName, filePath string) (*os.File, error) {
+	//dir, err := os.Getwd()
+	//if err != nil {
+	//	return nil, fmt.Errorf("os.Getwd err: %v", err)
+	//}
+
+
+	src :=  filePath
+	perm := CheckPermission(src)
+	if perm == true {
+		return nil, fmt.Errorf("file.CheckPermission Permission denied src: %s", src)
+	}
+
+	err := IsNotExistMkDir(src)
+	if err != nil {
+		return nil, fmt.Errorf("file.IsNotExistMkDir src: %s, err: %v", src, err)
+	}
+
+	f, err := Open(src+fileName, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0644)
+	if err != nil {
+		return nil, fmt.Errorf("Fail to OpenFile :%v", err)
+	}
+
+	return f, nil
+}

+ 45 - 0
pkg/logging/file.go

@@ -0,0 +1,45 @@
+package logging
+
+import (
+	"fmt"
+	"time"
+
+	"../../pkg/setting"
+)
+
+func getLogFilePath() string {
+	return fmt.Sprintf("%s%s", setting.AppSetting.RuntimeRootPath, setting.AppSetting.LogSavePath)
+}
+
+func getLogFileName() string {
+	return fmt.Sprintf("%s%s.%s",
+		setting.AppSetting.LogSaveName,
+		time.Now().Format(setting.AppSetting.TimeFormat),
+		setting.AppSetting.LogFileExt,
+	)
+}
+
+//func openLogFile(fileName, filePath string) (*os.File, error) {
+//	dir, err := os.Getwd()
+//	if err != nil {
+//		return nil, fmt.Errorf("os.Getwd err: %v", err)
+//	}
+//
+//	src := dir + "/" + filePath
+//	perm := file.CheckPermission(src)
+//	if perm == true {
+//		return nil, fmt.Errorf("file.CheckPermission Permission denied src: %s", src)
+//	}
+//
+//	err = file.IsNotExistMkDir(src)
+//	if err != nil {
+//		return nil, fmt.Errorf("file.IsNotExistMkDir src: %s, err: %v", src, err)
+//	}
+//
+//	f, err := file.Open(src+fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
+//	if err != nil {
+//		return nil, fmt.Errorf("Fail to OpenFile :%v", err)
+//	}
+//
+//	return f, nil
+//}

+ 126 - 0
pkg/logging/log.go

@@ -0,0 +1,126 @@
+package logging
+
+import (
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"path/filepath"
+	"runtime"
+	"time"
+
+	"../../pkg/file"
+	"../setting"
+	"github.com/gin-gonic/gin"
+)
+
+type Level int
+
+var (
+	F *os.File
+
+	DefaultPrefix      = ""
+	DefaultCallerDepth = 2
+	DefaultPath        string
+
+	logger     *log.Logger
+	logPrefix  = ""
+	levelFlags = []string{"DEBUG", "INFO", "WARN", "ERROR", "FATAL"}
+)
+
+const (
+	DEBUG Level = iota
+	INFO
+	WARNING
+	ERROR
+	FATAL
+)
+
+func Setup() {
+	var err error
+	//tchan :=time.Tick(24*time.Hour)
+	DefaultPath, _ = setting.GetCurrentPath()
+	filePath := DefaultPath + getLogFilePath()
+	fileName := getLogFileName()
+	F, err = file.MustOpen(fileName, filePath)
+	if err != nil {
+		log.Fatalf("logging.Setup err: %v", err)
+	}
+	println(filePath)
+	logger = log.New(F, DefaultPrefix, log.LstdFlags)
+	//gin.DefaultWriter = io.MultiWriter(F, os.Stdout)
+	go func() {
+		tchan := time.Tick(24 * time.Hour)
+		for {
+			select {
+			case <-tchan:
+				F.Close()
+				//fmt.Println("t1定时器")
+				filePath := DefaultPath + getLogFilePath()
+				fileName := getLogFileName()
+				F, err = file.MustOpen(fileName, filePath)
+				if err != nil {
+					log.Fatalf("logging.Setup err: %v", err)
+				}
+
+				logger = log.New(F, DefaultPrefix, log.LstdFlags)
+				gin.DefaultWriter = io.MultiWriter(F, os.Stdout)
+			}
+		}
+	}()
+
+	//// gin log设置
+	//gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
+	//
+	//	// 你的自定义格式
+	//	return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"%s\n",
+	//		param.ClientIP,
+	//		param.TimeStamp.Format(time.RFC1123),
+	//		param.Method,
+	//		param.Path,
+	//		param.Request.Proto,
+	//		param.StatusCode,
+	//		param.Latency,
+	//		param.Request.UserAgent(),
+	//		param.ErrorMessage,
+	//		param.Request.Form,
+	//	)
+	//})
+
+}
+
+func Debug(v ...interface{}) {
+	setPrefix(DEBUG)
+	logger.Println(v)
+}
+
+func Info(v ...interface{}) {
+	setPrefix(INFO)
+	logger.Println(v)
+}
+
+func Warn(v ...interface{}) {
+	setPrefix(WARNING)
+	logger.Println(v)
+}
+
+func Error(v ...interface{}) {
+	setPrefix(ERROR)
+	logger.Println(v)
+}
+
+func Fatal(v ...interface{}) {
+	setPrefix(FATAL)
+	logger.Fatalln(v)
+}
+
+func setPrefix(level Level) {
+	_, file, line, ok := runtime.Caller(DefaultCallerDepth)
+	if ok {
+		logPrefix = fmt.Sprintf("[%s][%s:%d]", levelFlags[level], filepath.Base(file), line)
+	} else {
+		logPrefix = fmt.Sprintf("[%s]", levelFlags[level])
+	}
+
+	logger.SetPrefix(logPrefix)
+}

+ 80 - 0
pkg/setting/setting.go

@@ -0,0 +1,80 @@
+package setting
+
+import (
+	"errors"
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+
+	"github.com/go-ini/ini"
+)
+
+type Database struct {
+	Type          string
+	User          string
+	Password      string
+	Host          string
+	Name          string
+	ShowXormlog   bool
+	ShowGetSqllog bool
+	CacheApiSql   bool
+	TablePrefix   string
+	FarmCode      string
+}
+
+var DatabaseSetting = &Database{}
+
+var cfg *ini.File
+
+var CurrentPath string
+
+func GetCurrentPath() (string, error) {
+	file, err := exec.LookPath(os.Args[0])
+	if err != nil {
+		return "", err
+	}
+	path, err := filepath.Abs(file)
+	if err != nil {
+		return "", err
+	}
+	//fmt.Println("path111:", path)
+	if runtime.GOOS == "windows" {
+		path = strings.Replace(path, "\\", "/", -1)
+	}
+	//fmt.Println("path222:", path)
+	i := strings.LastIndex(path, "/")
+	if i < 0 {
+		return "", errors.New(`Can't find "/" or "\".`)
+	}
+	//fmt.Println("path333:", path)
+	return string(path[0 : i+1]), nil
+}
+func Setup(dir string) {
+	var err error
+	if strings.Trim(dir, " ") == "" {
+		CurrentPath, err = GetCurrentPath()
+	} else {
+		CurrentPath = dir
+	}
+	cfg, err = ini.Load(CurrentPath + "app.ini")
+	if err != nil {
+		log.Fatalf("setting.Setup, fail to parse 'conf/app.ini': %v", err)
+	}
+	mapTo("database", DatabaseSetting)
+	DatabaseSetting.Host = DatabaseSetting.Host + ":3326"
+	DatabaseSetting.Type = "mysql"
+	DatabaseSetting.User = "root"
+	DatabaseSetting.Password = "root"
+	DatabaseSetting.Name = "tmrwatch2"
+
+}
+
+func mapTo(section string, v interface{}) {
+	err := cfg.Section(section).MapTo(v)
+	if err != nil {
+		log.Fatalf("Cfg.MapTo RedisSetting err: %v", err)
+	}
+}

+ 68 - 0
pkg/util/jwt.go

@@ -0,0 +1,68 @@
+package util
+
+import (
+	"fmt"
+	"github.com/dgrijalva/jwt-go"
+	"reflect"
+	"time"
+
+	"../../pkg/setting"
+)
+
+var JwtSecret = []byte(setting.AppSetting.JwtSecret)
+
+type Claims struct {
+	Username string `json:"username"`
+	Password string `json:"password"`
+	jwt.StandardClaims
+}
+
+func GenerateToken(username, password string) (string, error) {
+	nowTime := time.Now()
+	expireTime := nowTime.Add(12 * time.Hour)
+
+	claims := Claims{
+		username,
+		EncodeMD5(password),
+		jwt.StandardClaims{
+			ExpiresAt: expireTime.Unix(),
+			Issuer:    "https://github.com/kptyun/go-admin/",
+		},
+	}
+
+	tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+	token, err := tokenClaims.SignedString(JwtSecret)
+	return token, err
+}
+
+func ParseToken(token string) (*Claims, error) {
+	tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) {
+		return JwtSecret, nil
+	})
+
+	if tokenClaims != nil {
+		if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
+			return claims, nil
+		}
+	}
+
+	return nil, err
+}
+
+
+
+
+func GetIdFromClaims(key string, claims jwt.Claims) string {
+	v := reflect.ValueOf(claims)
+	if v.Kind() == reflect.Map {
+		for _, k := range v.MapKeys() {
+			value := v.MapIndex(k)
+
+			if fmt.Sprintf("%s", k.Interface()) == key {
+				return fmt.Sprintf("%v", value.Interface())
+			}
+		}
+	}
+	return ""
+}
+

+ 13 - 0
pkg/util/md5.go

@@ -0,0 +1,13 @@
+package util
+
+import (
+	"crypto/md5"
+	"encoding/hex"
+)
+
+func EncodeMD5(value string) string {
+	m := md5.New()
+	m.Write([]byte(value))
+
+	return hex.EncodeToString(m.Sum(nil))
+}

+ 82 - 0
pkg/util/offiaccount.go

@@ -0,0 +1,82 @@
+package util
+
+import (
+	"fmt"
+	"github.com/fastwego/offiaccount"
+	"github.com/fastwego/offiaccount/apis/menu"
+	"os"
+	"strings"
+)
+// 微信公众账号
+var OffiAccount *offiaccount.OffiAccount
+func init() {
+	// 加载配置文件
+
+	// 创建公众号实例
+	OffiAccount = offiaccount.New(offiaccount.Config{
+		Appid:          "wxe1cc563ba393dd1a",
+		Secret:         "25e56243da9581eab6f4d67a12ef4658",
+		//Token:          viper.GetString("TOKEN"),
+		//EncodingAESKey: viper.GetString("EncodingAESKey"),
+	})
+}
+func Send_Message2(access_token, msg string) {
+	app := offiaccount.New(offiaccount.Config{
+		Appid:  "APPID",
+		Secret: "SECRET",
+	})
+
+	// 调用 api
+	payload := []byte(`
+{
+     "button":[
+     {
+           "name":"菜单",
+           "sub_button":[
+           {	
+               "type":"view",
+               "name":"搜索",
+               "url":"http://www.baidu.com/"
+            }]
+       }]
+}`)
+
+	resp, err := menu.Create(app, payload)
+
+
+	fmt.Println(resp, err)
+}
+
+func messages1(touser string, toparty string, agentid int, content string) string {
+	msg := MESSAGES{
+		Touser:  touser,
+		Toparty: toparty,
+		Msgtype: "text",
+		Agentid: agentid,
+		Safe:    0,
+		Text: struct {
+			//Subject string `json:"subject"`
+			Content string `json:"content"`
+		}{Content: content},
+	}
+	sed_msg, _ := json.Marshal(msg)
+	//fmt.Printf("%s",string(sed_msg))
+	return string(sed_msg)
+}
+
+func main() {
+	touser := "BigBoss"                            //企业号中的用户帐号,在zabbix用户Media中配置,如果配置不正常,将按部门发送。
+	toparty := "2"                                 //企业号中的部门id。
+	agentid := 1000002                             //企业号中的应用id。
+	corpid := "xxxxxxxxxxxxxxxxx"                  //企业号的标识
+	corpsecret := "exxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ///企业号中的应用的Secret
+	accessToken := Get_AccessToken(corpid, corpsecret)
+	content := os.Args[1]
+	//  fmt.Println(content)
+	// 序列化成json之后,\n会被转义,也就是变成了\\n,使用str替换,替换掉转义
+	msg := strings.Replace(messages(touser, toparty, agentid, content), "\\\\", "\\", -1)
+
+	//  fmt.Println(strings.Replace(msg,"\\\\","\\",-1))
+	Send_Message(accessToken, msg)
+
+}

+ 18 - 0
pkg/util/pagination.go

@@ -0,0 +1,18 @@
+package util
+
+import (
+	"github.com/Unknwon/com"
+	"github.com/gin-gonic/gin"
+
+	"../../pkg/setting"
+)
+
+func GetPage(c *gin.Context) int {
+	result := 0
+	page := com.StrTo(c.Query("page")).MustInt()
+	if page > 0 {
+		result = (page - 1) * setting.AppSetting.PageSize
+	}
+
+	return result
+}

+ 114 - 0
pkg/util/snowflake.go

@@ -0,0 +1,114 @@
+package util
+import (
+	"errors"
+	"fmt"
+	"sync"
+	"time"
+)
+
+const (
+	twepoch        = int64(1417937700000) // 默认起始的时间戳 1449473700000 。计算时,减去这个值
+	DistrictIdBits = uint(5)              //区域 所占用位置
+	NodeIdBits     = uint(9)              //节点 所占位置
+	sequenceBits   = uint(10)             //自增ID 所占用位置
+
+	/*
+	 * 1 符号位  |  39 时间戳                                     | 5 区域  |  9 节点       | 10 (毫秒内)自增ID
+	 * 0        |  0000000 00000000 00000000 00000000 00000000  | 00000  | 000000 000   |  000000 0000
+	 *
+	 */
+	maxNodeId     = -1 ^ (-1 << NodeIdBits)     //节点 ID 最大范围
+	maxDistrictId = -1 ^ (-1 << DistrictIdBits) //最大区域范围
+
+	nodeIdShift        = sequenceBits //左移次数
+	DistrictIdShift    = sequenceBits + NodeIdBits
+	timestampLeftShift = sequenceBits + NodeIdBits + DistrictIdBits
+	sequenceMask       = -1 ^ (-1 << sequenceBits)
+	maxNextIdsNum      = 100 //单次获取ID的最大数量
+)
+
+type IdWorker struct {
+	sequence      int64 //序号
+	lastTimestamp int64 //最后时间戳
+	nodeId        int64 //节点ID
+	twepoch       int64
+	districtId    int64
+	mutex         sync.Mutex
+}
+
+// NewIdWorker new a snowflake id generator object.
+func NewIdWorker(NodeId int64) (*IdWorker, error) {
+	var districtId int64
+	districtId = 1 //暂时默认给1 ,方便以后扩展
+	idWorker := &IdWorker{}
+	if NodeId > maxNodeId || NodeId < 0 {
+		fmt.Sprintf("NodeId Id can't be greater than %d or less than 0", maxNodeId)
+		return nil, errors.New(fmt.Sprintf("NodeId Id: %d error", NodeId))
+	}
+	if districtId > maxDistrictId || districtId < 0 {
+		fmt.Sprintf("District Id can't be greater than %d or less than 0", maxDistrictId)
+		return nil, errors.New(fmt.Sprintf("District Id: %d error", districtId))
+	}
+	idWorker.nodeId = NodeId
+	idWorker.districtId = districtId
+	idWorker.lastTimestamp = -1
+	idWorker.sequence = 0
+	idWorker.twepoch = twepoch
+	idWorker.mutex = sync.Mutex{}
+	fmt.Sprintf("worker starting. timestamp left shift %d, District id bits %d, worker id bits %d, sequence bits %d, workerid %d", timestampLeftShift, DistrictIdBits, NodeIdBits, sequenceBits, NodeId)
+	return idWorker, nil
+}
+
+// timeGen generate a unix millisecond.
+func timeGen() int64 {
+	return time.Now().UnixNano() / int64(time.Millisecond)
+}
+
+// tilNextMillis spin wait till next millisecond.
+func tilNextMillis(lastTimestamp int64) int64 {
+	timestamp := timeGen()
+	for timestamp <= lastTimestamp {
+		timestamp = timeGen()
+	}
+	return timestamp
+}
+
+// NextId get a snowflake id.
+func (id *IdWorker) NextId() (int64, error) {
+	id.mutex.Lock()
+	defer id.mutex.Unlock()
+	return id.nextid()
+}
+
+// NextIds get snowflake ids.
+func (id *IdWorker) NextIds(num int) ([]int64, error) {
+	if num > maxNextIdsNum || num < 0 {
+		fmt.Sprintf("NextIds num can't be greater than %d or less than 0", maxNextIdsNum)
+		return nil, errors.New(fmt.Sprintf("NextIds num: %d error", num))
+	}
+	ids := make([]int64, num)
+	id.mutex.Lock()
+	defer id.mutex.Unlock()
+	for i := 0; i < num; i++ {
+		ids[i], _ = id.nextid()
+	}
+	return ids, nil
+}
+
+func (id *IdWorker) nextid() (int64, error) {
+	timestamp := timeGen()
+	if timestamp < id.lastTimestamp {
+		//    fmt.Sprintf("clock is moving backwards.  Rejecting requests until %d.", id.lastTimestamp)
+		return 0, errors.New(fmt.Sprintf("Clock moved backwards.  Refusing to generate id for %d milliseconds", id.lastTimestamp-timestamp))
+	}
+	if id.lastTimestamp == timestamp {
+		id.sequence = (id.sequence + 1) & sequenceMask
+		if id.sequence == 0 {
+			timestamp = tilNextMillis(id.lastTimestamp)
+		}
+	} else {
+		id.sequence = 0
+	}
+	id.lastTimestamp = timestamp
+	return ((timestamp - id.twepoch) << timestampLeftShift) | (id.districtId << DistrictIdShift) | (id.nodeId << nodeIdShift) | id.sequence, nil
+}

+ 56 - 0
pkg/util/wechatOpenId.go

@@ -0,0 +1,56 @@
+package util
+
+import (
+	"errors"
+	"fmt"
+	"net/http"
+)
+
+func GetOpenID(writer http.ResponseWriter, request *http.Request) {
+	var codeMap map[string]string
+	err := json.NewDecoder(request.Body).Decode(&codeMap)
+	if err != nil {
+		return
+	}
+	defer request.Body.Close()
+
+	code := codeMap["code"]
+	openid, err := SendWxAuthAPI(code)
+	if err != nil {
+		return
+	}
+	fmt.Println("my openid", openid)
+}
+
+const (
+	code2sessionURL = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"
+	appID           = "wx99b5bd356930780f"
+	appSecret       = "8ec4db6a9277b845413b470fa6ff5679"
+)
+
+func SendWxAuthAPI(code string) (string, error) {
+	url := fmt.Sprintf(code2sessionURL, appID, appSecret,code)
+	resp, err := http.DefaultClient.Get(url)
+	if err != nil {
+		println("DefaultClient err ",err.Error())
+		return "", err
+	}
+	var wxMap map[string]interface{}
+	err = json.NewDecoder(resp.Body).Decode(&wxMap)
+	if err != nil {
+		println("NewDecoder err ",err.Error(),resp.Body)
+		return "", err
+	}
+	if wxMap["openid"] == nil{
+		fmt.Printf("%v+",wxMap)
+		if wxMap["errmsg"] == nil {
+			return "", errors.New("openid为空")
+		}else {
+			return "", errors.New(wxMap["errmsg"].(string))
+		}
+
+	}
+	defer resp.Body.Close()
+
+	return wxMap["openid"].(string), nil
+}

+ 94 - 0
pkg/util/workwechat.go

@@ -0,0 +1,94 @@
+package util
+
+
+import (
+"bytes"
+"github.com/json-iterator/go"
+"io/ioutil"
+"net/http"
+"os"
+"strings"
+)
+
+var json = jsoniter.ConfigCompatibleWithStandardLibrary
+
+type JSON struct {
+	Access_token string `json:"access_token"`
+}
+
+type MESSAGES struct {
+	Touser string `json:"touser"`
+	Toparty string `json:"toparty"`
+	Msgtype string `json:"msgtype"`
+	Agentid int `json:"agentid"`
+	Text struct {
+		//Subject string `json:"subject"`
+		Content string `json:"content"`
+	} `json:"text"`
+	Safe int `json:"safe"`
+}
+
+func Get_AccessToken(corpid,corpsecret string) string {
+	gettoken_url := "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpid + "&corpsecret=" + corpsecret
+	//print(gettoken_url)
+	client := &http.Client{}
+	req, _ := client.Get(gettoken_url)
+	defer req.Body.Close()
+	body, _ := ioutil.ReadAll(req.Body)
+	//fmt.Printf("\n%q",string(body))
+	var json_str JSON
+	json.Unmarshal([]byte(body), &json_str)
+	//fmt.Printf("\n%q",json_str.Access_token)
+	return json_str.Access_token
+}
+
+func Send_Message(access_token,msg string) {
+	send_url := "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + access_token
+	//print(send_url)
+	client := &http.Client{}
+	req, _ := http.NewRequest("POST", send_url, bytes.NewBuffer([]byte(msg)))
+	req.Header.Set("Content-Type", "application/json")
+	req.Header.Set("charset","UTF-8")
+	resp, err := client.Do(req)
+	if err != nil {
+		panic(err)
+	}
+	defer resp.Body.Close()
+	//fmt.Println("response Status:", resp.Status)
+	//body, _ := ioutil.ReadAll(resp.Body)
+	//fmt.Println("response Body:", string(body))
+}
+
+func messages(touser string,toparty string,agentid int,content string) string{
+	msg := MESSAGES{
+		Touser: touser,
+		Toparty: toparty,
+		Msgtype: "text",
+		Agentid: agentid,
+		Safe: 0,
+		Text: struct {
+			//Subject string `json:"subject"`
+			Content string `json:"content"`
+		}{Content: content},
+	}
+	sed_msg, _ := json.Marshal(msg)
+	//fmt.Printf("%s",string(sed_msg))
+	return string(sed_msg)
+}
+
+func main1() {
+	touser := "BigBoss"  //企业号中的用户帐号,在zabbix用户Media中配置,如果配置不正常,将按部门发送。
+	toparty := "2"       //企业号中的部门id。
+	agentid:= 1000002    //企业号中的应用id。
+	corpid := "xxxxxxxxxxxxxxxxx"  //企业号的标识
+	corpsecret := "exxxxxxxxxxxxxxxxxxxxxxxxxxxxx"  ///企业号中的应用的Secret
+	accessToken := Get_AccessToken(corpid,corpsecret)
+	content := os.Args[1]
+	//  fmt.Println(content)
+	// 序列化成json之后,\n会被转义,也就是变成了\\n,使用str替换,替换掉转义
+	msg := strings.Replace(messages(touser,toparty,agentid,content),"\\\\","\\",-1)
+
+	//  fmt.Println(strings.Replace(msg,"\\\\","\\",-1))
+	Send_Message(accessToken,msg)
+
+}

BIN
tmrgo


BIN
update/KPTAdmin64.exe


BIN
update/PrconsoleV2.4.exe


+ 71 - 0
update/main.go

@@ -0,0 +1,71 @@
+package main
+
+import (
+	"fmt"
+	"io"
+	"net/http"
+	"os"
+	"errors"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"time"
+
+)
+
+func main(){
+
+	res, err := http.Get("https://kptyun.cn/file/PrconsoleV2.4.exe")
+	if err != nil {
+		panic(err)
+	}
+
+	if res.StatusCode != 200{
+		fmt.Println("更新文件不存在或网络错误")
+		time.Sleep(3*time.Second)
+		return
+	}
+	fmt.Println("更新中....")
+	res.Header.Get("Content-Disposition")
+	CurrentPath,err :=  GetCurrentPath()
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	err =os.Rename(CurrentPath+"PrconsoleV2.4.exe",CurrentPath+"PrconsoleV2.4.exe"+time.Now().Format("20060102150405"))
+	f, err := os.Create(CurrentPath+"PrconsoleV2.4.exe")
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	_,err =io.Copy(f, res.Body)
+	if err!= nil{
+		fmt.Println(err)
+		return
+	}
+	fmt.Println("更新成功")
+	time.Sleep(3*time.Second)
+}
+
+func GetCurrentPath() (string, error) {
+	file, err := exec.LookPath(os.Args[0])
+	if err != nil {
+		return "", err
+	}
+	path, err := filepath.Abs(file)
+	if err != nil {
+		return "", err
+	}
+	//fmt.Println("path111:", path)
+	if runtime.GOOS == "windows" {
+		path = strings.Replace(path, "\\", "/", -1)
+	}
+	//fmt.Println("path222:", path)
+	i := strings.LastIndex(path, "/")
+	if i < 0 {
+		return "", errors.New(`Can't find "/" or "\".`)
+	}
+	//fmt.Println("path333:", path)
+	return string(path[0 : i+1]), nil
+}

+ 3 - 0
update/win32 v2 - 副本.bat

@@ -0,0 +1,3 @@
+set GOARCH=386
+set GOOS=windows
+go build  -ldflags=" -w -H windowsgui"

+ 4 - 0
update/win64.bat

@@ -0,0 +1,4 @@
+set GOARCH=amd64
+set GOOS=windows
+go clean
+go build -o KPTAdmin64.exe

+ 3 - 0
win32 v2.bat

@@ -0,0 +1,3 @@
+set GOARCH=386
+set GOOS=windows
+go build  -ldflags="-H windowsgui"

+ 3 - 0
win32.bat

@@ -0,0 +1,3 @@
+set GOARCH=386
+set GOOS=windows
+go build -o PrconsoleV2.4_32.exe

+ 3 - 0
win32压缩.bat

@@ -0,0 +1,3 @@
+set GOARCH=386
+set GOOS=windows
+go build  -ldflags=" -w -H windowsgui"

+ 4 - 0
win64.bat

@@ -0,0 +1,4 @@
+set GOARCH=amd64
+set GOOS=windows
+go clean
+go build -o PrconsoleV2.4.exe