Explorar o código

fix:
1. datacenter_client结构调整
2. 增加5个接口

gaoyagang hai 1 ano
pai
achega
c8d0f6c39d

+ 0 - 165
datacenter_client/basic.go

@@ -1,165 +0,0 @@
-package datacenter_client
-
-import (
-	"bytes"
-	"crypto/md5"
-	"encoding/hex"
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
-	"metawant.greentech.com.cn/gaoyagang/gt-common/httplib"
-	"net/http"
-	"net/url"
-	"sort"
-	"time"
-)
-
-type DcApiClient struct {
-	ServerIp string
-	AppName string
-	AppSecret string
-}
-
-const (
-	S2_MIN_LENGTH           = 2048
-	S2_HEAD_LENGTH          = 200
-	S2_TAIL_LENGTH          = 200
-)
-
-func CreateDcApiClient(ip, appName, appSecret string) *DcApiClient {
-	return &DcApiClient{
-		ServerIp: ip,
-		AppName: appName,
-		AppSecret: appSecret,
-	}
-}
-
-func (d *DcApiClient) RequestMiddleProcess(h *httplib.HTTPRequest, projectId string) ([]byte, error) {
-	//h.Header("X-Forwarded-For", "127.0.0.1")
-	h.Header("APP-NAME", d.AppName)
-	ts := time.Now().Unix()
-	h.Param("project_id", projectId)
-	h.Param("ts", fmt.Sprintf("%d", ts))
-	sign, err := d.CreateSign(h)
-	if err != nil {
-		return nil, err
-	}
-	h.Param("sign", sign)
-	return h.Bytes()
-}
-
-func (d *DcApiClient)CreateSign(h *httplib.HTTPRequest) (string, error) {
-	s2, err := parseBody(h)
-
-	if err != nil {
-		fmt.Println("parseBody Error: ", err.Error())
-		return "", err
-	}
-	contentLength := h.GetRequest().ContentLength
-	if contentLength > S2_MIN_LENGTH {
-		h.Param("sign_flag", "1")
-		s2 = cutS2(s2)
-	} else {
-		s2, err = sortS2(s2)
-		if err != nil {
-			return "", err
-		}
-	}
-
-	s3 := contentLength
-	s1 := parseQuery(h)
-
-	m := md5.New()
-	m.Write([]byte(fmt.Sprintf("%s%s%d%s", s1, s2, s3, d.AppSecret)))
-	md5Str := hex.EncodeToString(m.Sum(nil))
-	//fmt.Println("s1", s1)
-	//fmt.Println("s2", s2)
-	//fmt.Println("s3", s3)
-	//fmt.Println("md5", md5Str)
-	return md5Str, nil
-}
-
-func cutS2(s2 string) string {
-	if s2 == "" {
-		return ""
-	}
-	s2l := len(s2)
-	//if s2l <= S2_MIN_LENGTH {
-	//	return s2
-	//}
-	return fmt.Sprintf("%s%s", s2[:S2_HEAD_LENGTH], s2[s2l-S2_TAIL_LENGTH:])
-}
-
-func sortS2(s2 string) (string, error) {
-	if s2 == "" {
-		return "", nil
-	}
-	var mi map[string]interface{}
-	if err := json.Unmarshal([]byte(s2), &mi); err != nil {
-		return "", err
-	}
-
-	//smi := SortMapByKey(mi)
-
-	if bs, err := json.Marshal(mi); err != nil {
-		return "", err
-	} else {
-		return string(bs), nil
-	}
-}
-
-func parseBody(r *httplib.HTTPRequest) (s2 string, err error) {
-	if r.GetRequest().Method == http.MethodGet {
-		return "", nil
-	}
-	body := r.GetRequest().Body
-
-	cnt, err := ioutil.ReadAll(body)
-	if err != nil {
-		return "", err
-	}
-	r.GetRequest().Body = ioutil.NopCloser(bytes.NewReader(cnt))
-
-	return string(cnt), nil
-}
-
-func parseQuery(r *httplib.HTTPRequest) string {
-	params := r.GetQueryParam()
-	delete(params, "sign")
-
-	val := url.Values{}
-	for k, v := range params {
-		for index, s := range v {
-			if index == 0 {
-				val.Set(k, s)
-			} else {
-				val.Add(k, s)
-			}
-		}
-	}
-	return val.Encode()
-}
-
-// SortMapByKey 对 map[string]interface{} 按照键进行排序
-func SortMapByKey(m map[string]interface{}) map[string]interface{} {
-	// 创建一个 map[string]int,用于记录键的索引
-	indexMap := make(map[string]int)
-	for k := range m {
-		indexMap[k] = len(indexMap)
-	}
-
-	// 对键进行排序
-	keys := make([]string, 0, len(indexMap))
-	for k := range indexMap {
-		keys = append(keys, k)
-	}
-	sort.Strings(keys)
-
-	// 创建排序后的 map[string]interface{}
-	sortedMap := make(map[string]interface{})
-	for _, k := range keys {
-		sortedMap[k] = m[k]
-	}
-
-	return sortedMap
-}

