diff --git a/src/api/mall/promotion/coupon/coupon.ts b/src/api/mall/promotion/coupon/coupon.ts
index 565b86f7..2ebff5da 100755
--- a/src/api/mall/promotion/coupon/coupon.ts
+++ b/src/api/mall/promotion/coupon/coupon.ts
@@ -16,3 +16,11 @@ export const getCouponPage = async (params: PageParam) => {
params: params
})
}
+
+// 发送优惠券
+export const sendCoupon = async (data: any) => {
+ return request.post({
+ url: '/promotion/coupon/send',
+ data: data
+ })
+}
diff --git a/src/api/mall/promotion/coupon/couponTemplate.ts b/src/api/mall/promotion/coupon/couponTemplate.ts
index 6a58876e..bf294441 100755
--- a/src/api/mall/promotion/coupon/couponTemplate.ts
+++ b/src/api/mall/promotion/coupon/couponTemplate.ts
@@ -9,7 +9,7 @@ export interface CouponTemplateVO {
takeType: number
usePrice: number
productScope: number
- productSpuIds: string
+ productSpuIds: number[]
validityType: number
validStartTime: Date
validEndTime: Date
@@ -73,6 +73,14 @@ export function getCouponTemplatePage(params: PageParam) {
})
}
+// 获得可用于领取的优惠劵模板分页
+export function getCanTakeCouponTemplatePage(params: PageParam) {
+ return request.get({
+ url: '/promotion/coupon-template/can-take-page',
+ params: params
+ })
+}
+
// 导出优惠劵模板 Excel
export function exportCouponTemplateExcel(params: PageParam) {
return request.get({
diff --git a/src/utils/constants.ts b/src/utils/constants.ts
index cd346a5c..03c1f999 100644
--- a/src/utils/constants.ts
+++ b/src/utils/constants.ts
@@ -220,6 +220,10 @@ export const PromotionProductScopeEnum = {
SPU: {
scope: 2,
name: '指定商品参与'
+ },
+ CATEGORY: {
+ scope: 3,
+ name: '指定品类参与'
}
}
diff --git a/src/views/mall/product/category/components/ProductCategorySelect.vue b/src/views/mall/product/category/components/ProductCategorySelect.vue
new file mode 100644
index 00000000..b8011290
--- /dev/null
+++ b/src/views/mall/product/category/components/ProductCategorySelect.vue
@@ -0,0 +1,47 @@
+
+
+
+
diff --git a/src/views/mall/product/spu/components/SpuTableSelect.vue b/src/views/mall/product/spu/components/SpuTableSelect.vue
index f8560aa3..d7d15439 100644
--- a/src/views/mall/product/spu/components/SpuTableSelect.vue
+++ b/src/views/mall/product/spu/components/SpuTableSelect.vue
@@ -1,81 +1,103 @@
@@ -85,12 +107,19 @@ import { defaultProps, handleTree } from '@/utils/tree'
import * as ProductCategoryApi from '@/api/mall/product/category'
import * as ProductSpuApi from '@/api/mall/product/spu'
+import { propTypes } from '@/utils/propTypes'
+
+type Spu = Required
defineOptions({ name: 'SpuTableSelect' })
-const message = useMessage() // 消息弹窗
+const props = defineProps({
+ // 多选
+ multiple: propTypes.bool.def(false)
+})
+
const total = ref(0) // 列表的总页数
-const list = ref([]) // 列表的数据
+const list = ref([]) // 列表的数据
const loading = ref(false) // 列表的加载中
const dialogVisible = ref(false) // 弹窗的是否展示
const queryParams = ref({
@@ -101,26 +130,24 @@ const queryParams = ref({
categoryId: null,
createTime: []
}) // 查询参数
-const spuListRef = ref>()
const selectedSpuId = ref() // 选中的商品 spuId
-/** 选中时触发 */
-const handleSelected = (row: ProductSpuApi.Spu) => {
- emits('change', row)
- // 关闭弹窗
- dialogVisible.value = false
- selectedSpuId.value = undefined
-}
-
-// 确认选择时的触发事件
-const emits = defineEmits<{
- (e: 'change', spu: ProductSpuApi.Spu): void
-}>()
-
/** 打开弹窗 */
-const open = () => {
+const open = (spus?: Spu[]) => {
+ if (spus && spus.length > 0) {
+ // todo check-box不显示选中?
+ checkedSpus.value = [...spus]
+ checkedSpuIds.value = spus.map((spu) => spu.id)
+ } else {
+ checkedSpus.value = []
+ checkedSpuIds.value = []
+ }
+ allChecked.value = false
+ checkedPageNos.value = []
+
dialogVisible.value = true
+ resetQuery()
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
@@ -138,6 +165,7 @@ const getList = async () => {
/** 搜索按钮操作 */
const handleQuery = () => {
+ queryParams.value.pageNo = 1
getList()
}
@@ -154,9 +182,65 @@ const resetQuery = () => {
getList()
}
+const allChecked = ref(false) //是否全选
+const checkedPageNos = ref([]) //选中的页码
+const checkedSpuIds = ref([]) //选中的商品ID
+const checkedSpus = ref([]) //选中的商品
+
+/** 单选中时触发 */
+const handleSingleSelected = (row: Spu) => {
+ emits('change', row)
+ // 关闭弹窗
+ dialogVisible.value = false
+ // 记住上次选择的ID
+ selectedSpuId.value = row.id
+}
+
+/** 多选完成 */
+const handleEmitChange = () => {
+ // 关闭弹窗
+ dialogVisible.value = false
+ emits('change', [...checkedSpus.value])
+}
+
+/** 确认选择时的触发事件 */
+const emits = defineEmits<{
+ (e: 'change', spu: Spu | Spu[] | any): void
+}>()
+
+/** 全选 */
+const handleCheckAll = (checked: boolean) => {
+ //todo 不触发?
+ console.log('checkAll', checked)
+ allChecked.value = checked
+ const index = checkedPageNos.value.indexOf(queryParams.value.pageNo)
+ checkedPageNos.value.push(queryParams.value.pageNo)
+ if (index > -1) {
+ checkedPageNos.value.splice(index, 1)
+ }
+
+ list.value.forEach((item) => handleCheckOne(checked, item))
+}
+
+/** 选中一行 */
+const handleCheckOne = (checked: boolean, spu: Spu) => {
+ if (checked) {
+ const index = checkedSpuIds.value.indexOf(spu.id)
+ if (index === -1) {
+ checkedSpuIds.value.push(spu.id)
+ checkedSpus.value.push(spu)
+ }
+ } else {
+ const index = checkedSpuIds.value.indexOf(spu.id)
+ if (index > -1) {
+ checkedSpuIds.value.splice(index, 1)
+ checkedSpus.value.splice(index, 1)
+ }
+ }
+}
+
const categoryList = ref() // 分类列表
const categoryTreeList = ref() // 分类树
-
/** 初始化 **/
onMounted(async () => {
await getList()
diff --git a/src/views/mall/promotion/coupon/components/CouponSend.vue b/src/views/mall/promotion/coupon/components/CouponSend.vue
new file mode 100644
index 00000000..7686539b
--- /dev/null
+++ b/src/views/mall/promotion/coupon/components/CouponSend.vue
@@ -0,0 +1,162 @@
+
+
+
+
+
diff --git a/src/views/mall/promotion/coupon/formatter.ts b/src/views/mall/promotion/coupon/formatter.ts
new file mode 100644
index 00000000..60eebb5d
--- /dev/null
+++ b/src/views/mall/promotion/coupon/formatter.ts
@@ -0,0 +1,44 @@
+import { CouponTemplateValidityTypeEnum, PromotionDiscountTypeEnum } from '@/utils/constants'
+import { formatDate } from '@/utils/formatTime'
+import { CouponTemplateVO } from '@/api/mall/promotion/coupon/couponTemplate'
+import { floatToFixed2 } from '@/utils'
+
+// 格式化【优惠金额/折扣】
+export const discountFormat = (row: CouponTemplateVO) => {
+ if (row.discountType === PromotionDiscountTypeEnum.PRICE.type) {
+ return `¥${floatToFixed2(row.discountPrice)}`
+ }
+ if (row.discountType === PromotionDiscountTypeEnum.PERCENT.type) {
+ return `${row.discountPrice}%`
+ }
+ return '未知【' + row.discountType + '】'
+}
+
+// 格式化【领取上限】
+export const takeLimitCountFormat = (row: CouponTemplateVO) => {
+ if (row.takeLimitCount === -1) {
+ return '无领取限制'
+ }
+ return `${row.takeLimitCount} 张/人`
+}
+
+// 格式化【有效期限】
+export const validityTypeFormat = (row: CouponTemplateVO) => {
+ if (row.validityType === CouponTemplateValidityTypeEnum.DATE.type) {
+ return `${formatDate(row.validStartTime)} 至 ${formatDate(row.validEndTime)}`
+ }
+ if (row.validityType === CouponTemplateValidityTypeEnum.TERM.type) {
+ return `领取后第 ${row.fixedStartTerm} - ${row.fixedEndTerm} 天内可用`
+ }
+ return '未知【' + row.validityType + '】'
+}
+
+// 格式化【剩余数量】
+export const remainedCountFormat = (row: CouponTemplateVO) => {
+ return row.totalCount - row.takeCount
+}
+
+// 格式化【最低消费】
+export const userPriceFormat = (row: CouponTemplateVO) => {
+ return `¥${floatToFixed2(row.usePrice)}`
+}
diff --git a/src/views/mall/promotion/coupon/template/CouponTemplateForm.vue b/src/views/mall/promotion/coupon/template/CouponTemplateForm.vue
index e0173c00..e511dd0c 100644
--- a/src/views/mall/promotion/coupon/template/CouponTemplateForm.vue
+++ b/src/views/mall/promotion/coupon/template/CouponTemplateForm.vue
@@ -29,7 +29,7 @@
@@ -43,7 +43,7 @@
@@ -68,7 +68,7 @@
@@ -84,7 +84,7 @@
@@ -94,7 +94,7 @@
@@ -133,7 +133,7 @@
@@ -141,7 +141,7 @@
@@ -162,21 +162,21 @@
v-if="formData.productScope === PromotionProductScopeEnum.SPU.scope"
prop="productSpuIds"
>
-
-
- {{ item.name }}
-
- ¥{{ (item.minPrice / 100.0).toFixed(2) }}
-
-
-
+
+
+
+
@@ -184,6 +184,7 @@
取 消
+
+
+
diff --git a/src/views/mall/promotion/coupon/template/index.vue b/src/views/mall/promotion/coupon/template/index.vue
index ee8dad46..ad0077ce 100755
--- a/src/views/mall/promotion/coupon/template/index.vue
+++ b/src/views/mall/promotion/coupon/template/index.vue
@@ -103,7 +103,7 @@
label="剩余数量"
align="center"
prop="totalCount"
- :formatter="(row) => row.totalCount - row.takeCount"
+ :formatter="remainedCountFormat"
/>
import * as CouponTemplateApi from '@/api/mall/promotion/coupon/couponTemplate'
-import {
- CommonStatusEnum,
- CouponTemplateValidityTypeEnum,
- PromotionDiscountTypeEnum
-} from '@/utils/constants'
+import { CommonStatusEnum } from '@/utils/constants'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
-import { dateFormatter, formatDate } from '@/utils/formatTime'
+import { dateFormatter } from '@/utils/formatTime'
import CouponTemplateForm from './CouponTemplateForm.vue'
+import {
+ discountFormat,
+ remainedCountFormat,
+ takeLimitCountFormat,
+ validityTypeFormat
+} from '@/views/mall/promotion/coupon/formatter'
defineOptions({ name: 'PromotionCouponTemplate' })
@@ -193,6 +195,7 @@ const queryParams = reactive({
pageSize: 10,
name: null,
status: null,
+ discountType: null,
type: null,
createTime: []
})
@@ -258,36 +261,6 @@ const handleDelete = async (id: number) => {
} catch {}
}
-// 格式化【优惠金额/折扣】
-const discountFormat = (row: any) => {
- if (row.discountType === PromotionDiscountTypeEnum.PRICE.type) {
- return `¥${(row.discountPrice / 100.0).toFixed(2)}`
- }
- if (row.discountType === PromotionDiscountTypeEnum.PERCENT.type) {
- return `¥${(row.discountPrice / 100.0).toFixed(2)}`
- }
- return '未知【' + row.discountType + '】'
-}
-
-// 格式化【领取上限】
-const takeLimitCountFormat = (row: any) => {
- if (row.takeLimitCount === -1) {
- return '无领取限制'
- }
- return `${row.takeLimitCount} 张/人`
-}
-
-// 格式化【有效期限】
-const validityTypeFormat = (row: any) => {
- if (row.validityType === CouponTemplateValidityTypeEnum.DATE.type) {
- return `${formatDate(row.validStartTime)} 至 ${formatDate(row.validEndTime)}`
- }
- if (row.validityType === CouponTemplateValidityTypeEnum.TERM.type) {
- return `领取后第 ${row.fixedStartTerm} - ${row.fixedEndTerm} 天内可用`
- }
- return '未知【' + row.validityType + '】'
-}
-
/** 初始化 **/
onMounted(() => {
getList()
diff --git a/src/views/member/user/index.vue b/src/views/member/user/index.vue
index bae5c048..672e9bfc 100644
--- a/src/views/member/user/index.vue
+++ b/src/views/member/user/index.vue
@@ -60,13 +60,21 @@
搜索
重置
+ 发送优惠券
-
+
+
@@ -145,6 +153,8 @@
+
+