Form.vue 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. <template>
  2. <Dialog :title="dialogTitle" v-model="dialogVisible">
  3. <el-form
  4. ref="formRef"
  5. :model="formData"
  6. :rules="formRules"
  7. label-width="120px"
  8. v-loading="formLoading"
  9. >
  10. <el-form-item :label="t('mall.showStores')" prop="shopId">
  11. <el-select
  12. v-model="formData.shopId"
  13. :placeholder="t('mall.selectStore')"
  14. >
  15. <el-option
  16. v-for="item in shopList"
  17. :key="item.id"
  18. :label="item.name"
  19. :value="item.id"
  20. />
  21. </el-select>
  22. </el-form-item>
  23. <el-form-item :label="t('mall.availableType')" prop="type">
  24. <el-radio-group v-model="formData.type">
  25. <el-radio :label="0">{{t('mall.generalPurpose')}}</el-radio>
  26. <el-radio :label="1">{{t('mall.used')}}</el-radio>
  27. <el-radio :label="2">{{t('mall.unused')}}</el-radio>
  28. </el-radio-group>
  29. </el-form-item>
  30. <el-form-item :label="t('mall.redeemCode')" prop="exchangeCode">
  31. <el-input v-model="formData.exchangeCode" :placeholder="t('mall.pleaseEnterTheRedemptionCode')" />
  32. </el-form-item>
  33. <el-form-item :label="t('mall.picture')" prop="image">
  34. <Materials v-model="formData.image" num="1" type="image" />
  35. </el-form-item>
  36. <el-form-item :label="t('mall.couponName')" prop="title">
  37. <el-input v-model="formData.title" :placeholder="t('mall.pleaseEnterTheNameOfTheCoupon')" />
  38. </el-form-item>
  39. <el-form-item :label="t('mall.howMuchToSpend')" prop="least">
  40. <el-input v-model="formData.least" :placeholder="t('mall.pleaseEnterTheAmountOfMoneySpent')" />
  41. </el-form-item>
  42. <el-form-item :label="t('mall.couponAmount')" prop="value">
  43. <el-input v-model="formData.value" :placeholder="t('mall.pleaseEnterTheAmountOfTheCoupon')" />
  44. </el-form-item>
  45. <el-form-item :label="t('mall.startTime')" prop="startTime">
  46. <el-date-picker
  47. v-model="formData.startTime"
  48. type="date"
  49. value-format="x"
  50. :placeholder="t('mall.selectStartTime')"
  51. />
  52. </el-form-item>
  53. <el-form-item :label="t('mall.closingTime')" prop="endTime">
  54. <el-date-picker
  55. v-model="formData.endTime"
  56. type="date"
  57. value-format="x"
  58. :placeholder="t('mall.selectTheEndTime')"
  59. />
  60. </el-form-item>
  61. <el-form-item :label="t('mall.numberOfIssues')" prop="distribute">
  62. <el-input v-model="formData.distribute" :placeholder="t('mall.pleaseEnterTheNumberOfIssues')" />
  63. </el-form-item>
  64. <el-form-item :label="t('mall.pointsRequired')" prop="score">
  65. <el-input v-model="formData.score" :placeholder="t('mall.pleaseEnterTheNumberOfPointsRequired')" />
  66. </el-form-item>
  67. <el-form-item :label="t('mall.limit')" prop="limit">
  68. <el-input v-model="formData.limit" :placeholder="t('mall.pleaseEnterTheQuantityLimit')" />
  69. </el-form-item>
  70. <el-form-item :label="t('mall.instructionsForUse')" prop="instructions">
  71. <el-input type="textarea" rows="5" v-model="formData.instructions" :placeholder="t('mall.pleaseEnterTheInstructionsForUse')" />
  72. </el-form-item>
  73. <el-form-item :label="t('mall.whetherItIsOnTheShelfOrNot')" prop="isSwitch">
  74. <el-radio-group v-model="formData.isSwitch">
  75. <el-radio :label="1">{{t('common.yes')}}</el-radio>
  76. <el-radio :label="0">{{t('common.no')}}</el-radio>
  77. </el-radio-group>
  78. </el-form-item>
  79. </el-form>
  80. <template #footer>
  81. <el-button @click="submitForm" type="primary" :disabled="formLoading">{{t('common.confirm')}}</el-button>
  82. <el-button @click="dialogVisible = false">{{t('common.cancel')}}</el-button>
  83. </template>
  84. </Dialog>
  85. </template>
  86. <script setup lang="ts">
  87. import * as Api from '@/api/mall/coupon/'
  88. import * as ShopApi from '@/api/mall/store/shop'
  89. const { t } = useI18n() // 国际化
  90. const message = useMessage() // 消息弹窗
  91. const dialogVisible = ref(false) // 弹窗的是否展示
  92. const dialogTitle = ref('') // 弹窗的标题
  93. const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
  94. const formType = ref('') // 表单的类型:create - 新增;update - 修改
  95. const formData = ref({
  96. id: undefined,
  97. shopId: undefined,
  98. shopName: undefined,
  99. title: undefined,
  100. isSwitch: undefined,
  101. least: undefined,
  102. value: undefined,
  103. startTime: undefined,
  104. endTime: undefined,
  105. weigh: undefined,
  106. type: undefined,
  107. exchangeCode: undefined,
  108. receive: undefined,
  109. distribute: undefined,
  110. score: undefined,
  111. instructions: undefined,
  112. image: undefined,
  113. limit: undefined
  114. })
  115. const shopList = ref([])
  116. const formRules = reactive({
  117. shopId: [{ required: true, message: t('mall.storeId0MeansGenericCantBeEmpty'), trigger: 'blur' }],
  118. title: [{ required: true, message: t('mall.couponNameCannotBeEmpty'), trigger: 'blur' }],
  119. least: [{ required: true, message: t('mall.consumptionOfHowMuchIsAvailableCanNotBeEmpty'), trigger: 'blur' }],
  120. value: [{ required: true, message: t('mall.couponAmountCannotBeEmpty'), trigger: 'blur' }],
  121. startTime: [{ required: true, message: t('mall.startTimeCannotBeEmpty'), trigger: 'blur' }],
  122. endTime: [{ required: true, message: t('mall.endTimeCannotBeEmpty'), trigger: 'blur' }],
  123. type: [{ required: true, message: t('mall.availableTypeCannotBeEmpty'), trigger: 'blur' }],
  124. distribute: [{ required: true, message: t('mall.theNumberOfCouponsIssuedCannotBeEmpty'), trigger: 'blur' }],
  125. limit: [{ required: true, message: t('mall.limitOnNumberOfCouponsCannotBeEmpty'), trigger: 'blur' }],
  126. instructions: [{ required: true, message: t('mall.descriptionOfUseCannotBeEmpty'), trigger: 'blur' }]
  127. })
  128. const formRef = ref() // 表单 Ref
  129. /** 打开弹窗 */
  130. const open = async (type: string, id?: number) => {
  131. dialogVisible.value = true
  132. dialogTitle.value = t('action.' + type)
  133. formType.value = type
  134. resetForm()
  135. getList()
  136. // 修改时,设置数据
  137. if (id) {
  138. formLoading.value = true
  139. try {
  140. formData.value = await Api.getCoupon(id)
  141. formData.value.shopId = Number(formData.value.shopId)
  142. } finally {
  143. formLoading.value = false
  144. }
  145. }
  146. }
  147. defineExpose({ open }) // 提供 open 方法,用于打开弹窗
  148. /** 提交表单 */
  149. const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
  150. const submitForm = async () => {
  151. // 校验表单
  152. if (!formRef) return
  153. const valid = await formRef.value.validate()
  154. if (!valid) return
  155. // 提交请求
  156. formLoading.value = true
  157. try {
  158. const data = formData.value as unknown as Api.VO
  159. if (formType.value === 'create') {
  160. await Api.createCoupon(data)
  161. message.success(t('common.createSuccess'))
  162. } else {
  163. await Api.updateCoupon(data)
  164. message.success(t('common.updateSuccess'))
  165. }
  166. dialogVisible.value = false
  167. // 发送操作成功的事件
  168. emit('success')
  169. } finally {
  170. formLoading.value = false
  171. }
  172. }
  173. const getList = async () => {
  174. try {
  175. const data = await ShopApi.getShopList()
  176. shopList.value = data
  177. } finally {
  178. }
  179. }
  180. /** 重置表单 */
  181. const resetForm = () => {
  182. formData.value = {
  183. id: undefined,
  184. shopId: undefined,
  185. shopName: undefined,
  186. title: undefined,
  187. isSwitch: 1,
  188. least: undefined,
  189. value: undefined,
  190. startTime: undefined,
  191. endTime: undefined,
  192. weigh: undefined,
  193. type: 0,
  194. exchangeCode: undefined,
  195. receive: undefined,
  196. distribute: undefined,
  197. score: undefined,
  198. instructions: undefined,
  199. image: undefined,
  200. limit: undefined
  201. }
  202. formRef.value?.resetFields()
  203. }
  204. </script>