RuleListCreate.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. <template>
  2. <base-dialog @cancel="cancelDialog">
  3. <div slot="header">{{$t('compute.perform_create')}}</div>
  4. <div slot="body">
  5. <a-form :form="form.fc" v-bind="formItemLayout">
  6. <a-form-item :label="$t('compute.text_228')">
  7. <a-input :placeholder="$t('validator.serverCreateName')" v-decorator="decorators.name" />
  8. </a-form-item>
  9. <a-form-item :label="$t('compute.text_913')">
  10. <a-radio-group v-decorator="decorators.trigger_type">
  11. <a-radio-button v-for="(v, k) in $t('flexGrouTriggerType')" :key="k" :value="k">{{v}}</a-radio-button>
  12. </a-radio-group>
  13. </a-form-item>
  14. <!-- 告警策略 -->
  15. <template v-if="form.fc.getFieldValue('trigger_type') === 'alarm' || !form.fc.getFieldValue('trigger_type')">
  16. <a-form-item :label="$t('compute.text_914')">
  17. <a-input-group compact>
  18. <a-select style="width: 50%" v-decorator="decorators.indicator">
  19. <a-select-option v-for="(v, k) in $t('flexGroupIndicator')" :key="k" :value="k">{{v}}</a-select-option>
  20. </a-select>
  21. <a-select style="width: 25%" v-decorator="decorators.operator">
  22. <a-select-option value="lt">{{$t('compute.text_915')}}</a-select-option>
  23. <a-select-option value="gt">{{$t('compute.text_916')}}</a-select-option>
  24. </a-select>
  25. <a-input-number v-decorator="decorators.value" :min="0" :max="form.fc.getFieldValue('alarm.indicator') && form.fc.getFieldValue('alarm.indicator') !== 'cpu' ? 999999999 : 100" />
  26. <span style="margin:5px 0 0 5px">
  27. {{ form.fc.getFieldValue('alarm.indicator') && form.fc.getFieldValue('alarm.indicator') !== 'cpu' ? 'b/s' : '%' }}
  28. </span>
  29. </a-input-group>
  30. </a-form-item>
  31. <a-form-item :label="$t('compute.text_917')">
  32. <a-select style="width: 50%" v-decorator="decorators.cycle">
  33. <a-select-option v-for="(v, k) in $t('flexGroupCycles')" :key="k" :value="parseInt(k)">{{v}}</a-select-option>
  34. </a-select>
  35. </a-form-item>
  36. <a-form-item :label="$t('compute.text_918')">
  37. <a-tooltip placement="top" :title="$t('compute.text_919')">
  38. <a-input-number v-decorator="decorators.cumulate" :min="1" :max="1000" />
  39. </a-tooltip>
  40. <div slot="extra">
  41. {{ $t('compute.text_920', [form.fc.getFieldValue('alarm.cumulate') || 3, form.fc.getFieldValue('alarm.cumulate') || 3]) }}
  42. </div>
  43. </a-form-item>
  44. </template>
  45. <!-- 定时策略 -->
  46. <template v-if="form.fc.getFieldValue('trigger_type') === 'timing'">
  47. <a-form-item :label="$t('compute.text_923')">
  48. <a-date-picker
  49. :showTime="{
  50. format: 'HH:mm',
  51. }"
  52. :disabledDate="disabledDate"
  53. :disabledTime="disabledDateTime"
  54. v-decorator="decorators.execTime"
  55. format="YYYY-MM-DD HH:mm" />
  56. </a-form-item>
  57. </template>
  58. <!-- 周期策略 -->
  59. <template v-if="form.fc.getFieldValue('trigger_type') === 'cycle'">
  60. <a-form-item :label="$t('compute.text_924')">
  61. <a-select v-decorator="decorators.cycle_type">
  62. <a-select-option v-for="(v, k) in $t('flexGroupCycleType')" :key="k" :value="k">{{v}}</a-select-option>
  63. </a-select>
  64. </a-form-item>
  65. <a-form-item :label="$t('compute.text_925')" v-if="form.fc.getFieldValue('cycleTimer.cycle_type') === 'week'">
  66. <a-select v-decorator="decorators.weekDays" mode="multiple">
  67. <a-select-option v-for="(v, k) in $t('flexGroupSubCycleTypeWeek')" :key="k" :value="parseInt(k)">{{v}}</a-select-option>
  68. </a-select>
  69. </a-form-item>
  70. <a-form-item :label="$t('compute.text_926')" v-if="form.fc.getFieldValue('cycleTimer.cycle_type') === 'month'">
  71. <a-select v-decorator="decorators.monthDays" mode="multiple">
  72. <a-select-option v-for="i in 31" :key="i" :value="parseInt(i)">{{$t('compute.text_927', [i])}}</a-select-option>
  73. </a-select>
  74. </a-form-item>
  75. <a-form-item :label="$t('compute.text_923')">
  76. <a-time-picker v-decorator="decorators.hourMinute" format="HH:mm" />
  77. </a-form-item>
  78. <a-form-item :label="$t('compute.text_928')">
  79. <a-range-picker
  80. v-decorator="decorators.startEndTime"
  81. :disabledDate="disabledDate"
  82. format="YYYY-MM-DD" />
  83. </a-form-item>
  84. </template>
  85. <a-form-item :label="$t('compute.text_929')">
  86. <a-input-group compact>
  87. <a-select style="width: 50%" v-decorator="decorators.action">
  88. <a-select-option v-for="(v, k) in $t('flexGroupRuleAction')" :key="k" :value="k">{{v}}</a-select-option>
  89. </a-select>
  90. <a-tooltip>
  91. <span slot="title">
  92. {{actionConfig(form.fc.getFieldValue('action')).tooltip}}
  93. </span>
  94. <a-input-number v-bind="actionConfig(form.fc.getFieldValue('action')).number" v-decorator="decorators.number" />
  95. </a-tooltip>
  96. <span style="margin:5px 0 0 5px">{{$t('compute.text_930')}}</span>
  97. </a-input-group>
  98. </a-form-item>
  99. <a-form-item :label="$t('compute.text_931')">
  100. <a-tooltip placement="top" :title="$t('compute.text_932')">
  101. <a-input-number v-decorator="decorators.cooling_time" :min="0" :max="1000" />
  102. </a-tooltip>
  103. <span style="margin:5px 0 0 5px">{{$t('compute.text_767')}}</span>
  104. <div slot="extra">
  105. {{$t('compute.text_933', [form.fc.getFieldValue('cooling_time') || 180])}}
  106. </div>
  107. </a-form-item>
  108. </a-form>
  109. </div>
  110. <div slot="footer">
  111. <a-button type="primary" @click="handleConfirm" :loading="loading">{{ $t('dialog.ok') }}</a-button>
  112. <a-button @click="cancelDialog">{{ $t('dialog.cancel') }}</a-button>
  113. </div>
  114. </base-dialog>
  115. </template>
  116. <script>
  117. // import * as R from 'ramda'
  118. import DialogMixin from '@/mixins/dialog'
  119. import WindowsMixin from '@/mixins/windows'
  120. import validateForm from '@/utils/validate'
  121. export default {
  122. name: 'FiexRuleListCreateDialog',
  123. mixins: [DialogMixin, WindowsMixin],
  124. data () {
  125. return {
  126. loading: false,
  127. scope: this.$store.getters.scope,
  128. form: {
  129. fc: this.$form.createForm(this),
  130. },
  131. formItemLayout: {
  132. wrapperCol: { span: 15 },
  133. labelCol: { span: 9 },
  134. },
  135. decorators: {
  136. name: [
  137. 'name',
  138. {
  139. validateTrigger: ['change', 'blur'],
  140. validateFirst: true,
  141. rules: [
  142. { required: true, message: this.$t('compute.text_210') },
  143. { validator: validateForm('serverCreateName') },
  144. ],
  145. },
  146. ],
  147. trigger_type: [
  148. 'trigger_type',
  149. {
  150. initialValue: 'alarm',
  151. rules: [
  152. { required: true, message: this.$t('compute.text_935') },
  153. ],
  154. },
  155. ],
  156. indicator: [
  157. 'alarm.indicator',
  158. {
  159. initialValue: 'cpu',
  160. rules: [
  161. { required: true, message: this.$t('compute.text_936') },
  162. ],
  163. },
  164. ],
  165. operator: [
  166. 'alarm.operator',
  167. {
  168. initialValue: 'gt',
  169. },
  170. ],
  171. value: [
  172. 'alarm.value',
  173. {
  174. initialValue: 80,
  175. },
  176. ],
  177. cumulate: [
  178. 'alarm.cumulate',
  179. {
  180. initialValue: 3,
  181. rules: [
  182. { required: true, message: this.$t('compute.text_937') },
  183. ],
  184. },
  185. ],
  186. cooling_time: [
  187. 'cooling_time',
  188. {
  189. initialValue: 180,
  190. rules: [
  191. { required: true, message: this.$t('compute.text_938') },
  192. ],
  193. },
  194. ],
  195. action: [
  196. 'action',
  197. {
  198. initialValue: 'add',
  199. rules: [
  200. { required: true, message: this.$t('compute.text_939') },
  201. ],
  202. },
  203. ],
  204. number: [
  205. 'number',
  206. {
  207. initialValue: 1,
  208. rules: [
  209. { required: true, message: this.$t('compute.text_940') },
  210. ],
  211. },
  212. ],
  213. cycle_type: [
  214. 'cycleTimer.cycle_type',
  215. {
  216. initialValue: 'day',
  217. rules: [
  218. { required: true, message: this.$t('compute.text_941') },
  219. ],
  220. },
  221. ],
  222. weekDays: [
  223. 'cycleTimer.week_days',
  224. {
  225. initialValue: [1, 2, 3, 4, 5],
  226. rules: [
  227. { required: true, message: this.$t('compute.text_942') },
  228. ],
  229. },
  230. ],
  231. monthDays: [
  232. 'cycleTimer.month_days',
  233. {
  234. initialValue: [1],
  235. rules: [
  236. { required: true, message: this.$t('compute.text_943') },
  237. ],
  238. },
  239. ],
  240. // 小时:分钟
  241. hourMinute: [
  242. 'hourMinute',
  243. {
  244. initialValue: this.$moment().startOf('day').add(2, 'h'),
  245. rules: [
  246. { required: true, message: this.$t('compute.text_944') },
  247. ],
  248. },
  249. ],
  250. // 有效时间
  251. startEndTime: [
  252. 'startEndTime',
  253. {
  254. // initialValue: [1],
  255. rules: [
  256. { required: true, message: this.$t('compute.text_945') },
  257. ],
  258. },
  259. ],
  260. execTime: [
  261. 'timer.execTime',
  262. {
  263. initialValue: this.$moment().add(1, 'h'),
  264. rules: [
  265. { required: true, message: this.$t('compute.text_923') },
  266. ],
  267. },
  268. ],
  269. cycle: [
  270. 'alarm.cycle',
  271. {
  272. initialValue: 300,
  273. rules: [
  274. { required: true, message: this.$t('compute.text_946') },
  275. ],
  276. },
  277. ],
  278. },
  279. }
  280. },
  281. methods: {
  282. actionConfig (type) {
  283. const { resData } = this.params
  284. if (type === 'set') {
  285. const number = {
  286. min: resData.min_instance_number,
  287. max: resData.max_instance_number,
  288. }
  289. const tooltip = this.$t('compute.text_947', [number.min, number.max])
  290. return {
  291. number,
  292. tooltip,
  293. }
  294. } else {
  295. const number = {
  296. min: 1,
  297. max: resData.max_instance_number,
  298. }
  299. const tooltip = this.$t('compute.text_948', [number.max])
  300. return {
  301. number,
  302. tooltip,
  303. }
  304. }
  305. },
  306. disabledDate (current) {
  307. return current && current < this.$moment().subtract(1, 'd').endOf('day')
  308. },
  309. range (start, end) {
  310. const result = []
  311. for (let i = start; i < end; i++) {
  312. result.push(i)
  313. }
  314. return result
  315. },
  316. disabledDateTime (_ = this.$moment(), type) {
  317. let disabledHours = []
  318. let disabledMinutes = []
  319. let disabledSeconds = []
  320. const dayDiff = _.diff(this.$moment(), 'days', true)
  321. const hourDiff = _.diff(this.$moment(), 'hours', true)
  322. const minutesDiff = _.diff(this.$moment(), 'minutes', true)
  323. // 当天
  324. if (dayDiff > -1 && dayDiff < 0) {
  325. disabledHours = this.range(0, this.$moment().hour())
  326. if (hourDiff > -1 && hourDiff < 0) {
  327. disabledMinutes = this.range(0, this.$moment().minute())
  328. if (minutesDiff > -1 && minutesDiff < 0) {
  329. disabledSeconds = this.range(0, this.$moment().second())
  330. }
  331. }
  332. }
  333. return {
  334. disabledHours: () => disabledHours,
  335. disabledMinutes: () => disabledMinutes,
  336. disabledSeconds: () => disabledSeconds,
  337. }
  338. },
  339. formatValues (values) {
  340. if (values.hourMinute) {
  341. // 转换为utc hour
  342. const time = this.$moment(values.hourMinute)
  343. values.cycleTimer.hour = time.subtract(time.utcOffset(), 'minutes').hour()
  344. values.cycleTimer.minute = values.hourMinute.minutes()
  345. delete values.hourMinute
  346. }
  347. if (values.startEndTime && values.startEndTime.length > 0) {
  348. values.cycleTimer.startTime = values.startEndTime[0].set({
  349. hour: 0,
  350. minute: 0,
  351. second: 0,
  352. })
  353. values.cycleTimer.endTime = values.startEndTime[1].set({
  354. hour: 23,
  355. minute: 59,
  356. second: 59,
  357. })
  358. delete values.startEndTime
  359. }
  360. if (values.alarm) {
  361. values.alarm.wrapper = 'average'
  362. }
  363. return values
  364. },
  365. async handleConfirm () {
  366. const manager = new this.$Manager('scalingpolicies', 'v1')
  367. const { validateFields } = this.form.fc
  368. const defaultParams = {
  369. unit: 's',
  370. scaling_group: this.params.resData.id,
  371. }
  372. try {
  373. const values = await validateFields()
  374. this.formatValues(values)
  375. this.loading = true
  376. await manager.create({
  377. data: Object.assign({}, defaultParams, this.formatValues(values)),
  378. })
  379. this.params.refresh()
  380. this.cancelDialog()
  381. } catch (err) {
  382. throw err
  383. } finally {
  384. this.loading = false
  385. }
  386. },
  387. },
  388. }
  389. </script>