review 营销活动
parent
fa71d3e7dd
commit
5d613e69b3
|
@ -49,6 +49,7 @@ export interface Spu {
|
||||||
recommendGood?: boolean // 是否优品
|
recommendGood?: boolean // 是否优品
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO @puhui999: SpuRespVO 合并到 SPU 里?前端少点 VO 类哈;
|
||||||
export interface SpuRespVO extends Spu {
|
export interface SpuRespVO extends Spu {
|
||||||
price: number
|
price: number
|
||||||
salesCount: number
|
salesCount: number
|
||||||
|
|
|
@ -60,8 +60,3 @@ export const updateSeckillActivity = async (data: SeckillActivityVO) => {
|
||||||
export const deleteSeckillActivity = async (id: number) => {
|
export const deleteSeckillActivity = async (id: number) => {
|
||||||
return await request.delete({ url: '/promotion/seckill-activity/delete?id=' + id })
|
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 })
|
|
||||||
}
|
|
||||||
|
|
|
@ -47,8 +47,3 @@ export const updateSeckillConfigStatus = (id: number, status: number) => {
|
||||||
export const deleteSeckillConfig = async (id: number) => {
|
export const deleteSeckillConfig = async (id: number) => {
|
||||||
return await request.delete({ url: '/promotion/seckill-config/delete?id=' + id })
|
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 })
|
|
||||||
}
|
|
||||||
|
|
|
@ -149,6 +149,21 @@ export const dateFormatter = (row, column, cellValue) => {
|
||||||
return formatDate(cellValue)
|
return formatDate(cellValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* element plus 的时间 Formatter 实现,使用 YYYY-MM-DD 格式
|
||||||
|
*
|
||||||
|
* @param row 行数据
|
||||||
|
* @param column 字段
|
||||||
|
* @param cellValue 字段值
|
||||||
|
*/
|
||||||
|
// @ts-ignore
|
||||||
|
export const dateFormatter2 = (row, column, cellValue) => {
|
||||||
|
if (!cellValue) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return formatDate(cellValue, 'YYYY-MM-DD')
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置起始日期,时间为00:00:00
|
* 设置起始日期,时间为00:00:00
|
||||||
* @param param 传入日期
|
* @param param 传入日期
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
>
|
>
|
||||||
<!-- 先选择 -->
|
<!-- 先选择 -->
|
||||||
<template #spuId>
|
<template #spuId>
|
||||||
<el-button @click="spuAndSkuSelectForm.open('秒杀商品选择')">添加商品</el-button>
|
<el-button @click="spuAndSkuSelectForm.open('秒杀商品选择')">选择商品</el-button>
|
||||||
|
<!-- TODO @puhui999:默认展开 SKU 哈,毕竟 SKU 是主角,SPU 是配角 -->
|
||||||
<SpuAndSkuList ref="spuAndSkuListRef" :spu-list="spuList" />
|
<SpuAndSkuList ref="spuAndSkuListRef" :spu-list="spuList" />
|
||||||
</template>
|
</template>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -18,6 +19,7 @@
|
||||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
</template>
|
</template>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
<!-- TODO @puhui999:这个组件是不是 SpuSelect,不需要带 sku 或者 Form 呀 -->
|
||||||
<SpuAndSkuSelectForm ref="spuAndSkuSelectForm" @confirm="selectSpu" />
|
<SpuAndSkuSelectForm ref="spuAndSkuSelectForm" @confirm="selectSpu" />
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" name="PromotionSeckillActivityForm" setup>
|
<script lang="ts" name="PromotionSeckillActivityForm" setup>
|
||||||
|
@ -37,6 +39,7 @@ const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
const formRef = ref() // 表单 Ref
|
const formRef = ref() // 表单 Ref
|
||||||
const spuAndSkuSelectForm = ref() // 商品和属性选择 Ref
|
const spuAndSkuSelectForm = ref() // 商品和属性选择 Ref
|
||||||
const spuAndSkuListRef = ref() // sku 秒杀配置组件Ref
|
const spuAndSkuListRef = ref() // sku 秒杀配置组件Ref
|
||||||
|
|
||||||
/** 打开弹窗 */
|
/** 打开弹窗 */
|
||||||
const open = async (type: string, id?: number) => {
|
const open = async (type: string, id?: number) => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
</el-table>
|
</el-table>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" name="SpuAndSkuList" setup>
|
<script lang="ts" name="SpuAndSkuList" setup>
|
||||||
// TODO 后续计划重新封装作为活动商品配置通用组件
|
// TODO 后续计划重新封装作为活动商品配置通用组件;可以等其他活动做到的时候,在统一处理 SPU 选择组件哈
|
||||||
import { formatToFraction } from '@/utils'
|
import { formatToFraction } from '@/utils'
|
||||||
import { createImageViewer } from '@/components/ImageViewer'
|
import { createImageViewer } from '@/components/ImageViewer'
|
||||||
import * as ProductSpuApi from '@/api/mall/product/spu'
|
import * as ProductSpuApi from '@/api/mall/product/spu'
|
||||||
|
@ -59,7 +59,9 @@ import {
|
||||||
SkuList
|
SkuList
|
||||||
} from '@/views/mall/product/spu/components'
|
} from '@/views/mall/product/spu/components'
|
||||||
import { SeckillProductVO, SpuExtension } from '@/api/mall/promotion/seckill/seckillActivity'
|
import { SeckillProductVO, SpuExtension } from '@/api/mall/promotion/seckill/seckillActivity'
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
// TODO @puhui999:是不是改成传递一个 spu 就好啦?
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
spuList: {
|
spuList: {
|
||||||
type: Array,
|
type: Array,
|
||||||
|
@ -72,7 +74,7 @@ interface spuProperty {
|
||||||
spuId: number
|
spuId: number
|
||||||
spuDetail: SpuExtension
|
spuDetail: SpuExtension
|
||||||
propertyList: Properties[]
|
propertyList: Properties[]
|
||||||
}
|
} // TODO @puhui999:类名首字母大写哈
|
||||||
|
|
||||||
const spuPropertyList = ref<spuProperty[]>([]) // spuId 对应的 sku 的属性列表
|
const spuPropertyList = ref<spuProperty[]>([]) // spuId 对应的 sku 的属性列表
|
||||||
/**
|
/**
|
||||||
|
@ -112,7 +114,6 @@ const ruleConfig: RuleConfig[] = [
|
||||||
geValue: 0.01
|
geValue: 0.01
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
const message = useMessage() // 消息弹窗
|
|
||||||
/**
|
/**
|
||||||
* 获取所有 sku 秒杀配置
|
* 获取所有 sku 秒杀配置
|
||||||
*/
|
*/
|
||||||
|
@ -132,6 +133,7 @@ const getSkuConfigs = (): SeckillProductVO[] => {
|
||||||
}
|
}
|
||||||
// 暴露出给表单提交时使用
|
// 暴露出给表单提交时使用
|
||||||
defineExpose({ getSkuConfigs })
|
defineExpose({ getSkuConfigs })
|
||||||
|
|
||||||
/** 商品图预览 */
|
/** 商品图预览 */
|
||||||
const imagePreview = (imgUrl: string) => {
|
const imagePreview = (imgUrl: string) => {
|
||||||
createImageViewer({
|
createImageViewer({
|
||||||
|
@ -139,6 +141,7 @@ const imagePreview = (imgUrl: string) => {
|
||||||
urlList: [imgUrl]
|
urlList: [imgUrl]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将传进来的值赋值给 skuList
|
* 将传进来的值赋值给 skuList
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -147,6 +147,7 @@ const spuListRef = ref<InstanceType<typeof ElTable>>()
|
||||||
const spuData = ref<ProductSpuApi.Spu | {}>() // 商品详情
|
const spuData = ref<ProductSpuApi.Spu | {}>() // 商品详情
|
||||||
const isExpand = ref(false) // 控制 SKU 列表显示
|
const isExpand = ref(false) // 控制 SKU 列表显示
|
||||||
const expandRowKeys = ref<number[]>() // 控制展开行需要设置 row-key 属性才能使用,该属性为展开行的 keys 数组。
|
const expandRowKeys = ref<number[]>() // 控制展开行需要设置 row-key 属性才能使用,该属性为展开行的 keys 数组。
|
||||||
|
|
||||||
// 计算商品属性
|
// 计算商品属性
|
||||||
const expandChange = async (row: ProductSpuApi.Spu, expandedRows: ProductSpuApi.Spu[]) => {
|
const expandChange = async (row: ProductSpuApi.Spu, expandedRows: ProductSpuApi.Spu[]) => {
|
||||||
spuData.value = {}
|
spuData.value = {}
|
||||||
|
@ -208,6 +209,8 @@ const confirm = () => {
|
||||||
// 关闭弹窗
|
// 关闭弹窗
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO @puhui999:直接叫商品选择;不用外部传入标题;
|
||||||
/** 打开弹窗 TODO 没做国际化 */
|
/** 打开弹窗 TODO 没做国际化 */
|
||||||
const open = (title: string) => {
|
const open = (title: string) => {
|
||||||
dialogTitle.value = title
|
dialogTitle.value = title
|
||||||
|
@ -226,6 +229,7 @@ const getList = async () => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
const handleQuery = () => {
|
const handleQuery = () => {
|
||||||
getList()
|
getList()
|
||||||
|
@ -243,6 +247,7 @@ const resetQuery = () => {
|
||||||
}
|
}
|
||||||
getList()
|
getList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 商品图预览 */
|
/** 商品图预览 */
|
||||||
const imagePreview = (imgUrl: string) => {
|
const imagePreview = (imgUrl: string) => {
|
||||||
createImageViewer({
|
createImageViewer({
|
||||||
|
@ -253,6 +258,7 @@ const imagePreview = (imgUrl: string) => {
|
||||||
|
|
||||||
const categoryList = ref() // 分类树
|
const categoryList = ref() // 分类树
|
||||||
|
|
||||||
|
// TODO @puhui999:商品搜索的时候,可以通过一级搜二级;所以这个校验可以去掉哈;也就是说,只允许挂在二级,但是一级可搜索到
|
||||||
/**
|
/**
|
||||||
* 校验所选是否为二级及以下节点
|
* 校验所选是否为二级及以下节点
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import type { CrudSchema } from '@/hooks/web/useCrudSchemas'
|
import type { CrudSchema } from '@/hooks/web/useCrudSchemas'
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter, dateFormatter2 } from '@/utils/formatTime'
|
||||||
import { getListAllSimple } from '@/api/mall/promotion/seckill/seckillConfig'
|
import { getListAllSimple } from '@/api/mall/promotion/seckill/seckillConfig'
|
||||||
|
|
||||||
// 表单校验
|
// 表单校验
|
||||||
|
@ -16,6 +16,7 @@ export const rules = reactive({
|
||||||
})
|
})
|
||||||
|
|
||||||
// CrudSchema https://doc.iocoder.cn/vue3/crud-schema/
|
// CrudSchema https://doc.iocoder.cn/vue3/crud-schema/
|
||||||
|
// TODO @puhui999:table 宽度调整下,有点太长啦;部分字段可以隐藏哈,根据需求;
|
||||||
const crudSchemas = reactive<CrudSchema[]>([
|
const crudSchemas = reactive<CrudSchema[]>([
|
||||||
{
|
{
|
||||||
label: '秒杀活动名称',
|
label: '秒杀活动名称',
|
||||||
|
@ -33,12 +34,12 @@ const crudSchemas = reactive<CrudSchema[]>([
|
||||||
{
|
{
|
||||||
label: '活动开始时间',
|
label: '活动开始时间',
|
||||||
field: 'startTime',
|
field: 'startTime',
|
||||||
formatter: dateFormatter,
|
formatter: dateFormatter2,
|
||||||
isSearch: true,
|
isSearch: true,
|
||||||
search: {
|
search: {
|
||||||
component: 'DatePicker',
|
component: 'DatePicker',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
valueFormat: 'YYYY-MM-DD',
|
||||||
type: 'daterange',
|
type: 'daterange',
|
||||||
defaultTime: [new Date('1 00:00:00'), new Date('1 23:59:59')]
|
defaultTime: [new Date('1 00:00:00'), new Date('1 23:59:59')]
|
||||||
}
|
}
|
||||||
|
@ -57,12 +58,12 @@ const crudSchemas = reactive<CrudSchema[]>([
|
||||||
{
|
{
|
||||||
label: '活动结束时间',
|
label: '活动结束时间',
|
||||||
field: 'endTime',
|
field: 'endTime',
|
||||||
formatter: dateFormatter,
|
formatter: dateFormatter2,
|
||||||
isSearch: true,
|
isSearch: true,
|
||||||
search: {
|
search: {
|
||||||
component: 'DatePicker',
|
component: 'DatePicker',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
valueFormat: 'YYYY-MM-DD',
|
||||||
type: 'daterange',
|
type: 'daterange',
|
||||||
defaultTime: [new Date('1 00:00:00'), new Date('1 23:59:59')]
|
defaultTime: [new Date('1 00:00:00'), new Date('1 23:59:59')]
|
||||||
}
|
}
|
||||||
|
@ -79,7 +80,7 @@ const crudSchemas = reactive<CrudSchema[]>([
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '秒杀时段',
|
label: '秒杀时段', // todo @PUHUI999: 在列表界面,格式化不对
|
||||||
field: 'configIds',
|
field: 'configIds',
|
||||||
form: {
|
form: {
|
||||||
component: 'Select',
|
component: 'Select',
|
||||||
|
@ -178,7 +179,7 @@ const crudSchemas = reactive<CrudSchema[]>([
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '秒杀活动商品',
|
label: '秒杀活动商品', // TODO @puhui999:格式化的商品不对;
|
||||||
field: 'spuId',
|
field: 'spuId',
|
||||||
form: {
|
form: {
|
||||||
colProps: {
|
colProps: {
|
||||||
|
@ -219,7 +220,7 @@ const crudSchemas = reactive<CrudSchema[]>([
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '状态',
|
label: '状态',
|
||||||
field: 'status',
|
field: 'status', // TODO @puhui999:状态在 table 格式化不对;
|
||||||
dictType: DICT_TYPE.COMMON_STATUS,
|
dictType: DICT_TYPE.COMMON_STATUS,
|
||||||
dictClass: 'number',
|
dictClass: 'number',
|
||||||
isForm: false,
|
isForm: false,
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
<!-- 表单弹窗:添加/修改 -->
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
<SeckillConfigForm ref="formRef" @success="getList" />
|
<SeckillConfigForm ref="formRef" @success="getList" />
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" name="SeckillConfig" setup>
|
<script lang="ts" name="PromotionSeckillConfig" setup>
|
||||||
import { allSchemas } from './seckillConfig.data'
|
import { allSchemas } from './seckillConfig.data'
|
||||||
import * as SeckillConfigApi from '@/api/mall/promotion/seckill/seckillConfig'
|
import * as SeckillConfigApi from '@/api/mall/promotion/seckill/seckillConfig'
|
||||||
import SeckillConfigForm from './SeckillConfigForm.vue'
|
import SeckillConfigForm from './SeckillConfigForm.vue'
|
||||||
|
@ -81,12 +81,14 @@ const { tableObject, tableMethods } = useTable({
|
||||||
})
|
})
|
||||||
// 获得表格的各种操作
|
// 获得表格的各种操作
|
||||||
const { getList, setSearchParams } = tableMethods
|
const { getList, setSearchParams } = tableMethods
|
||||||
|
|
||||||
/** 商品图预览 */
|
/** 商品图预览 */
|
||||||
const imagePreview = (imgUrl: string) => {
|
const imagePreview = (imgUrl: string) => {
|
||||||
createImageViewer({
|
createImageViewer({
|
||||||
urlList: [imgUrl]
|
urlList: [imgUrl]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 添加/修改操作 */
|
/** 添加/修改操作 */
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
const openForm = (type: string, id?: number) => {
|
const openForm = (type: string, id?: number) => {
|
||||||
|
@ -97,6 +99,7 @@ const openForm = (type: string, id?: number) => {
|
||||||
const handleDelete = (id: number) => {
|
const handleDelete = (id: number) => {
|
||||||
tableMethods.delList(id, false)
|
tableMethods.delList(id, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 修改用户状态 */
|
/** 修改用户状态 */
|
||||||
const handleStatusChange = async (row: SeckillConfigApi.SeckillConfigVO) => {
|
const handleStatusChange = async (row: SeckillConfigApi.SeckillConfigVO) => {
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Reference in New Issue