+ 24 - 0
datacenter_client/client/client.go

@@ -0,0 +1,24 @@
+package client
+
+import (
+	"metawant.greentech.com.cn/gaoyagang/gt-common/datacenter_client"
+	v1 "metawant.greentech.com.cn/gaoyagang/gt-common/datacenter_client/v1"
+	"metawant.greentech.com.cn/gaoyagang/gt-common/httplib"
+)
+
+// 创建一个v1版本的数据调用接口
+func CreateDcApiClient(ip, appName, appSecret string, settings httplib.HTTPSettings) datacenter_client.DcAPI {
+	client := v1.NewDcApi(v1.ClientOptions{
+		HTTPSettings: settings,
+		ServerIp:     ip,
+		AppName:      appName,
+		AppSecret:    appSecret,
+		// 以下两项暂时不使用了
+		//DoBefore:     nil,
+		//DoAfter:      nil,
+	})
+
+	return client
+}
+
+// 业务扩展中还会存在v2 ...

+ 34 - 0
datacenter_client/client/client_test.go

@@ -0,0 +1,34 @@
+package client
+
+import (
+	"metawant.greentech.com.cn/gaoyagang/gt-common/datacenter_client"
+	"metawant.greentech.com.cn/gaoyagang/gt-common/httplib"
+	"testing"
+)
+
+func TestCreateDcApiClient(t *testing.T) {
+	v1 := CreateDcApiClient("47.96.12.136:8788", "simulations", "e3fc084fda3d2a6628b9ce28abf21243", httplib.HTTPSettings{})
+
+	resp, err := v1.ObtainRangeMaxMin(&datacenter_client.RangeMaxMinReq{
+		ProjectId: "92",
+		ItemName:  "C.M.CIP_QXB1_A@out",
+		Stime:     "2023-12-27 12:05:44",
+		Etime:     "2024-01-27 12:05:44",
+	})
+
+	t.Log(resp)
+	t.Log(err)
+
+	resp1, err1 := v1.FindWorkingUfByCycle(datacenter_client.FindWorkingUfByCycleReq{
+		ProjectId:       92,
+		DeviceCode:      "UF-4001D",
+		FilterCycle:     16,
+		Step:            26,
+		FilterTimeStart: 3046.00,
+		FilterTimeEnd:   3546.00,
+		Limit:           5,
+	})
+
+	t.Log(resp1)
+	t.Log(err1)
+}

+ 0 - 60
datacenter_client/history_info.go

@@ -1,60 +0,0 @@
-package datacenter_client
-
-import (
-	"encoding/json"
-	"errors"
-	"fmt"
-	"log"
-	"metawant.greentech.com.cn/gaoyagang/gt-common/httplib"
-)
-
-type ItemHistoryReq struct {
-	ProjectId string
-	ItemName string
-	Stime string
-	Etime string
-}
-
-type ItemHistoryResp struct {
-	ProjectId int `json:"project_id"`
-	ItemName string `json:"item_name"`
-	Val float64 `json:"val"`
-	HTime string `json:"h_time"`
-}
-
-type ItemHistoryRespList struct {
-	List []ItemHistoryResp
-}
-
-type ItemHistoryBody struct {
-	Code int              		`json:"code"`
-	Msg  string             	`json:"msg"`
-	Data ItemHistoryRespList 	`json:"data"`
-}
-
-func (d *DcApiClient)GetItemHistory (req ItemHistoryReq) (resp []ItemHistoryResp, err error) {
-	url := fmt.Sprintf("http://%s/api/dtgateway/v1/item-history/info", d.ServerIp)
-	h := httplib.Get(url)
-	h.Param("project_id", req.ProjectId)
-	h.Param("item_name", req.ItemName)
-	h.Param("stime", req.Stime)
-	h.Param("etime", req.Etime)
-
-	body, err := d.RequestMiddleProcess(h, req.ProjectId)
-	if err != nil {
-		log.Println("GetItemHistory RequestMiddleProcess Error:", err)
-		return
-	}
-	result := &ItemHistoryBody{}
-	err = json.Unmarshal(body, &result)
-	if err != nil {
-		log.Println("GetItemHistory Unmarshal Error:", err)
-		return
-	}
-	if result.Code != 200 {
-		err = errors.New(result.Msg)
-		return
-	}
-	resp = result.Data.List
-	return
-}

+ 0 - 54
datacenter_client/multi_add.go

