feat: mall CombinationActivity
							parent
							
								
									341303b014
								
							
						
					
					
						commit
						2e96b1c984
					
				| 
						 | 
				
			
			@ -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 })
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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 当前传入的日期值
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
		Loading…
	
		Reference in New Issue