illuminating.go 9.5 KB

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