@@ -1,54 +0,0 @@
-package datacenter_client
-
-import (
-	"encoding/json"
-	"errors"
-	"fmt"
-	"log"
-	"metawant.greentech.com.cn/gaoyagang/gt-common/httplib"
-)
-
-type ItemHistoryData struct {
-	ProjectId int `json:"project_id"`
-	ItemName string  `json:"item_name"`
-	Val      float64 `json:"val"`
-	HTime    string  `json:"h_time"`
-}
-
-type MultiAddReq struct {
-	List []ItemHistoryData `json:"list"`
-}
-
-type MultiAddBody struct {
-	Code int              		`json:"code"`
-	Msg  string             	`json:"msg"`
-}
-
-func (d *DcApiClient) MultiAddData (req MultiAddReq) (err error) {
-	if len(req.List) == 0 {
-		return errors.New("无可插入数据")
-	}
-	url := fmt.Sprintf("http://%s/api/dtgateway/v1/item-history/multi-add", d.ServerIp)
-	h := httplib.Post(url)
-	_, err = h.JSONBody(req)
-	if err != nil {
-		return
-	}
-
-	body, err := d.RequestMiddleProcess(h, fmt.Sprintf("%d", req.List[0].ProjectId))
-	if err != nil {
-		log.Println("GetItemHistory Error:", err)
-		return
-	}
-	result := &ItemHistoryBody{}
-	err = json.Unmarshal(body, &result)
-	if err != nil {
-		log.Println("GetItemHistory Error:", err)
-		return
-	}
-	if result.Code != 200 {
-		err = errors.New(result.Msg)
-		return
-	}
-	return
-}

+ 0 - 53
datacenter_client/obtain_range_max_min.go

@@ -1,53 +0,0 @@
-package datacenter_client
-
-import (
-	"encoding/json"
-	"errors"
-	"fmt"
-	"log"
-	"metawant.greentech.com.cn/gaoyagang/gt-common/httplib"
-)
-
-type RangeMaxMinReq struct {
-	ProjectId string
-	ItemName string
-	Stime string
-	Etime string
-}
-
-type RangeMaxMinResp struct {
-	Code int                    `json:"code"`
-	Msg  string             	`json:"msg"`
-	Data *InstrumentCompareData `json:"data"`
-}
-type InstrumentCompareData struct {
-	Max float64 `json:"max_val"`
-	Min float64 `json:"min_val"`
-}
-
-func (d *DcApiClient) ObtainRangeMaxMin (req *RangeMaxMinReq) (resp *InstrumentCompareData, err error) {
-	url := fmt.Sprintf("http://%s/api/dtgateway/v1/item-history/max-min", d.ServerIp)
-	h := httplib.Get(url)
-	h.Param("project_id", req.ProjectId)
-	h.Param("item_name", req.ItemName)
-	h.Param("stime", req.Stime)
-	h.Param("etime", req.Etime)
-
-	body, err := d.RequestMiddleProcess(h, req.ProjectId)
-	if err != nil {
-		log.Println("ObtainRangeMaxMin Error:", err)
-		return
-	}
-	result := &RangeMaxMinResp{}
-	err = json.Unmarshal(body, &result)
-	if err != nil {
-		log.Println("ObtainRangeMaxMin Error:", err)
-		return
-	}
-	if result.Code != 200 {
-		err = errors.New(result.Msg)
-		return
-	}
-	resp = result.Data
-	return
-}

+ 271 - 0
datacenter_client/types.go

