siteInfoManageServices.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. package services
  2. import (
  3. "context"
  4. "fmt"
  5. "fwh-toolbox-server/domain"
  6. "fwh-toolbox-server/dto"
  7. "fwh-toolbox-server/repositories"
  8. "fwh-toolbox-server/task/queue/fwhQueue"
  9. "fwh-toolbox-server/utils/global"
  10. "math"
  11. "regexp"
  12. "strconv"
  13. "time"
  14. "github.com/xuri/excelize/v2"
  15. "go.uber.org/zap"
  16. )
  17. var VERSION_REGEX = regexp.MustCompile(`V(\d+)R(\d+)B(\d+)D(\d+)`)
  18. // 获取更新状态
  19. func GetSiteInfoUpdateStatus() (*domain.SiteInfoUpdateRecord, error) {
  20. return repositories.GetSiteInfoUpdateNewRecord()
  21. }
  22. // 请求更新站点信息表
  23. func UpdateSiteInfoDate() error {
  24. id, err := repositories.CreateSiteInfoUpdateInfo()
  25. if err != nil {
  26. return err
  27. }
  28. if err := fwhQueue.EnqueueSiteInfoUpdateTask(domain.TaskSiteInfoUpdate{
  29. Id: *id,
  30. }); err != nil {
  31. return err
  32. }
  33. return nil
  34. }
  35. // 获取站点信息表
  36. func QuerySiteInfoDataList(para dto.SiteInfoRequest) (*dto.ResPage[dto.SiteInfoDTO], error) {
  37. res, err := repositories.GetSiteInfoManageList(para.PageNum, para.PageSize, para.Filter, para.Search)
  38. if err != nil {
  39. return nil, err
  40. }
  41. idList := []string{}
  42. for _, data := range res.Data {
  43. idList = append(idList, *data.ExtTags...)
  44. }
  45. tagMap, err := repositories.GetSiteInfoTagsFromId(idList)
  46. if err != nil {
  47. zap.L().Error("QuerySiteInfoDataList GetSiteInfoTagsFromId failed.", zap.String("err", err.Error()), zap.Strings("idList", idList))
  48. return nil, err
  49. }
  50. result := dto.ResPage[dto.SiteInfoDTO]{
  51. Data: dto.SiteInfoDomainListToSiteInfoDTOList(res.Data, &tagMap),
  52. PageSize: res.PageSize,
  53. PageNum: res.PageNum,
  54. Total: res.Total,
  55. }
  56. return &result, nil
  57. }
  58. // 导出站点信息表
  59. func ExportSiteInfoDataList(filer *domain.SiteInfoFilter) (*excelize.File, error) {
  60. res, err := repositories.GetSiteInfoManageList(0, 0, filer, "")
  61. if err != nil {
  62. return nil, err
  63. }
  64. record, err := repositories.GetSiteInfoUpdateNewRecord()
  65. if err != nil {
  66. return nil, err
  67. }
  68. // 创建新的excel文件
  69. f := excelize.NewFile()
  70. // 写标题行
  71. f.SetCellValue("Sheet1", "A1", "SN")
  72. f.SetCellValue("Sheet1", "B1", "Installer")
  73. f.SetCellValue("Sheet1", "C1", "ActiveTime")
  74. f.SetCellValue("Sheet1", "D1", "Status")
  75. f.SetCellValue("Sheet1", "E1", "OnLineTime")
  76. f.SetCellValue("Sheet1", "F1", "OffLineTime")
  77. f.SetCellValue("Sheet1", "G1", "FhpSn")
  78. f.SetCellValue("Sheet1", "H1", "Version")
  79. f.SetCellValue("Sheet1", "I1", "SlVersion")
  80. f.SetCellValue("Sheet1", "J1", "SlVersionJson")
  81. f.SetCellValue("Sheet1", "K1", "MeterVersion")
  82. f.SetCellValue("Sheet1", "L1", "MbVersion")
  83. f.SetCellValue("Sheet1", "M1", "AwsVersion")
  84. f.SetCellValue("Sheet1", "N1", "AppVersion")
  85. f.SetCellValue("Sheet1", "O1", "ProtocolVer")
  86. f.SetCellValue("Sheet1", "P1", "SysHdVersion")
  87. f.SetCellValue("Sheet1", "Q1", "Remark")
  88. f.SetCellValue("Sheet1", "R1", "Country")
  89. f.SetCellValue("Sheet1", "S1", "Province")
  90. f.SetCellValue("Sheet1", "T1", "ManufactureDate")
  91. f.SetCellValue("Sheet1", "U1", "HardwareVersion")
  92. f.SetCellValue("Sheet1", "V1", "CveStatus")
  93. f.SetCellValue("Sheet1", "W1", "SecurityPatchLevel")
  94. f.SetCellValue("Sheet1", "X1", "TargetVersion")
  95. f.SetCellValue("Sheet1", "Y1", "LastUpgradeTime")
  96. f.SetCellValue("Sheet1", "Z1", "UpgradeStatus")
  97. f.SetCellValue("Sheet1", "AA1", "Owner/Maintainer")
  98. f.SetCellValue("Sheet1", "AB1", "DataSource")
  99. f.SetCellValue("Sheet1", "AC1", "LastUpdated")
  100. f.SetCellValue("Sheet1", "AD1", "ConnectType")
  101. f.SetCellValue("Sheet1", "AE1", "WifiSignal")
  102. f.SetCellValue("Sheet1", "AF1", "4GSignal")
  103. // 写入数据
  104. for i, d := range res.Data {
  105. f.SetCellValue("Sheet1", "A"+strconv.Itoa(i+2), d.Sn)
  106. f.SetCellValue("Sheet1", "B"+strconv.Itoa(i+2), global.Deref(d.InstallerName, ""))
  107. f.SetCellValue("Sheet1", "C"+strconv.Itoa(i+2), d.ActiveTime)
  108. f.SetCellValue("Sheet1", "D"+strconv.Itoa(i+2), func() string {
  109. switch d.Status {
  110. case 0:
  111. return "离线(0)"
  112. case 1:
  113. return "在线(1)"
  114. default:
  115. return fmt.Sprintf("未知(%d)", d.Status)
  116. }
  117. }())
  118. f.SetCellValue("Sheet1", "E"+strconv.Itoa(i+2), global.Deref(d.OnLineTime, ""))
  119. f.SetCellValue("Sheet1", "F"+strconv.Itoa(i+2), global.Deref(d.OffLineTime, ""))
  120. f.SetCellValue("Sheet1", "G"+strconv.Itoa(i+2), d.FhpSn)
  121. f.SetCellValue("Sheet1", "H"+strconv.Itoa(i+2), d.Version)
  122. f.SetCellValue("Sheet1", "I"+strconv.Itoa(i+2), d.SlVersion)
  123. f.SetCellValue("Sheet1", "J"+strconv.Itoa(i+2), d.SlVersionJson)
  124. f.SetCellValue("Sheet1", "K"+strconv.Itoa(i+2), global.Deref(d.MeterVersion, ""))
  125. f.SetCellValue("Sheet1", "L"+strconv.Itoa(i+2), global.Deref(d.MbVersion, ""))
  126. f.SetCellValue("Sheet1", "M"+strconv.Itoa(i+2), global.Deref(d.AwsVersion, ""))
  127. f.SetCellValue("Sheet1", "N"+strconv.Itoa(i+2), global.Deref(d.AppVersion, ""))
  128. f.SetCellValue("Sheet1", "O"+strconv.Itoa(i+2), d.ProtocolVer)
  129. f.SetCellValue("Sheet1", "P"+strconv.Itoa(i+2), d.SysHdVersion)
  130. f.SetCellValue("Sheet1", "Q"+strconv.Itoa(i+2), global.Deref(d.Remark, ""))
  131. f.SetCellValue("Sheet1", "R"+strconv.Itoa(i+2), d.Country)
  132. f.SetCellValue("Sheet1", "S"+strconv.Itoa(i+2), d.Province)
  133. var manufactureDate string = ""
  134. if len(d.Sn) > 9 {
  135. year := d.Sn[len(d.Sn)-8 : len(d.Sn)-6]
  136. week := d.Sn[len(d.Sn)-6 : len(d.Sn)-4]
  137. manufactureDate = fmt.Sprintf("%s年%s周", year, week)
  138. }
  139. f.SetCellValue("Sheet1", "T"+strconv.Itoa(i+2), manufactureDate)
  140. f.SetCellValue("Sheet1", "U"+strconv.Itoa(i+2), "V"+strconv.Itoa(d.SysHdVersion))
  141. f.SetCellValue("Sheet1", "V"+strconv.Itoa(i+2), "无")
  142. f.SetCellValue("Sheet1", "W"+strconv.Itoa(i+2), "安全")
  143. f.SetCellValue("Sheet1", "X"+strconv.Itoa(i+2), d.Version)
  144. f.SetCellValue("Sheet1", "Y"+strconv.Itoa(i+2), global.Deref(d.FirmUpgradeTime, ""))
  145. f.SetCellValue("Sheet1", "Z"+strconv.Itoa(i+2), "成功")
  146. f.SetCellValue("Sheet1", "AA"+strconv.Itoa(i+2), "Jerry Liang/LMT")
  147. f.SetCellValue("Sheet1", "AB"+strconv.Itoa(i+2), "Fleetview")
  148. f.SetCellValue("Sheet1", "AC"+strconv.Itoa(i+2), record.UpdateTime.Format(time.DateTime))
  149. f.SetCellValue("Sheet1", "AD"+strconv.Itoa(i+2), func() string {
  150. switch d.ConnType {
  151. case 0:
  152. return "未连接(0)"
  153. case 1:
  154. return "eth0(1)"
  155. case 2:
  156. return "eth1(2)"
  157. case 3:
  158. return "WIFI(3)"
  159. case 4:
  160. return "4G(4)"
  161. default:
  162. return fmt.Sprintf("未知(%d)", d.Status)
  163. }
  164. }())
  165. f.SetCellValue("Sheet1", "AE"+strconv.Itoa(i+2), func() string {
  166. s, err := strconv.ParseInt(d.WifiSignal, 10, 64)
  167. if err != nil {
  168. zap.L().Warn("WifiSignal ParseInt failed", zap.String("WifiSignal", d.WifiSignal), zap.String("err", err.Error()))
  169. return fmt.Sprintf("未知信号(%s)", d.WifiSignal)
  170. }
  171. if s < 0 {
  172. return fmt.Sprintf("Disable(%s)", d.WifiSignal)
  173. } else if s < 40 {
  174. return fmt.Sprintf("很弱/不可用(%s) %ddBm", d.WifiSignal, s/2-100)
  175. } else if s < 60 {
  176. return fmt.Sprintf("弱(%s) %ddBm", d.WifiSignal, s/2-100)
  177. } else if s < 80 {
  178. return fmt.Sprintf("中等/一般(%s) %ddBm", d.WifiSignal, s/2-100)
  179. } else {
  180. return fmt.Sprintf("强/良好(%s) > -50dBm", d.WifiSignal)
  181. }
  182. }())
  183. f.SetCellValue("Sheet1", "AF"+strconv.Itoa(i+2), func() string {
  184. if d.Signal == nil {
  185. return "Not Signal"
  186. }
  187. s, err := strconv.ParseInt(*d.Signal, 10, 64)
  188. if err != nil {
  189. zap.L().Warn("Signal ParseInt failed", zap.String("4GSignal", *d.Signal), zap.String("err", err.Error()))
  190. return fmt.Sprintf("未知信号(%s)", *d.Signal)
  191. }
  192. // 判断软件版本
  193. isNew := false
  194. if d.AppVersion != nil && *d.AppVersion != "" {
  195. match := VERSION_REGEX.FindStringSubmatch(*d.AppVersion)
  196. if match != nil {
  197. v := match[1]
  198. r := match[2]
  199. b := match[3]
  200. d := match[4]
  201. _ = d // 当前逻辑未使用
  202. if v == "10" {
  203. rInt, _ := strconv.Atoi(r)
  204. bInt, _ := strconv.Atoi(b)
  205. if rInt > 5 {
  206. isNew = true
  207. } else if rInt == 4 && bInt >= 14 {
  208. isNew = true
  209. }
  210. }
  211. }
  212. }
  213. if isNew {
  214. if s < 0 {
  215. return fmt.Sprintf("Disable(%s)", *d.Signal)
  216. } else if s <= 12 {
  217. return fmt.Sprintf("很差(%s) %ddBm", *d.Signal, int(math.Round(float64(s)/2.5-115)))
  218. } else if s <= 37 {
  219. return fmt.Sprintf("较差(%s) %ddBm", *d.Signal, int(math.Round(float64(s)/2.5-115)))
  220. } else if s <= 62 {
  221. return fmt.Sprintf("一般(%s) %ddBm", *d.Signal, int(math.Round(float64(s)/2.5-115)))
  222. } else if s <= 87 {
  223. return fmt.Sprintf("良好(%s) %ddBm", *d.Signal, int(math.Round(float64(s)/2.5-115)))
  224. } else {
  225. return fmt.Sprintf("极好(%s) %ddBm", *d.Signal, int(math.Round(float64(s)/2.5-115)))
  226. }
  227. } else {
  228. if s < 0 {
  229. return fmt.Sprintf("Disable(%s)", *d.Signal)
  230. } else if s <= 1 {
  231. return fmt.Sprintf("很差(%s) %ddBm", *d.Signal, s*2-113)
  232. } else if s <= 6 {
  233. return fmt.Sprintf("较差(%s) %ddBm", *d.Signal, s*2-113)
  234. } else if s <= 11 {
  235. return fmt.Sprintf("一般(%s) %ddBm", *d.Signal, s*2-113)
  236. } else if s <= 16 {
  237. return fmt.Sprintf("良好(%s) %ddBm", *d.Signal, s*2-113)
  238. } else {
  239. return fmt.Sprintf("极好(%s) %ddBm", *d.Signal, s*2-113)
  240. }
  241. }
  242. }())
  243. }
  244. return f, err
  245. }
  246. // 查询单个站点实时信息(同时更新单个站点数据)
  247. func GetSiteInfoData(sn string) (*dto.SiteInfoDTO, error) {
  248. res, err := repositories.QuerySiteInfoList(dto.SiteInfoPara{
  249. SN: &sn,
  250. PageSize: 10,
  251. PageNum: 1,
  252. })
  253. if err != nil {
  254. return nil, err
  255. }
  256. if res.Result == nil {
  257. return nil, fmt.Errorf("code: %s, msg: %s", strconv.Itoa(res.Code), res.Message)
  258. }
  259. if len(*res.Result) == 0 {
  260. return nil, fmt.Errorf("code: %s, msg: %s", strconv.Itoa(res.Code), res.Message)
  261. }
  262. domainData := domain.FwhSiteInfoToSiteInfoDomain(&(*res.Result)[0])
  263. // 数据插入数据库
  264. if err := repositories.InsertSiteInfoData(*domainData); err != nil {
  265. zap.L().Error("保存站点信息失败", zap.String("err", err.Error()), zap.String("sn", sn))
  266. }
  267. tagMap := make(map[string]*dto.SiteTagDTO)
  268. if domainData.ExtTags != nil {
  269. tagMap, err = repositories.GetSiteInfoTagsFromId(*domainData.ExtTags)
  270. if err != nil {
  271. zap.L().Error("GetSiteInfoData GetSiteInfoTagsFromId failed.", zap.String("err", err.Error()), zap.Strings("idList", *domainData.ExtTags))
  272. return nil, err
  273. }
  274. }
  275. dtoData := dto.SiteInfoDomainToSiteInfoDTO(domainData, &tagMap)
  276. return dtoData, nil
  277. }
  278. // 使能站点xlog
  279. func OperateSiteInfoEnableXlog(ctx context.Context, sn string) (string, error) {
  280. return repositories.FwhMqttEnableXlog(ctx, sn)
  281. }
  282. // 获取站点信息标签列表
  283. func GetSiteInfoTags(page uint, size uint, search string) (*dto.ResPage[dto.SiteTagDTO], error) {
  284. tags, err := repositories.GetSiteInfoTags(page, size, search)
  285. if err != nil {
  286. return nil, err
  287. }
  288. result := dto.ResPage[dto.SiteTagDTO]{
  289. Data: []dto.SiteTagDTO{},
  290. PageSize: tags.PageSize,
  291. PageNum: tags.PageNum,
  292. Total: tags.Total,
  293. }
  294. for _, tag := range tags.Data {
  295. result.Data = append(result.Data, *dto.SiteTagDomainToSiteTagDTO(&tag))
  296. }
  297. return &result, nil
  298. }
  299. // 创建或更新站点信息标签
  300. func UpdateSiteInfoTag(tag dto.SiteTagDTO) error {
  301. return repositories.UpdateSiteInfoTag(*dto.SiteSiteTagDTOToTagDomain(&tag))
  302. }