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
814b4631
authored
Aug 25, 2023
by
owen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
商品:完善后台商品评论功能
parent
2e68a523
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
805 additions
and
0 deletions
+805
-0
src/api/mall/product/comment.ts
+49
-0
src/views/mall/product/comment/CommentForm.vue
+198
-0
src/views/mall/product/comment/components/SkuTableSelect.vue
+94
-0
src/views/mall/product/comment/components/SpuTableSelect.vue
+167
-0
src/views/mall/product/comment/index.vue
+297
-0
No files found.
src/api/mall/product/comment.ts
0 → 100644
View file @
814b4631
import
request
from
'@/config/axios'
export
interface
CommentVO
{
id
:
number
userId
:
number
userNickname
:
string
userAvatar
:
string
anonymous
:
boolean
orderId
:
number
orderItemId
:
number
spuId
:
number
spuName
:
string
skuId
:
number
visible
:
boolean
scores
:
number
descriptionScores
:
number
benefitScores
:
number
content
:
string
picUrls
:
string
replyStatus
:
boolean
replyUserId
:
number
replyContent
:
string
replyTime
:
Date
}
// 查询商品评论列表
export
const
getCommentPage
=
async
(
params
)
=>
{
return
await
request
.
get
({
url
:
`/product/comment/page`
,
params
})
}
// 查询商品评论详情
export
const
getComment
=
async
(
id
:
number
)
=>
{
return
await
request
.
get
({
url
:
`/product/comment/get?id=`
+
id
})
}
// 添加自评
export
const
createComment
=
async
(
data
:
CommentVO
)
=>
{
return
await
request
.
post
({
url
:
`/product/comment/create`
,
data
})
}
// 显示 / 隐藏评论
export
const
updateCommentVisible
=
async
(
data
:
any
)
=>
{
return
await
request
.
put
({
url
:
`/product/comment/update-visible`
,
data
})
}
// 商家回复
export
const
replyComment
=
async
(
data
:
any
)
=>
{
return
await
request
.
put
({
url
:
`/product/comment/reply`
,
data
})
}
src/views/mall/product/comment/CommentForm.vue
0 → 100644
View file @
814b4631
<
template
>
<Dialog
title=
"添加虚拟评论"
v-model=
"dialogVisible"
>
<el-form
ref=
"formRef"
:model=
"formData"
:rules=
"formRules"
label-width=
"100px"
v-loading=
"formLoading"
>
<el-form-item
label=
"商品"
prop=
"spuId"
>
<div
@
click=
"handleSelectSpu"
class=
"w-60px h-60px"
>
<div
v-if=
"spuData && spuData.picUrl"
>
<el-image
:src=
"spuData.picUrl"
/>
</div>
<div
v-else
class=
"select-box"
>
<Icon
icon=
"ep:plus"
/>
</div>
</div>
</el-form-item>
<el-form-item
label=
"商品规格"
prop=
"skuId"
v-if=
"formData.spuId"
>
<div
@
click=
"handleSelectSku"
class=
"w-60px h-60px"
>
<div
v-if=
"skuData && skuData.picUrl"
>
<el-image
:src=
"skuData.picUrl"
/>
</div>
<div
v-else
class=
"select-box"
>
<Icon
icon=
"ep:plus"
/>
</div>
</div>
</el-form-item>
<el-form-item
label=
"用户头像"
prop=
"userAvatar"
>
<UploadImg
v-model=
"formData.userAvatar"
height=
"60px"
width=
"60px"
/>
</el-form-item>
<el-form-item
label=
"用户名称"
prop=
"userNickname"
>
<el-input
v-model=
"formData.userNickname"
placeholder=
"请输入用户名称"
/>
</el-form-item>
<el-form-item
label=
"评论内容"
prop=
"content"
>
<el-input
type=
"textarea"
v-model=
"formData.content"
/>
</el-form-item>
<el-form-item
label=
"评分星级"
prop=
"scores"
>
<el-rate
v-model=
"formData.scores"
/>
</el-form-item>
<el-form-item
label=
"描述星级"
prop=
"descriptionScores"
>
<el-rate
v-model=
"formData.descriptionScores"
/>
</el-form-item>
<el-form-item
label=
"服务星级"
prop=
"benefitScores"
>
<el-rate
v-model=
"formData.benefitScores"
/>
</el-form-item>
<el-form-item
label=
"评论图片"
prop=
"picUrls"
>
<UploadImgs
v-model=
"formData.picUrls"
:limit=
"9"
height=
"60px"
width=
"60px"
/>
</el-form-item>
</el-form>
<template
#
footer
>
<el-button
@
click=
"submitForm"
type=
"primary"
:disabled=
"formLoading"
>
确 定
</el-button>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
</
template
>
</Dialog>
<SpuTableSelect
ref=
"spuTableSelectRef"
@
change=
"handleSpuChange"
/>
<SkuTableSelect
ref=
"skuTableSelectRef"
@
change=
"handleSkuChange"
:spu-id=
"spuData.id"
/>
</template>
<
script
setup
lang=
"ts"
>
import
*
as
CommentApi
from
'@/api/mall/product/comment'
import
SpuTableSelect
from
'@/views/mall/product/comment/components/SpuTableSelect.vue'
import
*
as
ProductSpuApi
from
'@/api/mall/product/spu'
import
SkuTableSelect
from
'@/views/mall/product/comment/components/SkuTableSelect.vue'
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
formData
=
ref
({
id
:
undefined
,
userId
:
undefined
,
userNickname
:
undefined
,
userAvatar
:
undefined
,
spuId
:
undefined
,
spuName
:
undefined
,
skuId
:
undefined
,
scores
:
5
,
descriptionScores
:
5
,
benefitScores
:
5
,
content
:
undefined
,
picUrls
:
[]
})
const
formRules
=
reactive
({
spuId
:
[{
required
:
true
,
message
:
'商品不能为空'
,
trigger
:
'blur'
}],
skuId
:
[{
required
:
true
,
message
:
'规格不能为空'
,
trigger
:
'blur'
}],
userAvatar
:
[{
required
:
true
,
message
:
'用户头像不能为空'
,
trigger
:
'blur'
}],
userNickname
:
[{
required
:
true
,
message
:
'用户名称不能为空'
,
trigger
:
'blur'
}],
content
:
[{
required
:
true
,
message
:
'评论内容不能为空'
,
trigger
:
'blur'
}],
scores
:
[{
required
:
true
,
message
:
'评分星级不能为空'
,
trigger
:
'blur'
}],
descriptionScores
:
[{
required
:
true
,
message
:
'描述星级不能为空'
,
trigger
:
'blur'
}],
benefitScores
:
[{
required
:
true
,
message
:
'服务星级不能为空'
,
trigger
:
'blur'
}]
})
const
formRef
=
ref
()
// 表单 Ref
const
spuData
=
ref
<
ProductSpuApi
.
Spu
>
({})
const
skuData
=
ref
({
id
:
-
1
,
name
:
''
,
picUrl
:
''
})
/** 打开弹窗 */
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
dialogVisible
.
value
=
true
dialogTitle
.
value
=
t
(
'action.'
+
type
)
formType
.
value
=
type
resetForm
()
// 修改时,设置数据
if
(
id
)
{
formLoading
.
value
=
true
try
{
formData
.
value
=
await
CommentApi
.
getComment
(
id
)
}
finally
{
formLoading
.
value
=
false
}
}
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
/** 提交表单 */
const
emit
=
defineEmits
([
'success'
])
// 定义 success 事件,用于操作成功后的回调
const
submitForm
=
async
()
=>
{
// 校验表单
if
(
!
formRef
)
return
const
valid
=
await
formRef
.
value
.
validate
()
if
(
!
valid
)
return
// 提交请求
formLoading
.
value
=
true
try
{
//处理评论图片
const
picUrls
=
formData
.
value
.
picUrls
.
map
((
item
)
=>
{
return
item
?.
url
?
item
.
url
:
item
})
const
data
=
{
...
formData
.
value
,
picUrls
}
if
(
formType
.
value
===
'create'
)
{
await
CommentApi
.
createComment
(
data
)
message
.
success
(
t
(
'common.createSuccess'
))
}
dialogVisible
.
value
=
false
// 发送操作成功的事件
emit
(
'success'
)
}
finally
{
formLoading
.
value
=
false
}
}
/** 重置表单 */
const
resetForm
=
()
=>
{
formData
.
value
=
{
id
:
undefined
,
userId
:
undefined
,
userNickname
:
undefined
,
userAvatar
:
undefined
,
spuId
:
undefined
,
skuId
:
undefined
,
scores
:
5
,
descriptionScores
:
5
,
benefitScores
:
5
,
content
:
undefined
,
picUrls
:
[]
}
formRef
.
value
?.
resetFields
()
}
/** SPU 表格选择 */
const
spuTableSelectRef
=
ref
()
const
handleSelectSpu
=
()
=>
{
spuTableSelectRef
.
value
.
open
()
}
const
handleSpuChange
=
(
spu
:
ProductSpuApi
.
Spu
)
=>
{
spuData
.
value
=
spu
formData
.
value
.
spuId
=
spu
.
id
}
/** SKU 表格选择 */
const
skuTableSelectRef
=
ref
()
const
handleSelectSku
=
()
=>
{
skuTableSelectRef
.
value
.
open
()
}
const
handleSkuChange
=
(
sku
:
ProductSpuApi
.
Sku
)
=>
{
skuData
.
value
=
sku
formData
.
value
.
skuId
=
sku
.
id
}
</
script
>
<
style
>
.select-box
{
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
border
:
1px
dashed
var
(
--el-border-color-darker
);
border-radius
:
8px
;
width
:
100%
;
height
:
100%
;
}
</
style
>
src/views/mall/product/comment/components/SkuTableSelect.vue
0 → 100644
View file @
814b4631
<
template
>
<Dialog
v-model=
"dialogVisible"
:appendToBody=
"true"
title=
"选择规格"
width=
"700"
>
<el-table
v-loading=
"loading"
:data=
"list"
show-overflow-tooltip
>
<el-table-column
label=
"#"
width=
"55"
>
<template
#
default=
"
{ row }">
<el-radio
:label=
"row.id"
v-model=
"selectedSkuId"
@
change=
"handleSelected(row)"
>
</el-radio>
</
template
>
</el-table-column>
<el-table-column
label=
"图片"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
<el-image
:src=
"row.picUrl"
class=
"w-30px h-30px"
:preview-src-list=
"[row.picUrl]"
preview-teleported
/>
</
template
>
</el-table-column>
<el-table-column
label=
"规格"
align=
"center"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
{{
row
.
properties
?.
map
((
p
)
=>
p
.
valueName
)?.
join
(
' '
)
}}
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"销售价(元)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
{{
row
.
price
}}
</
template
>
</el-table-column>
</el-table>
</Dialog>
</template>
<
script
lang=
"ts"
setup
>
import
{
ElTable
}
from
'element-plus'
import
*
as
ProductSpuApi
from
'@/api/mall/product/spu'
import
{
propTypes
}
from
'@/utils/propTypes'
defineOptions
({
name
:
'SkuTableSelect'
})
const
props
=
defineProps
({
spuId
:
propTypes
.
number
.
def
(
null
)
})
const
message
=
useMessage
()
// 消息弹窗
const
list
=
ref
<
any
[]
>
([])
// 列表的数据
const
loading
=
ref
(
false
)
// 列表的加载中
const
dialogVisible
=
ref
(
false
)
// 弹窗的是否展示
const
selectedSkuId
=
ref
()
// 选中的商品 spuId
/** 选中时触发 */
const
handleSelected
=
(
row
:
ProductSpuApi
.
Sku
)
=>
{
emits
(
'change'
,
row
)
// 关闭弹窗
dialogVisible
.
value
=
false
selectedSkuId
.
value
=
undefined
}
// 确认选择时的触发事件
const
emits
=
defineEmits
<
{
(
e
:
'change'
,
spu
:
ProductSpuApi
.
Sku
):
void
}
>
()
/** 打开弹窗 */
const
open
=
()
=>
{
dialogVisible
.
value
=
true
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
/** 查询列表 */
const
getSpuDetail
=
async
()
=>
{
loading
.
value
=
true
try
{
const
spu
=
await
ProductSpuApi
.
getSpu
(
props
.
spuId
)
list
.
value
=
spu
.
skus
}
finally
{
loading
.
value
=
false
}
}
/** 初始化 **/
onMounted
(
async
()
=>
{})
watch
(
()
=>
props
.
spuId
,
()
=>
{
if
(
!
props
.
spuId
)
{
return
}
getSpuDetail
()
}
)
</
script
>
src/views/mall/product/comment/components/SpuTableSelect.vue
0 → 100644
View file @
814b4631
<
template
>
<Dialog
v-model=
"dialogVisible"
:appendToBody=
"true"
title=
"选择商品"
width=
"70%"
>
<el-row
:gutter=
"20"
class=
"mb-10px"
>
<el-col
:span=
"6"
>
<el-input
v-model=
"queryParams.name"
class=
"!w-240px"
clearable
placeholder=
"请输入商品名称"
@
keyup
.
enter=
"handleQuery"
/>
</el-col>
<el-col
:span=
"6"
>
<el-tree-select
v-model=
"queryParams.categoryId"
:data=
"categoryTreeList"
:props=
"defaultProps"
check-strictly
class=
"w-1/1"
node-key=
"id"
placeholder=
"请选择商品分类"
/>
</el-col>
<el-col
:span=
"6"
>
<el-date-picker
v-model=
"queryParams.createTime"
:default-time=
"[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class=
"!w-240px"
end-placeholder=
"结束日期"
start-placeholder=
"开始日期"
type=
"daterange"
value-format=
"YYYY-MM-DD HH:mm:ss"
/>
</el-col>
<el-col
:span=
"6"
>
<el-button
@
click=
"handleQuery"
>
<Icon
class=
"mr-5px"
icon=
"ep:search"
/>
搜索
</el-button>
<el-button
@
click=
"resetQuery"
>
<Icon
class=
"mr-5px"
icon=
"ep:refresh"
/>
重置
</el-button>
</el-col>
</el-row>
<el-table
ref=
"spuListRef"
v-loading=
"loading"
:data=
"list"
show-overflow-tooltip
>
<el-table-column
label=
"#"
width=
"55"
>
<template
#
default=
"
{ row }">
<el-radio
:label=
"row.id"
v-model=
"selectedSpuId"
@
change=
"handleSelected(row)"
>
</el-radio
>
</
template
>
</el-table-column>
<el-table-column
key=
"id"
align=
"center"
label=
"商品编号"
prop=
"id"
min-width=
"60"
/>
<el-table-column
label=
"商品图"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
<el-image
:src=
"row.picUrl"
class=
"w-30px h-30px"
:preview-src-list=
"[row.picUrl]"
preview-teleported
/>
</
template
>
</el-table-column>
<el-table-column
label=
"商品名称"
min-width=
"200"
prop=
"name"
/>
<el-table-column
label=
"商品分类"
min-width=
"100"
prop=
"categoryId"
>
<
template
#
default=
"{ row }"
>
<span>
{{
categoryList
.
find
((
c
)
=>
c
.
id
===
row
.
categoryId
)?.
name
}}
</span>
</
template
>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
v-model:limit=
"queryParams.pageSize"
v-model:page=
"queryParams.pageNo"
:total=
"total"
@
pagination=
"getList"
/>
</Dialog>
</template>
<
script
lang=
"ts"
setup
>
import
{
ElTable
}
from
'element-plus'
import
{
defaultProps
,
handleTree
}
from
'@/utils/tree'
import
*
as
ProductCategoryApi
from
'@/api/mall/product/category'
import
*
as
ProductSpuApi
from
'@/api/mall/product/spu'
defineOptions
({
name
:
'SpuTableSelect'
})
const
message
=
useMessage
()
// 消息弹窗
const
total
=
ref
(
0
)
// 列表的总页数
const
list
=
ref
<
any
[]
>
([])
// 列表的数据
const
loading
=
ref
(
false
)
// 列表的加载中
const
dialogVisible
=
ref
(
false
)
// 弹窗的是否展示
const
queryParams
=
ref
({
pageNo
:
1
,
pageSize
:
10
,
tabType
:
0
,
// 默认获取上架的商品
name
:
''
,
categoryId
:
null
,
createTime
:
[]
})
// 查询参数
const
spuListRef
=
ref
<
InstanceType
<
typeof
ElTable
>>
()
const
selectedSpuId
=
ref
()
// 选中的商品 spuId
/** 选中时触发 */
const
handleSelected
=
(
row
:
ProductSpuApi
.
Spu
)
=>
{
emits
(
'change'
,
row
)
// 关闭弹窗
dialogVisible
.
value
=
false
selectedSpuId
.
value
=
undefined
}
// 确认选择时的触发事件
const
emits
=
defineEmits
<
{
(
e
:
'change'
,
spu
:
ProductSpuApi
.
Spu
):
void
}
>
()
/** 打开弹窗 */
const
open
=
()
=>
{
dialogVisible
.
value
=
true
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
/** 查询列表 */
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
const
data
=
await
ProductSpuApi
.
getSpuPage
(
queryParams
.
value
)
list
.
value
=
data
.
list
total
.
value
=
data
.
total
}
finally
{
loading
.
value
=
false
}
}
/** 搜索按钮操作 */
const
handleQuery
=
()
=>
{
getList
()
}
/** 重置按钮操作 */
const
resetQuery
=
()
=>
{
queryParams
.
value
=
{
pageNo
:
1
,
pageSize
:
10
,
tabType
:
0
,
// 默认获取上架的商品
name
:
''
,
categoryId
:
null
,
createTime
:
[]
}
getList
()
}
const
categoryList
=
ref
()
// 分类列表
const
categoryTreeList
=
ref
()
// 分类树
/** 初始化 **/
onMounted
(
async
()
=>
{
await
getList
()
// 获得分类树
categoryList
.
value
=
await
ProductCategoryApi
.
getCategoryList
({})
categoryTreeList
.
value
=
handleTree
(
categoryList
.
value
,
'id'
,
'parentId'
)
})
</
script
>
src/views/mall/product/comment/index.vue
0 → 100644
View file @
814b4631
<
template
>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class=
"-mb-15px"
:model=
"queryParams"
ref=
"queryFormRef"
:inline=
"true"
label-width=
"68px"
>
<el-form-item
label=
"回复状态"
prop=
"replyStatus"
>
<el-select
v-model=
"queryParams.replyStatus"
>
<el-option
label=
"已回复"
:value=
"true"
/>
<el-option
label=
"未回复"
:value=
"false"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"商品名称"
prop=
"spuName"
>
<el-input
v-model=
"queryParams.spuName"
placeholder=
"请输入商品名称"
/>
</el-form-item>
<el-form-item
label=
"用户名称"
prop=
"userNickname"
>
<el-input
v-model=
"queryParams.userNickname"
placeholder=
"请输入用户名称"
/>
</el-form-item>
<el-form-item
label=
"订单编号"
prop=
"orderId"
>
<el-input
v-model=
"queryParams.orderId"
placeholder=
"请输入订单编号"
/>
</el-form-item>
<el-form-item
label=
"评论时间"
prop=
"createTime"
>
<el-date-picker
v-model=
"queryParams.createTime"
value-format=
"YYYY-MM-DD HH:mm:ss"
type=
"daterange"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
:default-time=
"[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item>
<el-button
@
click=
"handleQuery"
>
<Icon
icon=
"ep:search"
class=
"mr-5px"
/>
搜索
</el-button>
<el-button
@
click=
"resetQuery"
>
<Icon
icon=
"ep:refresh"
class=
"mr-5px"
/>
重置
</el-button>
<el-button
type=
"primary"
plain
@
click=
"openForm('create')"
v-hasPermi=
"['product:comment:create']"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
添加虚拟评论
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table
v-loading=
"loading"
:data=
"list"
:stripe=
"true"
:show-overflow-tooltip=
"false"
>
<el-table-column
label=
"评论编号"
align=
"center"
prop=
"id"
min-width=
"60"
/>
<el-table-column
label=
"用户名称"
align=
"center"
prop=
"userNickname"
width=
"80"
/>
<el-table-column
label=
"商品信息"
align=
"center"
min-width=
"210"
>
<template
#
default=
"scope"
>
<div
class=
"flex row items-center gap-x-4px"
>
<el-image
v-if=
"scope.row.skuPicUrl"
:src=
"scope.row.skuPicUrl"
:preview-src-list=
"[scope.row.skuPicUrl]"
class=
"w-30px h-30px shrink-0"
preview-teleported
/>
<div>
{{
scope
.
row
.
spuName
}}
</div>
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"评分星级"
align=
"center"
prop=
"scores"
width=
"80"
/>
<el-table-column
label=
"描述星级"
align=
"center"
prop=
"descriptionScores"
width=
"80"
/>
<el-table-column
label=
"服务星级"
align=
"center"
prop=
"benefitScores"
width=
"80"
/>
<el-table-column
label=
"评论内容"
align=
"center"
prop=
"content"
min-width=
"80"
>
<
template
#
default=
"scope"
>
<p>
{{
scope
.
row
.
content
}}
</p>
<div
class=
"flex justify-center gap-x-4px"
>
<el-image
v-for=
"(picUrl, index) in scope.row.picUrls"
:key=
"index"
:src=
"picUrl"
:preview-src-list=
"scope.row.picUrls"
:initial-index=
"index"
class=
"w-30px h-30px"
preview-teleported
/>
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"回复内容"
align=
"center"
prop=
"replyContent"
min-width=
"100"
show-overflow-tooltip
/>
<el-table-column
label=
"评论时间"
align=
"center"
prop=
"createTime"
:formatter=
"dateFormatter"
width=
"170"
/>
<el-table-column
label=
"状态"
align=
"center"
width=
"65px"
>
<
template
#
default=
"scope"
>
<el-switch
v-model=
"scope.row.visible"
:active-value=
"true"
:inactive-value=
"false"
v-hasPermi=
"['product:comment:update']"
@
change=
"handleVisibleChange(scope.row)"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"操作"
align=
"center"
min-width=
"60px"
fixed=
"right"
>
<
template
#
default=
"scope"
>
<el-button
link
type=
"primary"
@
click=
"handleReply(scope.row.id)"
v-hasPermi=
"['product:comment:update']"
>
回复
</el-button>
</
template
>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total=
"total"
v-model:page=
"queryParams.pageNo"
v-model:limit=
"queryParams.pageSize"
@
pagination=
"getList"
/>
</ContentWrap>
<!-- 表单弹窗:添加/修改 -->
<CommentForm
ref=
"formRef"
@
success=
"getList"
/>
<Dialog
title=
"回复"
v-model=
"replyDialog.visible"
>
<el-form
ref=
"replyFormRef"
:model=
"replyDialog.formData"
:rules=
"replyDialog.formRules"
label-width=
"100px"
v-loading=
"replyDialog.loading"
>
<el-form-item
label=
"回复内容"
prop=
"replyContent"
>
<el-input
type=
"textarea"
v-model=
"replyDialog.formData.replyContent"
/>
</el-form-item>
</el-form>
<
template
#
footer
>
<el-button
@
click=
"submitReplyForm"
type=
"primary"
:disabled=
"replyDialog.loading"
>
确 定
</el-button>
<el-button
@
click=
"replyDialog.visible = false"
>
取 消
</el-button>
</
template
>
</Dialog>
</template>
<
script
setup
lang=
"ts"
>
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
*
as
CommentApi
from
'@/api/mall/product/comment'
import
CommentForm
from
'./CommentForm.vue'
import
{
ElInput
}
from
'element-plus'
defineOptions
({
name
:
'ProductComment'
})
const
message
=
useMessage
()
// 消息弹窗
const
{
t
}
=
useI18n
()
// 国际化
const
loading
=
ref
(
true
)
// 列表的加载中
const
total
=
ref
(
0
)
// 列表的总页数
const
list
=
ref
([])
// 列表的数据
const
queryParams
=
reactive
({
pageNo
:
1
,
pageSize
:
10
,
userId
:
null
,
userNickname
:
null
,
userAvatar
:
null
,
anonymous
:
null
,
orderId
:
null
,
orderItemId
:
null
,
spuId
:
null
,
spuName
:
null
,
skuId
:
null
,
visible
:
null
,
scores
:
null
,
descriptionScores
:
null
,
benefitScores
:
null
,
content
:
null
,
picUrls
:
null
,
replyStatus
:
null
,
replyUserId
:
null
,
replyContent
:
null
,
replyTime
:
[],
createTime
:
[]
})
const
queryFormRef
=
ref
()
// 搜索的表单
/** 查询列表 */
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
const
data
=
await
CommentApi
.
getCommentPage
(
queryParams
)
// visible 如果为 null,会导致刷新的时候触发e-switch的change事件
data
.
list
.
forEach
((
item
)
=>
{
if
(
!
item
.
visible
)
{
item
.
visible
=
false
}
})
list
.
value
=
data
.
list
total
.
value
=
data
.
total
}
finally
{
loading
.
value
=
false
}
}
/** 搜索按钮操作 */
const
handleQuery
=
()
=>
{
queryParams
.
pageNo
=
1
getList
()
}
/** 重置按钮操作 */
const
resetQuery
=
()
=>
{
queryFormRef
.
value
.
resetFields
()
handleQuery
()
}
/** 添加/修改操作 */
const
formRef
=
ref
()
const
openForm
=
(
type
:
string
,
id
?:
number
)
=>
{
formRef
.
value
.
open
(
type
,
id
)
}
/** 回复 **/
const
replyFormRef
=
ref
()
const
replyDialog
=
reactive
({
visible
:
false
,
loading
:
false
,
formData
:
{
id
:
-
1
,
replyContent
:
''
},
formRules
:
{
replyContent
:
[{
required
:
true
,
message
:
'回复内容不能为空'
,
trigger
:
'blur'
}]
}
})
const
handleReply
=
(
id
:
number
)
=>
{
replyDialog
.
formData
.
id
=
id
replyDialog
.
formData
.
replyContent
=
''
replyDialog
.
visible
=
true
}
const
submitReplyForm
=
async
()
=>
{
const
valid
=
await
replyFormRef
?.
value
?.
validate
()
if
(
!
valid
)
return
replyDialog
.
loading
=
true
try
{
await
CommentApi
.
replyComment
(
replyDialog
.
formData
)
message
.
success
(
t
(
'common.createSuccess'
))
replyDialog
.
visible
=
false
await
getList
()
}
finally
{
replyDialog
.
loading
=
false
}
}
/** 显示/隐藏 **/
const
handleVisibleChange
=
async
(
row
:
CommentApi
.
CommentVO
)
=>
{
if
(
loading
.
value
)
{
return
}
let
changedValue
=
row
.
visible
try
{
await
message
.
confirm
(
changedValue
?
'是否显示评论?'
:
'是否隐藏评论?'
)
await
CommentApi
.
updateCommentVisible
({
id
:
row
.
id
,
visible
:
changedValue
})
await
getList
()
}
catch
{
row
.
visible
=
!
changedValue
}
}
/** 初始化 **/
onMounted
(()
=>
{
getList
()
})
</
script
>
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