Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
J
jyzb_platformV2
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Members
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
赵剑炜
jyzb_platformV2
Commits
6dd8d1c6
Commit
6dd8d1c6
authored
Dec 28, 2023
by
李小惠
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修改装备统计报表,新增人员统计报表接口
parent
bffded32
显示空白字符变更
内嵌
并排
正在显示
15 个修改的文件
包含
150 行增加
和
64 行删除
+150
-64
FinalTjOrgPoliceDto.java
jyzb-api/src/main/java/com/junmp/jyzb/api/bean/dto/TjDto/FinalTjOrgPoliceDto.java
+0
-3
TjOrgEqsDto.java
jyzb-api/src/main/java/com/junmp/jyzb/api/bean/dto/TjDto/TjOrgEqsDto.java
+1
-0
TjOrgPoliceDto.java
jyzb-api/src/main/java/com/junmp/jyzb/api/bean/dto/TjDto/TjOrgPoliceDto.java
+1
-0
TjOrgEqsReq.java
jyzb-api/src/main/java/com/junmp/jyzb/api/bean/query/TjReq/TjOrgEqsReq.java
+1
-0
TjOrgPoliceReq.java
jyzb-api/src/main/java/com/junmp/jyzb/api/bean/query/TjReq/TjOrgPoliceReq.java
+3
-2
TjController.java
jyzb-biz/src/main/java/com/junmp/jyzb/controller/TjController.java
+12
-5
InventorySummaryMapper.java
jyzb-biz/src/main/java/com/junmp/jyzb/mapper/InventorySummaryMapper.java
+6
-1
PoliceEquipmentMapper.java
jyzb-biz/src/main/java/com/junmp/jyzb/mapper/PoliceEquipmentMapper.java
+1
-1
TjService.java
jyzb-biz/src/main/java/com/junmp/jyzb/service/TjService.java
+3
-1
InventoryServiceImpl.java
jyzb-biz/src/main/java/com/junmp/jyzb/service/impl/InventoryServiceImpl.java
+1
-0
TjServiceImpl.java
jyzb-biz/src/main/java/com/junmp/jyzb/service/impl/TjServiceImpl.java
+61
-45
EquipmentCountSummaryMapper.xml
jyzb-biz/src/main/resources/mapper/EquipmentCountSummaryMapper.xml
+2
-2
InventorySummaryMapper.xml
jyzb-biz/src/main/resources/mapper/InventorySummaryMapper.xml
+9
-1
PoliceEquipmentMapper.xml
jyzb-biz/src/main/resources/mapper/PoliceEquipmentMapper.xml
+47
-1
PriceSumSummaryMapper.xml
jyzb-biz/src/main/resources/mapper/PriceSumSummaryMapper.xml
+2
-2
没有找到文件。
jyzb-api/src/main/java/com/junmp/jyzb/api/bean/dto/TjDto/FinalTjOrgPoliceDto.java
View file @
6dd8d1c6
...
...
@@ -4,9 +4,6 @@ import lombok.Data;
@Data
public
class
FinalTjOrgPoliceDto
{
private
String
policeId
;
private
String
policeName
;
private
String
policeCode
;
private
Integer
num
;
private
Integer
inNum
;
private
Integer
outNum
;
...
...
jyzb-api/src/main/java/com/junmp/jyzb/api/bean/dto/TjDto/TjOrgEqsDto.java
View file @
6dd8d1c6
...
...
@@ -53,4 +53,5 @@ public class TjOrgEqsDto {
private
Integer
destructionNumber
;
}
jyzb-api/src/main/java/com/junmp/jyzb/api/bean/dto/TjDto/TjOrgPoliceDto.java
View file @
6dd8d1c6
...
...
@@ -6,6 +6,7 @@ import lombok.Data;
public
class
TjOrgPoliceDto
{
private
String
policeId
;
private
String
policeName
;
private
String
policeCode
;
private
String
sizeId
;
private
String
sizeName
;
private
String
typeId
;
...
...
jyzb-api/src/main/java/com/junmp/jyzb/api/bean/query/TjReq/TjOrgEqsReq.java
View file @
6dd8d1c6
...
...
@@ -8,6 +8,7 @@ import java.util.List;
public
class
TjOrgEqsReq
extends
BaseRequest
{
//组织机构
private
Long
orgId
;
private
Long
parentOrgId
;
List
<
String
>
typeIdsList
;
private
List
<
String
>
sizeNameList
;
...
...
jyzb-api/src/main/java/com/junmp/jyzb/api/bean/query/TjReq/TjOrgPoliceReq.java
View file @
6dd8d1c6
...
...
@@ -8,7 +8,8 @@ import java.util.List;
@Data
public
class
TjOrgPoliceReq
extends
BaseRequest
{
private
Long
orgId
;
private
String
policeId
;
private
String
policeName
;
List
<
String
>
typeIdsList
;
private
List
<
String
>
sizeNameList
;
//
List<String> typeIdsList;
//
private List<String> sizeNameList;
}
jyzb-biz/src/main/java/com/junmp/jyzb/controller/TjController.java
View file @
6dd8d1c6
...
...
@@ -54,6 +54,13 @@ public class TjController {
public
ApiRes
<
FinalTjOrgEqsDto
>
TjOrgEqsSum
(
@RequestBody
TjOrgEqsReq
req
){
return
ApiRes
.
success
(
tjService
.
TjOrgEqsSum
(
req
));
}
//第二层数据
@PostMapping
(
"/TjOrgEqsSecondList"
)
@ApiOperation
(
"装备统计报表二层数据"
)
public
ApiRes
<
List
<
TjOrgEqsDto
>>
TjOrgEqsSecondList
(
@RequestBody
TjOrgEqsReq
req
){
return
ApiRes
.
success
(
tjService
.
TjOrgEqsSecondList
(
req
));
}
//装备统计报表(点击+后里面的数据)
@PostMapping
(
"/TjOrgEqsDetailPage"
)
@ApiOperation
(
"/查询组织机构下的装备统计明细分页"
)
...
...
@@ -157,11 +164,11 @@ public class TjController {
}
//人员统计报表(点击+后里面的数据)
@PostMapping
(
"/TjOrgPoliceDetailPage"
)
@ApiOperation
(
"/查询组织机构下的人员统计明细"
)
public
ApiRes
<
PageResult
<
TjOrgPoliceDto
>>
TjOrgPoliceDetailPage
(
@RequestBody
TjOrgPoliceReq
req
){
return
ApiRes
.
success
(
tjService
.
TjOrgPoliceDetailPage
(
req
));
}
//
@PostMapping("/TjOrgPoliceDetailPage")
//
@ApiOperation("/查询组织机构下的人员统计明细")
//
public ApiRes<PageResult<TjOrgPoliceDto>> TjOrgPoliceDetailPage(@RequestBody TjOrgPoliceReq req){
//
return ApiRes.success(tjService.TjOrgPoliceDetailPage(req));
//
}
@PostMapping
(
"/TjOrgPoliceDetailList"
)
@ApiOperation
(
"/查询组织机构下的人员统计明细"
)
public
ApiRes
<
List
<
TjOrgPoliceDto
>>
TjOrgPoliceDetailList
(
@RequestBody
TjOrgPoliceReq
req
){
...
...
jyzb-biz/src/main/java/com/junmp/jyzb/mapper/InventorySummaryMapper.java
View file @
6dd8d1c6
...
...
@@ -53,7 +53,7 @@ public interface InventorySummaryMapper extends BaseMapper<InventorySummary> {
List
<
TjOrgEqsDto
>
selectViewOrgeqsSum
();
void
useViewOrgeqs
(
@Param
(
"sql"
)
String
sql
);
void
useViewOrgeqs
(
@Param
(
"sql"
)
String
sql
,
@Param
(
"orgId"
)
Long
orgId
);
//获取合计
FinalTjOrgEqsDto
getSumByViewOrgeqsSum
();
...
...
@@ -81,4 +81,8 @@ public interface InventorySummaryMapper extends BaseMapper<InventorySummary> {
List
<
InventoryDto
>
GetDetailByTerms
(
@Param
(
"req"
)
InventoryReq
req
,
@Param
(
"pageNo"
)
Long
pageNo
,
@Param
(
"pageSize"
)
Long
pageSize
);
void
useViewOrgIdInSubordinate
(
@Param
(
"sql"
)
String
sql
);
void
useViewOrgIdInLevel
(
@Param
(
"sql"
)
String
sql
,
@Param
(
"orgId"
)
Long
orgId
);
}
\ No newline at end of file
jyzb-biz/src/main/java/com/junmp/jyzb/mapper/PoliceEquipmentMapper.java
View file @
6dd8d1c6
...
...
@@ -23,7 +23,7 @@ public interface PoliceEquipmentMapper extends BaseMapper<PoliceEquipment> {
FinalTjOrgPoliceDto
TjOrgPoliceSum
(
@Param
(
"req"
)
TjOrgPoliceReq
req
);
int
TjOrgPoliceDetailSum
(
@Param
(
"req"
)
TjOrgPoliceReq
req
);
//
int TjOrgPoliceDetailSum(@Param("req") TjOrgPoliceReq req);
List
<
TjOrgPoliceDto
>
TjOrgPoliceDetail
(
@Param
(
"req"
)
TjOrgPoliceReq
req
,
@Param
(
"pageNo"
)
Long
pageNo
,
@Param
(
"pageSize"
)
Long
pageSize
);
}
...
...
jyzb-biz/src/main/java/com/junmp/jyzb/service/TjService.java
View file @
6dd8d1c6
...
...
@@ -51,7 +51,9 @@ public interface TjService {
FinalTjOrgPoliceDto
TjOrgPoliceSum
(
TjOrgPoliceReq
req
);
PageResult
<
TjOrgPoliceDto
>
TjOrgPoliceDetailPage
(
TjOrgPoliceReq
req
);
//
PageResult<TjOrgPoliceDto> TjOrgPoliceDetailPage(TjOrgPoliceReq req);
List
<
TjOrgPoliceDto
>
TjOrgPoliceDetailList
(
TjOrgPoliceReq
req
);
List
<
TjOrgEqsDto
>
TjOrgEqsSecondList
(
TjOrgEqsReq
req
);
}
jyzb-biz/src/main/java/com/junmp/jyzb/service/impl/InventoryServiceImpl.java
View file @
6dd8d1c6
...
...
@@ -388,6 +388,7 @@ public class InventoryServiceImpl extends ServiceImpl<InventoryMapper, Inventory
}).
collect
(
Collectors
.
toList
());
return
updateBatchById
(
collect
);
}
// }
// else {
// List<Inventory> list = list(createWrapper(req));
...
...
jyzb-biz/src/main/java/com/junmp/jyzb/service/impl/TjServiceImpl.java
View file @
6dd8d1c6
package
com
.
junmp
.
jyzb
.
service
.
impl
;
import
cn.hutool.core.collection.CollectionUtil
;
import
cn.hutool.core.util.ObjectUtil
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.junmp.jyzb.api.bean.dto.EqsSumDto
;
...
...
@@ -126,26 +127,10 @@ public class TjServiceImpl implements TjService {
// List<String> typeIdsList = equipmentSizeService.selectByTypeIds(req.getTypeIdsList());
// List<String> sizeNameList = req.getSizeNameList();
//将前端传递的值进行处理并且执行存储过程
String
sql
=
"and (org_id="
+
req
.
getOrgId
()+
" or org_parent_id = "
+
req
.
getOrgId
()+
")"
;
if
(!
ObjectUtil
.
isEmpty
(
req
.
getTypeIdsList
())
&&
req
.
getTypeIdsList
().
size
()>
0
){
sql
+=
"and type_id in ("
;
for
(
String
typeId:
req
.
getTypeIdsList
())
{
sql
+=
typeId
+
","
;
}
sql
=
sql
.
substring
(
0
,
sql
.
length
()
-
1
);
sql
+=
")"
;
}
if
(!
ObjectUtil
.
isEmpty
(
req
.
getSizeNameList
())
&&
req
.
getSizeNameList
().
size
()>
0
){
sql
+=
"and size_name in ("
;
for
(
String
sizeName:
req
.
getSizeNameList
())
{
sql
+=
"'"
+
sizeName
+
"',"
;
}
sql
=
sql
.
substring
(
0
,
sql
.
length
()
-
1
);
sql
+=
")"
;
}
System
.
out
.
println
(
"sql = "
+
sql
);
String
sql
=
setSql
(
req
);
// System.out.println("sql = " + sql);
//执行存储过程
inventorySummaryMapper
.
useViewOrgeqs
(
sql
);
inventorySummaryMapper
.
useViewOrgeqs
(
sql
,
req
.
getOrgId
()
);
//查询视图
List
<
TjOrgEqsDto
>
tjOrgEqsDtoList
=
inventorySummaryMapper
.
selectViewOrgeqsSum
();
//查询出来的组织机构进行判断,如果该组织机构下的装备装备总数为0,那么将该组织机构从list中移除
...
...
@@ -172,6 +157,47 @@ public class TjServiceImpl implements TjService {
@Override
public
FinalTjOrgEqsDto
TjOrgEqsSum
(
TjOrgEqsReq
req
)
{
//将前端传递的值进行处理并且执行存储过程
String
sql
=
setSql
(
req
);
// System.out.println("sql = " + sql);
//执行存储过程
inventorySummaryMapper
.
useViewOrgeqs
(
sql
,
req
.
getOrgId
());
//在内存foreach还是去数据库再去查询一次
FinalTjOrgEqsDto
finalTjOrgEqsDto
=
inventorySummaryMapper
.
getSumByViewOrgeqsSum
();
if
(
ObjectUtil
.
isNotNull
(
finalTjOrgEqsDto
))
{
return
finalTjOrgEqsDto
;
}
else
{
return
new
FinalTjOrgEqsDto
();
}
}
@Override
public
List
<
TjOrgEqsDto
>
TjOrgEqsSecondList
(
TjOrgEqsReq
req
)
{
List
<
TjOrgEqsDto
>
tjOrgEqsDtoList
=
new
ArrayList
<>();
String
sql
=
setSql
(
req
);
if
(
req
.
getOrgId
()==
req
.
getParentOrgId
()){
inventorySummaryMapper
.
useViewOrgIdInLevel
(
sql
,
req
.
getOrgId
());
}
else
{
inventorySummaryMapper
.
useViewOrgIdInSubordinate
(
sql
);
}
//查询视图
tjOrgEqsDtoList
=
inventorySummaryMapper
.
selectViewOrgeqsSum
();
if
(
CollectionUtil
.
isNotEmpty
(
tjOrgEqsDtoList
)){
//查询出来的组织机构进行判断,如果该组织机构下的装备装备总数为0,那么将该组织机构从list中移除
tjOrgEqsDtoList
.
removeIf
(
tjOrgEqsDto
->
tjOrgEqsDto
.
getTotalNumber
()
==
0
);
//将组织机构进行排序后再进行返回
Comparator
<
TjOrgEqsDto
>
orgComparator
=
createOrgComparator
();
Collections
.
sort
(
tjOrgEqsDtoList
,
orgComparator
);
}
return
tjOrgEqsDtoList
;
}
private
String
setSql
(
TjOrgEqsReq
req
){
String
sql
=
"and (org_id="
+
req
.
getOrgId
()+
" or org_parent_id = "
+
req
.
getOrgId
()+
")"
;
if
(!
ObjectUtil
.
isEmpty
(
req
.
getTypeIdsList
())
&&
req
.
getTypeIdsList
().
size
()>
0
){
sql
+=
"and type_id in ("
;
...
...
@@ -189,21 +215,9 @@ public class TjServiceImpl implements TjService {
sql
=
sql
.
substring
(
0
,
sql
.
length
()
-
1
);
sql
+=
")"
;
}
System
.
out
.
println
(
"sql = "
+
sql
);
//执行存储过程
inventorySummaryMapper
.
useViewOrgeqs
(
sql
);
//在内存foreach还是去数据库再去查询一次
FinalTjOrgEqsDto
finalTjOrgEqsDto
=
inventorySummaryMapper
.
getSumByViewOrgeqsSum
();
if
(
ObjectUtil
.
isNotNull
(
finalTjOrgEqsDto
))
{
return
finalTjOrgEqsDto
;
}
else
{
return
new
FinalTjOrgEqsDto
();
}
return
sql
;
}
//查看装备统计详情
@Override
public
PageResult
<
InventorySumDto
>
TjOrgEqsDetailPage
(
TjOrgEqsReq
req
)
{
...
...
@@ -445,23 +459,25 @@ public class TjServiceImpl implements TjService {
}
}
@Override
public
PageResult
<
TjOrgPoliceDto
>
TjOrgPoliceDetailPage
(
TjOrgPoliceReq
req
)
{
if
(
ObjectUtil
.
isNull
(
req
.
getPageNo
())
&&
ObjectUtil
.
isNull
(
req
.
getPageSize
()))
{
req
.
setPageNo
(
1L
);
req
.
setPageSize
(
10L
);
}
int
size
=
policeEquipmentMapper
.
TjOrgPoliceDetailSum
(
req
);
List
<
TjOrgPoliceDto
>
returnList
=
policeEquipmentMapper
.
TjOrgPoliceDetail
(
req
,(
req
.
getPageNo
()-
1
)*
req
.
getPageSize
(),
req
.
getPageSize
());
Page
<
TjOrgPoliceDto
>
page
=
PageFactory
.
getDefaultPage
(
req
.
getPageNo
(),
req
.
getPageSize
());
page
.
setTotal
(
size
);
page
.
setRecords
(
returnList
);
return
PageResultFactory
.
createPageResult
(
page
);
}
//
@Override
//
public PageResult<TjOrgPoliceDto> TjOrgPoliceDetailPage(TjOrgPoliceReq req) {
//
if (ObjectUtil.isNull(req.getPageNo()) && ObjectUtil.isNull(req.getPageSize())) {
//
req.setPageNo(1L);
//
req.setPageSize(10L);
//
}
//
int size = policeEquipmentMapper.TjOrgPoliceDetailSum(req);
//
List<TjOrgPoliceDto> returnList=policeEquipmentMapper.TjOrgPoliceDetail(req,(req.getPageNo()-1)* req.getPageSize(),req.getPageSize());
//
Page<TjOrgPoliceDto> page = PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize());
//
page.setTotal(size);
//
page.setRecords(returnList);
//
return PageResultFactory.createPageResult(page);
//
}
@Override
public
List
<
TjOrgPoliceDto
>
TjOrgPoliceDetailList
(
TjOrgPoliceReq
req
)
{
List
<
TjOrgPoliceDto
>
returnList
=
policeEquipmentMapper
.
TjOrgPoliceDetail
(
req
,
null
,
null
);
return
returnList
;
}
}
jyzb-biz/src/main/resources/mapper/EquipmentCountSummaryMapper.xml
View file @
6dd8d1c6
...
...
@@ -38,12 +38,12 @@
<update
id=
"setSizeName"
>
update vie_price_sum_summary
set size_name=#{sizeName}
where size_id ={sizeId}
where size_id =
#
{sizeId}
</update>
<update
id=
"setTypeName"
>
update vie_price_sum_summary
set type_name=#{typeName}
where type_id ={typeId}
where type_id =
#
{typeId}
</update>
<delete
id=
"deleteAll"
>
delete from vie_equipment_count_summary where
...
...
jyzb-biz/src/main/resources/mapper/InventorySummaryMapper.xml
View file @
6dd8d1c6
...
...
@@ -407,9 +407,15 @@
</insert>
<insert
id=
"useViewOrgeqs"
statementType=
"CALLABLE"
>
{CALL view_orgeqs(#{sql,mode=IN})}
{CALL view_orgeqs(#{sql,mode=IN}
,#{orgId,mode=IN}
)}
</insert>
<insert
id=
"useViewOrgIdInSubordinate"
parameterType=
"java.lang.String"
>
{CALL view_orgIdInSubordinate(#{sql,mode=IN})}
</insert>
<insert
id=
"useViewOrgIdInLevel"
>
{CALL view_orgIdInLevel(#{sql,mode=IN},#{orgId,mode=IN})}
</insert>
<select
id=
"getSumByViewOrgeqsSum"
resultType=
"com.junmp.jyzb.api.bean.dto.TjDto.FinalTjOrgEqsDto"
>
select sum(total_number) as total_number,
...
...
@@ -687,4 +693,5 @@
</select>
</mapper>
\ No newline at end of file
jyzb-biz/src/main/resources/mapper/PoliceEquipmentMapper.xml
View file @
6dd8d1c6
...
...
@@ -21,6 +21,52 @@
update_time,create_time
</sql>
<select
id=
"TjOrgPolice"
resultType=
"com.junmp.jyzb.api.bean.dto.TjDto.TjOrgPoliceDto"
>
SELECT pe.police_id,max(pe.police_name) as police_name,sum(pe.num) as num,
sum(pe.in_num) as in_num,sum(pe.out_num) as out_num,max(p.police_code) as police_code
FROM `base_police_equipment` pe join base_policeman p on p.id=pe.police_id
where pe.org_id=#{req.orgId}
<if
test=
"req.policeName !=null and req.policeName != ''"
>
and pe.police_name like CONCAT('%', #{req.policeName}, '%')
</if>
GROUP BY pe.police_id
</select>
<select
id=
"getCount"
resultType=
"java.lang.Integer"
parameterType=
"com.junmp.jyzb.api.bean.query.TjReq.TjOrgPoliceReq"
>
select count(*) FROM(
SELECT pe.police_id,max(pe.police_name) as police_name,sum(pe.num) as num,
sum(pe.in_num) as in_num,sum(pe.out_num) as out_num,max(p.police_code) as police_code
FROM `base_police_equipment` pe join base_policeman p on p.id=pe.police_id
where pe.org_id=#{req.orgId}
<if
test=
"req.policeName !=null and req.policeName != ''"
>
and pe.police_name like CONCAT('%', #{req.policeName}, '%')
</if>
GROUP BY pe.police_id
) as a
</select>
<select
id=
"TjOrgPoliceSum"
resultType=
"com.junmp.jyzb.api.bean.dto.TjDto.FinalTjOrgPoliceDto"
parameterType=
"com.junmp.jyzb.api.bean.query.TjReq.TjOrgPoliceReq"
>
select sum(num) as num,sum(in_num)as in_num,sum(out_num) as out_num FROM
(
SELECT police_id,max(police_name) as police_name,
sum(num) as num,sum(in_num) as in_num,sum(out_num) as out_num
FROM `base_police_equipment`
where org_id=#{req.orgId}
<if
test=
"req.policeName !=null and req.policeName != ''"
>
and police_name like CONCAT('%', #{req.policeName}, '%')
</if>
GROUP BY police_id
) as a
</select>
<select
id=
"TjOrgPoliceDetail"
resultType=
"com.junmp.jyzb.api.bean.dto.TjDto.TjOrgPoliceDto"
>
SELECT MAX(police_id) as police_id,max(police_name) as police_name,size_id,max(size_name) as size_name,
type_id,max(type_name) as type_name,sum(num) as num,sum(in_num) as in_num,
sum(out_num) as out_num,GROUP_CONCAT(DISTINCT location_name) AS location_name
FROM `base_police_equipment`
where org_id=#{req.orgId} and police_id=#{req.policeId}
GROUP BY size_id, type_id
ORDER BY type_id
<if
test=
"pageNo != null and pageNo != '' and pageSize != null and pageSize != '' "
>
limit #{pageNo},#{pageSize}
</if>
</select>
</mapper>
jyzb-biz/src/main/resources/mapper/PriceSumSummaryMapper.xml
View file @
6dd8d1c6
...
...
@@ -4,12 +4,12 @@
<update
id=
"setSizeName"
>
update vie_equipment_count_summary
set size_name=#{sizeName}
where size_id ={sizeId}
where size_id =
#
{sizeId}
</update>
<update
id=
"setTypeName"
>
update vie_equipment_count_summary
set type_name=#{typeName}
where type_id ={typeId}
where type_id =
#
{typeId}
</update>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论