diff --git a/src/api/mall/promotion/seckill/seckillActivity.ts b/src/api/mall/promotion/seckill/seckillActivity.ts
new file mode 100644
index 00000000..2c59319c
--- /dev/null
+++ b/src/api/mall/promotion/seckill/seckillActivity.ts
@@ -0,0 +1,50 @@
+import request from '@/config/axios'
+
+export interface SeckillActivityVO {
+ id: number
+ spuId: number
+ name: string
+ status: number
+ remark: string
+ startTime: Date
+ endTime: Date
+ sort: number
+ configIds: string
+ orderCount: number
+ userCount: number
+ totalPrice: number
+ totalLimitCount: number
+ singleLimitCount: number
+ stock: number
+ totalStock: number
+}
+
+// 查询秒杀活动列表
+export const getSeckillActivityPage = async (params) => {
+ return await request.get({ url: '/promotion/seckill-activity/page', params })
+}
+
+// 查询秒杀活动详情
+export const getSeckillActivity = async (id: number) => {
+ return await request.get({ url: '/promotion/seckill-activity/get?id=' + id })
+}
+
+// 新增秒杀活动
+export const createSeckillActivity = async (data: SeckillActivityVO) => {
+ return await request.post({ url: '/promotion/seckill-activity/create', data })
+}
+
+// 修改秒杀活动
+export const updateSeckillActivity = async (data: SeckillActivityVO) => {
+ return await request.put({ url: '/promotion/seckill-activity/update', data })
+}
+
+// 删除秒杀活动
+export const deleteSeckillActivity = async (id: number) => {
+ return await request.delete({ url: '/promotion/seckill-activity/delete?id=' + id })
+}
+
+// 导出秒杀活动 Excel
+export const exportSeckillActivityApi = async (params) => {
+ return await request.download({ url: '/promotion/seckill-activity/export-excel', params })
+}
diff --git a/src/api/mall/promotion/seckill/seckillConfig.ts b/src/api/mall/promotion/seckill/seckillConfig.ts
index fb72936b..aff72821 100644
--- a/src/api/mall/promotion/seckill/seckillConfig.ts
+++ b/src/api/mall/promotion/seckill/seckillConfig.ts
@@ -19,6 +19,11 @@ export const getSeckillConfig = async (id: number) => {
return await request.get({ url: '/promotion/seckill-config/get?id=' + id })
}
+// 获得所有开启状态的秒杀时段精简列表
+export const getListAllSimple = async () => {
+ return await request.get({ url: '/promotion/seckill-config/list-all-simple' })
+}
+
// 新增秒杀时段配置
export const createSeckillConfig = async (data: SeckillConfigVO) => {
return await request.post({ url: '/promotion/seckill-config/create', data })
diff --git a/src/views/mall/product/spu/components/SkuList.vue b/src/views/mall/product/spu/components/SkuList.vue
index 4114bd09..6aa26a2b 100644
--- a/src/views/mall/product/spu/components/SkuList.vue
+++ b/src/views/mall/product/spu/components/SkuList.vue
@@ -118,7 +118,9 @@
max-height="500"
size="small"
style="width: 99%"
+ @selection-change="handleSelectionChange"
>
+
@@ -207,7 +209,8 @@ const props = defineProps({
default: () => []
},
isBatch: propTypes.bool.def(false), // 是否作为批量操作组件
- isDetail: propTypes.bool.def(false) // 是否作为 sku 详情组件
+ isDetail: propTypes.bool.def(false), // 是否作为 sku 详情组件
+ isComponent: propTypes.bool.def(false) // 是否作为 sku 选择组件
})
const formData: Ref = ref() // 表单数据
const skuList = ref([
@@ -263,6 +266,17 @@ const validateSku = (): boolean => {
return validate
}
+const emit = defineEmits<{
+ (e: 'selectionChange', value: Sku[]): void
+}>()
+/**
+ * 选择时触发
+ * @param Sku 传递过来的选中的 sku 是一个数组
+ */
+const handleSelectionChange = (val: Sku[]) => {
+ emit('selectionChange', val)
+}
+
/**
* 将传进来的值赋值给 skuList
*/
diff --git a/src/views/mall/product/spu/index.vue b/src/views/mall/product/spu/index.vue
index 76cb1166..8ffaab23 100644
--- a/src/views/mall/product/spu/index.vue
+++ b/src/views/mall/product/spu/index.vue
@@ -17,7 +17,6 @@
@keyup.enter="handleQuery"
/>
-
-
@@ -290,7 +283,8 @@ const queryParams = ref({
pageSize: 10,
tabType: 0,
name: '',
- categoryId: null
+ categoryId: null,
+ createTime: []
}) // 查询参数
const queryFormRef = ref() // 搜索的表单Ref
diff --git a/src/views/mall/promotion/seckill/activity/SeckillActivityForm.vue b/src/views/mall/promotion/seckill/activity/SeckillActivityForm.vue
new file mode 100644
index 00000000..c47c475f
--- /dev/null
+++ b/src/views/mall/promotion/seckill/activity/SeckillActivityForm.vue
@@ -0,0 +1,136 @@
+
+
+
+
+
+
diff --git a/src/views/mall/promotion/seckill/activity/components/SpuAndSkuSelectForm.vue b/src/views/mall/promotion/seckill/activity/components/SpuAndSkuSelectForm.vue
new file mode 100644
index 00000000..cf538fc2
--- /dev/null
+++ b/src/views/mall/promotion/seckill/activity/components/SpuAndSkuSelectForm.vue
@@ -0,0 +1,290 @@
+
+
+
+
+
diff --git a/src/views/mall/promotion/seckill/activity/components/index.ts b/src/views/mall/promotion/seckill/activity/components/index.ts
new file mode 100644
index 00000000..69dd429a
--- /dev/null
+++ b/src/views/mall/promotion/seckill/activity/components/index.ts
@@ -0,0 +1,3 @@
+import SpuAndSkuSelectForm from './SpuAndSkuSelectForm.vue'
+
+export { SpuAndSkuSelectForm }
diff --git a/src/views/mall/promotion/seckill/activity/index.vue b/src/views/mall/promotion/seckill/activity/index.vue
new file mode 100644
index 00000000..de9f71db
--- /dev/null
+++ b/src/views/mall/promotion/seckill/activity/index.vue
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/mall/promotion/seckill/activity/seckillActivity.data.ts b/src/views/mall/promotion/seckill/activity/seckillActivity.data.ts
new file mode 100644
index 00000000..70524b91
--- /dev/null
+++ b/src/views/mall/promotion/seckill/activity/seckillActivity.data.ts
@@ -0,0 +1,261 @@
+import type { CrudSchema } from '@/hooks/web/useCrudSchemas'
+import { dateFormatter } from '@/utils/formatTime'
+import { getListAllSimple } from '@/api/mall/promotion/seckill/seckillConfig'
+
+// 表单校验
+export const rules = reactive({
+ spuId: [required],
+ name: [required],
+ startTime: [required],
+ endTime: [required],
+ sort: [required],
+ configIds: [required],
+ totalLimitCount: [required],
+ singleLimitCount: [required],
+ totalStock: [required]
+})
+
+// CrudSchema https://doc.iocoder.cn/vue3/crud-schema/
+const crudSchemas = reactive([
+ {
+ label: '秒杀活动名称',
+ field: 'name',
+ isSearch: true,
+ form: {
+ colProps: {
+ span: 24
+ }
+ },
+ table: {
+ width: 120
+ }
+ },
+ {
+ label: '活动开始时间',
+ field: 'startTime',
+ formatter: dateFormatter,
+ isSearch: true,
+ search: {
+ component: 'DatePicker',
+ componentProps: {
+ valueFormat: 'YYYY-MM-DD HH:mm:ss',
+ type: 'daterange',
+ defaultTime: [new Date('1 00:00:00'), new Date('1 23:59:59')]
+ }
+ },
+ form: {
+ component: 'DatePicker',
+ componentProps: {
+ type: 'date',
+ valueFormat: 'x'
+ }
+ },
+ table: {
+ width: 300
+ }
+ },
+ {
+ label: '活动结束时间',
+ field: 'endTime',
+ formatter: dateFormatter,
+ isSearch: true,
+ search: {
+ component: 'DatePicker',
+ componentProps: {
+ valueFormat: 'YYYY-MM-DD HH:mm:ss',
+ type: 'daterange',
+ defaultTime: [new Date('1 00:00:00'), new Date('1 23:59:59')]
+ }
+ },
+ form: {
+ component: 'DatePicker',
+ componentProps: {
+ type: 'date',
+ valueFormat: 'x'
+ }
+ },
+ table: {
+ width: 300
+ }
+ },
+ {
+ label: '秒杀时段',
+ field: 'configIds',
+ form: {
+ component: 'Select',
+ componentProps: {
+ multiple: true,
+ optionsAlias: {
+ labelField: 'name',
+ valueField: 'id'
+ }
+ },
+ api: getListAllSimple
+ },
+ table: {
+ width: 300
+ }
+ },
+ {
+ label: '新增订单数',
+ field: 'orderCount',
+ isForm: false,
+ form: {
+ component: 'InputNumber',
+ value: 0
+ },
+ table: {
+ width: 300
+ }
+ },
+ {
+ label: '付款人数',
+ field: 'userCount',
+ isForm: false,
+ form: {
+ component: 'InputNumber',
+ value: 0
+ },
+ table: {
+ width: 300
+ }
+ },
+ {
+ label: '订单实付金额',
+ field: 'totalPrice',
+ isForm: false,
+ form: {
+ component: 'InputNumber',
+ value: 0
+ },
+ table: {
+ width: 300
+ }
+ },
+ {
+ label: '总限购数量',
+ field: 'totalLimitCount',
+ form: {
+ component: 'InputNumber',
+ value: 0
+ },
+ table: {
+ width: 300
+ }
+ },
+ {
+ label: '单次限够数量',
+ field: 'singleLimitCount',
+ form: {
+ component: 'InputNumber',
+ value: 0
+ },
+ table: {
+ width: 300
+ }
+ },
+ {
+ label: '秒杀库存',
+ field: 'stock',
+ isForm: false,
+ form: {
+ component: 'InputNumber',
+ value: 0
+ },
+ table: {
+ width: 300
+ }
+ },
+ {
+ label: '秒杀总库存',
+ field: 'totalStock',
+ form: {
+ component: 'InputNumber',
+ value: 0
+ },
+ table: {
+ width: 300
+ }
+ },
+ {
+ label: '秒杀活动商品',
+ field: 'spuId',
+ form: {
+ colProps: {
+ span: 24
+ }
+ },
+ table: {
+ width: 200
+ }
+ },
+ {
+ label: '创建时间',
+ field: 'createTime',
+ formatter: dateFormatter,
+ search: {
+ component: 'DatePicker',
+ componentProps: {
+ valueFormat: 'YYYY-MM-DD HH:mm:ss',
+ type: 'daterange',
+ defaultTime: [new Date('1 00:00:00'), new Date('1 23:59:59')]
+ }
+ },
+ isForm: false,
+ table: {
+ width: 300
+ }
+ },
+ {
+ label: '排序',
+ field: 'sort',
+ form: {
+ component: 'InputNumber',
+ value: 0
+ },
+ table: {
+ width: 300
+ }
+ },
+ {
+ label: '状态',
+ field: 'status',
+ dictType: DICT_TYPE.COMMON_STATUS,
+ dictClass: 'number',
+ isForm: false,
+ isSearch: true,
+ form: {
+ component: 'Radio'
+ },
+ table: {
+ width: 80
+ }
+ },
+ {
+ label: '备注',
+ field: 'remark',
+ form: {
+ component: 'Input',
+ componentProps: {
+ type: 'textarea',
+ rows: 4
+ },
+ colProps: {
+ span: 24
+ }
+ },
+ table: {
+ width: 300
+ }
+ },
+ {
+ label: '操作',
+ field: 'action',
+ isForm: false,
+ table: {
+ width: 120,
+ fixed: 'right'
+ }
+ }
+])
+export const { allSchemas } = useCrudSchemas(crudSchemas)