index.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. import _ from 'lodash'
  2. import * as R from 'ramda'
  3. import { metric_zh, alertStrategyMaps, preiodMaps, levelMaps } from '@Monitor/constants'
  4. import { channelMaps } from '@/constants'
  5. import i18n from '@/locales'
  6. import { transformUnit, arrayToObj } from '@/utils/utils'
  7. import { currencyUnitMap } from '@/constants/currency'
  8. export const levelColumn = {
  9. field: 'level',
  10. title: i18n.t('monitor.level'),
  11. minWidth: 40,
  12. slots: {
  13. default: ({ row }, h) => {
  14. const levelItem = levelMaps[row.level]
  15. const text = levelItem ? levelItem.label : row.level
  16. return [h('a-tag', {
  17. props: {
  18. color: levelItem ? levelItem.color : levelMaps.normal.color,
  19. },
  20. }, text)]
  21. },
  22. },
  23. }
  24. export const conditionColumn = {
  25. field: 'channel',
  26. title: i18n.t('monitor.text_11'),
  27. minWidth: 80,
  28. formatter: ({ row }) => {
  29. if (!row.channel || !row.channel.length) return '-'
  30. return row.channel.filter(val => ~val.indexOf('robot')).map(val => (channelMaps[val] || {}).label).join('、')
  31. },
  32. }
  33. export const robotsColumn = (robotList) => ({
  34. field: 'robot_ids',
  35. title: i18n.t('monitor.text_11'),
  36. slots: {
  37. default: ({ row }, h) => {
  38. if (!row.robot_ids || !row.robot_ids.length) return '-'
  39. const robotsMap = arrayToObj(robotList, 'id')
  40. const robotNames = row.robot_ids.map(val => robotsMap[val].name)
  41. return robotNames.map(val => {
  42. return h('a-tag', val)
  43. })
  44. },
  45. },
  46. })
  47. export const strategyColumn = (field = 'common_alert_metric_details', title = i18n.t('monitor.strategy_detail')) => ({
  48. field,
  49. title,
  50. minWidth: 120,
  51. slots: {
  52. default: ({ row }, h) => {
  53. const { filters, strategy, strategyArr = [] } = getMetircAlertUtil(row, field)
  54. if (!row[field]) return '-'
  55. let filterNode = null
  56. if (filters.length > 0) {
  57. filterNode = (
  58. <a-tag class="w-100">
  59. <div>{i18n.t('monitor.text_101')}: </div>
  60. {filters.map(v => <div class="w-100 text-truncate" title={v}>{v}</div>)}
  61. </a-tag>
  62. )
  63. }
  64. const strategys = strategyArr.map(item => <div>{item}</div>)
  65. if (row[field]?.length > 1) {
  66. return [
  67. <div>
  68. <div>{i18n.t('monitor.commonalert.alert_condition.content')}:</div>
  69. <div>{strategys}</div>
  70. {filterNode}
  71. </div>,
  72. ]
  73. }
  74. return [
  75. <div>
  76. <div>{strategy}</div>
  77. {filterNode}
  78. </div>,
  79. ]
  80. },
  81. },
  82. })
  83. export const projectTableColumn = {
  84. field: 'project',
  85. title: i18n.t('monitor.text00015'),
  86. slots: {
  87. default: ({ row }, h) => {
  88. if (!row.tenant && !row.project_domain) {
  89. return i18n.t('monitor.text00024')
  90. }
  91. const domain = row.project_domain || row.domain
  92. if (!row.tenant && domain) {
  93. return `${domain}${i18n.t('monitor.text00025')}`
  94. }
  95. if (row.tenant && domain) {
  96. return [
  97. <list-body-cell-wrap copy field='tenant' row={row} />,
  98. <list-body-cell-wrap hide-field copy field="domain" row={{ domain }}>
  99. <span class='text-weak'>{domain}</span>
  100. </list-body-cell-wrap>,
  101. ]
  102. }
  103. },
  104. },
  105. }
  106. export const recipientsColumn = recipientList => ({
  107. field: 'recipients',
  108. title: i18n.t('compute.text_740'),
  109. slots: {
  110. default: ({ row }, h) => {
  111. if (!row.recipients || !row.recipients.length) return '-'
  112. const recipientsMap = arrayToObj(recipientList, 'id')
  113. const recipientNames = []
  114. row.recipients.map(val => {
  115. if (recipientsMap[val]) {
  116. recipientNames.push(recipientsMap[val].name)
  117. }
  118. })
  119. return recipientNames.map(val => {
  120. return h('a-tag', val)
  121. })
  122. },
  123. },
  124. })
  125. export const rolesColumn = roleList => ({
  126. field: 'role_ids',
  127. title: i18n.t('monitor.role'),
  128. slots: {
  129. default: ({ row }, h) => {
  130. if (!row.role_ids || !row.role_ids.length) return '-'
  131. const rolesMap = arrayToObj(roleList, 'id')
  132. const roleNames = []
  133. row.role_ids.map(val => {
  134. if (rolesMap[val]) {
  135. roleNames.push(rolesMap[val].name)
  136. }
  137. })
  138. return roleNames.map(val => {
  139. return h('a-tag', val)
  140. })
  141. },
  142. },
  143. })
  144. export function getMetircAlertUtil (row, field, condition) {
  145. let strategy = '-'
  146. let strategyConfig = {
  147. measurement: '',
  148. period: '', // 时间间隔 2h 14d
  149. metric: '', // 监控指标
  150. comparator: '', // > < within
  151. threshold: null, // 阈值
  152. unit: '', // 单位
  153. time_from: row.time_from,
  154. }
  155. const strategyArr = []
  156. const strategyConfigArr = []
  157. const filters = []
  158. const getStrategyInfo = (detail) => {
  159. let measurement = detail.measurement_display_name || detail.measurement_desc || detail.measurement
  160. if (metric_zh[measurement]) measurement = metric_zh[measurement]
  161. strategyConfig.measurement = measurement
  162. let metric = _.get(detail, 'field_description.display_name') || detail.field_desc || detail.field
  163. if (metric) {
  164. metric = metric_zh[metric] || metric
  165. }
  166. strategyConfig.metric = metric
  167. const reduce = (alertStrategyMaps[detail.reduce]) || ''
  168. const alert_duration = row.alert_duration ? i18n.t('monitor.list.duration.label', [row.alert_duration]) : row[field].alert_duration ? i18n.t('monitor.list.duration.label', [row[field].alert_duration]) : ''
  169. let preiod = ((preiodMaps[row.period] || {}).label) || row.period || ((preiodMaps[detail.period] || {}).label) || detail.period
  170. let unit = detail.field_description ? _.get(detail, 'field_description.unit') : (R.type(row.eval_data) === 'Array' ? (_.get(row, 'eval_data[0].unit') || '') : '')
  171. let threshold = R.is(String, detail.threshold) ? { text: detail.threshold } : transformUnit(detail.threshold, unit)
  172. if (detail.measurement === 'cloudaccount_balance' && unit === 'RMB') {
  173. unit = ''
  174. if (detail.filters && detail.filters.length) {
  175. const targets = detail.filters.filter(item => item.key === 'currency')
  176. const cs = []
  177. targets.map(item => {
  178. if (item.value && !cs.includes(item.value)) {
  179. cs.push(item.value)
  180. }
  181. })
  182. if (cs.length === 1) {
  183. unit = currencyUnitMap[cs[0]]?.sign || ''
  184. }
  185. }
  186. threshold = R.is(String, detail.threshold) ? { text: detail.threshold } : unit ? { text: `${unit}${detail.threshold}` } : { text: detail.threshold }
  187. }
  188. let comparator = detail.comparator
  189. let txt = threshold.text
  190. if (detail.comparator === 'within_range' && detail.within_range) {
  191. comparator = ''
  192. txt = `[${detail.within_range[0]}${threshold.unit}, ${detail.within_range[1]}${threshold.unit}]`
  193. strategyConfig.within_range = detail.within_range
  194. }
  195. if (detail.comparator === 'within_range' && detail.threshold_range) {
  196. comparator = ''
  197. txt = i18n.t('monitor.threshold_range_in', [`${detail.threshold_range[0]}${unit || detail.unit || ''}`, `${detail.threshold_range[1]}${unit || detail.unit || ''}`])
  198. strategyConfig.within_range = detail.threshold_range
  199. }
  200. if (detail.comparator === 'outside_range' && detail.threshold_range) {
  201. comparator = ''
  202. txt = i18n.t('monitor.threshold_range_out', [`${detail.threshold_range[0]}${unit || detail.unit || ''}`, `${detail.threshold_range[1]}${unit || detail.unit || ''}`])
  203. strategyConfig.outside_range = detail.threshold_range
  204. }
  205. strategyConfig.comparator = detail.comparator
  206. strategyConfig.threshold = detail.threshold
  207. strategyConfig.unit = unit
  208. strategy = i18n.t('monitor.text_6', [measurement, metric, reduce, alert_duration, comparator, txt])
  209. if (detail.condition_type === 'nodata_query') { // 系统上报数据为空
  210. strategy = i18n.t('monitor.text_108', [alert_duration])
  211. }
  212. if (condition) return strategy // 只要触发条件信息
  213. if (preiod) {
  214. preiod = preiod.replace(i18n.t('monitor.text_103'), '')
  215. strategy += `${i18n.t('monitor.text_102', [preiod])}`
  216. strategyConfig.period = preiod
  217. }
  218. const silent_period = row.silent_period || row[field].silent_period
  219. if (silent_period) {
  220. let p = silent_period
  221. if (p.endsWith('m')) {
  222. const pi = parseInt(p.replace('m', ''))
  223. if (pi && pi >= 60 && pi % 60 === 0) {
  224. p = i18n.t('monitor.duration.silent.hour', [pi / 60])
  225. } else {
  226. p = i18n.t('monitor.duration.silent.minute', [p.replace('m', '')])
  227. }
  228. } else if (p.endsWith('h')) {
  229. p = i18n.t('monitor.duration.silent.hour', [p.replace('h', '')])
  230. }
  231. strategy += `${i18n.t('monitor.commonalerts.list.silent', [p])}`
  232. strategyConfig.period = silent_period
  233. }
  234. return {
  235. strategy,
  236. strategyConfig,
  237. }
  238. }
  239. if (row[field] && ((R.type(row[field]) === 'Array') || R.type(row[field]) === 'Object') && !R.isEmpty(row[field])) {
  240. let detail = ''
  241. if (R.type(row[field]) === 'Array') {
  242. detail = row[field][0]
  243. row[field].forEach(item => {
  244. const strategyInfo = getStrategyInfo(item)
  245. strategyArr.push(strategyInfo.strategy)
  246. strategyConfigArr.push(strategyInfo.strategyConfig)
  247. })
  248. } else if (R.type(row[field]) === 'Object') {
  249. detail = row[field]
  250. const strategyInfo = getStrategyInfo(detail)
  251. strategy = strategyInfo.strategy
  252. strategyConfig = strategyInfo.strategyConfig
  253. }
  254. if (detail.filters && detail.filters.length) {
  255. detail.filters.forEach((val, i) => {
  256. if (val.key) {
  257. if (val.key !== 'brand' || val.value.toLowerCase() !== 'onecloud') {
  258. filters.push(`${(val.condition && i !== 0) ? val.condition : ''} ${val.key} ${val.operator} ${val.value}`)
  259. } else {
  260. filters.push(`${(val.condition && i !== 0) ? val.condition : ''} ${val.key} ${val.operator} ${i18n.t('brand')}`)
  261. }
  262. }
  263. })
  264. }
  265. }
  266. return {
  267. strategy,
  268. strategyConfig,
  269. filters,
  270. strategyArr,
  271. strategyConfigArr,
  272. }
  273. }
  274. export const getResTypeColumn = ({ field = 'common_alert_metric_details' } = {}) => ({
  275. field: 'res_type',
  276. title: i18n.t('monitor.text_97'),
  277. formatter: ({ row }) => {
  278. const str = _.get(row[field], '[0].res_type')
  279. if (!str) return '-'
  280. if (i18n.te(`dictionary.${str}`)) return i18n.t(`dictionary.${str}`)
  281. return str
  282. },
  283. })
  284. export const getVerifiedContactTypesTableColumn = ({ field = 'channel', title = i18n.t('common_599'), vm } = {}) => {
  285. return {
  286. title: i18n.t('common_599'),
  287. field: 'channel',
  288. minWidth: 120,
  289. slots: {
  290. default: ({ row }, h) => {
  291. const color = '#52c41a'
  292. const channel = row.channel || []
  293. const renderComponents = []
  294. channel.forEach((ctype) => {
  295. switch (ctype) {
  296. case 'webconsole':
  297. renderComponents.push(<icon type='webconsole' style={{ color: color }} title={i18n.t('dictionary.webconsole')} />)
  298. break
  299. case 'email':
  300. renderComponents.push(<icon class='ml-2' type='email' style={{ color: color }} title={i18n.t('common.email')} />)
  301. break
  302. case 'mobile':
  303. renderComponents.push(<icon class='ml-2' type='mobile' style={{ color: color }} title={i18n.t('common.mobile')} />)
  304. break
  305. case 'dingtalk':
  306. renderComponents.push(<icon class='ml-2' type='dingtalk' style={{ color: color }} title={i18n.t('common.dingtalk')} />)
  307. break
  308. case 'feishu':
  309. renderComponents.push(<icon class='ml-2' type='feishu' style={{ color: color }} title={i18n.t('common.feishu')} />)
  310. break
  311. case 'workwx':
  312. renderComponents.push(<icon class='ml-2' type='workwx' style={{ color: color }} title={i18n.t('common.workwx')} />)
  313. break
  314. default:
  315. break
  316. }
  317. })
  318. return renderComponents
  319. },
  320. },
  321. }
  322. }
  323. export const getValueWithUnit = (value = 0, unit = '') => {
  324. const currencyUnitList = Object.keys(currencyUnitMap)
  325. // 金额类型的单位
  326. for (let i = 0; i < currencyUnitList.length; i++) {
  327. if (unit.indexOf(currencyUnitList[i]) !== -1) {
  328. return `${currencyUnitMap[currencyUnitList[i]].sign} ${value}`
  329. }
  330. }
  331. return value
  332. }
  333. export const getStrategyInfo = (detail) => {
  334. let strategy = '-'
  335. const strategyConfig = {
  336. measurement: '',
  337. period: '', // 时间间隔 2h 14d
  338. metric: '', // 监控指标
  339. comparator: '', // > < within
  340. threshold: null, // 阈值
  341. unit: '', // 单位
  342. time_from: detail.time_from,
  343. }
  344. let measurement = detail.measurement_display_name || detail.measurement_desc || detail.measurement
  345. if (metric_zh[measurement]) measurement = metric_zh[measurement]
  346. strategyConfig.measurement = measurement
  347. let metric = _.get(detail, 'field_description.display_name') || detail.field_desc || detail.field
  348. if (metric) {
  349. metric = metric_zh[metric] || metric
  350. }
  351. strategyConfig.metric = metric
  352. const reduce = (alertStrategyMaps[detail.reduce]) || ''
  353. const alert_duration = detail.alert_duration ? i18n.t('monitor.list.duration.label', [detail.alert_duration]) : detail.alert_duration ? i18n.t('monitor.list.duration.label', [detail.alert_duration]) : ''
  354. let preiod = ((preiodMaps[detail.period] || {}).label) || detail.period || ((preiodMaps[detail.period] || {}).label) || detail.period
  355. let unit = detail.field_description ? _.get(detail, 'field_description.unit') : (R.type(detail.eval_data) === 'Array' ? (_.get(detail, 'eval_data[0].unit') || '') : '')
  356. let threshold = R.is(String, detail.threshold) ? { text: detail.threshold } : transformUnit(detail.threshold, unit)
  357. if (detail.measurement === 'cloudaccount_balance' && unit === 'RMB') {
  358. unit = ''
  359. if (detail.filters && detail.filters.length) {
  360. const targets = detail.filters.filter(item => item.key === 'currency')
  361. const cs = []
  362. targets.map(item => {
  363. if (item.value && !cs.includes(item.value)) {
  364. cs.push(item.value)
  365. }
  366. })
  367. if (cs.length === 1) {
  368. unit = currencyUnitMap[cs[0]]?.sign || ''
  369. }
  370. }
  371. threshold = R.is(String, detail.threshold) ? { text: detail.threshold } : unit ? { text: `${unit}${detail.threshold}` } : { text: detail.threshold }
  372. }
  373. let comparator = detail.comparator
  374. let txt = threshold.text
  375. if (detail.comparator === 'within_range' && detail.within_range) {
  376. comparator = ''
  377. txt = `[${detail.within_range[0]}${threshold.unit}, ${detail.within_range[1]}${threshold.unit}]`
  378. strategyConfig.within_range = detail.within_range
  379. }
  380. strategyConfig.comparator = detail.comparator
  381. strategyConfig.threshold = detail.threshold
  382. strategyConfig.unit = unit
  383. strategy = i18n.t('monitor.text_6', [measurement, metric, reduce, alert_duration, comparator, txt])
  384. if (detail.condition_type === 'nodata_query') { // 系统上报数据为空
  385. strategy = i18n.t('monitor.text_108', [alert_duration])
  386. }
  387. if (preiod) {
  388. preiod = preiod.replace(i18n.t('monitor.text_103'), '')
  389. strategy += `${i18n.t('monitor.text_102', [preiod])}`
  390. strategyConfig.period = preiod
  391. }
  392. const silent_period = detail.silent_period
  393. if (silent_period) {
  394. let p = silent_period
  395. if (p.endsWith('m')) {
  396. const pi = parseInt(p.replace('m', ''))
  397. if (pi && pi >= 60 && pi % 60 === 0) {
  398. p = i18n.t('monitor.duration.silent.hour', [pi / 60])
  399. } else {
  400. p = i18n.t('monitor.duration.silent.minute', [p.replace('m', '')])
  401. }
  402. } else if (p.endsWith('h')) {
  403. p = i18n.t('monitor.duration.silent.hour', [p.replace('h', '')])
  404. }
  405. strategy += `${i18n.t('monitor.commonalerts.list.silent', [p])}`
  406. strategyConfig.period = silent_period
  407. }
  408. return {
  409. strategy,
  410. strategyConfig,
  411. }
  412. }