修复结算单管理问题
This commit is contained in:
parent
20d0d35146
commit
6a09cbeb70
@ -63,9 +63,9 @@
|
|||||||
align="center"
|
align="center"
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<div>基础费用:{{ scope.row.amount.toFixed(2) }}</div>
|
<!-- <div>基础费用:{{ scope.row.amount.toFixed(2) }}</div>
|
||||||
<div>附加费用:{{ scope.row.surchargeAmount.toFixed(4) }}</div>
|
<div>附加费用:{{ scope.row.surchargeAmount.toFixed(4) }}</div> -->
|
||||||
<div>总费用:{{ scope.row.totalAmount.toFixed(4) }}</div>
|
<div>{{ scope.row.totalAmount.toFixed(4) }}</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="areaName" label="区域" align="center" />
|
<el-table-column prop="areaName" label="区域" align="center" />
|
||||||
|
@ -58,9 +58,9 @@
|
|||||||
<el-table-column prop="orderTime" label="下单时间" align="center" width="180" />
|
<el-table-column prop="orderTime" label="下单时间" align="center" width="180" />
|
||||||
<el-table-column label="下单费用" width="180" align="center">
|
<el-table-column label="下单费用" width="180" align="center">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<div>基础费用:{{ scope.row.orderAmount.toFixed(2) }}</div>
|
<!-- <div>基础费用:{{ scope.row.orderAmount.toFixed(2) }}</div>
|
||||||
<div>附加费用:{{ scope.row.surchargeAmount.toFixed(4) }}</div>
|
<div>附加费用:{{ scope.row.surchargeAmount.toFixed(4) }}</div> -->
|
||||||
<div>总费用:{{ scope.row.totalAmount.toFixed(4) }}</div>
|
<div>{{ scope.row.totalAmount.toFixed(4) }}</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="scenicArea" label="景区" align="center" />
|
<el-table-column prop="scenicArea" label="景区" align="center" />
|
||||||
@ -108,23 +108,17 @@
|
|||||||
:visible.sync="dialogVisible"
|
:visible.sync="dialogVisible"
|
||||||
width="50%"
|
width="50%"
|
||||||
>
|
>
|
||||||
<el-table :data="settlementList">
|
<div class="settlement-list">
|
||||||
<el-table-column prop="scenicArea" label="委托方">
|
<el-card v-for="item in settlementList" :key="item.attractionId" class="settlement-card">
|
||||||
<template slot-scope="scope">
|
<div class="settlement-item">
|
||||||
委托方:{{ scope.row.scenicArea }}
|
<h3>委托方:{{ getScenicName(item.attractionId) }}</h3>
|
||||||
</template>
|
<div class="settlement-info">
|
||||||
</el-table-column>
|
<p>重量:{{ item.cargoWeight }} kg</p>
|
||||||
<el-table-column prop="weight" label="重量">
|
<p>金额:{{ item.totalAmount }} 元</p>
|
||||||
<template slot-scope="scope">
|
</div>
|
||||||
重量:{{ scope.row.weight }}
|
</div>
|
||||||
</template>
|
</el-card>
|
||||||
</el-table-column>
|
</div>
|
||||||
<el-table-column prop="amount" label="金额">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
金额:{{ scope.row.amount }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
<span slot="footer" class="dialog-footer">
|
||||||
<el-button @click="handleCancel">取消</el-button>
|
<el-button @click="handleCancel">取消</el-button>
|
||||||
<el-button type="primary" @click="handleConfirm">确认生成</el-button>
|
<el-button type="primary" @click="handleConfirm">确认生成</el-button>
|
||||||
@ -329,38 +323,13 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 按景区分组并生成结算列表
|
|
||||||
const ordersByScenic = {}
|
|
||||||
this.selection.forEach(order => {
|
|
||||||
if (!ordersByScenic[order.scenicArea]) {
|
|
||||||
ordersByScenic[order.scenicArea] = []
|
|
||||||
}
|
|
||||||
ordersByScenic[order.scenicArea].push(order)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 生成结算列表数据
|
|
||||||
this.settlementList = Object.keys(ordersByScenic).map(scenicArea => ({
|
|
||||||
scenicArea: scenicArea,
|
|
||||||
weight: '100kg', // 示例数据,实际应根据订单计算
|
|
||||||
amount: '100元' // 示例数据,实际应根据订单计算
|
|
||||||
}))
|
|
||||||
|
|
||||||
// 调用接口获取结算确认列表
|
// 调用接口获取结算确认列表
|
||||||
getGenerateSettleOrderConfirmList(this.selection.map(order => order.id))
|
getGenerateSettleOrderConfirmList(this.selection.map(order => order.id))
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.success) {
|
if (response) {
|
||||||
// 成功获取结算确认列表
|
// 成功获取结算确认列表,直接使用API返回的数据
|
||||||
this.settlementList = response.data || []
|
|
||||||
// 获取的数据为attractionId,cargoWeight,totalAmount,需要转换
|
this.settlementList = response || []
|
||||||
// 通过attractionId获取景区名称
|
|
||||||
this.settlementList = this.settlementList.map(item => {
|
|
||||||
const scenic = this.scenicAreaOptions.find(s => s.id === item.attractionId)
|
|
||||||
return {
|
|
||||||
scenicArea: scenic ? scenic.name : '未知景区',
|
|
||||||
weight: item.cargoWeight,
|
|
||||||
amount: item.totalAmount
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// 如果没有数据,提示用户
|
// 如果没有数据,提示用户
|
||||||
if (this.settlementList.length === 0) {
|
if (this.settlementList.length === 0) {
|
||||||
this.$message.warning('没有可生成结算单的订单')
|
this.$message.warning('没有可生成结算单的订单')
|
||||||
@ -387,7 +356,7 @@ export default {
|
|||||||
this.selection.map(order => order.id)
|
this.selection.map(order => order.id)
|
||||||
)
|
)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.success) {
|
if (response) {
|
||||||
this.$message.success('结算单生成成功')
|
this.$message.success('结算单生成成功')
|
||||||
this.dialogVisible = false
|
this.dialogVisible = false
|
||||||
this.$router.push('/order/orderDetail')
|
this.$router.push('/order/orderDetail')
|
||||||
@ -404,6 +373,11 @@ export default {
|
|||||||
|
|
||||||
handleCancel() {
|
handleCancel() {
|
||||||
this.dialogVisible = false
|
this.dialogVisible = false
|
||||||
|
},
|
||||||
|
|
||||||
|
getScenicName(attractionId) {
|
||||||
|
const scenic = this.scenicAreaOptions.find(s => s.id === attractionId)
|
||||||
|
return scenic ? scenic.name : '未知景区'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -486,4 +460,36 @@ export default {
|
|||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
padding: 20px 0;
|
padding: 20px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.settlement-list {
|
||||||
|
padding: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settlement-card {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: calc(33.33% - 7px);
|
||||||
|
min-width: 200px;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
.settlement-item {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin: 0 0 8px 0;
|
||||||
|
color: #303133;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settlement-info {
|
||||||
|
p {
|
||||||
|
margin: 4px 0;
|
||||||
|
color: #606266;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
|
<!-- PDF导出组件 -->
|
||||||
|
<settlement-pdf
|
||||||
|
v-if="currentSettlementId"
|
||||||
|
ref="settlementPdf"
|
||||||
|
:settlement-order-id="currentSettlementId"
|
||||||
|
v-show="false"
|
||||||
|
/>
|
||||||
<!-- 查询及操作区域 -->
|
<!-- 查询及操作区域 -->
|
||||||
<div class="head-container">
|
<div class="head-container">
|
||||||
<div class="filter-container">
|
<div class="filter-container">
|
||||||
@ -75,8 +82,12 @@
|
|||||||
<script>
|
<script>
|
||||||
import { getSettleOrderList } from '@/api/order'
|
import { getSettleOrderList } from '@/api/order'
|
||||||
import { getUserNameValue } from '@/api/dropdown'
|
import { getUserNameValue } from '@/api/dropdown'
|
||||||
|
import SettlementPdf from './orderDetail/settlementPdf.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
SettlementPdf
|
||||||
|
},
|
||||||
name: 'settlementOrder',
|
name: 'settlementOrder',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -89,6 +100,7 @@ export default {
|
|||||||
size: 10,
|
size: 10,
|
||||||
total: 2
|
total: 2
|
||||||
},
|
},
|
||||||
|
currentSettlementId: null,
|
||||||
tableData: [
|
tableData: [
|
||||||
{
|
{
|
||||||
attractionId: 2,
|
attractionId: 2,
|
||||||
@ -174,9 +186,20 @@ export default {
|
|||||||
query: { orderId: row.id.toString() }
|
query: { orderId: row.id.toString() }
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handlePrint(row) {
|
async handlePrint(row) {
|
||||||
// 打印结算单
|
if (row.id) {
|
||||||
console.log('打印结算单:', row)
|
this.currentSettlementId = row.id.toString()
|
||||||
|
try {
|
||||||
|
// 等待vue渲染
|
||||||
|
await this.$nextTick()
|
||||||
|
await this.$refs.settlementPdf.generatePDF()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error generating PDF:', error)
|
||||||
|
this.$message.error('导出PDF失败')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$message.warning('没有结算单ID')
|
||||||
|
}
|
||||||
},
|
},
|
||||||
handleGenerate() {
|
handleGenerate() {
|
||||||
this.$router.push('/order/generateOrder')
|
this.$router.push('/order/generateOrder')
|
||||||
|
@ -123,15 +123,15 @@
|
|||||||
<!-- 操作按钮 -->
|
<!-- 操作按钮 -->
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<el-button
|
<el-button
|
||||||
v-if="settlementStatus === 0"
|
:disabled="!(settlementStatus === 0)"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleCancelSettlement"
|
@click="handleCancelSettlement"
|
||||||
>
|
>
|
||||||
取消结算
|
取消结算
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="primary" @click="handlePrint">导出结算单</el-button>
|
<el-button type="primary" @click="handlePrint">打印结算单</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="settlementStatus === 0"
|
v-if="settlementStatus === 2"
|
||||||
type="success"
|
type="success"
|
||||||
@click="handleStatusChange(1)"
|
@click="handleStatusChange(1)"
|
||||||
>
|
>
|
||||||
@ -148,15 +148,17 @@
|
|||||||
|
|
||||||
<!-- PDF导出组件 -->
|
<!-- PDF导出组件 -->
|
||||||
<settlement-pdf
|
<settlement-pdf
|
||||||
|
v-if="$route.query.orderId"
|
||||||
ref="settlementPdf"
|
ref="settlementPdf"
|
||||||
:order-data="currentOrder"
|
:order-data="currentOrder"
|
||||||
|
:settlement-order-id="$route.query.orderId"
|
||||||
v-show="false"
|
v-show="false"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getSettleOrderDetail, updateSettleOrderStatus } from '@/api/order'
|
import { getSettleOrderDetail, updateSettleOrderStatus, printSettleOrderData } from '@/api/order'
|
||||||
import { getDetail } from "@/api/system/pilot";
|
import { getDetail } from "@/api/system/pilot";
|
||||||
import { getCustomerId } from '@/api/system/customer'
|
import { getCustomerId } from '@/api/system/customer'
|
||||||
import { getScenicValue } from '@/api/dropdown'
|
import { getScenicValue } from '@/api/dropdown'
|
||||||
@ -175,6 +177,7 @@ export default {
|
|||||||
scenicAreaOptions: [],
|
scenicAreaOptions: [],
|
||||||
settlementStatus: 0,
|
settlementStatus: 0,
|
||||||
currentOrder: null,
|
currentOrder: null,
|
||||||
|
originalData: [], // 存储原始数据,用于筛选
|
||||||
query: {
|
query: {
|
||||||
batchNo: "",
|
batchNo: "",
|
||||||
scenicArea: "",
|
scenicArea: "",
|
||||||
@ -223,6 +226,7 @@ export default {
|
|||||||
const scenic = scenicResponse.find(s => s.key === item.attractionId)
|
const scenic = scenicResponse.find(s => s.key === item.attractionId)
|
||||||
item.scenicName = scenic ? scenic.value : ''
|
item.scenicName = scenic ? scenic.value : ''
|
||||||
}))
|
}))
|
||||||
|
this.originalData = settleOrderDetail // 保存原始数据
|
||||||
this.tableData = settleOrderDetail
|
this.tableData = settleOrderDetail
|
||||||
if(settleOrderDetail.length > 0) {
|
if(settleOrderDetail.length > 0) {
|
||||||
this.currentOrder = settleOrderDetail[0]
|
this.currentOrder = settleOrderDetail[0]
|
||||||
@ -237,23 +241,39 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async handleSearch() {
|
handleSearch() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
try {
|
try {
|
||||||
const params = {
|
// 从原始数据中筛选
|
||||||
batchNo: this.query.batchNo,
|
const filteredData = this.originalData.filter(item => {
|
||||||
attractionId: this.query.scenicArea,
|
let matchesBatchNo = true
|
||||||
startTime: this.query.dateRange ? this.query.dateRange[0] : null,
|
let matchesScenicArea = true
|
||||||
endTime: this.query.dateRange ? this.query.dateRange[1] : null
|
let matchesDateRange = true
|
||||||
}
|
|
||||||
const settleOrderDetail = await getSettleOrderDetail(params)
|
// 批次号筛选
|
||||||
await Promise.all(settleOrderDetail.map(async (item) => {
|
if (this.query.batchNo) {
|
||||||
const customerResponse = await getCustomerId(item.customerId)
|
matchesBatchNo = item.batchNo.toLowerCase().includes(this.query.batchNo.toLowerCase())
|
||||||
item.customerName = customerResponse.name
|
}
|
||||||
const scenic = this.scenicAreaOptions.find(s => s.value === item.attractionId)
|
|
||||||
item.scenicName = scenic ? scenic.label : ''
|
// 景区筛选
|
||||||
}))
|
if (this.query.scenicArea) {
|
||||||
this.tableData = settleOrderDetail
|
matchesScenicArea = item.attractionId === this.query.scenicArea
|
||||||
|
}
|
||||||
|
|
||||||
|
// 日期范围筛选
|
||||||
|
if (this.query.dateRange && this.query.dateRange.length === 2) {
|
||||||
|
const orderDate = new Date(item.createTime)
|
||||||
|
const startDate = new Date(this.query.dateRange[0])
|
||||||
|
const endDate = new Date(this.query.dateRange[1])
|
||||||
|
startDate.setHours(0, 0, 0, 0)
|
||||||
|
endDate.setHours(23, 59, 59, 999)
|
||||||
|
matchesDateRange = orderDate >= startDate && orderDate <= endDate
|
||||||
|
}
|
||||||
|
|
||||||
|
return matchesBatchNo && matchesScenicArea && matchesDateRange
|
||||||
|
})
|
||||||
|
|
||||||
|
this.tableData = filteredData
|
||||||
// 重置分页到第一页
|
// 重置分页到第一页
|
||||||
this.page.current = 1
|
this.page.current = 1
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -307,16 +327,17 @@ export default {
|
|||||||
this.page.current = val;
|
this.page.current = val;
|
||||||
},
|
},
|
||||||
async handlePrint() {
|
async handlePrint() {
|
||||||
// 调用PDF组件的导出方法
|
if (this.$route.query.orderId) {
|
||||||
if (this.currentOrder) {
|
|
||||||
try {
|
try {
|
||||||
|
// Wait for Vue to render the component
|
||||||
|
await this.$nextTick()
|
||||||
await this.$refs.settlementPdf.generatePDF()
|
await this.$refs.settlementPdf.generatePDF()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error generating PDF:', error)
|
console.error('Error generating PDF:', error)
|
||||||
this.$message.error('导出PDF失败')
|
this.$message.error('导出PDF失败')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.$message.warning('没有可导出的订单数据')
|
this.$message.warning('没有结算单ID')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async handleStatusChange(status) {
|
async handleStatusChange(status) {
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import html2pdf from 'html2pdf.js'
|
import html2pdf from 'html2pdf.js'
|
||||||
|
import { printSettleOrderData } from '@/api/order'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SettlementPdf',
|
name: 'SettlementPdf',
|
||||||
@ -68,6 +69,10 @@ export default {
|
|||||||
orderData: {
|
orderData: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
|
},
|
||||||
|
settlementOrderId: {
|
||||||
|
type: [String, Number],
|
||||||
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@ -80,7 +85,8 @@ export default {
|
|||||||
amount: '',
|
amount: '',
|
||||||
amountCN: '',
|
amountCN: '',
|
||||||
items: []
|
items: []
|
||||||
}
|
},
|
||||||
|
pdfData: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@ -94,39 +100,51 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
formatData(orderData) {
|
async formatData(data) {
|
||||||
if (!orderData) {
|
if (!data) {
|
||||||
console.warn('No order data provided')
|
console.warn('No data provided')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.log('Formatting order data:', orderData)
|
|
||||||
// 格式化数据以适应PDF模板
|
// 格式化数据以适应PDF模板
|
||||||
this.data = {
|
this.data = {
|
||||||
statementId: orderData.orderNo || '',
|
statementId: this.settlementOrderId || '',
|
||||||
date: orderData.createTime || '',
|
date: data.settlementTimeScope || '',
|
||||||
customer: orderData.customerName || '',
|
customer: data.clientName || '',
|
||||||
quantity: orderData.cargoWeight ? `${orderData.cargoWeight}KG` : '0KG',
|
quantity: data.cargoWeight ? `${data.cargoWeight}KG` : '0KG',
|
||||||
amount: orderData.totalAmount ? `${orderData.totalAmount}元` : '0元',
|
amount: data.totalAmount ? `${data.totalAmount}元` : '0元',
|
||||||
amountCN: this.convertToChinese(orderData.totalAmount || 0),
|
amountCN: data.totalAmountUpper || '',
|
||||||
items: [{
|
items: data.settlementDetailList ? data.settlementDetailList.map(item => ({
|
||||||
orderNo: orderData.orderType === 1?'载物飞行':'载人飞行' || orderData.orderNo || '',
|
orderNo: item.orderNo || '',
|
||||||
execTime: orderData.orderFinishTime || '',
|
execTime: item.orderCreateTime || '',
|
||||||
weight: orderData.cargoWeight ? `${orderData.cargoWeight}KG` : '0KG',
|
weight: item.cargoWeight ? `${item.cargoWeight}KG` : '0KG',
|
||||||
amount: orderData.totalAmount ? `${orderData.totalAmount}元` : '0元',
|
amount: item.totalAmount ? `${item.totalAmount}元` : '0元',
|
||||||
confirmer: orderData.createBy || ''
|
confirmer: item.confirmPerson || ''
|
||||||
}]
|
})) : []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
generatePDF() {
|
async generatePDF() {
|
||||||
const element = this.$refs.pdfContent
|
try {
|
||||||
const opt = {
|
// 调用接口获取数据
|
||||||
margin: 0.5,
|
const response = await printSettleOrderData(this.settlementOrderId)
|
||||||
filename: `${this.data.statementId}.pdf`,
|
this.pdfData = response
|
||||||
image: { type: 'jpeg', quality: 0.98 },
|
// 格式化数据
|
||||||
html2canvas: { scale: 2 },
|
await this.formatData(response)
|
||||||
jsPDF: { unit: 'in', format: 'a4', orientation: 'portrait' }
|
|
||||||
|
// 生成PDF
|
||||||
|
const element = this.$refs.pdfContent
|
||||||
|
const opt = {
|
||||||
|
margin: 0.5,
|
||||||
|
filename: `结算单_${this.data.statementId}.pdf`,
|
||||||
|
image: { type: 'jpeg', quality: 0.98 },
|
||||||
|
html2canvas: { scale: 2 },
|
||||||
|
jsPDF: { unit: 'in', format: 'a4', orientation: 'portrait' }
|
||||||
|
}
|
||||||
|
return html2pdf().set(opt).from(element).save()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error generating PDF:', error)
|
||||||
|
throw error
|
||||||
}
|
}
|
||||||
return html2pdf().set(opt).from(element).save()
|
|
||||||
},
|
},
|
||||||
convertToChinese(num) {
|
convertToChinese(num) {
|
||||||
const digitCN = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
|
const digitCN = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
|
||||||
|
Loading…
Reference in New Issue
Block a user