fix: 订单查询改为先搜客户再查该客户的订单
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:
@@ -6,23 +6,47 @@
|
|||||||
<text class="search-icon">🔍</text>
|
<text class="search-icon">🔍</text>
|
||||||
<input
|
<input
|
||||||
class="search-input"
|
class="search-input"
|
||||||
v-model="customerName"
|
v-model="keyword"
|
||||||
placeholder="请输入客户姓名"
|
placeholder="输入客户姓名搜索"
|
||||||
placeholder-class="placeholder"
|
placeholder-class="placeholder"
|
||||||
@confirm="searchOrders"
|
@input="searchCustomers"
|
||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
<button class="search-btn" @click="searchOrders">查询</button>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 搜索结果 -->
|
<!-- 搜索结果列表 -->
|
||||||
<scroll-view scroll-y class="result-section">
|
<scroll-view scroll-y class="result-section">
|
||||||
<view v-if="loading" class="loading">加载中...</view>
|
<view v-if="loading" class="loading">加载中...</view>
|
||||||
<view v-else-if="orders.length === 0 && searched" class="empty">
|
<view v-else-if="customers.length === 0 && keyword" class="empty">
|
||||||
<text class="empty-icon">📋</text>
|
<text class="empty-icon">👤</text>
|
||||||
<text class="empty-text">未找到相关订单</text>
|
<text class="empty-text">未找到相关客户</text>
|
||||||
</view>
|
</view>
|
||||||
<view v-else-if="orders.length > 0" class="order-list">
|
<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="orders-section" v-if="selectedCustomer && orders.length > 0">
|
||||||
|
<view class="orders-header">
|
||||||
|
<text class="orders-title">{{ selectedCustomer.name }} 的订单</text>
|
||||||
|
</view>
|
||||||
|
<scroll-view scroll-y class="orders-list">
|
||||||
<view
|
<view
|
||||||
v-for="order in orders"
|
v-for="order in orders"
|
||||||
:key="order.orderId"
|
:key="order.orderId"
|
||||||
@@ -36,61 +60,78 @@
|
|||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="card-body">
|
<view class="card-body">
|
||||||
<text class="customer-name">👤 {{ order.customerName || '散客' }}</text>
|
|
||||||
<text class="order-amount">实付: ¥{{ order.actualAmount }}</text>
|
<text class="order-amount">实付: ¥{{ order.actualAmount }}</text>
|
||||||
<text class="order-time">{{ formatTime(order.createdAt) }}</text>
|
<text class="order-time">{{ formatTime(order.createdAt) }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
|
||||||
<view v-else class="hint">
|
|
||||||
<text>请输入客户姓名进行查询</text>
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import orderApi from '@/api/order'
|
import orderApi from '@/api/order'
|
||||||
|
import customerApi from '@/api/customer'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
customerName: '',
|
keyword: '',
|
||||||
|
customers: [],
|
||||||
|
selectedCustomer: null,
|
||||||
orders: [],
|
orders: [],
|
||||||
loading: false,
|
loading: false
|
||||||
searched: false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async searchOrders() {
|
async searchCustomers() {
|
||||||
if (!this.customerName.trim()) {
|
if (!this.keyword.trim()) {
|
||||||
uni.showToast({ title: '请输入客户姓名', icon: 'none' })
|
this.customers = []
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loading = true
|
this.loading = true
|
||||||
this.searched = 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.loadOrders()
|
||||||
|
},
|
||||||
|
clearSelection() {
|
||||||
|
this.selectedCustomer = null
|
||||||
this.orders = []
|
this.orders = []
|
||||||
|
},
|
||||||
|
async loadOrders() {
|
||||||
|
if (!this.selectedCustomer) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await orderApi.getOrders({
|
const res = await orderApi.getOrders({
|
||||||
customerName: this.customerName.trim(),
|
customerId: this.selectedCustomer.customerId,
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 50
|
pageSize: 50
|
||||||
})
|
})
|
||||||
this.orders = res.records || []
|
this.orders = res.records || []
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
uni.showToast({ title: '查询失败', icon: 'none' })
|
console.error(e)
|
||||||
} finally {
|
|
||||||
this.loading = false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getStatusClass(status) {
|
getStatusClass(status) {
|
||||||
const map = {
|
const map = {
|
||||||
1: 'status-success',
|
1: 'status-success',
|
||||||
2: 'status-cancel',
|
2: 'status-cancel'
|
||||||
3: 'status-refunding',
|
|
||||||
4: 'status-refunded'
|
|
||||||
}
|
}
|
||||||
return map[status] || ''
|
return map[status] || ''
|
||||||
},
|
},
|
||||||
@@ -98,9 +139,7 @@ export default {
|
|||||||
const map = {
|
const map = {
|
||||||
0: '未完成',
|
0: '未完成',
|
||||||
1: '已完成',
|
1: '已完成',
|
||||||
2: '已取消',
|
2: '已取消'
|
||||||
3: '退款中',
|
|
||||||
4: '已退款'
|
|
||||||
}
|
}
|
||||||
return map[status] || '未知'
|
return map[status] || '未知'
|
||||||
},
|
},
|
||||||
@@ -111,7 +150,7 @@ export default {
|
|||||||
viewDetail(order) {
|
viewDetail(order) {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '订单详情',
|
title: '订单详情',
|
||||||
content: `订单号: ${order.orderNo}\n客户: ${order.customerName || '散客'}\n原价: ¥${order.totalAmount}\n优惠: ¥${order.discountAmount}\n实付: ¥${order.actualAmount}\n状态: ${this.getStatusText(order.status)}`,
|
content: `订单号: ${order.orderNo}\n原价: ¥${order.totalAmount}\n优惠: ¥${order.discountAmount}\n实付: ¥${order.actualAmount}\n状态: ${this.getStatusText(order.status)}`,
|
||||||
showCancel: false
|
showCancel: false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -128,12 +167,9 @@ export default {
|
|||||||
.search-section {
|
.search-section {
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
padding: 30rpx;
|
padding: 30rpx;
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-bar {
|
.search-bar {
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background: rgba(255, 255, 255, 0.95);
|
background: rgba(255, 255, 255, 0.95);
|
||||||
@@ -157,74 +193,116 @@ export default {
|
|||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-btn {
|
|
||||||
margin-left: 20rpx;
|
|
||||||
background: #fff;
|
|
||||||
color: #667eea;
|
|
||||||
font-size: 28rpx;
|
|
||||||
padding: 16rpx 32rpx;
|
|
||||||
border-radius: 40rpx;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-section {
|
.result-section {
|
||||||
height: calc(100vh - 180rpx);
|
height: 400rpx;
|
||||||
padding: 20rpx;
|
padding: 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading, .hint {
|
.loading, .empty {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #999;
|
color: #999;
|
||||||
padding: 60rpx;
|
padding: 60rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.empty {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
padding: 100rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.empty-icon {
|
.empty-icon {
|
||||||
font-size: 80rpx;
|
font-size: 60rpx;
|
||||||
margin-bottom: 20rpx;
|
display: block;
|
||||||
}
|
|
||||||
|
|
||||||
.empty-text {
|
|
||||||
color: #999;
|
|
||||||
font-size: 28rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.order-list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.order-card {
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 16rpx;
|
|
||||||
padding: 24rpx;
|
|
||||||
margin-bottom: 20rpx;
|
|
||||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.06);
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 16rpx;
|
margin-bottom: 16rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.order-no {
|
.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-size: 28rpx;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.order-status {
|
.customer-phone {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
padding: 4rpx 16rpx;
|
color: #999;
|
||||||
border-radius: 20rpx;
|
margin-top: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow {
|
||||||
|
font-size: 36rpx;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.orders-section {
|
||||||
|
background: #fff;
|
||||||
|
padding: 20rpx;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.orders-header {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.orders-title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.orders-list {
|
||||||
|
height: 500rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-card {
|
||||||
|
padding: 20rpx;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-no {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-status {
|
||||||
|
font-size: 22rpx;
|
||||||
|
padding: 4rpx 12rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-success {
|
.status-success {
|
||||||
@@ -239,17 +317,11 @@ export default {
|
|||||||
|
|
||||||
.card-body {
|
.card-body {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
justify-content: space-between;
|
||||||
gap: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.customer-name {
|
|
||||||
font-size: 26rpx;
|
|
||||||
color: #666;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.order-amount {
|
.order-amount {
|
||||||
font-size: 30rpx;
|
font-size: 28rpx;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #ff4d4f;
|
color: #ff4d4f;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user