code review:优惠劵逻辑
This commit is contained in:
parent
190c6e384c
commit
4f7d6793fd
@ -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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 初始化 **/
|
/** 初始化 **/
|
||||||
|
Loading…
Reference in New Issue
Block a user