@@ -0,0 +1,271 @@
+package datacenter_client
+
+type (
+	// 公共部分
+
+	ItemHistoryResp struct {
+		ProjectId int     `json:"project_id"`
+		ItemName  string  `json:"item_name"`
+		Val       float64 `json:"val"`
+		HTime     string  `json:"h_time"`
+	}
+
+	InstrumentCompareData struct {
+		Max float64 `json:"max_val"`
+		Min float64 `json:"min_val"`
+	}
+
+	WorkingPump struct {
+		Id           int64
+		ProjectId    int64
+		DeviceCode   string
+		FeedPressure float64
+		OutPressure  float64
+		Duration     int64
+		Current      float64
+		Frequency    float64
+		Lift         float64
+		Efficiency   float64
+		RunStatus    int64
+		FaultStatus  int64
+		CTime        string
+	}
+
+	WorkingChest struct {
+		Id                  int64
+		ProjectId           int64
+		DeviceCode          string
+		Switch              int64
+		Level               float64
+		AgitatorStatus      int64
+		AgitatorDuration    int64
+		AgitatorFaultStatus int64
+		CTime               string
+	}
+
+	WorkingRo struct {
+		Id                  int64
+		ProjectId           int64
+		DeviceCode          string
+		WaterTemperature    float64
+		FeedFlow_1St        float64
+		ConFlow_1St         float64
+		ProductFlow_1St     float64
+		FeedPressure_1St    float64
+		ConPressure_1St     float64
+		ProductPressure_1St float64
+		Tmp_1St             float64
+		Flux_1St            float64
+		Permeability_1St    float64
+		FeedFlow_2Nd        float64
+		ConFlow_2Nd         float64
+		ProductFlow_2Nd     float64
+		FeedPressure_2Nd    float64
+		ConPressure_2Nd     float64
+		ProductPressure_2Nd float64
+		Tmp_2Nd             float64
+		Flux_2Nd            float64
+		Permeability_2Nd    float64
+		FeedFlow_3Th        float64
+		ConFlow_3Th         float64
+		ProductFlow_3Th     float64
+		FeedPressure_3Th    float64
+		ConPressure_3Th     float64
+		ProductPressure_3Th float64
+		Tmp_3Th             float64
+		Flux_3Th            float64
+		Permeability_3Th    float64
+		FeedWqTurbidity     float64
+		FeedWqPh            int64
+		ProductWqPh         int64
+		FeedWqAl            float64
+		ProductWqAl         float64
+		FeedWqFe            float64
+		ProductWqFe         float64
+		FeedWqMn            float64
+		ProductWqMn         float64
+		FeedWqSio2          float64
+		ProductWqSio2       float64
+		FeedWqCod           float64
+		ProductWqCod        float64
+		FeedWqP             float64
+		ProductWqP          float64
+		Step                int64
+		CTime               string
+	}
+
+	WorkingUf struct {
+		Id               int64
+		ProjectId        int64
+		DeviceCode       string
+		WaterTemperature float64
+		FeedFlow         float64
+		ConFlow          float64
+		ProductFlow      float64
+		FeedPressure     float64
+		ConPressure      float64
+		ProductPressure  float64
+		Tmp              float64
+		Flux             float64
+		FeedWqTurbidity  float64
+		FeedWqPh         int64
+		ProductWqPh      int64
+		FeedWqAl         float64
+		ProductWqAl      float64
+		FeedWqFe         float64
+		ProductWqFe      float64
+		FeedWqMn         float64
+		ProductWqMn      float64
+		FeedWqSio2       float64
+		ProductWqSio2    float64
+		FeedWqCod        float64
+		ProductWqCod     float64
+		FeedWqP          float64
+		ProductWqP       float64
+		Step             int64
+		FilterTime       float64
+		FilterCycle      int64
+		CTime            string
+	}
+)
+
+type (
+	// 请求参数部分
+
+	FindWorkingUfByCycleReq struct {
+		ProjectId       int64
+		DeviceCode      string
+		FilterCycle     int64
+		Step            int64
+		FilterTimeStart float64
+		FilterTimeEnd   float64
+		Limit           int64
+	}
+
+	DcWorkingReq struct {
+		ProjectId  int64
+		DeviceCode string
+		Stime      string
+		Etime      string
+		Page       int64
+		PageSize   int64
+		Order      string
+	}
+
+	// 点位最大 and 最小值请求
+	RangeMaxMinReq struct {
+		ProjectId string
+		ItemName  string
+		Stime     string
+		Etime     string
+	}
+
+	ItemHistoryReq struct {
+		ProjectId string
+		ItemName  string
+		Stime     string
+		Etime     string
+	}
+
+	// 点位数据写入结构
+	ItemHistoryData struct {
+		ProjectId int     `json:"project_id"`
+		ItemName  string  `json:"item_name"`
+		Val       float64 `json:"val"`
+		HTime     string  `json:"h_time"`
+	}
+
+	// 点位数据写入请求
+	MultiAddReq struct {
+		List []ItemHistoryData `json:"list"`
+	}
+)
+
+type (
+	// 响应结构部分
+
+	GetWorkingPumpByCodeResp struct {
+		Code int    `json:"code"`
+		Msg  string `json:"msg"`
+		Data struct {
+			List []WorkingPump `json:"list"`
+		} `json:"data"`
+	}
+
+	GetWorkingChestByCodeResp struct {
+		Code int    `json:"code"`
+		Msg  string `json:"msg"`
+		Data struct {
+			List []WorkingChest `json:"list"`
+		} `json:"data"`
+	}
+
+	GetWorkingRoByCodeResp struct {
+		Code int    `json:"code"`
+		Msg  string `json:"msg"`
+		Data struct {
+			List []WorkingRo `json:"list"`
+		} `json:"data"`
+	}
+
+	FindWorkingUfByCycleResp struct {
+		Code int    `json:"code"`
+		Msg  string `json:"msg"`
+		Data struct {
+			List []WorkingUf `json:"list"`
+		} `json:"data"`
+	}
+
+	GetWorkingUfByCodeResp struct {
+		Code int    `json:"code"`
+		Msg  string `json:"msg"`
+		Data struct {
+			List []WorkingUf `json:"list"`
+		} `json:"data"`
+	}
+
+	RangeMaxMinResp struct {
+		Code int                    `json:"code"`
+		Msg  string                 `json:"msg"`
+		Data *InstrumentCompareData `json:"data"`
+	}
+
+	ItemHistoryRespList struct {
+		List []ItemHistoryResp
+	}
+
+	MultiAddBody struct {
+		Code int    `json:"code"`
+		Msg  string `json:"msg"`
+	}
+
+	ItemHistoryBody struct {
+		Code int                 `json:"code"`
+		Msg  string              `json:"msg"`
+		Data ItemHistoryRespList `json:"data"`
+	}
+)
+
+type (
+	// DcAPI 在这里定义了数据中心接口, 具体实现在版本目录中(目前只有v1)
+
+	DcAPI interface {
+		// GetItemHistory 查询历史点位数据
+		GetItemHistory(req ItemHistoryReq) (resp []ItemHistoryResp, err error)
+		// MultiAddData 点位数据写入
+		MultiAddData(req MultiAddReq) (err error)
+		// ObtainRangeMaxMin 查询最大最小值
+		ObtainRangeMaxMin(req *RangeMaxMinReq) (resp *InstrumentCompareData, err error)
+
+		// GetWorkingUfByCode 获得uf工况数据
+		GetWorkingUfByCode(DcWorkingReq) (*GetWorkingUfByCodeResp, error)
+		// FindWorkingUfByCycle 查询uf工况数据, 按周期进行过滤
+		FindWorkingUfByCycle(FindWorkingUfByCycleReq) (*FindWorkingUfByCycleResp, error)
+		// GetWorkingRoByCode 查询ro工况数据
+		GetWorkingRoByCode(DcWorkingReq) (*GetWorkingRoByCodeResp, error)
+		// GetWorkingChestByCode 查询液体容器类工况数据
+		GetWorkingChestByCode(DcWorkingReq) (*GetWorkingChestByCodeResp, error)
+		// GetWorkingPumpByCode 查询泵类工况数据
+		GetWorkingPumpByCode(DcWorkingReq) (*GetWorkingPumpByCodeResp, error)
+	}
+)

