mirror of
				https://gitee.com/hhyykk/ipms-sjy-ui.git
				synced 2025-11-04 12:18:43 +08:00 
			
		
		
		
	code review:优惠劵逻辑
This commit is contained in:
		@@ -215,15 +215,15 @@ export const CouponTemplateValidityTypeEnum = {
 | 
				
			|||||||
export const PromotionProductScopeEnum = {
 | 
					export const PromotionProductScopeEnum = {
 | 
				
			||||||
  ALL: {
 | 
					  ALL: {
 | 
				
			||||||
    scope: 1,
 | 
					    scope: 1,
 | 
				
			||||||
    name: '全部商品参与'
 | 
					    name: '通用劵'
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  SPU: {
 | 
					  SPU: {
 | 
				
			||||||
    scope: 2,
 | 
					    scope: 2,
 | 
				
			||||||
    name: '指定商品参与'
 | 
					    name: '商品劵'
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  CATEGORY: {
 | 
					  CATEGORY: {
 | 
				
			||||||
    scope: 3,
 | 
					    scope: 3,
 | 
				
			||||||
    name: '指定品类参与'
 | 
					    name: '品类劵'
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,7 @@ const props = defineProps({
 | 
				
			|||||||
  multiple: propTypes.bool.def(false) // 是否多选
 | 
					  multiple: propTypes.bool.def(false) // 是否多选
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** 选中的分类ID */
 | 
					/** 选中的分类 ID */
 | 
				
			||||||
const selectCategoryId = computed({
 | 
					const selectCategoryId = computed({
 | 
				
			||||||
  get: () => {
 | 
					  get: () => {
 | 
				
			||||||
    return props.value
 | 
					    return props.value
 | 
				
			||||||
@@ -37,8 +37,8 @@ const selectCategoryId = computed({
 | 
				
			|||||||
/** 分类选择 */
 | 
					/** 分类选择 */
 | 
				
			||||||
const emit = defineEmits(['update:modelValue'])
 | 
					const emit = defineEmits(['update:modelValue'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** 初始化 **/
 | 
				
			||||||
const categoryList = ref([]) // 分类树
 | 
					const categoryList = ref([]) // 分类树
 | 
				
			||||||
 | 
					 | 
				
			||||||
onMounted(async () => {
 | 
					onMounted(async () => {
 | 
				
			||||||
  // 获得分类树
 | 
					  // 获得分类树
 | 
				
			||||||
  const data = await ProductCategoryApi.getCategoryList({})
 | 
					  const data = await ProductCategoryApi.getCategoryList({})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <Dialog v-model="dialogVisible" :appendToBody="true" title="发送优惠券" width="70%">
 | 
					  <Dialog v-model="dialogVisible" :appendToBody="true" title="发送优惠券" width="70%">
 | 
				
			||||||
 | 
					    <!-- 搜索工作栏 -->
 | 
				
			||||||
    <el-form
 | 
					    <el-form
 | 
				
			||||||
      ref="queryFormRef"
 | 
					      ref="queryFormRef"
 | 
				
			||||||
      :inline="true"
 | 
					      :inline="true"
 | 
				
			||||||
@@ -27,6 +28,8 @@
 | 
				
			|||||||
        </el-button>
 | 
					        </el-button>
 | 
				
			||||||
      </el-form-item>
 | 
					      </el-form-item>
 | 
				
			||||||
    </el-form>
 | 
					    </el-form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <!-- 列表 -->
 | 
				
			||||||
    <el-table v-loading="loading" :data="list" show-overflow-tooltip>
 | 
					    <el-table v-loading="loading" :data="list" show-overflow-tooltip>
 | 
				
			||||||
      <el-table-column align="center" label="优惠券名称" prop="name" min-width="60" />
 | 
					      <el-table-column align="center" label="优惠券名称" prop="name" min-width="60" />
 | 
				
			||||||
      <el-table-column
 | 
					      <el-table-column
 | 
				
			||||||
@@ -41,7 +44,7 @@
 | 
				
			|||||||
        label="最低消费"
 | 
					        label="最低消费"
 | 
				
			||||||
        prop="usePrice"
 | 
					        prop="usePrice"
 | 
				
			||||||
        min-width="60"
 | 
					        min-width="60"
 | 
				
			||||||
        :formatter="userPriceFormat"
 | 
					        :formatter="usePriceFormat"
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
      <el-table-column
 | 
					      <el-table-column
 | 
				
			||||||
        align="center"
 | 
					        align="center"
 | 
				
			||||||
@@ -72,6 +75,7 @@
 | 
				
			|||||||
      </el-table-column>
 | 
					      </el-table-column>
 | 
				
			||||||
    </el-table>
 | 
					    </el-table>
 | 
				
			||||||
    <!-- 分页 -->
 | 
					    <!-- 分页 -->
 | 
				
			||||||
 | 
					    <!-- TODO 疯狂:可以看看,为啥弹窗没把分页包进去,可能和 footer 有关? -->
 | 
				
			||||||
    <Pagination
 | 
					    <Pagination
 | 
				
			||||||
      v-model:limit="queryParams.pageSize"
 | 
					      v-model:limit="queryParams.pageSize"
 | 
				
			||||||
      v-model:page="queryParams.pageNo"
 | 
					      v-model:page="queryParams.pageNo"
 | 
				
			||||||
@@ -80,18 +84,17 @@
 | 
				
			|||||||
    />
 | 
					    />
 | 
				
			||||||
  </Dialog>
 | 
					  </Dialog>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					 | 
				
			||||||
<script lang="ts" setup>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
import * as CouponTemplateApi from '@/api/mall/promotion/coupon/couponTemplate'
 | 
					import * as CouponTemplateApi from '@/api/mall/promotion/coupon/couponTemplate'
 | 
				
			||||||
import * as CouponApi from '@/api/mall/promotion/coupon/coupon'
 | 
					import * as CouponApi from '@/api/mall/promotion/coupon/coupon'
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  discountFormat,
 | 
					  discountFormat,
 | 
				
			||||||
  remainedCountFormat,
 | 
					  remainedCountFormat,
 | 
				
			||||||
  userPriceFormat,
 | 
					  usePriceFormat,
 | 
				
			||||||
  validityTypeFormat
 | 
					  validityTypeFormat
 | 
				
			||||||
} from '@/views/mall/promotion/coupon/formatter'
 | 
					} from '@/views/mall/promotion/coupon/formatter'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defineOptions({ name: 'PromotionCouponSend' })
 | 
					defineOptions({ name: 'PromotionCouponSendForm' })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const message = useMessage() // 消息弹窗
 | 
					const message = useMessage() // 消息弹窗
 | 
				
			||||||
const total = ref(0) // 列表的总页数
 | 
					const total = ref(0) // 列表的总页数
 | 
				
			||||||
@@ -147,7 +150,7 @@ const handleSendCoupon = async (templateId: number) => {
 | 
				
			|||||||
  try {
 | 
					  try {
 | 
				
			||||||
    sendLoading.value = true
 | 
					    sendLoading.value = true
 | 
				
			||||||
    await CouponApi.sendCoupon({ templateId, userIds })
 | 
					    await CouponApi.sendCoupon({ templateId, userIds })
 | 
				
			||||||
 | 
					    // 提示
 | 
				
			||||||
    message.success('发送成功')
 | 
					    message.success('发送成功')
 | 
				
			||||||
    dialogVisible.value = false
 | 
					    dialogVisible.value = false
 | 
				
			||||||
  } finally {
 | 
					  } finally {
 | 
				
			||||||
@@ -39,6 +39,6 @@ export const remainedCountFormat = (row: CouponTemplateVO) => {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 格式化【最低消费】
 | 
					// 格式化【最低消费】
 | 
				
			||||||
export const userPriceFormat = (row: CouponTemplateVO) => {
 | 
					export const usePriceFormat = (row: CouponTemplateVO) => {
 | 
				
			||||||
  return `¥${floatToFixed2(row.usePrice)}`
 | 
					  return `¥${floatToFixed2(row.usePrice)}`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,41 @@
 | 
				
			|||||||
      <el-form-item label="优惠券名称" prop="name">
 | 
					      <el-form-item label="优惠券名称" prop="name">
 | 
				
			||||||
        <el-input v-model="formData.name" placeholder="请输入优惠券名称" />
 | 
					        <el-input v-model="formData.name" placeholder="请输入优惠券名称" />
 | 
				
			||||||
      </el-form-item>
 | 
					      </el-form-item>
 | 
				
			||||||
      <el-form-item label="优惠券类型" prop="discountType">
 | 
					      <el-form-item label="优惠劵类型" prop="productScope">
 | 
				
			||||||
 | 
					        <el-radio-group v-model="formData.productScope">
 | 
				
			||||||
 | 
					          <el-radio
 | 
				
			||||||
 | 
					            v-for="dict in getIntDictOptions(DICT_TYPE.PROMOTION_PRODUCT_SCOPE)"
 | 
				
			||||||
 | 
					            :key="dict.value"
 | 
				
			||||||
 | 
					            :label="dict.value"
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            {{ dict.label }}
 | 
				
			||||||
 | 
					          </el-radio>
 | 
				
			||||||
 | 
					        </el-radio-group>
 | 
				
			||||||
 | 
					      </el-form-item>
 | 
				
			||||||
 | 
					      <el-form-item
 | 
				
			||||||
 | 
					        label="商品"
 | 
				
			||||||
 | 
					        v-if="formData.productScope === PromotionProductScopeEnum.SPU.scope"
 | 
				
			||||||
 | 
					        prop="productSpuIds"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <div class="flex items-center gap-1 flex-wrap">
 | 
				
			||||||
 | 
					          <div class="select-box spu-pic" v-for="(spu, index) in productSpus" :key="spu.id">
 | 
				
			||||||
 | 
					            <el-image :src="spu.picUrl" />
 | 
				
			||||||
 | 
					            <Icon icon="ep:circle-close-filled" class="del-icon" @click="handleRemoveSpu(index)" />
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          <div class="select-box" @click="openSpuTableSelect">
 | 
				
			||||||
 | 
					            <Icon icon="ep:plus" />
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </el-form-item>
 | 
				
			||||||
 | 
					      <!-- TODO 疯狂:要不把 productSpuIds 改成 productScopeValues,更通用?另外,改完后,涉及到优惠劵的匹配逻辑,要补充分类相关的逻辑,例如说获得匹配的优惠劵列表之类的,包括使用卷的时候; -->
 | 
				
			||||||
 | 
					      <el-form-item
 | 
				
			||||||
 | 
					        label="分类"
 | 
				
			||||||
 | 
					        v-if="formData.productScope === PromotionProductScopeEnum.CATEGORY.scope"
 | 
				
			||||||
 | 
					        prop="productCategoryIds"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <ProductCategorySelect v-model="formData.productCategoryIds" />
 | 
				
			||||||
 | 
					      </el-form-item>
 | 
				
			||||||
 | 
					      <el-form-item label="优惠类型" prop="discountType">
 | 
				
			||||||
        <el-radio-group v-model="formData.discountType">
 | 
					        <el-radio-group v-model="formData.discountType">
 | 
				
			||||||
          <el-radio
 | 
					          <el-radio
 | 
				
			||||||
            v-for="dict in getIntDictOptions(DICT_TYPE.PROMOTION_DISCOUNT_TYPE)"
 | 
					            v-for="dict in getIntDictOptions(DICT_TYPE.PROMOTION_DISCOUNT_TYPE)"
 | 
				
			||||||
@@ -147,37 +181,6 @@
 | 
				
			|||||||
        />
 | 
					        />
 | 
				
			||||||
        天有效
 | 
					        天有效
 | 
				
			||||||
      </el-form-item>
 | 
					      </el-form-item>
 | 
				
			||||||
      <el-form-item label="活动商品" prop="productScope">
 | 
					 | 
				
			||||||
        <el-radio-group v-model="formData.productScope">
 | 
					 | 
				
			||||||
          <el-radio
 | 
					 | 
				
			||||||
            v-for="dict in getIntDictOptions(DICT_TYPE.PROMOTION_PRODUCT_SCOPE)"
 | 
					 | 
				
			||||||
            :key="dict.value"
 | 
					 | 
				
			||||||
            :label="dict.value"
 | 
					 | 
				
			||||||
          >
 | 
					 | 
				
			||||||
            {{ dict.label }}
 | 
					 | 
				
			||||||
          </el-radio>
 | 
					 | 
				
			||||||
        </el-radio-group>
 | 
					 | 
				
			||||||
      </el-form-item>
 | 
					 | 
				
			||||||
      <el-form-item
 | 
					 | 
				
			||||||
        v-if="formData.productScope === PromotionProductScopeEnum.SPU.scope"
 | 
					 | 
				
			||||||
        prop="productSpuIds"
 | 
					 | 
				
			||||||
      >
 | 
					 | 
				
			||||||
        <div class="flex items-center gap-1 flex-wrap">
 | 
					 | 
				
			||||||
          <div class="select-box spu-pic" v-for="(spu, index) in productSpus" :key="spu.id">
 | 
					 | 
				
			||||||
            <el-image :src="spu.picUrl" />
 | 
					 | 
				
			||||||
            <Icon icon="ep:circle-close-filled" class="del-icon" @click="handleRemoveSpu(index)" />
 | 
					 | 
				
			||||||
          </div>
 | 
					 | 
				
			||||||
          <div class="select-box" @click="openSpuTableSelect">
 | 
					 | 
				
			||||||
            <Icon icon="ep:plus" />
 | 
					 | 
				
			||||||
          </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
      </el-form-item>
 | 
					 | 
				
			||||||
      <el-form-item
 | 
					 | 
				
			||||||
        v-if="formData.productScope === PromotionProductScopeEnum.CATEGORY.scope"
 | 
					 | 
				
			||||||
        prop="productCategoryIds"
 | 
					 | 
				
			||||||
      >
 | 
					 | 
				
			||||||
        <ProductCategorySelect v-model="formData.productCategoryIds" multiple />
 | 
					 | 
				
			||||||
      </el-form-item>
 | 
					 | 
				
			||||||
    </el-form>
 | 
					    </el-form>
 | 
				
			||||||
    <template #footer>
 | 
					    <template #footer>
 | 
				
			||||||
      <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
 | 
					      <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
 | 
				
			||||||
@@ -367,6 +370,7 @@ const getProductScope = async () => {
 | 
				
			|||||||
      productSpus.value = await ProductSpuApi.getSpuDetailList(formData.value.productSpuIds)
 | 
					      productSpus.value = await ProductSpuApi.getSpuDetailList(formData.value.productSpuIds)
 | 
				
			||||||
      break
 | 
					      break
 | 
				
			||||||
    case PromotionProductScopeEnum.CATEGORY.scope:
 | 
					    case PromotionProductScopeEnum.CATEGORY.scope:
 | 
				
			||||||
 | 
					      // TODO @疯狂:貌似分类不会选中。
 | 
				
			||||||
      formData.value.productCategoryIds = formData.value.productSpuIds
 | 
					      formData.value.productCategoryIds = formData.value.productSpuIds
 | 
				
			||||||
      formData.value.productSpuIds = []
 | 
					      formData.value.productSpuIds = []
 | 
				
			||||||
      break
 | 
					      break
 | 
				
			||||||
@@ -375,7 +379,7 @@ const getProductScope = async () => {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** 活动商品 按钮 */
 | 
					/** 活动商品的按钮 */
 | 
				
			||||||
const spuTableSelectRef = ref()
 | 
					const spuTableSelectRef = ref()
 | 
				
			||||||
const openSpuTableSelect = () => {
 | 
					const openSpuTableSelect = () => {
 | 
				
			||||||
  spuTableSelectRef.value.open(productSpus.value)
 | 
					  spuTableSelectRef.value.open(productSpus.value)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -154,7 +154,7 @@
 | 
				
			|||||||
  <!-- 修改用户等级弹窗 -->
 | 
					  <!-- 修改用户等级弹窗 -->
 | 
				
			||||||
  <UpdateLevelForm ref="updateLevelFormRef" @success="getList" />
 | 
					  <UpdateLevelForm ref="updateLevelFormRef" @success="getList" />
 | 
				
			||||||
  <!-- 发送优惠券弹窗 -->
 | 
					  <!-- 发送优惠券弹窗 -->
 | 
				
			||||||
  <CouponSend ref="couponSend" />
 | 
					  <CouponSendForm ref="couponSendFormRef" />
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
import { dateFormatter } from '@/utils/formatTime'
 | 
					import { dateFormatter } from '@/utils/formatTime'
 | 
				
			||||||
@@ -164,7 +164,7 @@ import MemberTagSelect from '@/views/member/tag/components/MemberTagSelect.vue'
 | 
				
			|||||||
import MemberLevelSelect from '@/views/member/level/components/MemberLevelSelect.vue'
 | 
					import MemberLevelSelect from '@/views/member/level/components/MemberLevelSelect.vue'
 | 
				
			||||||
import MemberGroupSelect from '@/views/member/group/components/MemberGroupSelect.vue'
 | 
					import MemberGroupSelect from '@/views/member/group/components/MemberGroupSelect.vue'
 | 
				
			||||||
import UpdateLevelForm from '@/views/member/user/UpdateLevelForm.vue'
 | 
					import UpdateLevelForm from '@/views/member/user/UpdateLevelForm.vue'
 | 
				
			||||||
import CouponSend from '@/views/mall/promotion/coupon/components/CouponSend.vue'
 | 
					import CouponSendForm from '@/views/mall/promotion/coupon/components/CouponSendForm.vue'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defineOptions({ name: 'MemberUser' })
 | 
					defineOptions({ name: 'MemberUser' })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -224,14 +224,13 @@ const handleSelectionChange = (rows: UserApi.UserVO[]) => {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** 发送优惠券 */
 | 
					/** 发送优惠券 */
 | 
				
			||||||
const couponSend = ref()
 | 
					const couponSendFormRef = ref()
 | 
				
			||||||
const openCoupon = () => {
 | 
					const openCoupon = () => {
 | 
				
			||||||
  if (selectedIds.value.length === 0) {
 | 
					  if (selectedIds.value.length === 0) {
 | 
				
			||||||
    message.warning('请选择要发送优惠券的用户')
 | 
					    message.warning('请选择要发送优惠券的用户')
 | 
				
			||||||
    return
 | 
					    return
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  couponSendFormRef.value.open(selectedIds.value)
 | 
				
			||||||
  couponSend.value.open(selectedIds.value)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** 初始化 **/
 | 
					/** 初始化 **/
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user