diff --git a/src/api/mall/promotion/seckill/seckillConfig.ts b/src/api/mall/promotion/seckill/seckillConfig.ts
new file mode 100644
index 00000000..d941ed4d
--- /dev/null
+++ b/src/api/mall/promotion/seckill/seckillConfig.ts
@@ -0,0 +1,41 @@
+import request from '@/config/axios'
+
+export interface SeckillConfigVO {
+  id: number
+  name: string
+  startTime: Date
+  endTime: Date
+  seckillActivityCount: number
+  picUrl: string
+  status: number
+}
+
+// 查询秒杀时段配置列表
+export const getSeckillConfigPage = async (params) => {
+  return await request.get({ url: '/promotion/seckill-config/page', params })
+}
+
+// 查询秒杀时段配置详情
+export const getSeckillConfig = async (id: number) => {
+  return await request.get({ url: '/promotion/seckill-config/get?id=' + id })
+}
+
+// 新增秒杀时段配置
+export const createSeckillConfig = async (data: SeckillConfigVO) => {
+  return await request.post({ url: '/promotion/seckill-config/create', data })
+}
+
+// 修改秒杀时段配置
+export const updateSeckillConfig = async (data: SeckillConfigVO) => {
+  return await request.put({ url: '/promotion/seckill-config/update', data })
+}
+
+// 删除秒杀时段配置
+export const deleteSeckillConfig = async (id: number) => {
+  return await request.delete({ url: '/promotion/seckill-config/delete?id=' + id })
+}
+
+// 导出秒杀时段配置 Excel
+export const exportSeckillConfigApi = async (params) => {
+  return await request.download({ url: '/promotion/seckill-config/export-excel', params })
+}
diff --git a/src/utils/formatTime.ts b/src/utils/formatTime.ts
index 0d68e362..b27cabdf 100644
--- a/src/utils/formatTime.ts
+++ b/src/utils/formatTime.ts
@@ -155,7 +155,7 @@ export const dateFormatter = (row, column, cellValue) => {
  * @returns 带时间00:00:00的日期
  */
 export function beginOfDay(param: Date) {
-  return new Date(param.getFullYear(), param.getMonth(), param.getDate(), 0, 0, 0, 0)
+  return new Date(param.getFullYear(), param.getMonth(), param.getDate(), 0, 0, 0)
 }
 
 /**
@@ -164,7 +164,7 @@ export function beginOfDay(param: Date) {
  * @returns 带时间23:59:59的日期
  */
 export function endOfDay(param: Date) {
-  return new Date(param.getFullYear(), param.getMonth(), param.getDate(), 23, 59, 59, 999)
+  return new Date(param.getFullYear(), param.getMonth(), param.getDate(), 23, 59, 59)
 }
 
 /**
diff --git a/src/views/mall/promotion/seckill/config/SeckillConfigForm.vue b/src/views/mall/promotion/seckill/config/SeckillConfigForm.vue
new file mode 100644
index 00000000..a4675f71
--- /dev/null
+++ b/src/views/mall/promotion/seckill/config/SeckillConfigForm.vue
@@ -0,0 +1,70 @@
+<template>
+  <Dialog v-model="dialogVisible" :title="dialogTitle">
+    <Form ref="formRef" v-loading="formLoading" :rules="rules" :schema="allSchemas.formSchema" />
+    <template #footer>
+      <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+<script lang="ts" name="SeckillConfigForm" setup>
+import { cloneDeep } from 'lodash-es'
+import * as SeckillConfigApi from '@/api/mall/promotion/seckill/seckillConfig'
+import { allSchemas, format, rules } from './seckillConfig.data'
+
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+
+const dialogVisible = ref(false) // 弹窗的是否展示
+const dialogTitle = ref('') // 弹窗的标题
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formType = ref('') // 表单的类型:create - 新增;update - 修改
+const formRef = ref() // 表单 Ref
+
+/** 打开弹窗 */
+const open = async (type: string, id?: number) => {
+  dialogVisible.value = true
+  dialogTitle.value = t('action.' + type)
+  formType.value = type
+  // 修改时,设置数据
+  if (id) {
+    formLoading.value = true
+    try {
+      const data = await SeckillConfigApi.getSeckillConfig(id)
+      const info = cloneDeep(data)
+      data.startTime = format(info.startTime)
+      data.endTime = format(info.endTime)
+      formRef.value.setValues(data)
+    } finally {
+      formLoading.value = false
+    }
+  }
+}
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  // 校验表单
+  if (!formRef) return
+  const valid = await formRef.value.getElFormRef().validate()
+  if (!valid) return
+  // 提交请求
+  formLoading.value = true
+  try {
+    const data = formRef.value.formModel as SeckillConfigApi.SeckillConfigVO
+    if (formType.value === 'create') {
+      await SeckillConfigApi.createSeckillConfig(data)
+      message.success(t('common.createSuccess'))
+    } else {
+      await SeckillConfigApi.updateSeckillConfig(data)
+      message.success(t('common.updateSuccess'))
+    }
+    dialogVisible.value = false
+    // 发送操作成功的事件
+    emit('success')
+  } finally {
+    formLoading.value = false
+  }
+}
+</script>
diff --git a/src/views/mall/promotion/seckill/config/index.vue b/src/views/mall/promotion/seckill/config/index.vue
new file mode 100644
index 00000000..8c7dee8d
--- /dev/null
+++ b/src/views/mall/promotion/seckill/config/index.vue
@@ -0,0 +1,101 @@
+<template>
+  <!-- 搜索工作栏 -->
+  <ContentWrap>
+    <Search :schema="allSchemas.searchSchema" @reset="setSearchParams" @search="setSearchParams">
+      <!-- 新增等操作按钮 -->
+      <template #actionMore>
+        <el-button
+          v-hasPermi="['promotion:seckill-config:create']"
+          plain
+          type="primary"
+          @click="openForm('create')"
+        >
+          <Icon class="mr-5px" icon="ep:plus" />
+          新增
+        </el-button>
+      </template>
+    </Search>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap>
+    <Table
+      v-model:currentPage="tableObject.currentPage"
+      v-model:pageSize="tableObject.pageSize"
+      :columns="allSchemas.tableColumns"
+      :data="tableObject.tableList"
+      :loading="tableObject.loading"
+      :pagination="{
+        total: tableObject.total
+      }"
+    >
+      <template #startTime="{ row }">
+        {{ format(row.startTime) }}
+      </template>
+      <template #endTime="{ row }">
+        {{ format(row.endTime) }}
+      </template>
+      <template #picUrl="{ row }">
+        <el-image :src="row.picUrl" class="w-30px h-30px" @click="imagePreview(row.picUrl)" />
+      </template>
+      <template #action="{ row }">
+        <el-button
+          v-hasPermi="['promotion:seckill-config:update']"
+          link
+          type="primary"
+          @click="openForm('update', row.id)"
+        >
+          编辑
+        </el-button>
+        <el-button
+          v-hasPermi="['promotion:seckill-config:delete']"
+          link
+          type="danger"
+          @click="handleDelete(row.id)"
+        >
+          删除
+        </el-button>
+      </template>
+    </Table>
+  </ContentWrap>
+
+  <!-- 表单弹窗:添加/修改 -->
+  <SeckillConfigForm ref="formRef" @success="getList" />
+</template>
+<script lang="ts" name="SeckillConfig" setup>
+import { allSchemas, format } from './seckillConfig.data'
+import * as SeckillConfigApi from '@/api/mall/promotion/seckill/seckillConfig'
+import SeckillConfigForm from './SeckillConfigForm.vue'
+import { createImageViewer } from '@/components/ImageViewer'
+
+// tableObject:表格的属性对象,可获得分页大小、条数等属性
+// tableMethods:表格的操作对象,可进行获得分页、删除记录等操作
+// 详细可见:https://doc.iocoder.cn/vue3/crud-schema/
+const { tableObject, tableMethods } = useTable({
+  getListApi: SeckillConfigApi.getSeckillConfigPage, // 分页接口
+  delListApi: SeckillConfigApi.deleteSeckillConfig // 删除接口
+})
+// 获得表格的各种操作
+const { getList, setSearchParams } = tableMethods
+/** 商品图预览 */
+const imagePreview = (imgUrl: string) => {
+  createImageViewer({
+    urlList: [imgUrl]
+  })
+}
+/** 添加/修改操作 */
+const formRef = ref()
+const openForm = (type: string, id?: number) => {
+  formRef.value.open(type, id)
+}
+
+/** 删除按钮操作 */
+const handleDelete = (id: number) => {
+  tableMethods.delList(id, false)
+}
+
+/** 初始化 **/
+onMounted(() => {
+  getList()
+})
+</script>
diff --git a/src/views/mall/promotion/seckill/config/seckillConfig.data.ts b/src/views/mall/promotion/seckill/config/seckillConfig.data.ts
new file mode 100644
index 00000000..65c35611
--- /dev/null
+++ b/src/views/mall/promotion/seckill/config/seckillConfig.data.ts
@@ -0,0 +1,93 @@
+import type { CrudSchema } from '@/hooks/web/useCrudSchemas'
+import { dateFormatter } from '@/utils/formatTime'
+
+// 表单校验
+export const rules = reactive({
+  name: [required],
+  startTime: [required],
+  endTime: [required],
+  seckillActivityCount: [required],
+  picUrl: [required],
+  status: [required]
+})
+
+// CrudSchema https://doc.iocoder.cn/vue3/crud-schema/
+const crudSchemas = reactive<CrudSchema[]>([
+  {
+    label: '秒杀时段名称',
+    field: 'name',
+    isSearch: true
+  },
+  {
+    label: '开始时间点',
+    field: 'startTime',
+    isSearch: false,
+    search: {
+      component: 'TimePicker'
+    },
+    form: {
+      component: 'TimePicker',
+      componentProps: {
+        valueFormat: 'HH:mm:ss'
+      }
+    }
+  },
+  {
+    label: '结束时间点',
+    field: 'endTime',
+    isSearch: false,
+    search: {
+      component: 'TimePicker'
+    },
+    form: {
+      component: 'TimePicker',
+      componentProps: {
+        valueFormat: 'HH:mm:ss'
+      }
+    }
+  },
+  {
+    label: '秒杀主图',
+    field: 'picUrl',
+    isSearch: false,
+    form: {
+      component: 'UploadImg'
+    }
+  },
+  {
+    label: '状态',
+    field: 'status',
+    dictType: DICT_TYPE.COMMON_STATUS,
+    dictClass: 'number',
+    isSearch: true,
+    form: {
+      component: 'Radio'
+    }
+  },
+  {
+    label: '创建时间',
+    field: 'createTime',
+    isForm: false,
+    isSearch: false,
+    formatter: dateFormatter
+  },
+  {
+    label: '操作',
+    field: 'action',
+    isForm: false
+  }
+])
+export const { allSchemas } = useCrudSchemas(crudSchemas)
+
+/**
+ *  添加这个函数呢是因为数据库表使用 time 类型存的时分秒信息,对应实体类字段使用的 LocalTime,然后返回给前端的就数据是
+ *  '00:05:00' 会变成 [0,5],所以才使用此方法转一道。我想着或许直接后台返回字符串格式的
+ * @param data
+ */
+export const format = (data: number[]): string => {
+  if (typeof data === 'undefined') {
+    return ''
+  }
+  const paddedData = data.length >= 3 ? data.slice(0, 3) : [...data, 0, 0].slice(0, 3)
+  return paddedData.map((num) => num.toString().padStart(2, '0')).join(':')
+}