|
@@ -30,6 +30,11 @@
|
|
|
<span class="days-tag" v-if="order.daysLater">{{ order.daysLater }}</span>
|
|
<span class="days-tag" v-if="order.daysLater">{{ order.daysLater }}</span>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ <!-- 新增右侧按钮组 -->
|
|
|
|
|
+ <div class="card-right" style="display: flex; align-items: center; gap: 10px; padding-left: 20px;">
|
|
|
|
|
+ <el-button type="primary" size="small" plain round icon="User" @click="openCustomerDetail" :loading="orderInfoLoading">用户档案</el-button>
|
|
|
|
|
+ <el-button type="success" size="small" plain round @click="openPetDetail" :loading="orderInfoLoading" style="margin-left: 0;">宠物档案</el-button>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -57,11 +62,11 @@
|
|
|
|
|
|
|
|
<div class="row-2 categories-row"
|
|
<div class="row-2 categories-row"
|
|
|
style="margin-top: 6px; display:flex; gap:4px; flex-wrap:wrap;">
|
|
style="margin-top: 6px; display:flex; gap:4px; flex-wrap:wrap;">
|
|
|
- <el-tag v-for="cat in (currentRider.tags || [])" :key="cat" size="small"
|
|
|
|
|
- :type="getTagType(cat)" effect="plain">{{ getTagText(cat) }}</el-tag>
|
|
|
|
|
|
|
+ <el-tag v-for="typeId in (currentRider.serviceTypes ? String(currentRider.serviceTypes).split(',') : [])" :key="typeId" size="small"
|
|
|
|
|
+ type="primary" effect="plain">{{ getServiceTypeText(typeId) }}</el-tag>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="row-3 time-row" style="margin-top: 4px;">
|
|
<div class="row-3 time-row" style="margin-top: 4px;">
|
|
|
- <span class="last-time">下一单: {{ currentRider.nextOrderTime || '14:30' }}</span>
|
|
|
|
|
|
|
+ <span class="last-time">下一单: {{ currentRider.nextOrderTime || '-' }}</span>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -98,11 +103,11 @@
|
|
|
|
|
|
|
|
<div class="row-2 categories-row"
|
|
<div class="row-2 categories-row"
|
|
|
style="margin-top: 6px; display:flex; gap:4px; flex-wrap:wrap;">
|
|
style="margin-top: 6px; display:flex; gap:4px; flex-wrap:wrap;">
|
|
|
- <el-tag v-for="cat in (rider.tags || [])" :key="cat" size="small"
|
|
|
|
|
- :type="getTagType(cat)" effect="plain">{{ getTagText(cat) }}</el-tag>
|
|
|
|
|
|
|
+ <el-tag v-for="typeId in (rider.serviceTypes ? String(rider.serviceTypes).split(',') : [])" :key="typeId" size="small"
|
|
|
|
|
+ type="primary" effect="plain">{{ getServiceTypeText(typeId) }}</el-tag>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="row-3 time-row" style="margin-top: 4px">
|
|
<div class="row-3 time-row" style="margin-top: 4px">
|
|
|
- <span class="last-time">下一单: {{ rider.nextOrderTime || '14:30' }}</span>
|
|
|
|
|
|
|
+ <span class="last-time">下一单: {{ rider.nextOrderTime || '-' }}</span>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -141,6 +146,9 @@
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</el-dialog>
|
|
</el-dialog>
|
|
|
|
|
+
|
|
|
|
|
+ <CustomerDetailDrawer v-model:visible="customerDialogVisible" :customer-id="customerId" />
|
|
|
|
|
+ <PetDetailDrawer v-model:visible="petDialogVisible" :pet-id="petId" />
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
@@ -148,6 +156,10 @@ import { ref, computed, watch } from 'vue'
|
|
|
import { ElMessage } from 'element-plus'
|
|
import { ElMessage } from 'element-plus'
|
|
|
import { pageFulfillerOnOrder } from '@/api/fulfiller/pool'
|
|
import { pageFulfillerOnOrder } from '@/api/fulfiller/pool'
|
|
|
import { listAllTag } from '@/api/fulfiller/tag'
|
|
import { listAllTag } from '@/api/fulfiller/tag'
|
|
|
|
|
+import { getSubOrderInfo } from '@/api/order/subOrder/index'
|
|
|
|
|
+import { listServiceOnOrder } from '@/api/service/list/index'
|
|
|
|
|
+import CustomerDetailDrawer from './CustomerDetailDrawer.vue'
|
|
|
|
|
+import PetDetailDrawer from './PetDetailDrawer.vue'
|
|
|
|
|
|
|
|
const props = defineProps({
|
|
const props = defineProps({
|
|
|
visible: Boolean,
|
|
visible: Boolean,
|
|
@@ -179,6 +191,12 @@ const dispatchSearchQuery = ref('')
|
|
|
const selectedRiderId = ref(null)
|
|
const selectedRiderId = ref(null)
|
|
|
const dispatchFee = ref(0)
|
|
const dispatchFee = ref(0)
|
|
|
|
|
|
|
|
|
|
+const customerDialogVisible = ref(false)
|
|
|
|
|
+const petDialogVisible = ref(false)
|
|
|
|
|
+const customerId = ref(null)
|
|
|
|
|
+const petId = ref(null)
|
|
|
|
|
+const orderInfoLoading = ref(false)
|
|
|
|
|
+
|
|
|
const loadAllTags = async () => {
|
|
const loadAllTags = async () => {
|
|
|
if (allTags.value && allTags.value.length > 0) return
|
|
if (allTags.value && allTags.value.length > 0) return
|
|
|
try {
|
|
try {
|
|
@@ -189,6 +207,20 @@ const loadAllTags = async () => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+const serviceOptions = ref([])
|
|
|
|
|
+const loadServiceOptions = async () => {
|
|
|
|
|
+ if (serviceOptions.value.length > 0) return
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await listServiceOnOrder()
|
|
|
|
|
+ serviceOptions.value = res?.data || []
|
|
|
|
|
+ } catch { /* ignore */ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const getServiceTypeText = (id) => {
|
|
|
|
|
+ const s = serviceOptions.value.find(item => String(item.id) === String(id))
|
|
|
|
|
+ return s ? s.name : String(id)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
const loadRiders = async () => {
|
|
const loadRiders = async () => {
|
|
|
try {
|
|
try {
|
|
|
const res = await pageFulfillerOnOrder({
|
|
const res = await pageFulfillerOnOrder({
|
|
@@ -200,7 +232,7 @@ const loadRiders = async () => {
|
|
|
const list = res?.rows || []
|
|
const list = res?.rows || []
|
|
|
ridersList.value = list.map(r => ({
|
|
ridersList.value = list.map(r => ({
|
|
|
...r,
|
|
...r,
|
|
|
- nextOrderTime: r.nextOrderTime || '14:30'
|
|
|
|
|
|
|
+ nextOrderTime: r.nextOrderTime || '-'
|
|
|
}))
|
|
}))
|
|
|
total.value = res?.total || 0
|
|
total.value = res?.total || 0
|
|
|
|
|
|
|
@@ -224,13 +256,52 @@ watch(() => props.visible, (val) => {
|
|
|
currentRider.value = null
|
|
currentRider.value = null
|
|
|
dispatchSearchQuery.value = ''
|
|
dispatchSearchQuery.value = ''
|
|
|
selectedRiderId.value = null
|
|
selectedRiderId.value = null
|
|
|
- dispatchFee.value = 0
|
|
|
|
|
|
|
+ // price 单位为分,转成元显示
|
|
|
|
|
+ dispatchFee.value = props.order?.price ? Number((props.order.price / 100).toFixed(2)) : 0
|
|
|
pageNum.value = 1
|
|
pageNum.value = 1
|
|
|
loadAllTags()
|
|
loadAllTags()
|
|
|
|
|
+ loadServiceOptions()
|
|
|
loadRiders()
|
|
loadRiders()
|
|
|
|
|
+
|
|
|
|
|
+ // 获取订单详细信息
|
|
|
|
|
+ customerId.value = null
|
|
|
|
|
+ petId.value = null
|
|
|
|
|
+ orderInfoLoading.value = true
|
|
|
|
|
+ getSubOrderInfo(props.order.id).then((res) => {
|
|
|
|
|
+ if(res.data) {
|
|
|
|
|
+ // 如果 usrCustomer / usrPet 是对象则取其 id,如果是 ID 直接取
|
|
|
|
|
+ customerId.value = res.data.usrCustomer?.id || res.data.usrCustomer
|
|
|
|
|
+ petId.value = res.data.usrPet?.id || res.data.usrPet
|
|
|
|
|
+
|
|
|
|
|
+ // 接到详情后,把真实的金额放进去(后端金额单位为分)
|
|
|
|
|
+ if (res.data.price !== undefined && res.data.price !== null) {
|
|
|
|
|
+ dispatchFee.value = Number((res.data.price / 100).toFixed(2))
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch((e) => {
|
|
|
|
|
+ console.error('获取订单详细信息失败', e)
|
|
|
|
|
+ }).finally(() => {
|
|
|
|
|
+ orderInfoLoading.value = false
|
|
|
|
|
+ })
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
+const openCustomerDetail = () => {
|
|
|
|
|
+ if (!customerId.value) {
|
|
|
|
|
+ ElMessage.warning('未能获取到用户信息')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ customerDialogVisible.value = true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const openPetDetail = () => {
|
|
|
|
|
+ if (!petId.value) {
|
|
|
|
|
+ ElMessage.warning('未能获取到宠物信息')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ petDialogVisible.value = true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
const getTagText = (tagId) => {
|
|
const getTagText = (tagId) => {
|
|
|
const t = tagMap.value?.[tagId]
|
|
const t = tagMap.value?.[tagId]
|
|
|
return t?.name || String(tagId)
|
|
return t?.name || String(tagId)
|