illuminating.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. package service
  2. import (
  3. "bytes"
  4. "city_chips/internal/model"
  5. "city_chips/internal/repository"
  6. "context"
  7. "encoding/json"
  8. "errors"
  9. "fmt"
  10. "github.com/spf13/viper"
  11. "io"
  12. "net/http"
  13. "net/url"
  14. "reflect"
  15. )
  16. type IlluminatingService interface {
  17. GetIlluminating(ctx context.Context, id int64) (*model.Illuminating, error)
  18. Illuminating(method, url string, body any) ([]byte, error)
  19. GetStatistics() ([]byte, error)
  20. GetBaseecic(currentPage, device_type_id, devices_enabled, pageSize int, query string) (model.IlluminatingBaseecic, error)
  21. }
  22. func NewIlluminatingService(
  23. service *Service,
  24. illuminatingRepository repository.IlluminatingRepository,
  25. viperViper *viper.Viper,
  26. client *http.Client,
  27. ) IlluminatingService {
  28. if client == nil {
  29. client = http.DefaultClient
  30. }
  31. return &illuminatingService{
  32. Service: service,
  33. illuminatingRepository: illuminatingRepository,
  34. conf: viperViper,
  35. client: client,
  36. }
  37. }
  38. type illuminatingService struct {
  39. *Service
  40. illuminatingRepository repository.IlluminatingRepository
  41. conf *viper.Viper
  42. client *http.Client
  43. }
  44. func (s *illuminatingService) GetIlluminating(ctx context.Context, id int64) (*model.Illuminating, error) {
  45. return s.illuminatingRepository.GetIlluminating(ctx, id)
  46. }
  47. // func (s *illuminatingService) Illuminating(methond, url string, body any) ([]byte, error) {
  48. // urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.login")
  49. // authorization := s.conf.GetString("illuminating.authorization")
  50. // clientId := s.conf.GetInt("illuminating.clientId")
  51. // mobile := s.conf.GetString("illuminating.mobile")
  52. // password := s.conf.GetString("illuminating.password")
  53. // requst := model.LoginRequst{
  54. // Authorization: authorization,
  55. // ClientId: clientId,
  56. // Mobile: mobile,
  57. // Password: password,
  58. // }
  59. // var login model.Login
  60. // var reqBody io.Reader
  61. // bodyBytes, err := json.Marshal(requst)
  62. // if err != nil {
  63. // return nil, err
  64. // }
  65. // reqBody = bytes.NewBuffer(bodyBytes)
  66. // request, err := http.NewRequest("POST", urls, reqBody)
  67. // if err != nil {
  68. // return nil, err
  69. // }
  70. // client := &http.Client{}
  71. // response, err := client.Do(request)
  72. // defer response.Body.Close()
  73. // if err != nil {
  74. // return nil, err
  75. // }
  76. // responseBody, err := io.ReadAll(response.Body)
  77. // if err != nil {
  78. // return nil, err
  79. // }
  80. // err = json.Unmarshal(responseBody, &login)
  81. // if err != nil {
  82. // return nil, err
  83. // }
  84. // if body != nil {
  85. // bodyBytes, err := json.Marshal(requst)
  86. // if err != nil {
  87. // return nil, err
  88. // }
  89. // reqBody = bytes.NewBuffer(bodyBytes)
  90. // }
  91. // var Bodys io.Reader
  92. // if body != nil {
  93. // Bytes, err := json.Marshal(body)
  94. // if err != nil {
  95. // return nil, err
  96. // }
  97. // Bodys = bytes.NewBuffer(Bytes)
  98. // }
  99. // newRequest, err := http.NewRequest(methond, url, Bodys)
  100. // if err != nil {
  101. // return nil, err
  102. // }
  103. // newRequest.Header.Set("Authorization", login.AccessToken)
  104. // newResponse, err := client.Do(newRequest)
  105. // defer newResponse.Body.Close()
  106. // if err != nil {
  107. // return nil, err
  108. // }
  109. // respBody, err := io.ReadAll(newResponse.Body)
  110. // if err != nil {
  111. // return nil, err
  112. // }
  113. // return respBody, nil
  114. // }
  115. func (s *illuminatingService) Illuminating(method, url string, body any) ([]byte, error) {
  116. login, err := s.login()
  117. if err != nil {
  118. return nil, err
  119. }
  120. var reqBody io.Reader
  121. var finalURL = url
  122. // 如果是 GET 请求,把 body 当作 query 参数处理
  123. if method == http.MethodGet || method == "" {
  124. vals, err := buildQueryParams(body)
  125. if err != nil {
  126. return nil, err
  127. }
  128. finalURL = addQueryParams(url, vals)
  129. } else {
  130. // 非 GET 请求才构造 body
  131. reqBody, err = buildRequestBody(body)
  132. if err != nil {
  133. return nil, err
  134. }
  135. }
  136. request, err := http.NewRequest(method, finalURL, reqBody)
  137. if err != nil {
  138. return nil, err
  139. }
  140. request.Header.Set("Authorization", login.AccessToken)
  141. response, err := s.client.Do(request)
  142. if err != nil {
  143. return nil, err
  144. }
  145. defer response.Body.Close()
  146. respBody, err := io.ReadAll(response.Body)
  147. if err != nil {
  148. return nil, err
  149. }
  150. return respBody, nil
  151. }
  152. // login 封装登录逻辑
  153. func (s *illuminatingService) login() (*model.Login, error) {
  154. auth := s.conf.GetString("illuminating.authorization")
  155. clientId := s.conf.GetInt("illuminating.clientId")
  156. mobile := s.conf.GetString("illuminating.mobile")
  157. password := s.conf.GetString("illuminating.password")
  158. loginReq := model.LoginRequst{
  159. Authorization: auth,
  160. ClientId: clientId,
  161. Mobile: mobile,
  162. Password: password,
  163. }
  164. bodyBytes, err := json.Marshal(loginReq)
  165. if err != nil {
  166. return nil, err
  167. }
  168. url := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.login")
  169. request, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes))
  170. if err != nil {
  171. return nil, err
  172. }
  173. response, err := s.client.Do(request)
  174. if err != nil {
  175. return nil, err
  176. }
  177. defer response.Body.Close()
  178. respBody, err := io.ReadAll(response.Body)
  179. if err != nil {
  180. return nil, err
  181. }
  182. var login model.Login
  183. if err := json.Unmarshal(respBody, &login); err != nil {
  184. return nil, err
  185. }
  186. return &login, nil
  187. }
  188. // 构建请求体工具函数
  189. func buildRequestBody(body any) (io.Reader, error) {
  190. if body == nil {
  191. return nil, nil
  192. }
  193. bodyBytes, err := json.Marshal(body)
  194. if err != nil {
  195. return nil, err
  196. }
  197. return bytes.NewBuffer(bodyBytes), nil
  198. }
  199. func buildQueryParams(params any) (url.Values, error) {
  200. vals := make(url.Values)
  201. switch p := params.(type) {
  202. case nil:
  203. return vals, nil
  204. case url.Values:
  205. return p, nil
  206. case map[string]string:
  207. for k, v := range p {
  208. vals.Add(k, v)
  209. }
  210. case map[string][]string:
  211. for k, v := range p {
  212. for _, vv := range v {
  213. vals.Add(k, vv)
  214. }
  215. }
  216. default:
  217. // 使用反射解析结构体字段
  218. t := reflect.TypeOf(p)
  219. v := reflect.ValueOf(p)
  220. for i := 0; i < t.NumField(); i++ {
  221. field := t.Field(i)
  222. value := v.Field(i).Interface()
  223. tag := field.Tag.Get("json")
  224. if tag == "" {
  225. tag = field.Name
  226. }
  227. vals.Add(tag, fmt.Sprintf("%v", value))
  228. }
  229. }
  230. return vals, nil
  231. }
  232. func addQueryParams(baseURL string, values url.Values) string {
  233. if len(values) == 0 {
  234. return baseURL
  235. }
  236. u, err := url.Parse(baseURL)
  237. if err != nil {
  238. return baseURL // 忽略错误直接返回原值
  239. }
  240. q := u.Query()
  241. for k, vs := range values {
  242. for _, v := range vs {
  243. q.Add(k, v)
  244. }
  245. }
  246. u.RawQuery = q.Encode()
  247. return u.String()
  248. }
  249. // GetStatistics 获取统计信息
  250. func (s *illuminatingService) GetStatistics() ([]byte, error) {
  251. urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.statistics")
  252. illuminating, err := s.Illuminating("GET", urls, nil)
  253. if err != nil {
  254. return nil, errors.New("获取统计信息失败")
  255. }
  256. return illuminating, nil
  257. }
  258. // GetBaseecic 获取照明监控列表
  259. func (s *illuminatingService) GetBaseecic(currentPage, device_type_id, devices_enabled, pageSize int, query string) (model.IlluminatingBaseecic, error) {
  260. var baseecic model.IlluminatingBaseecic
  261. urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.baseecic")
  262. m := make(map[string]any)
  263. m["currentPage"] = currentPage
  264. m["device_type_id"] = device_type_id
  265. m["devices_enabled"] = devices_enabled
  266. m["pageSize"] = pageSize
  267. m["query"] = query
  268. illuminating, err := s.Illuminating("POST", urls, m)
  269. if err != nil {
  270. return model.IlluminatingBaseecic{}, errors.New("获取统计信息失败")
  271. }
  272. err = json.Unmarshal(illuminating, &baseecic)
  273. if err != nil {
  274. return model.IlluminatingBaseecic{}, errors.New("json反序列化失败")
  275. }
  276. return baseecic, nil
  277. }