illuminating.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. package service
  2. import (
  3. "bytes"
  4. "city_chips/internal/model"
  5. "city_chips/internal/repository"
  6. "encoding/json"
  7. "errors"
  8. "fmt"
  9. "github.com/spf13/viper"
  10. "io"
  11. "net/http"
  12. "net/url"
  13. "reflect"
  14. "strings"
  15. )
  16. type IlluminatingService interface {
  17. Illuminating(method, url string, body any) ([]byte, error)
  18. GetStatistics() ([]byte, error)
  19. GetBaseecic(currentPage, device_type_id, devices_enabled, gateway_id, pageSize int, query, devices_udid string) (model.IlluminatingBaseecic, error)
  20. GetAlarm(currentPage, pageSize int) ([]byte, error)
  21. GetAlarmStatistics(start_time, end_time string) ([]byte, error)
  22. GetgatewayFind() (model.GatewayFind, error)
  23. DevicesControl(agreement_json, request_id, udid string, source int) (model.DevicesControl, error)
  24. GetDeviceOrgid(currentPage, pageSize, searchText string) ([]byte, error)
  25. GetBuildingRegionRoomTree(building_id, region_parent_id string) ([]byte, error)
  26. CategoryPart(id, type_id int) (model.CategoryPart, error)
  27. DeviceAllMini(device_type_id, devices_enabled, position_id, position_type int) (model.DeviceAllMini, error)
  28. TimingSave(rust map[string]any) (model.ResponeTimingSave, error)
  29. ChangeState(timing_id, timing_state int) ([]byte, error)
  30. GetTypeFind(category_id, devices_enabled, id, types int) (model.GetTypeFind, error)
  31. GetTimingId(timing_id string) (model.TimingId, error)
  32. }
  33. func NewIlluminatingService(
  34. service *Service,
  35. illuminatingRepository repository.IlluminatingRepository,
  36. viperViper *viper.Viper,
  37. client *http.Client,
  38. ) IlluminatingService {
  39. if client == nil {
  40. client = http.DefaultClient
  41. }
  42. return &illuminatingService{
  43. Service: service,
  44. illuminatingRepository: illuminatingRepository,
  45. conf: viperViper,
  46. client: client,
  47. }
  48. }
  49. type illuminatingService struct {
  50. *Service
  51. illuminatingRepository repository.IlluminatingRepository
  52. conf *viper.Viper
  53. client *http.Client
  54. }
  55. func (s *illuminatingService) Illuminating(method, url string, body any) ([]byte, error) {
  56. login, err := s.login()
  57. if err != nil {
  58. return nil, err
  59. }
  60. var reqBody io.Reader
  61. var finalURL = url
  62. // 如果是 GET 请求,把 body 当作 query 参数处理
  63. if method == http.MethodGet || method == "" {
  64. vals, err := buildQueryParams(body)
  65. if err != nil {
  66. return nil, err
  67. }
  68. finalURL = addQueryParams(url, vals)
  69. } else {
  70. // 非 GET 请求才构造 body
  71. reqBody, err = buildRequestBody(body)
  72. if err != nil {
  73. return nil, err
  74. }
  75. }
  76. request, err := http.NewRequest(method, finalURL, reqBody)
  77. if err != nil {
  78. return nil, err
  79. }
  80. request.Header.Set("Authorization", login.AccessToken)
  81. response, err := s.client.Do(request)
  82. if err != nil {
  83. return nil, err
  84. }
  85. defer response.Body.Close()
  86. respBody, err := io.ReadAll(response.Body)
  87. if err != nil {
  88. return nil, err
  89. }
  90. return respBody, nil
  91. }
  92. // login 封装登录逻辑
  93. func (s *illuminatingService) login() (*model.Login, error) {
  94. auth := s.conf.GetString("illuminating.authorization")
  95. clientId := s.conf.GetInt("illuminating.clientId")
  96. mobile := s.conf.GetString("illuminating.mobile")
  97. password := s.conf.GetString("illuminating.password")
  98. loginReq := model.LoginRequst{
  99. Authorization: auth,
  100. ClientId: clientId,
  101. Mobile: mobile,
  102. Password: password,
  103. }
  104. bodyBytes, err := json.Marshal(loginReq)
  105. if err != nil {
  106. return nil, err
  107. }
  108. url := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.login")
  109. request, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes))
  110. if err != nil {
  111. return nil, err
  112. }
  113. response, err := s.client.Do(request)
  114. if err != nil {
  115. return nil, err
  116. }
  117. defer response.Body.Close()
  118. respBody, err := io.ReadAll(response.Body)
  119. if err != nil {
  120. return nil, err
  121. }
  122. var login model.Login
  123. if err := json.Unmarshal(respBody, &login); err != nil {
  124. return nil, err
  125. }
  126. return &login, nil
  127. }
  128. // 构建请求体工具函数
  129. func buildRequestBody(body any) (io.Reader, error) {
  130. if body == nil {
  131. return nil, nil
  132. }
  133. bodyBytes, err := json.Marshal(body)
  134. if err != nil {
  135. return nil, err
  136. }
  137. return bytes.NewBuffer(bodyBytes), nil
  138. }
  139. func buildQueryParams(params any) (url.Values, error) {
  140. vals := make(url.Values)
  141. switch p := params.(type) {
  142. case nil:
  143. return vals, nil
  144. case url.Values:
  145. return p, nil
  146. case map[string]string:
  147. for k, v := range p {
  148. vals.Add(k, v)
  149. }
  150. case map[string][]string:
  151. for k, v := range p {
  152. for _, vv := range v {
  153. vals.Add(k, vv)
  154. }
  155. }
  156. default:
  157. // 使用反射解析结构体字段
  158. t := reflect.TypeOf(p)
  159. v := reflect.ValueOf(p)
  160. for i := 0; i < t.NumField(); i++ {
  161. field := t.Field(i)
  162. value := v.Field(i).Interface()
  163. tag := field.Tag.Get("json")
  164. if tag == "" {
  165. tag = field.Name
  166. }
  167. vals.Add(tag, fmt.Sprintf("%v", value))
  168. }
  169. }
  170. return vals, nil
  171. }
  172. func addQueryParams(baseURL string, values url.Values) string {
  173. if len(values) == 0 {
  174. return baseURL
  175. }
  176. u, err := url.Parse(baseURL)
  177. if err != nil {
  178. return baseURL // 忽略错误直接返回原值
  179. }
  180. q := u.Query()
  181. for k, vs := range values {
  182. for _, v := range vs {
  183. q.Add(k, v)
  184. }
  185. }
  186. u.RawQuery = q.Encode()
  187. return u.String()
  188. }
  189. // GetStatistics 获取统计信息
  190. func (s *illuminatingService) GetStatistics() ([]byte, error) {
  191. urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.statistics")
  192. illuminating, err := s.Illuminating("GET", urls, nil)
  193. if err != nil {
  194. return nil, errors.New("获取统计信息失败")
  195. }
  196. return illuminating, nil
  197. }
  198. // GetDeviceStatistics 获取设备统计信息
  199. func (s *illuminatingService) GetDeviceStatistics() ([]byte, error) {
  200. urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.deviceStatistics")
  201. illuminating, err := s.Illuminating("GET", urls, nil)
  202. if err != nil {
  203. return nil, errors.New("获取设备统计信息失败")
  204. }
  205. return illuminating, nil
  206. }
  207. // GetAlarm 获取报警信息
  208. func (s *illuminatingService) GetAlarm(currentPage, pageSize int) ([]byte, error) {
  209. urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.alarm")
  210. m := make(map[string]any)
  211. m["currentPage"] = currentPage
  212. m["pageSize"] = pageSize
  213. illuminating, err := s.Illuminating("POST", urls, m)
  214. if err != nil {
  215. return nil, errors.New("获取统计信息失败")
  216. }
  217. return illuminating, nil
  218. }
  219. // GetAlarmStatistics 获取报警统计信息
  220. func (s *illuminatingService) GetAlarmStatistics(start_time, end_time string) ([]byte, error) {
  221. urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.alarmStatistics")
  222. urls += "?start_time=" + start_time + "&end_time=" + end_time
  223. illuminating, err := s.Illuminating("GET", urls, nil)
  224. if err != nil {
  225. return nil, errors.New("获取统计信息失败")
  226. }
  227. return illuminating, nil
  228. }
  229. // GetBaseecic 获取照明监控列表
  230. func (s *illuminatingService) GetBaseecic(currentPage, device_type_id, devices_enabled, gateway_id, pageSize int, query, devices_udid string) (model.IlluminatingBaseecic, error) {
  231. var baseecic model.IlluminatingBaseecic
  232. urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.baseecic")
  233. m := make(map[string]any)
  234. m["currentPage"] = currentPage
  235. m["pageSize"] = pageSize
  236. if currentPage == 0 {
  237. m["currentPage"] = 1
  238. }
  239. if pageSize == 0 {
  240. m["pageSize"] = 20
  241. }
  242. if device_type_id != 0 {
  243. m["device_type_id"] = device_type_id
  244. }
  245. if devices_enabled != 0 {
  246. m["devices_enabled"] = devices_enabled
  247. }
  248. if gateway_id != 0 {
  249. m["gateway_id"] = gateway_id
  250. }
  251. if devices_udid != "" {
  252. m["devices_udid"] = devices_udid
  253. }
  254. if query != "" {
  255. m["query"] = query
  256. }
  257. illuminating, err := s.Illuminating("POST", urls, m)
  258. if err != nil {
  259. return model.IlluminatingBaseecic{}, errors.New("获取统计信息失败")
  260. }
  261. err = json.Unmarshal(illuminating, &baseecic)
  262. if err != nil {
  263. return model.IlluminatingBaseecic{}, errors.New("json反序列化失败")
  264. }
  265. return baseecic, nil
  266. }
  267. // GetgatewayFind 获取网关列表
  268. func (s *illuminatingService) GetgatewayFind() (model.GatewayFind, error) {
  269. var gateway model.GatewayFind
  270. urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.gatewayFind")
  271. m := make(map[string]any)
  272. m["gateway_type"] = -1
  273. illuminating, err := s.Illuminating("POST", urls, m)
  274. if err != nil {
  275. return model.GatewayFind{}, errors.New("获取统计信息失败")
  276. }
  277. err = json.Unmarshal(illuminating, &gateway)
  278. if err != nil {
  279. return model.GatewayFind{}, errors.New("json反序列化失败")
  280. }
  281. return gateway, nil
  282. }
  283. // DevicesControl 设备控制
  284. func (s *illuminatingService) DevicesControl(agreement_json, request_id, udid string, source int) (model.DevicesControl, error) {
  285. var devicesControl model.DevicesControl
  286. urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.devicesControl")
  287. m := make(map[string]any)
  288. m["agreement_json"] = agreement_json
  289. if request_id != "" {
  290. m["request_id"] = request_id
  291. }
  292. m["source"] = source
  293. m["udid"] = udid
  294. illuminating, err := s.Illuminating("POST", urls, m)
  295. if err != nil {
  296. return model.DevicesControl{}, errors.New("控制灯光设备失败")
  297. }
  298. err = json.Unmarshal(illuminating, &devicesControl)
  299. if err != nil {
  300. return model.DevicesControl{}, errors.New("json反序列化失败")
  301. }
  302. return devicesControl, nil
  303. }
  304. // GetDeviceOrgid 获取定时策略
  305. func (s *illuminatingService) GetDeviceOrgid(currentPage, pageSize, searchText string) ([]byte, error) {
  306. searchText = strings.ReplaceAll(searchText, " ", "")
  307. urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.deviceOrgid")
  308. urls += "?currentPage=" + currentPage + "&pageSize=" + pageSize + "&searchText=" + searchText
  309. illuminating, err := s.Illuminating("GET", urls, nil)
  310. if err != nil {
  311. return nil, errors.New("获取统计信息失败")
  312. }
  313. return illuminating, nil
  314. }
  315. // GetBuildingRegionRoomTree 获取建筑区域房间树
  316. func (s *illuminatingService) GetBuildingRegionRoomTree(building_id, region_parent_id string) ([]byte, error) {
  317. urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.getBuildingRegionRoomTree")
  318. if building_id != "" && region_parent_id == "" {
  319. urls += "?building_id=" + building_id
  320. }
  321. if region_parent_id != "" && building_id != "" {
  322. urls += "?building_id=" + building_id + "&region_parent_id=" + region_parent_id
  323. }
  324. illuminating, err := s.Illuminating("GET", urls, nil)
  325. if err != nil {
  326. return nil, errors.New("获取建筑区域房间树失败")
  327. }
  328. return illuminating, nil
  329. }
  330. // CategoryPart 获取分类
  331. func (s *illuminatingService) CategoryPart(id, type_id int) (model.CategoryPart, error) {
  332. urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.categoryPart")
  333. var respone model.CategoryPart
  334. m := make(map[string]any)
  335. if id == 0 {
  336. m["id"] = 1
  337. } else {
  338. m["id"] = id
  339. }
  340. if type_id == 0 {
  341. m["type"] = 1
  342. } else {
  343. m["type"] = type_id
  344. }
  345. illuminating, err := s.Illuminating("POST", urls, m)
  346. if err != nil {
  347. return model.CategoryPart{}, errors.New("获取分类失败")
  348. }
  349. err = json.Unmarshal(illuminating, &respone)
  350. if err != nil {
  351. return model.CategoryPart{}, errors.New("json反序列化失败")
  352. }
  353. return respone, nil
  354. }
  355. // DeviceAllMini 获取所有设备型号
  356. func (s *illuminatingService) DeviceAllMini(device_type_id, devices_enabled, position_id, position_type int) (model.DeviceAllMini, error) {
  357. urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.deviceAllMini")
  358. var respone model.DeviceAllMini
  359. m := make(map[string]any)
  360. m["device_type_id"] = device_type_id
  361. m["devices_enabled"] = devices_enabled
  362. m["position_id"] = position_id
  363. m["position_type"] = position_type
  364. illuminating, err := s.Illuminating("POST", urls, m)
  365. if err != nil {
  366. return model.DeviceAllMini{}, errors.New("获取分类失败")
  367. }
  368. err = json.Unmarshal(illuminating, &respone)
  369. if err != nil {
  370. return model.DeviceAllMini{}, errors.New("json反序列化失败")
  371. }
  372. return respone, nil
  373. }
  374. // TimingSave 保存定时策略
  375. func (s *illuminatingService) TimingSave(rust map[string]any) (model.ResponeTimingSave, error) {
  376. urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.timingSave")
  377. var respone model.ResponeTimingSave
  378. illuminating, err := s.Illuminating("POST", urls, rust)
  379. if err != nil {
  380. return model.ResponeTimingSave{}, errors.New("获取分类失败")
  381. }
  382. err = json.Unmarshal(illuminating, &respone)
  383. if err != nil {
  384. return model.ResponeTimingSave{}, errors.New("json反序列化失败")
  385. }
  386. return respone, nil
  387. }
  388. // ChangeState 修改定时策略状态
  389. func (s *illuminatingService) ChangeState(timing_id, timing_state int) ([]byte, error) {
  390. urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.changeState")
  391. m := make(map[string]any)
  392. m["timing_id"] = timing_id
  393. m["timing_state"] = timing_state
  394. illuminating, err := s.Illuminating("POST", urls, m)
  395. if err != nil {
  396. return nil, errors.New("获取分类失败")
  397. }
  398. return illuminating, nil
  399. }
  400. // GetTypeFind 获取设备型号
  401. func (s *illuminatingService) GetTypeFind(category_id, devices_enabled, id, types int) (model.GetTypeFind, error) {
  402. var respone model.GetTypeFind
  403. urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.typeFind")
  404. m := make(map[string]any)
  405. m["category_id"] = category_id
  406. m["devices_enabled"] = devices_enabled
  407. m["id"] = id
  408. m["type"] = types
  409. illuminating, err := s.Illuminating("POST", urls, m)
  410. if err != nil {
  411. return model.GetTypeFind{}, errors.New("获取分类失败")
  412. }
  413. err = json.Unmarshal(illuminating, &respone)
  414. if err != nil {
  415. return model.GetTypeFind{}, errors.New("json反序列化失败")
  416. }
  417. return respone, nil
  418. }
  419. // GettimingId 获取定时策略详情
  420. func (s *illuminatingService) GetTimingId(timing_id string) (model.TimingId, error) {
  421. var respone model.TimingId
  422. urls := s.conf.GetString("illuminating.baseUrl") + s.conf.GetString("illuminating.api.timingId")
  423. if timing_id != "" {
  424. urls += "?timing_id=" + timing_id
  425. }
  426. illuminating, err := s.Illuminating("GET", urls, nil)
  427. if err != nil {
  428. return model.TimingId{}, errors.New("获取定时策略详情失败")
  429. }
  430. err = json.Unmarshal(illuminating, &respone)
  431. if err != nil {
  432. return model.TimingId{}, errors.New("json反序列化失败")
  433. }
  434. return respone, nil
  435. }