feat: 新增退货功能,订单列表增加退货状态(9)
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -54,6 +54,12 @@
|
|||||||
"navigationBarTitleText": "订单查询"
|
"navigationBarTitleText": "订单查询"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/order/return",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "退货"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/stock/list",
|
"path": "pages/stock/list",
|
||||||
"style": {
|
"style": {
|
||||||
|
|||||||
@@ -74,6 +74,10 @@
|
|||||||
<Icon name="search" :size="48" color="#fff" />
|
<Icon name="search" :size="48" color="#fff" />
|
||||||
<text class="menu-card-title">订单查询</text>
|
<text class="menu-card-title">订单查询</text>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="menu-card" @click="goTo('/pages/order/return')">
|
||||||
|
<Icon name="right" :size="48" color="#fff" />
|
||||||
|
<text class="menu-card-title">退货</text>
|
||||||
|
</view>
|
||||||
<view class="menu-card" @click="goStock()">
|
<view class="menu-card" @click="goStock()">
|
||||||
<Icon name="stock" :size="48" color="#fff" />
|
<Icon name="stock" :size="48" color="#fff" />
|
||||||
<text class="menu-card-title">库存管理</text>
|
<text class="menu-card-title">库存管理</text>
|
||||||
|
|||||||
@@ -208,7 +208,8 @@ export default {
|
|||||||
1: 'status-success',
|
1: 'status-success',
|
||||||
2: 'status-cancel',
|
2: 'status-cancel',
|
||||||
3: 'status-refunding',
|
3: 'status-refunding',
|
||||||
4: 'status-refunded'
|
4: 'status-refunded',
|
||||||
|
9: 'status-returning'
|
||||||
}
|
}
|
||||||
return map[status] || ''
|
return map[status] || ''
|
||||||
},
|
},
|
||||||
@@ -218,7 +219,8 @@ export default {
|
|||||||
1: '已完成',
|
1: '已完成',
|
||||||
2: '已取消',
|
2: '已取消',
|
||||||
3: '退款中',
|
3: '退款中',
|
||||||
4: '已退款'
|
4: '已退款',
|
||||||
|
9: '退货中'
|
||||||
}
|
}
|
||||||
return map[status] || '未知'
|
return map[status] || '未知'
|
||||||
},
|
},
|
||||||
@@ -367,6 +369,11 @@ export default {
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status-returning {
|
||||||
|
background: linear-gradient(135deg, #fa8c16 0%, #ffc069 100%);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
/* 卡片主体 */
|
/* 卡片主体 */
|
||||||
.card-body {
|
.card-body {
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
|
|||||||
532
src/pages/order/return.vue
Normal file
532
src/pages/order/return.vue
Normal file
@@ -0,0 +1,532 @@
|
|||||||
|
<template>
|
||||||
|
<view class="page">
|
||||||
|
<!-- 搜索栏 -->
|
||||||
|
<view class="search-section">
|
||||||
|
<view class="search-bar">
|
||||||
|
<text class="search-icon">🔍</text>
|
||||||
|
<input
|
||||||
|
class="search-input"
|
||||||
|
v-model="keyword"
|
||||||
|
placeholder="输入客户姓名或手机号搜索"
|
||||||
|
placeholder-class="placeholder"
|
||||||
|
@input="searchCustomers"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 搜索结果列表 -->
|
||||||
|
<scroll-view scroll-y class="result-section">
|
||||||
|
<view v-if="loading" class="loading">加载中...</view>
|
||||||
|
<view v-else-if="customers.length === 0 && keyword" class="empty">
|
||||||
|
<text class="empty-icon">👤</text>
|
||||||
|
<text class="empty-text">未找到相关客户</text>
|
||||||
|
</view>
|
||||||
|
<view v-else-if="customers.length > 0" class="customer-list">
|
||||||
|
<view
|
||||||
|
v-for="customer in customers"
|
||||||
|
:key="customer.customerId"
|
||||||
|
class="customer-card"
|
||||||
|
@click="selectCustomer(customer)"
|
||||||
|
>
|
||||||
|
<view class="customer-info">
|
||||||
|
<text class="customer-name">{{ customer.name }}</text>
|
||||||
|
<text class="customer-phone">{{ customer.phone || '' }}</text>
|
||||||
|
</view>
|
||||||
|
<text class="arrow">›</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-else-if="selectedCustomer" class="selected-info">
|
||||||
|
<text>已选择: {{ selectedCustomer.name }}</text>
|
||||||
|
<text class="clear-btn" @click="clearSelection">清除</text>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
|
||||||
|
<!-- 已选客户的商品列表(可退货) -->
|
||||||
|
<view class="goods-section" v-if="selectedCustomer">
|
||||||
|
<view class="goods-header">
|
||||||
|
<text class="goods-title">{{ selectedCustomer.name }} 可退货的商品</text>
|
||||||
|
</view>
|
||||||
|
<scroll-view scroll-y class="goods-list">
|
||||||
|
<view
|
||||||
|
v-for="item in returnableGoods"
|
||||||
|
:key="item.productId + '_' + item.orderId"
|
||||||
|
class="goods-card"
|
||||||
|
>
|
||||||
|
<view class="goods-info">
|
||||||
|
<text class="goods-name">{{ item.productName }}</text>
|
||||||
|
<text class="goods-spec">{{ item.spec || '-' }}</text>
|
||||||
|
<text class="goods-order">订单: {{ item.orderNo }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="goods-action">
|
||||||
|
<text class="goods-qty">已购: {{ item.quantity }},可退: {{ item.returnableQty }}</text>
|
||||||
|
<button
|
||||||
|
class="return-btn"
|
||||||
|
@click="showReturnDialog(item)"
|
||||||
|
:disabled="item.returnableQty <= 0"
|
||||||
|
>
|
||||||
|
退货
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="returnableGoods.length === 0" class="empty-tip">
|
||||||
|
暂无可退货商品
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 退货数量弹窗 -->
|
||||||
|
<view class="popup-mask" v-if="showPopup" @click="closePopup"></view>
|
||||||
|
<view class="popup-content" v-if="showPopup">
|
||||||
|
<view class="popup-header">
|
||||||
|
<text class="popup-title">退货 - {{ currentItem.productName }}</text>
|
||||||
|
<text class="popup-close" @click="closePopup">×</text>
|
||||||
|
</view>
|
||||||
|
<view class="popup-body">
|
||||||
|
<view class="popup-info">
|
||||||
|
<text>订单: {{ currentItem.orderNo }}</text>
|
||||||
|
<text>可退数量: {{ currentItem.returnableQty }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="popup-qty">
|
||||||
|
<text class="qty-label">退货数量</text>
|
||||||
|
<view class="qty-input-wrapper">
|
||||||
|
<text class="qty-minus" @click="qtyMinus">-</text>
|
||||||
|
<input
|
||||||
|
class="qty-input"
|
||||||
|
type="number"
|
||||||
|
v-model="returnQty"
|
||||||
|
/>
|
||||||
|
<text class="qty-plus" @click="qtyPlus">+</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="popup-footer">
|
||||||
|
<button class="popup-btn cancel" @click="closePopup">取消</button>
|
||||||
|
<button class="popup-btn confirm" @click="confirmReturn">确定</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import orderApi from '@/api/order'
|
||||||
|
import customerApi from '@/api/customer'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
keyword: '',
|
||||||
|
customers: [],
|
||||||
|
selectedCustomer: null,
|
||||||
|
returnableGoods: [],
|
||||||
|
loading: false,
|
||||||
|
// 弹窗相关
|
||||||
|
showPopup: false,
|
||||||
|
currentItem: {},
|
||||||
|
returnQty: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async searchCustomers() {
|
||||||
|
if (!this.keyword.trim()) {
|
||||||
|
this.customers = []
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loading = true
|
||||||
|
try {
|
||||||
|
const res = await customerApi.getCustomers({
|
||||||
|
keyword: this.keyword.trim(),
|
||||||
|
page: 1,
|
||||||
|
pageSize: 20
|
||||||
|
})
|
||||||
|
this.customers = res.records || []
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
} finally {
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async selectCustomer(customer) {
|
||||||
|
this.selectedCustomer = customer
|
||||||
|
this.keyword = ''
|
||||||
|
this.customers = []
|
||||||
|
this.loadReturnableGoods()
|
||||||
|
},
|
||||||
|
clearSelection() {
|
||||||
|
this.selectedCustomer = null
|
||||||
|
this.returnableGoods = []
|
||||||
|
},
|
||||||
|
async loadReturnableGoods() {
|
||||||
|
if (!this.selectedCustomer) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await orderApi.getOrders({
|
||||||
|
customerId: this.selectedCustomer.customerId,
|
||||||
|
status: 1, // 已完成
|
||||||
|
page: 1,
|
||||||
|
pageSize: 100
|
||||||
|
})
|
||||||
|
const orders = res.records || []
|
||||||
|
|
||||||
|
// 收集每个已完成订单的商品
|
||||||
|
const goodsMap = {}
|
||||||
|
for (const order of orders) {
|
||||||
|
try {
|
||||||
|
const detail = await orderApi.getOrderDetail(order.orderId)
|
||||||
|
const items = detail.items || []
|
||||||
|
for (const item of items) {
|
||||||
|
const key = item.productId
|
||||||
|
if (!goodsMap[key]) {
|
||||||
|
goodsMap[key] = {
|
||||||
|
productId: item.productId,
|
||||||
|
productName: item.productName,
|
||||||
|
spec: item.productSpec,
|
||||||
|
orderId: order.orderId,
|
||||||
|
orderNo: order.orderNo,
|
||||||
|
quantity: 0,
|
||||||
|
returnableQty: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goodsMap[key].quantity += item.quantity
|
||||||
|
// TODO: 需要查询已退货数量,这里暂用quantity
|
||||||
|
goodsMap[key].returnableQty = goodsMap[key].quantity
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.returnableGoods = Object.values(goodsMap)
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showReturnDialog(item) {
|
||||||
|
this.currentItem = item
|
||||||
|
this.returnQty = 1
|
||||||
|
this.showPopup = true
|
||||||
|
},
|
||||||
|
closePopup() {
|
||||||
|
this.showPopup = false
|
||||||
|
},
|
||||||
|
qtyMinus() {
|
||||||
|
if (this.returnQty > 1) {
|
||||||
|
this.returnQty--
|
||||||
|
}
|
||||||
|
},
|
||||||
|
qtyPlus() {
|
||||||
|
if (this.returnQty < this.currentItem.returnableQty) {
|
||||||
|
this.returnQty++
|
||||||
|
}
|
||||||
|
},
|
||||||
|
confirmReturn() {
|
||||||
|
if (this.returnQty <= 0 || this.returnQty > this.currentItem.returnableQty) {
|
||||||
|
uni.showToast({ title: '退货数量无效', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uni.showToast({ title: '退货成功', icon: 'success' })
|
||||||
|
// TODO: 调用后端创建退货订单
|
||||||
|
this.closePopup()
|
||||||
|
this.loadReturnableGoods()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background: #f8f9fa;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-section {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
padding: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
border-radius: 50rpx;
|
||||||
|
padding: 0 30rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-icon {
|
||||||
|
font-size: 32rpx;
|
||||||
|
margin-right: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-section {
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading, .empty {
|
||||||
|
text-align: center;
|
||||||
|
color: #999;
|
||||||
|
padding: 60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-icon {
|
||||||
|
font-size: 60rpx;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-info {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx;
|
||||||
|
background: #e6f7ff;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
margin: 20rpx;
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear-btn {
|
||||||
|
color: #ff4d4f;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.customer-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.customer-card {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
background: #fff;
|
||||||
|
padding: 24rpx;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.customer-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.customer-name {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.customer-phone {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow {
|
||||||
|
font-size: 36rpx;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-section {
|
||||||
|
flex: 1;
|
||||||
|
background: #fff;
|
||||||
|
padding: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-header {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-list {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-card {
|
||||||
|
padding: 20rpx;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-info {
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-name {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-spec {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-order {
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-action {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-qty {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.return-btn {
|
||||||
|
padding: 10rpx 30rpx;
|
||||||
|
background: #ff4d4f;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 24rpx;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.return-btn[disabled] {
|
||||||
|
background: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-tip {
|
||||||
|
text-align: center;
|
||||||
|
color: #999;
|
||||||
|
padding: 60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 弹窗 */
|
||||||
|
.popup-mask {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-content {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 32rpx 32rpx 0 0;
|
||||||
|
padding: 40rpx 30rpx;
|
||||||
|
padding-bottom: calc(40rpx + env(safe-area-inset-bottom));
|
||||||
|
z-index: 101;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-close {
|
||||||
|
font-size: 48rpx;
|
||||||
|
color: #999;
|
||||||
|
padding: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-info {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
color: #666;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-qty {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qty-label {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
width: 160rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qty-input-wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: #f5f5f5;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qty-minus, .qty-plus {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 40rpx;
|
||||||
|
color: #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qty-input {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32rpx;
|
||||||
|
background: transparent;
|
||||||
|
border-left: 1rpx solid #eee;
|
||||||
|
border-right: 1rpx solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-footer {
|
||||||
|
display: flex;
|
||||||
|
gap: 20rpx;
|
||||||
|
margin-top: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-btn {
|
||||||
|
flex: 1;
|
||||||
|
height: 88rpx;
|
||||||
|
line-height: 88rpx;
|
||||||
|
border-radius: 44rpx;
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-btn.cancel {
|
||||||
|
background: #f5f5f5;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-btn.confirm {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
<input
|
<input
|
||||||
class="search-input"
|
class="search-input"
|
||||||
v-model="keyword"
|
v-model="keyword"
|
||||||
placeholder="输入客户姓名搜索"
|
placeholder="输入客户姓名或手机号搜索"
|
||||||
placeholder-class="placeholder"
|
placeholder-class="placeholder"
|
||||||
@input="searchCustomers"
|
@input="searchCustomers"
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user