Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
319d8e02f6
@ -6,16 +6,19 @@ type GetInventoryListRequest struct {
|
||||
PageSize int `form:"page_size"` // 分页大小
|
||||
ProductId int64 `form:"product_id"` // 商品ID
|
||||
WarehouseID int64 `form:"warehouse_id"` // 仓库ID
|
||||
LocationID int64 `form:"location_id"` // 库位ID
|
||||
ISBN string `form:"isbn"` // ISBN
|
||||
Name string `form:"name"` // 商品名称
|
||||
}
|
||||
|
||||
// GetInventoryGroupedListRequest 获取按仓库库位分组的库存列表请求
|
||||
type GetInventoryGroupedListRequest struct {
|
||||
Page int `form:"page"` // 页码
|
||||
PageSize int `form:"page_size"` // 分页大小
|
||||
ProductId int64 `form:"product_id"` // 商品ID
|
||||
WarehouseID int64 `form:"warehouse_id"` // 仓库ID
|
||||
Page int `form:"page"` // 页码
|
||||
PageSize int `form:"page_size"` // 分页大小
|
||||
ProductId int64 `form:"product_id"` // 商品ID
|
||||
WarehouseID int64 `form:"warehouse_id"` // 仓库ID
|
||||
LocationID int64 `form:"location_id"` // 库位ID
|
||||
Keyword string `form:"keyword"` // 关键词搜索(库位编号/商品名称/条码)
|
||||
}
|
||||
|
||||
// GetInventoryDetailRequest 获取库存明细请求
|
||||
@ -30,6 +33,7 @@ type GetInventoryLogListRequest struct {
|
||||
ISBN string `form:"isbn"` // ISBN
|
||||
BookName string `form:"book_name"` // 图书名称
|
||||
WarehouseID int64 `form:"warehouse_id"` // 仓库ID
|
||||
LocationID int64 `form:"location_id"` // 库位ID
|
||||
ChangeType int8 `form:"change_type"` // 库存流水类型
|
||||
RelatedOrderNo string `form:"related_order_no"` // 关联订单号
|
||||
StartDate int64 `form:"start_date"` // 开始时间
|
||||
|
||||
@ -8,6 +8,7 @@ type GetOutboundOrderListRequest struct {
|
||||
Status int8 `form:"status"`
|
||||
CustomerID int64 `form:"customer_id"`
|
||||
WarehouseID int64 `form:"warehouse_id"`
|
||||
LocationID int64 `form:"location_id"`
|
||||
StartDate int64 `form:"start_date"`
|
||||
EndDate int64 `form:"end_date"`
|
||||
AssociationOrderNo string `form:"association_order_no"`
|
||||
|
||||
@ -8,6 +8,7 @@ type GetSalesOrderListRequest struct {
|
||||
Status int8 `form:"status"`
|
||||
CustomerID int64 `form:"customer_id"`
|
||||
WarehouseID int64 `form:"warehouse_id"`
|
||||
LocationID int64 `form:"location_id"`
|
||||
StartDate int64 `form:"start_date"`
|
||||
EndDate int64 `form:"end_date"`
|
||||
AssociationOrderNo string `form:"association_order_no"`
|
||||
@ -22,18 +23,13 @@ type GetSalesOrderDetailRequest struct {
|
||||
|
||||
// GetSalesOrderDetailListRequest 获取销售订单详情列表请求
|
||||
type GetSalesOrderDetailListRequest struct {
|
||||
Page int `form:"page"`
|
||||
PageSize int `form:"page_size"`
|
||||
//SoNo string `form:"so_no"`
|
||||
//Status int8 `form:"status"`
|
||||
//CustomerID int64 `form:"customer_id"`
|
||||
//WarehouseID int64 `form:"warehouse_id"`
|
||||
//StartDate int64 `form:"start_date"`
|
||||
//EndDate int64 `form:"end_date"`
|
||||
Page int `form:"page"`
|
||||
PageSize int `form:"page_size"`
|
||||
SoNo string `form:"so_no"`
|
||||
Status int8 `form:"status"`
|
||||
CustomerID int64 `form:"customer_id"`
|
||||
WarehouseID int64 `form:"warehouse_id"`
|
||||
LocationID int64 `form:"location_id"`
|
||||
StartDate int64 `form:"start_date"`
|
||||
EndDate int64 `form:"end_date"`
|
||||
AssociationOrderNo string `form:"association_order_no"`
|
||||
|
||||
@ -12,6 +12,8 @@ type GetShippingOrderListRequest struct {
|
||||
AssociationOrderNo string `form:"association_order_no" json:"association_order_no"`
|
||||
LogisticsNo string `form:"logistics_no" json:"logistics_no"`
|
||||
ShopType int `form:"shop_type" json:"shop_type"`
|
||||
WarehouseID int64 `form:"warehouse_id" json:"warehouse_id"`
|
||||
LocationID int64 `form:"location_id" json:"location_id"`
|
||||
}
|
||||
|
||||
// GetShippingOrderDetailRequest 获取发货单详情请求
|
||||
@ -31,4 +33,6 @@ type GetShippingOrderDetailListRequest struct {
|
||||
AssociationOrderNo string `form:"association_order_no" json:"association_order_no"`
|
||||
LogisticsNo string `form:"logistics_no" json:"logistics_no"`
|
||||
ShopType int `form:"shop_type" json:"shop_type"`
|
||||
WarehouseID int64 `form:"warehouse_id" json:"warehouse_id"`
|
||||
LocationID int64 `form:"location_id" json:"location_id"`
|
||||
}
|
||||
|
||||
@ -52,6 +52,7 @@ type SalesOrderItem struct {
|
||||
SalesPersonID int64 `json:"sales_person_id"`
|
||||
Remark string `json:"remark"`
|
||||
LogisticsNo string `json:"logistics_no"`
|
||||
LocationCode string `json:"location_code"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at"`
|
||||
}
|
||||
@ -107,7 +108,7 @@ type SalesOrderDetailItem struct {
|
||||
}
|
||||
|
||||
// ConvertSalesOrderToItem 将销售订单模型转换为响应项
|
||||
func ConvertSalesOrderToItem(order models.SalesOrder, customerName string, warehouseName string, logisticsNo string) SalesOrderItem {
|
||||
func ConvertSalesOrderToItem(order models.SalesOrder, customerName string, warehouseName string, logisticsNo string, locationCode string) SalesOrderItem {
|
||||
return SalesOrderItem{
|
||||
ID: order.ID,
|
||||
SoNo: order.SoNo,
|
||||
@ -129,6 +130,7 @@ func ConvertSalesOrderToItem(order models.SalesOrder, customerName string, wareh
|
||||
SalesPersonID: order.SalesPersonID,
|
||||
Remark: order.Remark,
|
||||
LogisticsNo: logisticsNo,
|
||||
LocationCode: locationCode,
|
||||
CreatedAt: order.CreatedAt,
|
||||
UpdatedAt: order.UpdatedAt,
|
||||
}
|
||||
|
||||
@ -5,11 +5,13 @@ type DashboardStatistResponse struct {
|
||||
TotalOrderCount int64 `json:"total_order_count"` // 今日订单数
|
||||
TotalReceivingCount int64 `json:"total_receiving_count"` // 今日入库数
|
||||
TotalOutboundCount int64 `json:"total_outbound_count"` // 今日出库数
|
||||
TotalSaleCount int64 `json:"total_sale_count"` // 今日销售数
|
||||
TotalSaleCount int64 `json:"total_sale_count"` // 今日销售数(保留兼容)
|
||||
TodaySaleAmount int64 `json:"today_sale_amount"` // 今日销售金额(分)
|
||||
YesterdayOrderCount int64 `json:"yesterday_order_count"` // 昨日订单数
|
||||
YesterdayReceivingCount int64 `json:"yesterday_receiving_count"` // 昨日入库数
|
||||
YesterdayOutboundCount int64 `json:"yesterday_outbound_count"` // 昨日出库数
|
||||
YesterdaySaleCount int64 `json:"yesterday_sale_count"` // 昨日销售数
|
||||
YesterdaySaleCount int64 `json:"yesterday_sale_count"` // 昨日销售数(保留兼容)
|
||||
YesterdaySaleAmount int64 `json:"yesterday_sale_amount"` // 昨日销售金额(分)
|
||||
UserStats []UserStatItem `json:"user_stats"` // 个人统计数据
|
||||
ProductTotal int64 `json:"product_total"` // 商品总量
|
||||
InventoryTotal int64 `json:"inventory_total"` // 库存量
|
||||
|
||||
@ -4,7 +4,7 @@ package response
|
||||
type StoreInfoResponse struct {
|
||||
StoreName string `json:"store_name"` // 店铺名称
|
||||
StoreType string `json:"store_type"` // 店铺类型描述
|
||||
SaleCount int64 `json:"sale_count"` // 销售数量(时间范围内该店铺的销售订单数)
|
||||
SaleAmount int64 `json:"sale_amount"` // 销售金额(时间范围内该店铺的销售订单总金额,单位:分)
|
||||
OutboundCount int64 `json:"outbound_count"` // 出库次数(当前表结构无店铺维度,暂返回 0)
|
||||
ReceivingCount int64 `json:"receiving_count"` // 入库次数(当前表结构无店铺维度,暂返回 0)
|
||||
OrderCount int64 `json:"order_count"` // 订单数量(同 sale_count,从 sales_order 表统计)
|
||||
|
||||
@ -51,6 +51,9 @@ func (s *InventoryService) GetInventoryList(req systemReq.GetInventoryListReques
|
||||
if req.WarehouseID > 0 {
|
||||
query = query.Where("inventory.warehouse_id = ?", req.WarehouseID)
|
||||
}
|
||||
if req.LocationID > 0 {
|
||||
query = query.Where("i.location_id = ?", req.LocationID)
|
||||
}
|
||||
if req.ISBN != "" {
|
||||
query = query.Where("p.barcode LIKE ?", "%"+req.ISBN+"%")
|
||||
}
|
||||
@ -142,12 +145,21 @@ func (s *InventoryService) GetInventoryGroupedList(req systemReq.GetInventoryGro
|
||||
`).
|
||||
Joins("LEFT JOIN warehouse w ON inventory_detail.warehouse_id = w.id AND w.is_del = 0").
|
||||
Joins("LEFT JOIN location l ON inventory_detail.location_id = l.id AND l.is_del = 0").
|
||||
Joins("LEFT JOIN product p ON inventory_detail.product_id = p.id AND p.is_del = 0").
|
||||
Where("inventory_detail.is_del = ?", 0).
|
||||
Group("inventory_detail.warehouse_id, w.name, w.code, inventory_detail.location_id, l.code")
|
||||
|
||||
if req.WarehouseID > 0 {
|
||||
groupQuery = groupQuery.Where("inventory_detail.warehouse_id = ?", req.WarehouseID)
|
||||
}
|
||||
if req.LocationID > 0 {
|
||||
groupQuery = groupQuery.Where("inventory_detail.location_id = ?", req.LocationID)
|
||||
}
|
||||
|
||||
if req.Keyword != "" {
|
||||
kw := "%" + req.Keyword + "%"
|
||||
groupQuery = groupQuery.Where("(l.code LIKE ? OR p.name LIKE ? OR p.barcode LIKE ?)", kw, kw, kw)
|
||||
}
|
||||
|
||||
var total int64
|
||||
if err := groupQuery.Count(&total).Error; err != nil {
|
||||
@ -199,6 +211,10 @@ func (s *InventoryService) GetInventoryGroupedList(req systemReq.GetInventoryGro
|
||||
if req.ProductId > 0 {
|
||||
detailQuery = detailQuery.Where("inventory_detail.product_id = ?", req.ProductId)
|
||||
}
|
||||
if req.Keyword != "" {
|
||||
kw := "%" + req.Keyword + "%"
|
||||
detailQuery = detailQuery.Where("(p.name LIKE ? OR p.barcode LIKE ?)", kw, kw)
|
||||
}
|
||||
|
||||
var details []struct {
|
||||
models.InventoryDetail
|
||||
@ -459,6 +475,9 @@ func (s *InventoryService) GetInventoryLogList(req systemReq.GetInventoryLogList
|
||||
if req.WarehouseID > 0 {
|
||||
query = query.Where("inventory_log.warehouse_id = ?", req.WarehouseID)
|
||||
}
|
||||
if req.LocationID > 0 {
|
||||
query = query.Where("inventory_log.location_id = ?", req.LocationID)
|
||||
}
|
||||
if req.ChangeType > 0 {
|
||||
query = query.Where("inventory_log.change_type = ?", req.ChangeType)
|
||||
}
|
||||
|
||||
@ -35,6 +35,12 @@ func (s *OutboundService) GetOutboundOrderList(req systemReq.GetOutboundOrderLis
|
||||
if req.WarehouseID > 0 {
|
||||
query = query.Where("outbound_order.warehouse_id = ?", req.WarehouseID)
|
||||
}
|
||||
if req.LocationID > 0 {
|
||||
subQuery := databaseConn.Table("outbound_order_item").
|
||||
Select("outbound_order_item.out_order_id").
|
||||
Where("outbound_order_item.is_del = 0 AND outbound_order_item.location_id = ?", req.LocationID)
|
||||
query = query.Where("outbound_order.id IN (?)", subQuery)
|
||||
}
|
||||
if req.OutNo != "" {
|
||||
query = query.Where("outbound_order.out_no LIKE ?", "%"+req.OutNo+"%")
|
||||
}
|
||||
|
||||
@ -60,6 +60,14 @@ func (s *SalesService) GetSalesOrderList(req systemReq.GetSalesOrderListRequest,
|
||||
if req.ShopType > 0 {
|
||||
query = query.Where("sales_order.shop_type = ?", req.ShopType)
|
||||
}
|
||||
if req.LocationID > 0 {
|
||||
subQuery := databaseConn.Table("sales_order_item soi").
|
||||
Select("DISTINCT soi.sales_order_id").
|
||||
Joins("JOIN product p ON soi.product_id = p.id AND p.is_del = 0").
|
||||
Joins("JOIN inventory_detail id ON p.id = id.product_id AND id.is_del = 0").
|
||||
Where("id.location_id = ?", req.LocationID)
|
||||
query = query.Where("sales_order.id IN (?)", subQuery)
|
||||
}
|
||||
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
@ -109,6 +117,26 @@ func (s *SalesService) GetSalesOrderList(req systemReq.GetSalesOrderListRequest,
|
||||
logByOrderID[row.SalesOrderID] = row.LogisticsNos
|
||||
}
|
||||
|
||||
// 收集库位编码(通过 sales_order_item → product → inventory_detail → location 链路)
|
||||
type locRow struct {
|
||||
SalesOrderID int64 `gorm:"column:sales_order_id"`
|
||||
LocationCodes string `gorm:"column:location_codes"`
|
||||
}
|
||||
var locRows []locRow
|
||||
databaseConn.Table("sales_order_item").
|
||||
Select("sales_order_id, COALESCE(GROUP_CONCAT(DISTINCT l.code SEPARATOR ', '), '') as location_codes").
|
||||
Joins("JOIN product p ON sales_order_item.product_id = p.id AND p.is_del = 0").
|
||||
Joins("JOIN inventory_detail id ON p.id = id.product_id AND id.is_del = 0").
|
||||
Joins("JOIN location l ON id.location_id = l.id").
|
||||
Where("sales_order_id IN ? AND sales_order_item.is_del = ?", orderIDs, 0).
|
||||
Group("sales_order_id").
|
||||
Scan(&locRows)
|
||||
|
||||
locByOrderID := make(map[int64]string, len(locRows))
|
||||
for _, row := range locRows {
|
||||
locByOrderID[row.SalesOrderID] = row.LocationCodes
|
||||
}
|
||||
|
||||
orderItems := make([]systemRes.SalesOrderItem, 0, len(orders))
|
||||
for _, order := range orders {
|
||||
orderItems = append(orderItems, systemRes.ConvertSalesOrderToItem(
|
||||
@ -116,6 +144,7 @@ func (s *SalesService) GetSalesOrderList(req systemReq.GetSalesOrderListRequest,
|
||||
order.CustomerName,
|
||||
order.WarehouseName,
|
||||
logByOrderID[order.ID],
|
||||
locByOrderID[order.ID],
|
||||
))
|
||||
}
|
||||
|
||||
@ -190,6 +219,14 @@ func (s *SalesService) GetSalesOrderDetailList(req systemReq.GetSalesOrderDetail
|
||||
if req.ShopType > 0 {
|
||||
query = query.Where("sales_order.shop_type = ?", req.ShopType)
|
||||
}
|
||||
if req.LocationID > 0 {
|
||||
subQuery := databaseConn.Table("sales_order_item soi").
|
||||
Select("DISTINCT soi.sales_order_id").
|
||||
Joins("JOIN product p ON soi.product_id = p.id AND p.is_del = 0").
|
||||
Joins("JOIN inventory_detail id ON p.id = id.product_id AND id.is_del = 0").
|
||||
Where("id.location_id = ?", req.LocationID)
|
||||
query = query.Where("sales_order.id IN (?)", subQuery)
|
||||
}
|
||||
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
|
||||
@ -65,6 +65,21 @@ func (s *ShippingService) GetShippingOrderList(req systemReq.GetShippingOrderLis
|
||||
Where("shipping_order_item.is_del = 0 AND sales_order.shop_type = ?", req.ShopType)
|
||||
query = query.Where("shipping_order.id IN (?)", subQuery)
|
||||
}
|
||||
if req.WarehouseID > 0 {
|
||||
subQuery := databaseConn.Table("shipping_order_item").
|
||||
Select("shipping_order_item.shipping_order_id").
|
||||
Joins("INNER JOIN outbound_order_item ON shipping_order_item.outbound_order_item_id = outbound_order_item.id AND outbound_order_item.is_del = 0").
|
||||
Joins("INNER JOIN location ON outbound_order_item.location_id = location.id AND location.is_del = 0").
|
||||
Where("shipping_order_item.is_del = 0 AND location.warehouse_id = ?", req.WarehouseID)
|
||||
query = query.Where("shipping_order.id IN (?)", subQuery)
|
||||
}
|
||||
if req.LocationID > 0 {
|
||||
subQuery := databaseConn.Table("shipping_order_item").
|
||||
Select("shipping_order_item.shipping_order_id").
|
||||
Joins("INNER JOIN outbound_order_item ON shipping_order_item.outbound_order_item_id = outbound_order_item.id AND outbound_order_item.is_del = 0").
|
||||
Where("shipping_order_item.is_del = 0 AND outbound_order_item.location_id = ?", req.LocationID)
|
||||
query = query.Where("shipping_order.id IN (?)", subQuery)
|
||||
}
|
||||
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
@ -339,6 +354,21 @@ func (s *ShippingService) GetShippingOrderDetailList(req systemReq.GetShippingOr
|
||||
Where("shipping_order_item.is_del = 0 AND sales_order.shop_type = ?", req.ShopType)
|
||||
query = query.Where("shipping_order.id IN (?)", subQuery)
|
||||
}
|
||||
if req.WarehouseID > 0 {
|
||||
subQuery := databaseConn.Table("shipping_order_item").
|
||||
Select("shipping_order_item.shipping_order_id").
|
||||
Joins("INNER JOIN outbound_order_item ON shipping_order_item.outbound_order_item_id = outbound_order_item.id AND outbound_order_item.is_del = 0").
|
||||
Joins("INNER JOIN location ON outbound_order_item.location_id = location.id AND location.is_del = 0").
|
||||
Where("shipping_order_item.is_del = 0 AND location.warehouse_id = ?", req.WarehouseID)
|
||||
query = query.Where("shipping_order.id IN (?)", subQuery)
|
||||
}
|
||||
if req.LocationID > 0 {
|
||||
subQuery := databaseConn.Table("shipping_order_item").
|
||||
Select("shipping_order_item.shipping_order_id").
|
||||
Joins("INNER JOIN outbound_order_item ON shipping_order_item.outbound_order_item_id = outbound_order_item.id AND outbound_order_item.is_del = 0").
|
||||
Where("shipping_order_item.is_del = 0 AND outbound_order_item.location_id = ?", req.LocationID)
|
||||
query = query.Where("shipping_order.id IN (?)", subQuery)
|
||||
}
|
||||
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
|
||||
@ -223,8 +223,8 @@ func (s *StatistService) getDashboardStatRealtime(databaseConn *gorm.DB, startDa
|
||||
defer wg.Done()
|
||||
statErr = databaseConn.Model(&models.SalesOrder{}).
|
||||
Select(`
|
||||
COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? THEN 1 ELSE 0 END), 0) as today_count,
|
||||
COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? THEN 1 ELSE 0 END), 0) as yesterday_count
|
||||
COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? THEN total_amount ELSE 0 END), 0) as today_count,
|
||||
COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? THEN total_amount ELSE 0 END), 0) as yesterday_count
|
||||
`, todayStart, todayEnd, yesterdayStart, yesterdayEnd).
|
||||
Where("is_del = ?", 0).
|
||||
Scan(&salesStat).Error
|
||||
@ -338,11 +338,11 @@ func (s *StatistService) getDashboardStatRealtime(databaseConn *gorm.DB, startDa
|
||||
TotalOrderCount: salesStat.TodayCount,
|
||||
TotalReceivingCount: receivingStat.TodayCount,
|
||||
TotalOutboundCount: outboundStat.TodayCount,
|
||||
TotalSaleCount: salesStat.TodayCount,
|
||||
TodaySaleAmount: salesStat.TodayCount,
|
||||
YesterdayOrderCount: salesStat.YesterdayCount,
|
||||
YesterdayReceivingCount: receivingStat.YesterdayCount,
|
||||
YesterdayOutboundCount: outboundStat.YesterdayCount,
|
||||
YesterdaySaleCount: salesStat.YesterdayCount,
|
||||
YesterdaySaleAmount: salesStat.YesterdayCount,
|
||||
UserStats: userStats,
|
||||
ProductTotal: productTotal,
|
||||
InventoryTotal: inventoryTotal,
|
||||
|
||||
@ -76,6 +76,7 @@ func (s *StoreInfoService) StoreInfo(req systemReq.StoreInfoRequest, db ...*gorm
|
||||
type storeStat struct {
|
||||
ShopName string
|
||||
SaleCount int64
|
||||
SaleAmount int64
|
||||
OutboundCount int64
|
||||
ReceivingCount int64
|
||||
ShippingCount int64
|
||||
@ -93,10 +94,11 @@ func (s *StoreInfoService) StoreInfo(req systemReq.StoreInfoRequest, db ...*gorm
|
||||
type row struct {
|
||||
Name string `gorm:"column:sales_person"`
|
||||
Cnt int64 `gorm:"column:cnt"`
|
||||
Amt int64 `gorm:"column:amt"`
|
||||
}
|
||||
var rows []row
|
||||
err := databaseConn.Raw(`
|
||||
SELECT sales_person, COUNT(*) AS cnt
|
||||
SELECT sales_person, COUNT(*) AS cnt, COALESCE(SUM(total_amount), 0) AS amt
|
||||
FROM sales_order
|
||||
WHERE is_del = 0 AND created_at >= ? AND created_at <= ? AND sales_person != ''
|
||||
GROUP BY sales_person
|
||||
@ -115,6 +117,7 @@ func (s *StoreInfoService) StoreInfo(req systemReq.StoreInfoRequest, db ...*gorm
|
||||
statByName[n] = &storeStat{ShopName: n}
|
||||
}
|
||||
statByName[n].SaleCount = r.Cnt
|
||||
statByName[n].SaleAmount = r.Amt
|
||||
}
|
||||
mu.Unlock()
|
||||
}()
|
||||
@ -254,7 +257,7 @@ func (s *StoreInfoService) StoreInfo(req systemReq.StoreInfoRequest, db ...*gorm
|
||||
result = append(result, systemRes.StoreInfoResponse{
|
||||
StoreName: name,
|
||||
StoreType: storeType,
|
||||
SaleCount: st.SaleCount,
|
||||
SaleAmount: st.SaleAmount,
|
||||
OutboundCount: st.OutboundCount,
|
||||
ReceivingCount: st.ReceivingCount,
|
||||
OrderCount: st.SaleCount,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user