Bladeren bron

feat: mall CombinationActivity

puhui999 1 jaar geleden
bovenliggende
commit
2e96b1c984

+ 48 - 0
src/api/mall/promotion/combination/combinationactivity.ts

@@ -0,0 +1,48 @@
+import request from '@/config/axios'
+
+export interface CombinationActivityVO {
+  id: number
+  name: string
+  spuId: number
+  totalLimitCount: number
+  singleLimitCount: number
+  startTime: Date
+  endTime: Date
+  userSize: number
+  totalNum: number
+  successNum: number
+  orderUserCount: number
+  virtualGroup: number
+  status: number
+  limitDuration: number
+}
+
+// 查询拼团活动列表
+export const getCombinationActivityPage = async (params) => {
+  return await request.get({ url: '/promotion/combination-activity/page', params })
+}
+
+// 查询拼团活动详情
+export const getCombinationActivity = async (id: number) => {
+  return await request.get({ url: '/promotion/combination-activity/get?id=' + id })
+}
+
+// 新增拼团活动
+export const createCombinationActivity = async (data: CombinationActivityVO) => {
+  return await request.post({ url: '/promotion/combination-activity/create', data })
+}
+
+// 修改拼团活动
+export const updateCombinationActivity = async (data: CombinationActivityVO) => {
+  return await request.put({ url: '/promotion/combination-activity/update', data })
+}
+
+// 删除拼团活动
+export const deleteCombinationActivity = async (id: number) => {
+  return await request.delete({ url: '/promotion/combination-activity/delete?id=' + id })
+}
+
+// 导出拼团活动 Excel
+export const exportCombinationActivity = async (params) => {
+  return await request.download({ url: '/promotion/combination-activity/export-excel', params })
+}

+ 7 - 0
src/utils/formatTime.ts

@@ -23,6 +23,13 @@ export function formatDate(date: Date, format?: string): string {
   return dayjs(date).format(format)
 }
 