+ 25 - 0
datacenter_client/v1/FindWorkingUfByCycle.go

@@ -0,0 +1,25 @@
+package v1
+
+import (
+	"fmt"
+	"metawant.greentech.com.cn/gaoyagang/gt-common/datacenter_client"
+	"metawant.greentech.com.cn/gaoyagang/gt-common/httplib"
+	"strconv"
+)
+
+func (d *DcApi) FindWorkingUfByCycle(params datacenter_client.FindWorkingUfByCycleReq) (*datacenter_client.FindWorkingUfByCycleResp, error) {
+	serviceName := "/working-uf/cycle"
+	h := httplib.Get(d.serviceUrl(serviceName))
+	h.Param("project_id", strconv.FormatInt(params.ProjectId, 10))
+	h.Param("device_code", params.DeviceCode)
+	h.Param("filter_cycle", strconv.FormatInt(params.FilterCycle, 10))
+	h.Param("step", strconv.FormatInt(params.Step, 10))
+	h.Param("filter_time_start", fmt.Sprintf("%f", params.FilterTimeStart))
+	h.Param("filter_time_end", fmt.Sprintf("%f", params.FilterTimeEnd))
+	h.Param("limit", strconv.FormatInt(params.Limit, 10))
+
+	resp := &datacenter_client.FindWorkingUfByCycleResp{}
+
+	err := d.call(h, resp)
+	return resp, err
+}

+ 30 - 0
datacenter_client/v1/GetItemHistory.go

@@ -0,0 +1,30 @@
+package v1
+
+import (
+	"errors"
+	"log"
+	"metawant.greentech.com.cn/gaoyagang/gt-common/datacenter_client"
+	"metawant.greentech.com.cn/gaoyagang/gt-common/httplib"
+)
+
+func (d *DcApi) GetItemHistory(req datacenter_client.ItemHistoryReq) (resp []datacenter_client.ItemHistoryResp, err error) {
+	url := d.serviceUrl("/item-history/info")
+	h := httplib.Get(url)
+	h.Param("project_id", req.ProjectId)
+	h.Param("item_name", req.ItemName)
+	h.Param("stime", req.Stime)
+	h.Param("etime", req.Etime)
+
+	result := &datacenter_client.ItemHistoryBody{}
+	err = d.call(h, result)
+	if err != nil {
+		log.Println("GetItemHistory Unmarshal Error:", err)
+		return
+	}
+	if result.Code != 200 {
+		err = errors.New(result.Msg)
+		return
+	}
+	resp = result.Data.List
+	return
+}

+ 23 - 0
datacenter_client/v1/GetWorkingChestByCode.go

@@ -0,0 +1,23 @@
+package v1
+
+import (
+	"metawant.greentech.com.cn/gaoyagang/gt-common/datacenter_client"
+	"metawant.greentech.com.cn/gaoyagang/gt-common/httplib"
+	"strconv"
+)
+
+func (d *DcApi) GetWorkingChestByCode(params datacenter_client.DcWorkingReq) (*datacenter_client.GetWorkingChestByCodeResp, error) {
+	serviceName := "/working-uf/cycle"
+	h := httplib.Get(d.serviceUrl(serviceName))
+	h.Param("project_id", strconv.FormatInt(params.ProjectId, 10))
+	h.Param("device_code", params.DeviceCode)
+	h.Param("stime", params.Stime)
+	h.Param("etime", params.Etime)
+	h.Param("page", strconv.FormatInt(params.Page, 10))
+	h.Param("page_size", strconv.FormatInt(params.PageSize, 10))
+	h.Param("order", params.Order)
+
+	resp := &datacenter_client.GetWorkingChestByCodeResp{}
+	err := d.call(h, resp)
+	return resp, err
+}

+ 23 - 0
datacenter_client/v1/GetWorkingPumpByCode.go

@@ -0,0 +1,23 @@
+package v1
+
+import (
+	"metawant.greentech.com.cn/gaoyagang/gt-common/datacenter_client"
+	"metawant.greentech.com.cn/gaoyagang/gt-common/httplib"
+	"strconv"
+)
+
+func (d *DcApi) GetWorkingPumpByCode(params datacenter_client.DcWorkingReq) (*datacenter_client.GetWorkingPumpByCodeResp, error) {
+	serviceName := "/working-uf/cycle"
+	h := httplib.Get(d.serviceUrl(serviceName))
+	h.Param("project_id", strconv.FormatInt(params.ProjectId, 10))
+	h.Param("device_code", params.DeviceCode)
+	h.Param("stime", params.Stime)
+	h.Param("etime", params.Etime)
+	h.Param("page", strconv.FormatInt(params.Page, 10))
+	h.Param("page_size", strconv.FormatInt(params.PageSize, 10))
+	h.Param("order", params.Order)
+
+	resp := &datacenter_client.GetWorkingPumpByCodeResp{}
+	err := d.call(h, resp)
+	return resp, err
+}

+ 23 - 0
datacenter_client/v1/GetWorkingRoByCode.go

@@ -0,0 +1,23 @@
+package v1
+
+import (
+	"metawant.greentech.com.cn/gaoyagang/gt-common/datacenter_client"
+	"metawant.greentech.com.cn/gaoyagang/gt-common/httplib"
+	"strconv"
+)
+
+func (d *DcApi) GetWorkingRoByCode(params datacenter_client.DcWorkingReq) (*datacenter_client.GetWorkingRoByCodeResp, error) {
+	serviceName := "/working-uf/cycle"
+	h := httplib.Get(d.serviceUrl(serviceName))
+	h.Param("project_id", strconv.FormatInt(params.ProjectId, 10))
+	h.Param("device_code", params.DeviceCode)
+	h.Param("stime", params.Stime)
+	h.Param("etime", params.Etime)
+	h.Param("page", strconv.FormatInt(params.Page, 10))
+	h.Param("page_size", strconv.FormatInt(params.PageSize, 10))
+	h.Param("order", params.Order)
+
+	resp := &datacenter_client.GetWorkingRoByCodeResp{}
+	err := d.call(h, resp)
+	return resp, err
+}

+ 23 - 0
datacenter_client/v1/GetWorkingUfByCode.go

@@ -0,0 +1,23 @@
+package v1
+
+import (
+	"metawant.greentech.com.cn/gaoyagang/gt-common/datacenter_client"
+	"metawant.greentech.com.cn/gaoyagang/gt-common/httplib"
+	"strconv"
+)
+
+func (d *DcApi) GetWorkingUfByCode(params datacenter_client.DcWorkingReq) (*datacenter_client.GetWorkingUfByCodeResp, error) {
+	serviceName := "/working-uf/info"
+	h := httplib.Get(d.serviceUrl(serviceName))
+	h.Param("project_id", strconv.FormatInt(params.ProjectId, 10))
+	h.Param("device_code", params.DeviceCode)
+	h.Param("stime", params.Stime)
+	h.Param("etime", params.Etime)
+	h.Param("page", strconv.FormatInt(params.Page, 10))
+	h.Param("page_size", strconv.FormatInt(params.PageSize, 10))
+	h.Param("order", params.Order)
+
+	resp := &datacenter_client.GetWorkingUfByCodeResp{}
+	err := d.call(h, resp)
+	return resp, err
+}

+ 32 - 0
datacenter_client/v1/MultiAddData.go

@@ -0,0 +1,32 @@
+package v1
+
+import (
+	"errors"
+	"log"
+	"metawant.greentech.com.cn/gaoyagang/gt-common/datacenter_client"
+	"metawant.greentech.com.cn/gaoyagang/gt-common/httplib"
+)
+
+func (d *DcApi) MultiAddData(req datacenter_client.MultiAddReq) (err error) {
+	if len(req.List) == 0 {
+		return errors.New("无可插入数据")
+	}
+	url := d.serviceUrl("/item-history/multi-add")
+	h := httplib.Post(url)
+	_, err = h.JSONBody(req)
+	if err != nil {
+		return
+	}
+
+	result := &datacenter_client.ItemHistoryBody{}
+	err = d.call(h, result)
+	if err != nil {
+		log.Println("GetItemHistory Error:", err)
+		return
+	}
+	if result.Code != 200 {
+		err = errors.New(result.Msg)
+		return
+	}
+	return
+}

