siteInfoManageServices.go 9.6 KB

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