+/**
+ * 获取当前的日期+时间
+ */
+export function getNowDateTime() {
+  return dayjs().format('YYYY-MM-DD HH:mm:ss')
+}
+
 /**
  * 获取当前日期是第几周
  * @param dateTime 当前传入的日期值

+ 74 - 0
src/views/mall/promotion/combination/activity/CombinationActivityForm.vue

@@ -0,0 +1,74 @@
+<template>
+  <Dialog v-model="dialogVisible" :title="dialogTitle">
+    <Form
+      ref="formRef"
+      v-loading="formLoading"
+      :is-col="true"
+      :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" setup>
+import * as CombinationActivityApi from '@/api/mall/promotion/combination/combinationactivity'
+import { allSchemas, rules } from './combinationActivity.data'
+
+defineOptions({ name: 'PromotionCombinationActivityForm' })
+
+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 CombinationActivityApi.getCombinationActivity(id)
+      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 CombinationActivityApi.CombinationActivityVO
+    if (formType.value === 'create') {
+      await CombinationActivityApi.createCombinationActivity(data)
+      message.success(t('common.createSuccess'))
+    } else {
+      await CombinationActivityApi.updateCombinationActivity(data)
+      message.success(t('common.updateSuccess'))
+    }
+    dialogVisible.value = false
+    // 发送操作成功的事件
+    emit('success')
+  } finally {
+    formLoading.value = false
+  }
+}
+</script>

+ 168 - 0
src/views/mall/promotion/combination/activity/combinationActivity.data.ts

@@ -0,0 +1,168 @@
+import type { CrudSchema } from '@/hooks/web/useCrudSchemas'
+import { dateFormatter, getNowDateTime } from '@/utils/formatTime'
+
+// 表单校验
+export const rules = reactive({
+  name: [required],
+  totalLimitCount: [required],
+  singleLimitCount: [required],
+  startTime: [required],
+  endTime: [required],
+  userSize: [required],
+  totalNum: [required],
+  successNum: [required],
+  orderUserCount: [required],
+  virtualGroup: [required],
+  status: [required],
+  limitDuration: [required]
+})
+
+// CrudSchema https://doc.iocoder.cn/vue3/crud-schema/
+const crudSchemas = reactive<CrudSchema[]>([
+  {
+    label: '拼团名称',
+    field: 'name',
+    isSearch: true,
+    isTable: false,
+    form: {
+      colProps: {
+        span: 24
+      }
+    }
+  },
+  {
+    label: '活动时间',
+    field: 'activityTime',
+    formatter: dateFormatter,
+    search: {
+      show: true,
+      component: 'DatePicker',
+      componentProps: {
+        valueFormat: 'YYYY-MM-DD HH:mm:ss',
+        type: 'datetimerange'
+      }
+    },
+    form: {
+      component: 'DatePicker',
+      componentProps: {
+        valueFormat: 'YYYY-MM-DD HH:mm:ss',
+        type: 'datetimerange'
+      },
+      value: [getNowDateTime(), getNowDateTime()],
+      colProps: {
+        span: 24
+      }
+    }
+  },
+  {
+    label: '参与人数',
+    field: 'orderUserCount',
+    isSearch: false,
+    form: {
+      component: 'InputNumber',
+      labelMessage: '参与人数不能少于两人',
+      value: 2
+    }
+  },
+  {
+    label: '限制时长',
+    field: 'limitDuration',
+    isSearch: false,
+    isTable: false,
+    form: {
+      component: 'InputNumber',
+      labelMessage: '限制时长(小时)',
+      componentProps: {
+        placeholder: '请输入限制时长(小时)'
+      }
+    }
+  },
+  {
+    label: '总限购数量',
+    field: 'totalLimitCount',
+    isSearch: false,
+    isTable: false,
+    form: {
+      component: 'InputNumber',
+      value: 0
+    }
+  },
+  {
+    label: '单次限购数量',
+    field: 'singleLimitCount',
+    isSearch: false,
+    isTable: false,
+    form: {
+      component: 'InputNumber',
+      value: 0
+    }
+  },
+  {
+    label: '购买人数',
+    field: 'userSize',
+    isSearch: false,
+    isForm: false
+  },
+  {
+    label: '开团组数',
+    field: 'totalNum',
+    isSearch: false,
+    isForm: false
+  },
+  {
+    label: '成团组数',
+    field: 'successNum',
+    isSearch: false,
+    isForm: false
+  },
+  {
+    label: '虚拟成团',
+    field: 'virtualGroup',
+    isSearch: false,
+    isTable: false,
+    form: {
+      component: 'InputNumber',
+      value: 0
+    }
+  },
+  {
+    label: '活动状态',
+    field: 'status',
+    dictType: DICT_TYPE.COMMON_STATUS,
+    dictClass: 'number',
+    isSearch: true,
+    isForm: false
+  },
+  {
+    label: '创建时间',
+    field: 'createTime',
+    formatter: dateFormatter,
+    isSearch: false,
+    isTable: false,
+    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
+  },
+  {
+    label: '拼团商品',
+    field: 'spuId',
+    isSearch: false,
+    form: {
+      colProps: {
+        span: 24
+      }
+    }
+  },
+  {
+    label: '操作',
+    field: 'action',
+    isForm: false
+  }
+])
+export const { allSchemas } = useCrudSchemas(crudSchemas)

+ 88 - 0
src/views/mall/promotion/combination/activity/index.vue

@@ -0,0 +1,88 @@
+<template>
+  <!-- 搜索工作栏 -->
+  <ContentWrap>
+    <Search :schema="allSchemas.searchSchema" @reset="setSearchParams" @search="setSearchParams">
+      <!-- 新增等操作按钮 -->
+      <template #actionMore>
+        <el-button
+          v-hasPermi="['promotion:combination-activity: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 #action="{ row }">
+        <el-button
+          v-hasPermi="['promotion:combination-activity:update']"
+          link
+          type="primary"
+          @click="openForm('update', row.id)"
+        >
+          编辑
+        </el-button>
+        <el-button
+          v-hasPermi="['promotion:combination-activity:delete']"
+          link
+          type="danger"
+          @click="handleDelete(row.id)"
+        >
+          删除
+        </el-button>
+      </template>
+    </Table>
+  </ContentWrap>
+
+  <!-- 表单弹窗:添加/修改 -->
+  <CombinationActivityForm ref="formRef" @success="getList" />
+</template>
+<script lang="ts" setup>
+import { allSchemas } from './combinationActivity.data'
+import * as CombinationActivityApi from '@/api/mall/promotion/combination/combinationactivity'
+import CombinationActivityForm from './CombinationActivityForm.vue'
+
+defineOptions({ name: 'PromotionCombinationActivity' })
+
+// tableObject:表格的属性对象,可获得分页大小、条数等属性
+// tableMethods:表格的操作对象,可进行获得分页、删除记录等操作
+// 详细可见:https://doc.iocoder.cn/vue3/crud-schema/
+const { tableObject, tableMethods } = useTable({
+  getListApi: CombinationActivityApi.getCombinationActivityPage, // 分页接口
+  delListApi: CombinationActivityApi.deleteCombinationActivity // 删除接口
+})
+// 获得表格的各种操作
+const { getList, setSearchParams } = tableMethods
+
+/** 添加/修改操作 */
+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>