Create.vue 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. <template>
  2. <base-dialog @cancel="cancelDialog">
  3. <div slot="header">{{ params.type === 'create_billtask' ? $t('common.create') : $t('bill.rerun_bill') }}</div>
  4. <div slot="body">
  5. <a-form-model
  6. ref="form"
  7. class="mt-3"
  8. :model="form"
  9. :rules="rules">
  10. <a-form-model-item :label="$t('cloudenv.task_type')" v-bind="formItemLayout" prop="task_type">
  11. <base-select
  12. v-model="form.task_type"
  13. :options="taskTypeOpts"
  14. :select-props="{placeholder: $t('common.tips.select', [$t('cloudenv.task_type')])}"
  15. :disabled-items="disabledActions"
  16. @change="taskTypeChange" />
  17. </a-form-model-item>
  18. <a-form-model-item v-if="isMonthShow" :label="$t('cloudenv.text_212')" v-bind="formItemLayout" prop="start_day">
  19. <span slot="extra" style="color:red;">{{ blockTip }}</span>
  20. <a-form-model-item style="display:inline-block" prop="start_day">
  21. <a-month-picker v-model="form.start_day" :disabled-date="dateDisabledStart" @change="startChange" :disabled="ignore_time" />
  22. </a-form-model-item>
  23. <span class="ml-2 mr-2">~</span>
  24. <a-form-model-item style="display:inline-block" prop="end_day">
  25. <a-month-picker v-model="form.end_day" :disabled-date="dateDisabledEnd" :disabled="ignore_time" />
  26. </a-form-model-item>
  27. <a-checkbox class="ml-2" v-model="ignore_time">{{$t('cloudenv.run_all_bills')}}</a-checkbox>
  28. </a-form-model-item>
  29. </a-form-model>
  30. </div>
  31. <div slot="footer">
  32. <a-button type="primary" @click="handleConfirm" :loading="loading">{{ $t('dialog.ok') }}</a-button>
  33. <a-button @click="cancelDialog">{{ $t('dialog.cancel') }}</a-button>
  34. </div>
  35. </base-dialog>
  36. </template>
  37. <script>
  38. import DialogMixin from '@/mixins/dialog'
  39. import WindowsMixin from '@/mixins/windows'
  40. export default {
  41. name: 'BilltasksCreateDialog',
  42. components: {
  43. },
  44. mixins: [DialogMixin, WindowsMixin],
  45. data () {
  46. const TaskTypeList = ['pull_bill', 'prepaid_amortizing', 'project_sharing', 'recalculate', 'predict', 'delete_bill', 'sync_product'].filter(key => {
  47. const { cost_conversion_available, enable_prediction } = this.$store.state.common.bill?.globalConfig || {}
  48. if (key === 'recalculate' && !cost_conversion_available) return false
  49. if (key === 'predict' && !enable_prediction) return false
  50. return true
  51. })
  52. const { data = [] } = this.params
  53. const initDisabledActions = []
  54. if (data.some(item => item.status === 'deleted')) {
  55. initDisabledActions.push('pull_bill', 'prepaid_amortizing', 'project_sharing', 'recalculate', 'predict')
  56. }
  57. let initTaskType = 'pull_bill'
  58. for (let i = 0; i < TaskTypeList.length; i++) {
  59. if (!initDisabledActions.includes(TaskTypeList[i])) {
  60. initTaskType = TaskTypeList[i]
  61. break
  62. }
  63. }
  64. return {
  65. loading: false,
  66. accountLoading: false,
  67. formItemLayout: {
  68. wrapperCol: {
  69. span: 21,
  70. },
  71. labelCol: {
  72. span: 3,
  73. },
  74. },
  75. form: {
  76. account_id: data.map(item => item.id),
  77. task_type: initTaskType,
  78. start_day: this.$moment(),
  79. end_day: this.$moment(),
  80. },
  81. rules: {
  82. account_id: [{ required: true, message: this.$t('common.tips.select', [this.$t('dictionary.cloudaccount')]) }],
  83. task_type: [{ required: true, message: this.$t('common.tips.select', [this.$t('cloudenv.task_type')]) }],
  84. start_day: [{ required: true, message: this.$t('common.tips.select', [this.$t('cloudenv.text_461')]) }],
  85. end_day: [{ required: true, message: this.$t('common.tips.select', [this.$t('cloudenv.text_462')]) }],
  86. },
  87. taskTypeOpts: TaskTypeList.map(id => {
  88. return {
  89. id,
  90. name: this.$t(`cloudenv.task_type.${id}`),
  91. }
  92. }),
  93. accountParams: {
  94. scope: this.$store.getters.scope,
  95. },
  96. disabledActions: initDisabledActions,
  97. blockMonths: [],
  98. ignore_time: false,
  99. }
  100. },
  101. computed: {
  102. isMonthShow () {
  103. return !(this.form.task_type === 'delete_bill' && this.params.data.some(item => item.status === 'deleted'))
  104. },
  105. start () {
  106. return this.$moment(this.form.start_day).format('YYYY-MM')
  107. },
  108. end () {
  109. return this.$moment(this.form.end_day).format('YYYY-MM')
  110. },
  111. selectedMonths () {
  112. const list = []
  113. const start = this.$moment(this.start)
  114. const end = this.$moment(this.end)
  115. // eslint-disable-next-line
  116. while (end > start || start.format('M') === end.format('M')) {
  117. list.push(start.format('YYYYMM'))
  118. start.add(1, 'month')
  119. }
  120. return list
  121. },
  122. blockTip () {
  123. const blockMonths = []
  124. this.selectedMonths.map(month => {
  125. if (this.blockMonths.includes(month)) {
  126. blockMonths.push(`${month.slice(0, 4)}-${month.slice(4, 6)}`)
  127. }
  128. })
  129. return blockMonths.length ? this.$t('cloudenv.block_month_tip', [blockMonths.join('、')]) : ''
  130. },
  131. },
  132. watch: {
  133. 'form.task_type': {
  134. handler (val, oldVal) {
  135. if (oldVal === 'predict') {
  136. this.form.start_day = this.$moment()
  137. this.form.end_day = this.$moment()
  138. }
  139. },
  140. },
  141. start: {
  142. handler (val) {
  143. this.fetchBlockAccount()
  144. },
  145. },
  146. end: {
  147. handler (val) {
  148. this.fetchBlockAccount()
  149. },
  150. },
  151. },
  152. created () {
  153. this.$bM = new this.$Manager('billtasks/submit', 'v1')
  154. this.fetchBlockAccount()
  155. },
  156. methods: {
  157. fetchBlockAccount () {
  158. new this.$Manager('blocking_accounts', 'v1').list({
  159. params: {
  160. enabled: true,
  161. filter: [`month.in(${this.selectedMonths.join(',')})`, `account_id.in(${this.params.account_id})`],
  162. },
  163. }).then(res => {
  164. const { data = [] } = res.data
  165. this.blockMonths = data.map(item => `${item.month}`)
  166. })
  167. },
  168. startChange (value) {
  169. const dateEnd = this.form.end_day
  170. if (dateEnd && value > dateEnd) {
  171. this.form.end_day = value
  172. }
  173. },
  174. dateDisabledStart (value) {
  175. if (this.params.accountData?.provider === 'extdb' && this.form.task_type === 'pull_bill') return false
  176. if (value > this.$moment()) return this.form.task_type !== 'predict'
  177. return false
  178. },
  179. dateDisabledEnd (value) {
  180. const dateStart = this.form.start_day
  181. if (dateStart && value < dateStart) return true
  182. if (this.params.accountData?.provider === 'extdb' && this.form.task_type === 'pull_bill') return false
  183. if (value > this.$moment()) return this.form.task_type !== 'predict'
  184. return false
  185. },
  186. validateForm () {
  187. return new Promise((resolve, reject) => {
  188. this.$refs.form.validate((valid, err) => {
  189. if (valid) {
  190. resolve(valid)
  191. } else {
  192. reject(err)
  193. }
  194. })
  195. })
  196. },
  197. async handleConfirm () {
  198. this.loading = true
  199. try {
  200. const validate = await this.validateForm()
  201. if (!validate) return
  202. const data = {
  203. account_id: this.params.data.map(item => item.id),
  204. task_type: this.form.task_type,
  205. }
  206. if (this.isMonthShow && !this.ignore_time) {
  207. data.start_day = parseInt(this.$moment(this.form.start_day).startOf('month').format('YYYYMMDD'))
  208. data.end_day = parseInt(this.$moment(this.form.end_day).endOf('month').format('YYYYMMDD'))
  209. }
  210. await this.$bM.create({
  211. data,
  212. })
  213. this.params.success && this.params.success()
  214. this.loading = false
  215. this.cancelDialog()
  216. } catch (error) {
  217. this.loading = false
  218. }
  219. },
  220. },
  221. }
  222. </script>
  223. <style lang="less" scoped>
  224. .share-label {
  225. .share-text {
  226. width: 50px;
  227. text-align: center;
  228. display: inline-block;
  229. height: 32px;
  230. padding: 0 5px;
  231. border: 1px solid #d9d9d9;
  232. line-height: 31px;
  233. }
  234. }
  235. </style>