BigQueryBillForm.vue 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. <template>
  2. <div>
  3. <a-alert :showIcon="false" :message="$t('cloudenv.text_194')" banner />
  4. <a-form class="pt-3" :form="form.fc" v-bind="formLayout">
  5. <a-divider orientation="left">{{$t('cloudenv.text_199')}}</a-divider>
  6. <a-form-item :label="$t('cloudenv.text_200')">
  7. <a-radio-group v-model="billingType">
  8. <a-radio-button :value="1">{{$t('cloudenv.text_201')}}</a-radio-button>
  9. <a-radio-button :value="2">{{$t('cloudenv.text_202')}}</a-radio-button>
  10. </a-radio-group>
  11. </a-form-item>
  12. <a-form-item
  13. :label="$t('cloudenv.text_201')"
  14. v-if="billingType === 2"
  15. :extra="$t('cloudenv.text_203')">
  16. <a-select
  17. :filterOption="filterOption"
  18. showSearch
  19. :loading="cloudAccountLoading"
  20. v-decorator="decorators.billing_bigquery_account">
  21. <template v-for="item in cloudAccounts">
  22. <a-select-option v-if="id !== item.id" :key="item.id" :value="item.id">{{item.name}}</a-select-option>
  23. </template>
  24. </a-select>
  25. </a-form-item>
  26. <a-form-item :label="$t('cloudenv.text_2041')">
  27. <a-input v-decorator="decorators.billing_bigquery_table" />
  28. </a-form-item>
  29. <a-form-item :label="$t('cloudenv.billing_scope')">
  30. <a-radio-group v-decorator="decorators.billing_scope">
  31. <a-radio-button value="managed" key="managed">{{ $t('cloudenv.billing_scope.managed') }}</a-radio-button>
  32. <a-radio-button value="all" key="all">{{ $t('cloudenv.billing_scope.all') }}</a-radio-button>
  33. </a-radio-group>
  34. </a-form-item>
  35. <a-form-item :label="$t('cloudenv.text_210')" :extra="$t('cloudenv.text_211')">
  36. <a-switch v-decorator="decorators.sync_info" />
  37. </a-form-item>
  38. <a-form-item
  39. :label="$t('cloudenv.text_212')"
  40. v-if="form.fc.getFieldValue('sync_info')"
  41. :extra="$t('cloudenv.text_213')">
  42. <a-form-item style="display:inline-block">
  43. <a-month-picker
  44. v-decorator="decorators.start_day"
  45. :disabled-date="dateDisabledStart"
  46. format="YYYY-MM" />
  47. </a-form-item>
  48. <span class="ml-2 mr-2">~</span>
  49. <a-form-item style="display:inline-block">
  50. <a-month-picker
  51. v-decorator="decorators.end_day"
  52. :disabled-date="dateDisabledEnd"
  53. format="YYYY-MM" />
  54. </a-form-item>
  55. </a-form-item>
  56. </a-form>
  57. </div>
  58. </template>
  59. <script>
  60. import * as R from 'ramda'
  61. import DialogMixin from '@/mixins/dialog'
  62. import WindowsMixin from '@/mixins/windows'
  63. export default {
  64. name: 'BigQueryBillForm',
  65. mixins: [DialogMixin, WindowsMixin],
  66. props: {
  67. account: {
  68. type: Object,
  69. },
  70. },
  71. data () {
  72. return {
  73. loading: false,
  74. cloudAccounts: [],
  75. cloudAccountLoading: false,
  76. cloudAccount: {},
  77. billingType: 1,
  78. form: {
  79. fc: this.$form.createForm(this),
  80. },
  81. billTasks: {
  82. '7 days': this.$t('cloudenv.text_214'),
  83. '1 months': this.$t('cloudenv.text_215'),
  84. '3 months': this.$t('cloudenv.text_216'),
  85. '6 months': this.$t('cloudenv.text_217'),
  86. },
  87. formLayout: {
  88. wrapperCol: {
  89. md: { span: 18 },
  90. xl: { span: 20 },
  91. xxl: { span: 22 },
  92. },
  93. labelCol: {
  94. md: { span: 6 },
  95. xl: { span: 3 },
  96. xxl: { span: 2 },
  97. },
  98. },
  99. offsetFormLayout: {
  100. wrapperCol: {
  101. md: { span: 18, offset: 6 },
  102. xl: { span: 20, offset: 3 },
  103. xxl: { span: 22, offset: 2 },
  104. },
  105. },
  106. }
  107. },
  108. computed: {
  109. id () {
  110. return (this.account && this.account.id) || (this.cloudAccount && this.cloudAccount.id)
  111. },
  112. provider () {
  113. const { provider } = this.$route.query
  114. return provider || (this.cloudAccount && this.cloudAccount.provider)
  115. },
  116. isGoogle () {
  117. return this.provider === 'Google'
  118. },
  119. decorators () {
  120. const { options = {} } = this.cloudAccount
  121. return {
  122. billing_bigquery_account: [
  123. 'billing_bigquery_account',
  124. {
  125. initialValue: options.billing_bigquery_account,
  126. },
  127. ],
  128. billing_bigquery_table: [
  129. 'billing_bigquery_table',
  130. {
  131. initialValue: options.billing_bigquery_table,
  132. rules: [
  133. { required: true, message: this.$t('cloudenv.text_220') },
  134. ],
  135. },
  136. ],
  137. sync_info: [
  138. 'sync_info',
  139. {
  140. initialValue: false,
  141. valuePropName: 'checked',
  142. },
  143. ],
  144. start_day: ['start_day', {
  145. initialValue: this.$moment().startOf('month'),
  146. rules: [{ required: true, message: this.$t('common.tips.select', [this.$t('cloudenv.text_461')]) }],
  147. }],
  148. end_day: ['end_day', {
  149. initialValue: this.$moment(),
  150. rules: [{ required: true, message: this.$t('common.tips.select', [this.$t('cloudenv.text_462')]) }],
  151. }],
  152. billing_scope: [
  153. 'billing_scope',
  154. {
  155. initialValue: options.billing_scope || 'managed',
  156. rules: [
  157. { required: true, message: this.$t('cloudenv.billing_scope.prompt') },
  158. ],
  159. },
  160. ],
  161. }
  162. },
  163. },
  164. created () {
  165. this.manager = new this.$Manager('cloudaccounts')
  166. this.fetchs()
  167. },
  168. methods: {
  169. async fetchs () {
  170. await this.fetchCloudAccount()
  171. await this.fetchCloudAccounts()
  172. },
  173. filterOption (input, option) {
  174. return (
  175. option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
  176. )
  177. },
  178. async fetchCloudAccounts () {
  179. const { id } = this.$route.query
  180. if (!id) {
  181. return false
  182. }
  183. this.cloudAccountLoading = true
  184. try {
  185. const params = {
  186. scope: this.$store.getters.scope,
  187. brand: this.provider || this.cloudAccount.brand,
  188. }
  189. const { data } = await this.manager.list({ params })
  190. this.cloudAccounts = data.data || []
  191. } catch (err) {
  192. throw err
  193. } finally {
  194. this.cloudAccountLoading = false
  195. }
  196. },
  197. async fetchCloudAccount () {
  198. const { id } = this.$route.query
  199. if (!id) {
  200. this.cloudAccount = this.account
  201. return false
  202. }
  203. try {
  204. const { data } = await this.manager.get({
  205. id,
  206. params: {
  207. details: true,
  208. },
  209. })
  210. // billing_scope没有时默认选中一个
  211. if (!data.options || !data.options.billing_scope) {
  212. data.options = data.options || {}
  213. data.options.billing_scope = data.options.billing_scope || 'managed'
  214. }
  215. this.cloudAccount = data
  216. if (data && data.options && data.options.billing_bucket_account) {
  217. this.billingType = 2
  218. }
  219. return data
  220. } catch (err) {
  221. throw err
  222. }
  223. },
  224. dateDisabledStart (value) {
  225. const dateEnd = this.form.fc.getFieldValue('end_day')
  226. if (dateEnd && value > dateEnd) return true
  227. if (value > this.$moment()) return true
  228. return false
  229. },
  230. dateDisabledEnd (value) {
  231. const dateStart = this.form.fc.getFieldValue('start_day')
  232. if (dateStart && value < dateStart) return true
  233. if (value > this.$moment()) return true
  234. return false
  235. },
  236. async postBillTasks (id, values) {
  237. const manager = new this.$Manager('billtasks/submit', 'v1')
  238. try {
  239. const { start_day, end_day } = values
  240. const data = {
  241. account_id: id,
  242. start_day: parseInt(this.$moment(start_day).startOf('month').format('YYYYMMDD')),
  243. end_day: parseInt(this.$moment(end_day).endOf('month').format('YYYYMMDD')),
  244. task_type: 'pull_bill',
  245. }
  246. await manager.create({
  247. data,
  248. })
  249. } catch (err) {
  250. throw err
  251. }
  252. },
  253. async doSubmit ({ id } = this.cloudAccount, isGoCloudaccount = true) {
  254. try {
  255. const values = await this.form.fc.validateFields()
  256. if (values.sync_info) {
  257. this.postBillTasks(id, values)
  258. }
  259. delete values.sync_info
  260. delete values.start_day
  261. delete values.end_day
  262. const p = { ...values }
  263. for (const key in p) {
  264. if (R.is(String, p[key])) {
  265. p[key] = p[key].trim()
  266. }
  267. }
  268. const params = {
  269. id,
  270. data: {
  271. options: p,
  272. },
  273. }
  274. if (this.billingType === 1) {
  275. params.data = {
  276. remove_options: ['billing_bucket_account'],
  277. ...params.data,
  278. }
  279. }
  280. await this.manager.update(params)
  281. // if (isGoCloudaccount) {
  282. // this.$router.push('/cloudaccount')
  283. // }
  284. } catch (err) {
  285. throw err
  286. }
  287. },
  288. async testPost () {
  289. const values = await this.form.fc.validateFields()
  290. values.cloudaccount_id = this.id
  291. delete values.sync_info
  292. delete values.month
  293. const p = { ...values }
  294. for (const key in p) {
  295. if (R.is(String, p[key])) {
  296. p[key] = p[key].trim()
  297. }
  298. }
  299. const res = await new this.$Manager('bigquery_options', 'v1').performClassAction({
  300. action: 'verify',
  301. data: p,
  302. })
  303. if (!res || !res.data || !res.data.status) return false
  304. if (res.data.status === 'success') {
  305. this.$notification.success({
  306. message: this.$t('common_270'),
  307. description: this.$t('common_271'),
  308. })
  309. } else if (res.data.msg && res.data.msg === 'bucket file not found') {
  310. this.$notification.warning({
  311. message: this.$t('cloudenv.text_577'),
  312. description: (
  313. <div>
  314. {this.$t('cloudenv.text_578')}<br />{this.$t('cloudenv.text_579')}
  315. </div>
  316. ),
  317. })
  318. } else return false
  319. },
  320. },
  321. }
  322. </script>
  323. <style scoped>
  324. </style>