index.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. <template>
  2. <a-row v-loading="loading">
  3. <a-col :span="{ span: 24 }" class="mb-5">
  4. <alert-form
  5. v-if="!commonalertId || (loaded && !loading)"
  6. ref="alertFormRef"
  7. :alertData="alertData"
  8. :threshold.sync="threshold"
  9. :timeRangeParams="timeRangeParams"
  10. :isUpdate="isUpdate"
  11. :commonalertId="commonalertId"
  12. @scopeChange="scopeChange" />
  13. </a-col>
  14. </a-row>
  15. </template>
  16. <script>
  17. import * as R from 'ramda'
  18. import _ from 'lodash'
  19. import { getSignature } from '@/utils/crypto'
  20. import { timeOpts } from '@/constants/monitor'
  21. import { MONITOR_MAX_POINTERS } from '@Monitor/constants'
  22. import AlertForm from './form'
  23. export default {
  24. name: 'Commonalert',
  25. components: {
  26. AlertForm,
  27. },
  28. props: {
  29. isUpdate: {
  30. type: Boolean,
  31. default: false,
  32. },
  33. commonalertId: {
  34. type: String,
  35. },
  36. },
  37. data () {
  38. return {
  39. series: [],
  40. timeOpts,
  41. time: '1h',
  42. customTime: null,
  43. formmMetric: null,
  44. threshold: undefined,
  45. alertData: null,
  46. loading: false,
  47. loaded: false,
  48. chartLoading: false,
  49. pager: { seriesIndex: 0, total: 0, page: 1, limit: 10 },
  50. lineDescription: {},
  51. scopeParams: {},
  52. }
  53. },
  54. computed: {
  55. timeFormatStr () {
  56. const defaultTimeFormat = 'YYYY-MM-DD HH:mm'
  57. return _.get(this.timeOpts, '[this.time].timeFormat') || defaultTimeFormat
  58. },
  59. lineChartOptions () {
  60. if (!this.threshold) {
  61. return {
  62. legend: {
  63. show: false,
  64. },
  65. }
  66. }
  67. return {
  68. sampling: 'average',
  69. animation: false,
  70. legend: {
  71. show: false,
  72. },
  73. series: [{
  74. markLine: {
  75. lineStyle: {
  76. color: '#f5222d',
  77. },
  78. data: [{
  79. name: this.$t('monitor.text00014'),
  80. yAxis: this.threshold,
  81. label: {
  82. position: 'insideEndBottom',
  83. },
  84. }],
  85. },
  86. }],
  87. }
  88. },
  89. timeRangeParams () {
  90. const params = {}
  91. if (this.time === 'custom') { // 自定义时间
  92. if (this.customTime && this.customTime.from && this.customTime.to) {
  93. params.from = this.customTime.from
  94. params.to = this.customTime.to
  95. }
  96. } else {
  97. params.from = this.time
  98. }
  99. return params
  100. },
  101. timeGroup () {
  102. let tg = '1m'
  103. let diffHour = 1
  104. const noNumberReg = /\D+/g
  105. if (this.time === 'custom') {
  106. diffHour = this.customTime.from.replace(noNumberReg, '') - this.customTime.to.replace(noNumberReg, '')
  107. } else {
  108. diffHour = this.time.replace(noNumberReg, '')
  109. }
  110. const diff = diffHour * 60 // 变分钟
  111. tg = `${diff / MONITOR_MAX_POINTERS}m`
  112. return tg
  113. },
  114. },
  115. watch: {
  116. time () {
  117. this.fetchData()
  118. },
  119. customTime () {
  120. this.fetchData()
  121. },
  122. scopeParams () {
  123. this.fetchData()
  124. },
  125. },
  126. created () {
  127. if (this.commonalertId) {
  128. this.fetchCommonalert().then((res) => {
  129. if (this.alertData && this.alertData.common_alert_metric_details && this.alertData.common_alert_metric_details.length > 0) {
  130. const desc = this.alertData.common_alert_metric_details[0].field_description
  131. this.lineDescription.isUpdate = true
  132. this.lineDescription.metric_res_type = this.alertData.common_alert_metric_details[0].res_type
  133. if (this.alertData.common_alert_metric_details[0].measurement === 'cloudaccount_balance') {
  134. desc.unit = 'currency'
  135. }
  136. this.$set(this.lineDescription, 'description', desc || {})
  137. }
  138. })
  139. }
  140. },
  141. methods: {
  142. async fetchCommonalert () {
  143. try {
  144. this.loading = true
  145. const { data } = await new this.$Manager('commonalerts', 'v1')
  146. .get({
  147. id: this.commonalertId,
  148. params: { scope: this.$store.getters.scope },
  149. })
  150. this.alertData = data
  151. const time = _.get(this.alertData, 'settings.conditions[0].query.from')
  152. if (~time.indexOf('now-')) {
  153. this.time = 'custom'
  154. this.customTime = {
  155. from: time,
  156. to: _.get(this.alertData, 'settings.conditions[0].query.to') || 'now',
  157. }
  158. } else {
  159. this.time = this.timeOpts[time] ? time : '1h'
  160. }
  161. this.loading = false
  162. } catch (error) {
  163. this.loading = false
  164. throw error
  165. } finally {
  166. this.loaded = true
  167. }
  168. },
  169. cancel () {
  170. this.$router.push('/commonalerts')
  171. },
  172. reset () {
  173. this.$refs.alertFormRef.form.fc.resetFields()
  174. },
  175. resetChart () {
  176. this.series = []
  177. },
  178. scopeChange (scopeParams) {
  179. this.scopeParams = scopeParams
  180. },
  181. async submit () {
  182. try {
  183. const { fd, metric_query } = await this.$refs.alertFormRef.validate()
  184. const data = {
  185. scope: fd.scope,
  186. // interval: this.timeGroup,
  187. alert_duration: fd.alert_duration,
  188. generate_name: fd.name,
  189. description: fd.description,
  190. reason: fd.reason,
  191. period: fd.period,
  192. channel: fd.channel,
  193. recipients: fd.recipients,
  194. alert_type: 'normal', // normal(自定义) system(系统内置)
  195. level: fd.level,
  196. metric_query,
  197. disable_notify_recovery: fd.disable_notify_recovery,
  198. }
  199. if (fd.silent_period) {
  200. data.silent_period = fd.silent_period
  201. }
  202. // if (fd.comparator === 'nodata') {
  203. // data.metric_query[0].condition_type = 'nodata_query'
  204. // }
  205. if (fd.channel) {
  206. data.channel = fd.channel
  207. } else {
  208. data.channel = []
  209. }
  210. if (fd.robot_ids) {
  211. data.robot_ids = fd.robot_ids
  212. } else {
  213. data.robot_ids = []
  214. }
  215. if (fd.enabled_contact_types) {
  216. data.channel.push(...fd.enabled_contact_types)
  217. }
  218. if (fd.roles) {
  219. data.roles = fd.roles
  220. }
  221. if (fd.domain || fd.domain_id) data.domain_id = (fd.domain || fd.domain_id)
  222. if (fd.project) data.project_id = fd.project
  223. if (fd.from) {
  224. data.from = fd.from
  225. } else {
  226. const periodNum = parseInt(fd.period)
  227. const unit = fd.period.split('').pop()
  228. if (unit === 'm' && periodNum * fd.alert_duration < 10) {
  229. data.from = '10m'
  230. } else {
  231. data.from = (periodNum * fd.alert_duration) + unit
  232. }
  233. }
  234. if (data.metric_query && data.metric_query.length > 1) {
  235. data.metric_query.map(item => {
  236. item.operator = 'or'
  237. })
  238. }
  239. this.$emit('update:loading', true)
  240. if (this.isUpdate) {
  241. await new this.$Manager('commonalerts', 'v1').update({ id: this.commonalertId, data })
  242. this.$store.commit('keepAlive/ADD_DELAY_EVENT', { name: 'ResourceListSingleRefresh', params: this.commonalertId })
  243. } else {
  244. await new this.$Manager('commonalerts', 'v1').create({ data })
  245. }
  246. this.$emit('update:loading', false)
  247. this.$message.success(this.$t('common.success'))
  248. this.cancel()
  249. } catch (error) {
  250. this.$emit('update:loading', false)
  251. throw error
  252. }
  253. },
  254. async pageChange (pager) {
  255. await this._refresh(pager.limit, (pager.page - 1) * pager.limit)
  256. },
  257. async _refresh (limit, offset) {
  258. try {
  259. await this.fetchData(limit, offset)
  260. } catch (error) {
  261. this.formmMetric = { model: {} }
  262. throw error
  263. }
  264. },
  265. async refresh (params) {
  266. this.formmMetric = R.is(Object, params) ? [{ model: params }] : null
  267. await this._refresh(10, 0)
  268. },
  269. async fetchData (limit = this.pager.limit, offset = 0) {
  270. try {
  271. const data = {
  272. metric_query: this.formmMetric,
  273. interval: this.timeGroup,
  274. slimit: limit,
  275. soffset: offset,
  276. ...this.scopeParams,
  277. }
  278. if (this.time === 'custom') { // 自定义时间
  279. if (this.customTime && this.customTime.from && this.customTime.to) {
  280. data.from = this.customTime.from
  281. data.to = this.customTime.to
  282. }
  283. } else {
  284. data.from = this.time
  285. }
  286. if (!data.metric_query || !data.from || !_.get(data.metric_query, '[0].model.measurement') || !_.get(data.metric_query, '[0].model.select')) return
  287. this.chartLoading = true
  288. data.signature = getSignature(data)
  289. const { data: { series = [], series_total = 0 } } = await new this.$Manager('unifiedmonitors', 'v1').performAction({ id: 'query', action: '', data })
  290. this.series = []
  291. this.$nextTick(_ => {
  292. if (this.lineDescription.id === 'balance' && this.lineDescription.metric_res_type === 'cloudaccount') {
  293. const currencyList = []
  294. series.map(item => {
  295. const { tags = {} } = item
  296. const { currency = 'CNY' } = tags
  297. if (!currencyList.includes(currency)) {
  298. currencyList.push(currency)
  299. }
  300. })
  301. if (currencyList.length !== 1 && this.lineDescription.description) {
  302. this.lineDescription.description.unit = ''
  303. }
  304. if (currencyList.length === 1 && this.lineDescription.description) {
  305. this.lineDescription.description.unit = 'currency'
  306. }
  307. }
  308. this.series = series
  309. this.pager = { seriesIndex: 0, total: series_total, page: 1 + offset / limit, limit: limit }
  310. this.chartLoading = false
  311. })
  312. } catch (error) {
  313. this.chartLoading = false
  314. throw error
  315. }
  316. },
  317. },
  318. }
  319. </script>