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
a75720ec
authored
Jun 17, 2023
by
puhui999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 秒杀时段管理
parent
d31ade7a
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
307 additions
and
2 deletions
+307
-2
src/api/mall/promotion/seckill/seckillConfig.ts
+41
-0
src/utils/formatTime.ts
+2
-2
src/views/mall/promotion/seckill/config/SeckillConfigForm.vue
+70
-0
src/views/mall/promotion/seckill/config/index.vue
+101
-0
src/views/mall/promotion/seckill/config/seckillConfig.data.ts
+93
-0
No files found.
src/api/mall/promotion/seckill/seckillConfig.ts
0 → 100644
View file @
a75720ec
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
})
}
src/utils/formatTime.ts
View file @
a75720ec
...
@@ -155,7 +155,7 @@ export const dateFormatter = (row, column, cellValue) => {
...
@@ -155,7 +155,7 @@ export const dateFormatter = (row, column, cellValue) => {
* @returns 带时间00:00:00的日期
* @returns 带时间00:00:00的日期
*/
*/
export
function
beginOfDay
(
param
:
Date
)
{
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) {
...
@@ -164,7 +164,7 @@ export function beginOfDay(param: Date) {
* @returns 带时间23:59:59的日期
* @returns 带时间23:59:59的日期
*/
*/
export
function
endOfDay
(
param
:
Date
)
{
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
)
}
}
/**
/**
...
...
src/views/mall/promotion/seckill/config/SeckillConfigForm.vue
0 → 100644
View file @
a75720ec
<
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
>
src/views/mall/promotion/seckill/config/index.vue
0 → 100644
View file @
a75720ec
<
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
>
src/views/mall/promotion/seckill/config/seckillConfig.data.ts
0 → 100644
View file @
a75720ec
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
(
':'
)
}
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