+ 32 - 0
datacenter_client/v1/ObtainRangeMaxMin.go

@@ -0,0 +1,32 @@
+package v1
+
+import (
+	"errors"
+	"log"
+	"metawant.greentech.com.cn/gaoyagang/gt-common/datacenter_client"
+	"metawant.greentech.com.cn/gaoyagang/gt-common/httplib"
+)
+
+func (d *DcApi) ObtainRangeMaxMin(req *datacenter_client.RangeMaxMinReq) (resp *datacenter_client.InstrumentCompareData, err error) {
+	url := d.serviceUrl("/item-history/max-min")
+	h := httplib.Get(url)
+	h.Param("project_id", req.ProjectId)
+	h.Param("item_name", req.ItemName)
+	h.Param("stime", req.Stime)
+	h.Param("etime", req.Etime)
+
+	result := &datacenter_client.RangeMaxMinResp{}
+
+	err = d.call(h, result)
+
+	if err != nil {
+		log.Println("ObtainRangeMaxMin Error:", err)
+		return
+	}
+	if result.Code != 200 {
+		err = errors.New(result.Msg)
+		return
+	}
+	resp = result.Data
+	return
+}

+ 224 - 0
datacenter_client/v1/v1.go

@@ -0,0 +1,224 @@
+package v1
+
+import (
+	"bytes"
+	"crypto/md5"
+	"encoding/hex"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io/ioutil"
+	"metawant.greentech.com.cn/gaoyagang/gt-common/datacenter_client"
+	"metawant.greentech.com.cn/gaoyagang/gt-common/httplib"
+	"net/http"
+	"net/url"
+	"time"
+)
+
+type (
+	DcApi struct {
+		options ClientOptions
+	}
+
+	// ClientOptions 客户端配置选项
+	ClientOptions struct {
+		httplib.HTTPSettings
+		ServerIp  string
+		AppName   string
+		AppSecret string
+
+		DoBefore []func(r *httplib.HTTPRequest) error
+		DoAfter  []func(r *httplib.HTTPRequest) error
+	}
+)
+
+func NewDcApi(options ClientOptions) *DcApi {
+	dcapi := &DcApi{}
+
+	if len(options.DoBefore) == 0 {
+		options.DoBefore = make([]func(r *httplib.HTTPRequest) error, 0)
+	}
+	options.DoBefore = append(options.DoBefore, dcapi.signMiddleware)
+
+	dcapi.options = options
+
+	return dcapi
+}
+
+// SetHttpSettings 设置客户端选择
+// ShowDebug       bool
+// UserAgent       string
+// TLSClientConfig *tls.Config
+// Proxy           func(*http.Request) (*url.URL, error)
+// Transport       http.RoundTripper
+// CheckRedirect   func(req *http.Request, via []*http.Request) error
+// EnableCookie    bool
+// Gzip            bool
+// DumpBody        bool
+// Retries         int // if set to -1 means will retry forever
+// ConnectTimeout  time.Duration
+// KeepAlive       time.Duration
+// Timeout         time.Duration
+func (d *DcApi) SetHttpSettings(settings httplib.HTTPSettings) {
+	d.options.HTTPSettings = settings
+}
+
+func (d *DcApi) serviceUrl(serviceName string) string {
+	return fmt.Sprintf("%s%s%s%s", "http://", d.options.ServerIp, "/api/dtgateway/v1", serviceName)
+}
+
+// 实际执行请求
+func (d *DcApi) call(r *httplib.HTTPRequest, resp any) error {
+	for _, bf := range d.options.DoBefore {
+		if err := bf(r); err != nil {
+			return err
+		}
+	}
+
+	response, err := r.Response()
+	if err != nil {
+		return err
+	}
+
+	if response.StatusCode != http.StatusOK {
+		msg, _ := r.String()
+		return errors.New(fmt.Sprintf("response status code: %d, body: %s", response.StatusCode, msg))
+	}
+
+	if xerr := r.ToJSON(resp); err != nil {
+		return errors.New(fmt.Sprintf("response to json error %s", xerr.Error()))
+	}
+
+	// 这里应该增加一个记录日志的after
+	for _, af := range d.options.DoAfter {
+		if err := af(r); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// 数据签名middleware
+func (d *DcApi) signMiddleware(r *httplib.HTTPRequest) error {
+	// 验证公共参数
+	if d.options.AppName == "" {
+		return errors.New(fmt.Sprintf("error: %d app name empty", datacenter_client.DC_PARAMS_APP_NAME_MISSION))
+	}
+
+	if d.options.AppSecret == "" {
+		return errors.New(fmt.Sprintf("error: %d app secret empty", datacenter_client.DC_PARAMS_APP_SECRET_MISSION))
+	}
+
+	queryParams := r.GetQueryParam()
+	if pids, ok := queryParams["project_id"]; !ok || len(pids) == 0 {
+		return errors.New(fmt.Sprintf("error: %d project id empty", datacenter_client.DC_PARAMS_PROJECT_ID_MISSION))
+	} else {
+		r.Param("project_id", pids[0])
+	}
+
+	r.Param("ts", fmt.Sprintf("%d", time.Now().Unix()))
+	sign, err := CalcSign(r, d.options.AppSecret)
+	if err != nil {
+		return errors.New(fmt.Sprintf("error: %d check data sign error", datacenter_client.DC_DATA_SIGN_ERROR))
+	}
+
+	r.Param("sign", sign)
+
+	// 设置headers信息
+	r.Header("APP-NAME", d.options.AppName)
+
+	return nil
+}
+
+func cutS2(s2 string) string {
+	if s2 == "" {
+		return ""
+	}
+	s2l := len(s2)
+	//if s2l <= S2_MIN_LENGTH {
+	//	return s2
+	//}
+	return fmt.Sprintf("%s%s", s2[:datacenter_client.S2_HEAD_LENGTH], s2[s2l-datacenter_client.S2_TAIL_LENGTH:])
+}
+
+func sortS2(s2 string) (string, error) {
+	if s2 == "" {
+		return "", nil
+	}
+	var mi map[string]interface{}
+	if err := json.Unmarshal([]byte(s2), &mi); err != nil {
+		return "", err
+	}
+
+	//smi := SortMapByKey(mi)
+
+	if bs, err := json.Marshal(mi); err != nil {
+		return "", err
+	} else {
+		return string(bs), nil
+	}
+}
+
+func CalcSign(r *httplib.HTTPRequest, secret string) (string, error) {
+	s2, err := parseBody(r)
+
+	if err != nil {
+		fmt.Println("parseBody Error: ", err.Error())
+		return "", err
+	}
+	contentLength := r.GetRequest().ContentLength
+	if contentLength > datacenter_client.S2_MIN_LENGTH {
+		r.Param("sign_flag", "1")
+		s2 = cutS2(s2)
+	} else {
+		s2, err = sortS2(s2)
+		if err != nil {
+			return "", err
+		}
+	}
+
+	s3 := contentLength
+	s1 := parseQuery(r)
+
+	m := md5.New()
+	m.Write([]byte(fmt.Sprintf("%s%s%d%s", s1, s2, s3, secret)))
+	md5Str := hex.EncodeToString(m.Sum(nil))
+	//fmt.Println("s1", s1)
+	//fmt.Println("s2", s2)
+	//fmt.Println("s3", s3)
+	//fmt.Println("md5", md5Str)
+	return md5Str, nil
+}
+
+func parseBody(r *httplib.HTTPRequest) (s2 string, err error) {
+	if r.GetRequest().Method == http.MethodGet {
+		return "", nil
+	}
+	body := r.GetRequest().Body
+
+	cnt, err := ioutil.ReadAll(body)
+	if err != nil {
+		return "", err
+	}
+	r.GetRequest().Body = ioutil.NopCloser(bytes.NewReader(cnt))
+
+	return string(cnt), nil
+}
+
+func parseQuery(r *httplib.HTTPRequest) string {
+	params := r.GetQueryParam()
+	delete(params, "sign")
+
+	val := url.Values{}
+	for k, v := range params {
+		for index, s := range v {
+			if index == 0 {
+				val.Set(k, s)
+			} else {
+				val.Add(k, s)
+			}
+		}
+	}
+	return val.Encode()
+}

+ 16 - 0
datacenter_client/var.go

@@ -0,0 +1,16 @@
+package datacenter_client
+
+const (
+	S2_MIN_LENGTH  = 2048
+	S2_HEAD_LENGTH = 200
+	S2_TAIL_LENGTH = 200
+
+	// 定义数据中心错误码
+
+	DC_OK                        = 200
+	DC_PARAMS_APP_NAME_MISSION   = 10001
+	DC_PARAMS_APP_SECRET_MISSION = 10002
+	DC_PARAMS_PROJECT_ID_MISSION = 10003
+
+	DC_DATA_SIGN_ERROR = 11000
+)

+ 1 - 1
envitem/func_test.go

@@ -10,7 +10,7 @@ func TestEnvItem_GetCurrentData(t *testing.T) {
 	SetOptions(Options{GtServerIp: "47.96.12.136:8788"})
 	e := EnvItem{
 		ProjectId: 92,
-		Item:      "C.M.LT_CIP@out,C.M.RO1_DB@time_CS_display",
+		Item:      "C.M.LT_QSC@out",
 	}
 
 	v, ht, err := e.getCurrentValue()