Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
5d613e69
authored
Jun 24, 2023
by
YunaiV
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
review 营销活动
parent
fa71d3e7
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
45 additions
and
23 deletions
+45
-23
src/api/mall/product/spu.ts
+1
-0
src/api/mall/promotion/seckill/seckillActivity.ts
+0
-5
src/api/mall/promotion/seckill/seckillConfig.ts
+0
-5
src/utils/formatTime.ts
+15
-0
src/views/mall/promotion/seckill/activity/SeckillActivityForm.vue
+4
-1
src/views/mall/promotion/seckill/activity/components/SpuAndSkuList.vue
+6
-3
src/views/mall/promotion/seckill/activity/components/SpuAndSkuSelectForm.vue
+6
-0
src/views/mall/promotion/seckill/activity/seckillActivity.data.ts
+9
-8
src/views/mall/promotion/seckill/config/index.vue
+4
-1
No files found.
src/api/mall/product/spu.ts
View file @
5d613e69
...
@@ -49,6 +49,7 @@ export interface Spu {
...
@@ -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
...
...
src/api/mall/promotion/seckill/seckillActivity.ts
View file @
5d613e69
...
@@ -60,8 +60,3 @@ export const updateSeckillActivity = async (data: SeckillActivityVO) => {
...
@@ -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
})
}
src/api/mall/promotion/seckill/seckillConfig.ts
View file @
5d613e69
...
@@ -47,8 +47,3 @@ export const updateSeckillConfigStatus = (id: number, status: number) => {
...
@@ -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
})
}
src/utils/formatTime.ts
View file @
5d613e69
...
@@ -150,6 +150,21 @@ export const dateFormatter = (row, column, cellValue) => {
...
@@ -150,6 +150,21 @@ export const dateFormatter = (row, column, 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 传入日期
* @returns 带时间00:00:00的日期
* @returns 带时间00:00:00的日期
...
...
src/views/mall/promotion/seckill/activity/SeckillActivityForm.vue
View file @
5d613e69
...
@@ -9,7 +9,8 @@
...
@@ -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 @@
...
@@ -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 - 修改
...
@@ -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
...
...
src/views/mall/promotion/seckill/activity/components/SpuAndSkuList.vue
View file @
5d613e69
...
@@ -47,7 +47,7 @@
...
@@ -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 {
...
@@ -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 {
...
@@ -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[] = [
...
@@ -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[] => {
...
@@ -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) => {
...
@@ -139,6 +141,7 @@ const imagePreview = (imgUrl: string) => {
urlList
:
[
imgUrl
]
urlList
:
[
imgUrl
]
})
})
}
}
/**
/**
* 将传进来的值赋值给 skuList
* 将传进来的值赋值给 skuList
*/
*/
...
...
src/views/mall/promotion/seckill/activity/components/SpuAndSkuSelectForm.vue
View file @
5d613e69
...
@@ -147,6 +147,7 @@ const spuListRef = ref<InstanceType<typeof ElTable>>()
...
@@ -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 = () => {
...
@@ -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 () => {
...
@@ -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 = () => {
...
@@ -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) => {
...
@@ -253,6 +258,7 @@ const imagePreview = (imgUrl: string) => {
const
categoryList
=
ref
()
// 分类树
const
categoryList
=
ref
()
// 分类树
// TODO @puhui999:商品搜索的时候,可以通过一级搜二级;所以这个校验可以去掉哈;也就是说,只允许挂在二级,但是一级可搜索到
/**
/**
* 校验所选是否为二级及以下节点
* 校验所选是否为二级及以下节点
*/
*/
...
...
src/views/mall/promotion/seckill/activity/seckillActivity.data.ts
View file @
5d613e69
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({
...
@@ -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[]>([
...
@@ -33,12 +34,12 @@ const crudSchemas = reactive<CrudSchema[]>([
{
{
label
:
'活动开始时间'
,
label
:
'活动开始时间'
,
field
:
'startTime'
,
field
:
'startTime'
,
formatter
:
dateFormatter
,
formatter
:
dateFormatter
2
,
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[]>([
...
@@ -57,12 +58,12 @@ const crudSchemas = reactive<CrudSchema[]>([
{
{
label
:
'活动结束时间'
,
label
:
'活动结束时间'
,
field
:
'endTime'
,
field
:
'endTime'
,
formatter
:
dateFormatter
,
formatter
:
dateFormatter
2
,
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[]>([
...
@@ -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[]>([
...
@@ -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[]>([
...
@@ -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
,
...
...
src/views/mall/promotion/seckill/config/index.vue
View file @
5d613e69
...
@@ -64,7 +64,7 @@
...
@@ -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=
"
Promotion
SeckillConfig"
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({
...
@@ -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) => {
...
@@ -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
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment