parent
a6ac0080ec
commit
9994670465
@ -0,0 +1,123 @@
|
||||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
pb "moredoc/api/v1"
|
||||
"moredoc/middleware/auth"
|
||||
"moredoc/model"
|
||||
"moredoc/util"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type ReportAPIService struct {
|
||||
pb.UnimplementedReportAPIServer
|
||||
dbModel *model.DBModel
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewReportAPIService(dbModel *model.DBModel, logger *zap.Logger) (service *ReportAPIService) {
|
||||
return &ReportAPIService{dbModel: dbModel, logger: logger.Named("ReportAPIService")}
|
||||
}
|
||||
|
||||
func (s *ReportAPIService) checkLogin(ctx context.Context) (*auth.UserClaims, error) {
|
||||
return checkGRPCLogin(s.dbModel, ctx)
|
||||
}
|
||||
|
||||
func (s *ReportAPIService) checkPermission(ctx context.Context) (*auth.UserClaims, error) {
|
||||
return checkGRPCPermission(s.dbModel, ctx)
|
||||
}
|
||||
|
||||
func (s *ReportAPIService) CreateReport(ctx context.Context, req *pb.Report) (*emptypb.Empty, error) {
|
||||
UserClaims, err := s.checkLogin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.DocumentId == 0 {
|
||||
return nil, status.Error(codes.InvalidArgument, "文档参数不正确")
|
||||
}
|
||||
|
||||
report, _ := s.dbModel.GetReportByDocUser(req.DocumentId, UserClaims.UserId)
|
||||
if report.Id > 0 {
|
||||
return nil, status.Error(codes.AlreadyExists, "您已举报过当前文档")
|
||||
}
|
||||
|
||||
util.CopyStruct(req, &report)
|
||||
report.UserId = UserClaims.UserId
|
||||
err = s.dbModel.CreateReport(&report)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "创建举报失败")
|
||||
}
|
||||
|
||||
return &emptypb.Empty{}, nil
|
||||
}
|
||||
|
||||
func (s *ReportAPIService) UpdateReport(ctx context.Context, req *pb.Report) (*emptypb.Empty, error) {
|
||||
_, err := s.checkPermission(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
report := &model.Report{}
|
||||
util.CopyStruct(req, report)
|
||||
err = s.dbModel.UpdateReport(report, "status", "remark")
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "更新举报失败")
|
||||
}
|
||||
|
||||
return &emptypb.Empty{}, nil
|
||||
}
|
||||
|
||||
func (s *ReportAPIService) DeleteReport(ctx context.Context, req *pb.DeleteReportRequest) (*emptypb.Empty, error) {
|
||||
_, err := s.checkPermission(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = s.dbModel.DeleteReport(req.Id)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "删除举报失败")
|
||||
}
|
||||
|
||||
return &emptypb.Empty{}, nil
|
||||
}
|
||||
|
||||
func (s *ReportAPIService) ListReport(ctx context.Context, req *pb.ListReportRequest) (*pb.ListReportReply, error) {
|
||||
_, err := s.checkPermission(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
opt := &model.OptionGetReportList{
|
||||
WithCount: true,
|
||||
Page: int(req.Page),
|
||||
Size: int(req.Size_),
|
||||
QueryLike: make(map[string][]interface{}),
|
||||
QueryIn: make(map[string][]interface{}),
|
||||
}
|
||||
|
||||
if req.Wd != "" {
|
||||
opt.QueryLike["document_title"] = []interface{}{req.Wd}
|
||||
}
|
||||
|
||||
if len(req.Status) > 0 {
|
||||
opt.QueryIn["status"] = util.Slice2Interface(req.Status)
|
||||
}
|
||||
|
||||
reports, total, err := s.dbModel.GetReportList(opt)
|
||||
if err != nil && err != gorm.ErrRecordNotFound {
|
||||
return nil, status.Error(codes.Internal, "获取举报列表失败")
|
||||
}
|
||||
|
||||
pbReport := &pb.ListReportReply{
|
||||
Total: total,
|
||||
Report: reports,
|
||||
}
|
||||
return pbReport, nil
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
import service from '~/utils/request'
|
||||
|
||||
export const createReport = (data) => {
|
||||
return service({
|
||||
url: '/api/v1/report',
|
||||
method: 'post',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
export const updateReport = (data) => {
|
||||
return service({
|
||||
url: '/api/v1/report',
|
||||
method: 'put',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteReport = (params) => {
|
||||
return service({
|
||||
url: '/api/v1/report',
|
||||
method: 'delete',
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
export const listReport = (params) => {
|
||||
return service({
|
||||
url: '/api/v1/report/list',
|
||||
method: 'get',
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,137 @@
|
||||
<template>
|
||||
<div class="com-form-report">
|
||||
<el-form
|
||||
ref="report"
|
||||
label-position="top"
|
||||
label-width="80px"
|
||||
:model="report"
|
||||
>
|
||||
<el-form-item label="文档">
|
||||
<el-input v-model="report.document_title" :disabled="true"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="举报原因">
|
||||
<el-radio-group v-model="report.reason" class="report-reason">
|
||||
<el-row>
|
||||
<el-col
|
||||
:span="8"
|
||||
v-for="item in reportOptions"
|
||||
:key="'rs' + item.value"
|
||||
>
|
||||
<el-radio :label="item.value">{{ item.label }}</el-radio>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<template v-if="isAdmin">
|
||||
<el-form-item label="处理状态">
|
||||
<el-switch
|
||||
v-model="report.status"
|
||||
active-text="已处理"
|
||||
inactive-text="未处理"
|
||||
>
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="处理备注">
|
||||
<el-input
|
||||
v-model="report.remark"
|
||||
placeholder="请输入文档处理相关备注"
|
||||
type="textarea"
|
||||
rows="3"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-check"
|
||||
class="btn-block"
|
||||
@click="setReport"
|
||||
>提交</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { createReport, updateReport } from '~/api/report'
|
||||
import { reportOptions } from '~/utils/enum'
|
||||
export default {
|
||||
name: 'FormReport',
|
||||
props: {
|
||||
isAdmin: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
initReport: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
id: 0,
|
||||
report_id: 0,
|
||||
document_id: 0,
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
report: { id: 0, status: 0 },
|
||||
reportOptions,
|
||||
statusOptions: [
|
||||
{ label: '未处理', value: 0 },
|
||||
{ label: '已处理', value: 1 },
|
||||
],
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
initReport: {
|
||||
handler(val) {
|
||||
this.report = { status: 0, ...val }
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.report = this.initReport
|
||||
},
|
||||
methods: {
|
||||
async setReport() {
|
||||
if (this.report.id > 0) {
|
||||
const res = await updateReport(this.report)
|
||||
if (res.status === 200) {
|
||||
this.$message.success('更新成功')
|
||||
this.$emit('success')
|
||||
} else {
|
||||
this.$message.error(res.data.message)
|
||||
}
|
||||
} else {
|
||||
const res = await createReport(this.report)
|
||||
if (res.status === 200) {
|
||||
this.$message.success('提交成功')
|
||||
this.$emit('success')
|
||||
} else {
|
||||
this.$message.error(res.data.message)
|
||||
}
|
||||
}
|
||||
},
|
||||
reset() {
|
||||
this.report = { id: 0 }
|
||||
this.$refs.report.resetFields()
|
||||
this.$refs.report.clearValidate()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.com-form-report {
|
||||
.el-select {
|
||||
width: 100%;
|
||||
}
|
||||
.report-reason {
|
||||
width: 100%;
|
||||
.el-radio {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,236 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-card shadow="never" class="search-card">
|
||||
<FormSearch
|
||||
:fields="searchFormFields"
|
||||
:loading="loading"
|
||||
:show-create="false"
|
||||
:show-delete="true"
|
||||
:disabled-delete="selectedRow.length === 0"
|
||||
@onSearch="onSearch"
|
||||
@onCreate="onCreate"
|
||||
@onDelete="batchDelete"
|
||||
/>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mgt-20px">
|
||||
<TableList
|
||||
:loading="loading"
|
||||
:table-data="reports"
|
||||
:fields="tableListFields"
|
||||
:show-actions="true"
|
||||
:show-view="false"
|
||||
:show-edit="true"
|
||||
:show-delete="true"
|
||||
:show-select="true"
|
||||
@selectRow="selectRow"
|
||||
@editRow="editRow"
|
||||
@deleteRow="deleteRow"
|
||||
/>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mgt-20px">
|
||||
<div class="text-right">
|
||||
<el-pagination
|
||||
background
|
||||
:current-page="search.page"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:page-size="search.size"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handlePageChange"
|
||||
>
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog
|
||||
:title="report.id ? '编辑举报' : '新增举报'"
|
||||
:visible.sync="formReportVisible"
|
||||
width="640px"
|
||||
>
|
||||
<FormReport
|
||||
ref="reportForm"
|
||||
:init-report="report"
|
||||
:is-admin="true"
|
||||
@success="formReportSuccess"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listReport, deleteReport } from '~/api/report'
|
||||
import { reportOptions } from '~/utils/enum'
|
||||
import TableList from '~/components/TableList.vue'
|
||||
import FormSearch from '~/components/FormSearch.vue'
|
||||
import FormReport from '~/components/FormReport.vue'
|
||||
export default {
|
||||
components: { TableList, FormSearch, FormReport },
|
||||
layout: 'admin',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
formReportVisible: false,
|
||||
search: {
|
||||
wd: '',
|
||||
page: 1,
|
||||
status: [],
|
||||
size: 10,
|
||||
},
|
||||
reports: [],
|
||||
reportOptions,
|
||||
total: 0,
|
||||
searchFormFields: [],
|
||||
tableListFields: [],
|
||||
selectedRow: [],
|
||||
report: { id: 0 },
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
this.initSearchForm()
|
||||
this.initTableListFields()
|
||||
await this.listReport()
|
||||
},
|
||||
methods: {
|
||||
async listReport() {
|
||||
this.loading = true
|
||||
const res = await listReport(this.search)
|
||||
if (res.status === 200) {
|
||||
this.reports = res.data.report
|
||||
this.total = res.data.total
|
||||
} else {
|
||||
this.$message.error(res.data.message)
|
||||
}
|
||||
this.loading = false
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.search.size = val
|
||||
this.listReport()
|
||||
},
|
||||
handlePageChange(val) {
|
||||
this.search.page = val
|
||||
this.listReport()
|
||||
},
|
||||
onSearch(search) {
|
||||
this.search = { ...this.search, page: 1, ...search }
|
||||
this.listReport()
|
||||
},
|
||||
onCreate() {
|
||||
this.report = { id: 0 }
|
||||
this.formReportVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.reportForm.reset()
|
||||
})
|
||||
},
|
||||
async editRow(row) {
|
||||
this.report = row
|
||||
this.formReportVisible = true
|
||||
},
|
||||
formReportSuccess() {
|
||||
this.formReportVisible = false
|
||||
this.listReport()
|
||||
},
|
||||
batchDelete() {
|
||||
this.$confirm(
|
||||
`您确定要删除选中的【${this.selectedRow.length}条】举报吗?删除之后不可恢复!`,
|
||||
'温馨提示',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(async () => {
|
||||
const ids = this.selectedRow.map((item) => item.id)
|
||||
const res = await deleteReport({ id: ids })
|
||||
if (res.status === 200) {
|
||||
this.$message.success('删除成功')
|
||||
this.listReport()
|
||||
} else {
|
||||
this.$message.error(res.data.message)
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
deleteRow(row) {
|
||||
this.$confirm(
|
||||
`您确定要删除对文档【${row.document_title}】的举报吗?删除之后不可恢复!`,
|
||||
'温馨提示',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(async () => {
|
||||
const res = await deleteReport({ id: row.id })
|
||||
if (res.status === 200) {
|
||||
this.$message.success('删除成功')
|
||||
this.listReport()
|
||||
} else {
|
||||
this.$message.error(res.data.message)
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
selectRow(rows) {
|
||||
this.selectedRow = rows
|
||||
},
|
||||
initSearchForm() {
|
||||
this.searchFormFields = [
|
||||
{
|
||||
type: 'text',
|
||||
label: '关键字',
|
||||
name: 'wd',
|
||||
placeholder: '请输入关键字',
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '状态',
|
||||
name: 'enable',
|
||||
placeholder: '请选择状态',
|
||||
multiple: true,
|
||||
options: [
|
||||
{ label: '启用', value: 1 },
|
||||
{ label: '禁用', value: 0 },
|
||||
],
|
||||
},
|
||||
]
|
||||
},
|
||||
initTableListFields() {
|
||||
const reasonEnum = {}
|
||||
this.reportOptions.forEach((item) => {
|
||||
reasonEnum[item.value] = item
|
||||
})
|
||||
|
||||
this.tableListFields = [
|
||||
{ prop: 'id', label: 'ID', width: 80, type: 'number', fixed: 'left' },
|
||||
{
|
||||
prop: 'status',
|
||||
label: '是否已处理',
|
||||
width: 100,
|
||||
type: 'bool',
|
||||
fixed: 'left',
|
||||
},
|
||||
{ prop: 'document_title', label: '名称', minWidth: 150, fixed: 'left' },
|
||||
{
|
||||
prop: 'reason',
|
||||
label: '举报原因',
|
||||
width: 80,
|
||||
type: 'enum',
|
||||
enum: reasonEnum,
|
||||
},
|
||||
{
|
||||
prop: 'username',
|
||||
label: '举报人',
|
||||
width: 100,
|
||||
},
|
||||
{ prop: 'remark', label: '处理描述', minWidth: 150 },
|
||||
{ prop: 'created_at', label: '举报时间', width: 160, type: 'datetime' },
|
||||
{ prop: 'updated_at', label: '更新时间', width: 160, type: 'datetime' },
|
||||
]
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
Loading…
Reference in new issue