| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- package services
- import (
- "fmt"
- "net/url"
- "strings"
- "time"
- "fwh-toolbox-server/domain"
- )
- // Each document kind owns its content identity version. Bump only the affected
- // kind when its query, parsing, or stored content semantics change.
- var dataDownloadContentIdentityVersion = map[domain.DataDownloadKind]string{
- domain.DataDownloadPowerFlow: "v1",
- domain.DataDownloadMqttLog: "v1",
- domain.DataDownloadEventAlarm: "v1",
- domain.DataDownloadAlarmSnapshot: "v1",
- domain.DataDownloadEmsLog: "v1",
- domain.DataDownloadFaultRecord: "v2",
- domain.DataDownloadUpdateLog: "v1",
- }
- type dataDownloadRequestKeyField struct {
- name string
- value string
- }
- // buildDataDownloadRequestKey identifies the requested logical document. The
- // fields intentionally differ by kind so task-only or irrelevant parameters do
- // not reduce reuse between otherwise equivalent requests.
- func buildDataDownloadRequestKey(item *domain.DataDownloadItem) (string, error) {
- if item == nil {
- return "", fmt.Errorf("data download item is nil")
- }
- contentVersion, ok := dataDownloadContentIdentityVersion[item.Kind]
- if !ok {
- return "", fmt.Errorf("unsupported data download kind %q", item.Kind)
- }
- if item.SiteSN == "" {
- return "", fmt.Errorf("site SN is required for %s", item.Kind)
- }
- fields := []dataDownloadRequestKeyField{
- {name: "kind", value: string(item.Kind)},
- {name: "content_version", value: contentVersion},
- }
- addSite := func() {
- fields = append(fields, dataDownloadRequestKeyField{name: "site_sn", value: item.SiteSN})
- }
- addDate := func() error {
- if _, err := time.Parse(time.DateOnly, item.Date); err != nil {
- return fmt.Errorf("invalid data date %q for %s", item.Date, item.Kind)
- }
- fields = append(fields, dataDownloadRequestKeyField{name: "date", value: item.Date})
- return nil
- }
- addSubtype := func() error {
- if item.Subtype == "" {
- return fmt.Errorf("subtype is required for %s", item.Kind)
- }
- fields = append(fields, dataDownloadRequestKeyField{name: "subtype", value: item.Subtype})
- return nil
- }
- addTimezone := func() error {
- if item.Timezone == "" {
- return fmt.Errorf("timezone is required for %s", item.Kind)
- }
- fields = append(fields, dataDownloadRequestKeyField{name: "timezone", value: item.Timezone})
- return nil
- }
- switch item.Kind {
- case domain.DataDownloadPowerFlow, domain.DataDownloadEventAlarm, domain.DataDownloadAlarmSnapshot:
- addSite()
- if err := addDate(); err != nil {
- return "", err
- }
- if err := addTimezone(); err != nil {
- return "", err
- }
- case domain.DataDownloadMqttLog:
- addSite()
- if err := addDate(); err != nil {
- return "", err
- }
- if err := addSubtype(); err != nil {
- return "", err
- }
- if err := addTimezone(); err != nil {
- return "", err
- }
- case domain.DataDownloadEmsLog:
- addSite()
- if err := addDate(); err != nil {
- return "", err
- }
- if err := addSubtype(); err != nil {
- return "", err
- }
- case domain.DataDownloadFaultRecord:
- if item.DeviceSN == "" || item.DeviceType == "" {
- return "", fmt.Errorf("device SN and device type are required for %s", item.Kind)
- }
- fields = append(fields,
- dataDownloadRequestKeyField{name: "device_sn", value: item.DeviceSN},
- dataDownloadRequestKeyField{name: "device_type", value: item.DeviceType},
- )
- if err := addDate(); err != nil {
- return "", err
- }
- if err := addTimezone(); err != nil {
- return "", err
- }
- case domain.DataDownloadUpdateLog:
- addSite()
- }
- var key strings.Builder
- key.WriteString("dd-request-v1")
- for _, field := range fields {
- key.WriteByte('|')
- key.WriteString(field.name)
- key.WriteByte('=')
- key.WriteString(url.QueryEscape(field.value))
- }
- return key.String(), nil
- }
|