| @ -0,0 +1,448 @@ | |||
| <template> | |||
| <div class="order_detail_wrapper"> | |||
| <el-main v-loading="loading"> | |||
| <el-card class="mt10"> | |||
| <el-descriptions title="订单信息" :column="2" border label-class-name="my-label" | |||
| contentClassName="my-content"> | |||
| <el-descriptions-item label="订单编号">{{ orderDetail.orderSn }}</el-descriptions-item> | |||
| <el-descriptions-item label="订单金额">¥{{ orderDetail.price }}</el-descriptions-item> | |||
| <el-descriptions-item label="订单详细地址">{{ orderDetail.address }}</el-descriptions-item> | |||
| </el-descriptions> | |||
| </el-card> | |||
| <el-card class="mt10"> | |||
| <el-descriptions title="接单信息" :column="2" border label-class-name="my-label" | |||
| contentClassName="my-content"> | |||
| <el-descriptions-item label="派单次数">{{ orderDetail.num }}</el-descriptions-item> | |||
| <el-descriptions-item label="接单时间">{{ parseTime(orderDetail.acceptTime, '') || '最终接单的时间' }}</el-descriptions-item> | |||
| <el-descriptions-item label="接单用时(h)">{{ orderDetail.whenTakOrders ? (orderDetail.whenTakOrders / 3600).toFixed(2) : '--' }}</el-descriptions-item> | |||
| <el-descriptions-item label="最终接单伴宠师"> | |||
| <span style="color: #409eff;" v-if="orderDetail.userId && getAppUsersPhone(orderDetail.userId)"> | |||
| {{ getAppUsersPhone(orderDetail.userId) }} | |||
| </span> | |||
| <span style="color: #f00;" v-else-if="orderDetail.userId">伴宠师已离职/已不是伴宠师</span> | |||
| </el-descriptions-item> | |||
| </el-descriptions> | |||
| </el-card> | |||
| <el-card class="mt10"> | |||
| <el-descriptions title="开始派单记录" :column="2" border label-class-name="my-label" | |||
| contentClassName="my-content"> | |||
| <el-descriptions-item label="开始派单的时间">{{ parseTime(orderDetail.createTime, '') || '' }}</el-descriptions-item> | |||
| <el-descriptions-item label="开始派单类型"> | |||
| <dict-tag :options="dict.type.applet_order_type" :value="orderDetail.createType" /> | |||
| </el-descriptions-item> | |||
| <el-descriptions-item label="开始派单指定伴宠师"> | |||
| <span style="color: #409eff;" v-if="orderDetail.createUserIdJson"> | |||
| {{ orderDetail.createUserIdJson }} | |||
| </span> | |||
| </el-descriptions-item> | |||
| <!-- <el-descriptions-item label="开始派单接单伴宠师"> | |||
| <span style="color: #409eff;" v-if="orderDetail.createAcceptUserId"> | |||
| {{ orderDetail.createAcceptUserId }} | |||
| </span> | |||
| </el-descriptions-item> --> | |||
| </el-descriptions> | |||
| </el-card> | |||
| <el-card class="mt10"> | |||
| <el-descriptions title="最新派单记录" :column="2" border label-class-name="my-label" | |||
| contentClassName="my-content"> | |||
| <el-descriptions-item label="最新派单的时间">{{ parseTime(orderDetail.newOrderTime, '') || '' }}</el-descriptions-item> | |||
| <el-descriptions-item label="最新派单类型"> | |||
| <dict-tag :options="dict.type.applet_order_type" :value="orderDetail.type" /> | |||
| </el-descriptions-item> | |||
| <el-descriptions-item label="最新派单指定伴宠师"> | |||
| <span style="color: #409eff;" v-if="orderDetail.userIdJson"> | |||
| {{ orderDetail.userIdJson }} | |||
| </span> | |||
| </el-descriptions-item> | |||
| <el-descriptions-item label="最新派单接单伴宠师"> | |||
| <span style="color: #409eff;" v-if="orderDetail.userId && getAppUsersPhone(orderDetail.userId)"> | |||
| {{ getAppUsersPhone(orderDetail.userId) }} | |||
| </span> | |||
| <span style="color: #f00;" v-else-if="orderDetail.userId">伴宠师已离职/已不是伴宠师</span> | |||
| </el-descriptions-item> | |||
| </el-descriptions> | |||
| </el-card> | |||
| <el-card class="mt10"> | |||
| <div slot="header" class="clearfix"> | |||
| <span style="font-size: 16px;font-weight: bold">服务项目及费用</span> | |||
| </div> | |||
| <div class="service-items"> | |||
| <div v-for="(item, index) in serviceItems" :key="index" class="service-item"> | |||
| <div class="service-item-header"> | |||
| <div class="service-date">{{ item.day }}</div> | |||
| <div class="service-name">{{ item.itemsText.join('、') }}</div> | |||
| <div class="service-price">¥{{ item.price.toFixed(2) }}</div> | |||
| </div> | |||
| <div class="service-pets" v-if="item.pets && item.pets.length"> | |||
| <div v-for="(pet, petIndex) in item.pets" :key="petIndex" class="pet-info"> | |||
| <div class="pet-header"> | |||
| <el-avatar :size="40" :src="pet.photo" icon="el-icon-user-solid"></el-avatar> | |||
| <span class="pet-name">{{ pet.name }}</span> | |||
| </div> | |||
| <div class="pet-services"> | |||
| <div v-for="(service, serviceIndex) in pet.itemList" :key="serviceIndex" | |||
| class="service-detail"> | |||
| <span class="service-detail-name">{{ service.productName }}</span> | |||
| <span class="service-detail-price">¥{{ service.salePrice.toFixed(2) }} × {{ | |||
| service.quantity }}次</span> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </el-card> | |||
| <el-card class="mt10" v-if="dateFrequencyList.length > 0"> | |||
| <div slot="header" style="font-size: 16px;font-weight: bold;">日订单列表</div> | |||
| <el-table :data="dateFrequencyList" v-loading="tableLoading" style="width: 100%"> | |||
| <el-table-column label="服务日期" align="center" prop="serviceDate" /> | |||
| <el-table-column label="接单伴宠师" align="center" prop="masterId"> | |||
| <template slot-scope="scope"> | |||
| <div style="display: flex; align-items: center; justify-content: center;"> | |||
| <div style="margin-right: 10px;"> | |||
| <el-avatar :size="40" :src="scope.row.master.userImage" icon="el-icon-user-solid" | |||
| style="background-color: #409EFF;"> | |||
| </el-avatar> | |||
| </div> | |||
| <div style="display: flex; flex-direction: column; align-items: flex-start;"> | |||
| <div style="font-weight: bold; margin-bottom: 2px;"> | |||
| {{ scope.row.master.userName || '未分配' }} | |||
| </div> | |||
| <div style="font-size: 12px; color: #999;"> | |||
| ID: {{ scope.row.masterId || '--' }} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column label="宠物" align="center" prop="status"> | |||
| <template slot-scope="scope"> | |||
| <div style="display: flex; align-items: center; justify-content: center;" | |||
| v-for="(pet, index) in scope.row.pets" :key="index"> | |||
| <div style="margin-right: 10px;"> | |||
| <el-avatar :size="40" :src="pet.photo" icon="el-icon-user-solid" | |||
| style="background-color: #409EFF;"> | |||
| </el-avatar> | |||
| </div> | |||
| <div style="display: flex; flex-direction: column; align-items: flex-start;"> | |||
| <div style="margin-bottom: 2px;"> | |||
| {{ pet.name }} | {{ pet.breed }} | {{ pet.bodyType }} | |||
| </div> | |||
| <div style="font-size: 12px; color: #999;"> | |||
| {{pet.orderItemList.map(n => n.productName).join(',')}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column label="完成状态" align="center" prop="status"> | |||
| <template slot-scope="scope"> | |||
| <dict-tag :options="dict.type.order_check_status" :value="scope.row.status" /> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column label="完成时间" align="center" prop="completionTime" /> | |||
| <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | |||
| <template slot-scope="scope"> | |||
| <el-button size="mini" type="text" icon="el-icon-full-screen" | |||
| @click="handleCheckin(scope.row)">打卡信息</el-button> | |||
| </template> | |||
| </el-table-column> | |||
| </el-table> | |||
| </el-card> | |||
| </el-main> | |||
| <!-- 打卡弹窗 --> | |||
| <checkin-dialog v-model="checkinDialogVisible" :order-data="currentOrderData"> | |||
| </checkin-dialog> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { getAppletOrder, getAppletOrderDetail } from "@/api/model/AppletOrder"; | |||
| import { listAppletOrderDateFrequency } from "@/api/model/appletOrderDateFrequency"; | |||
| import { listAppUsers } from "@/api/model/AppUsers"; | |||
| import CheckinDialog from "@/components/CheckinDialog.vue"; | |||
| import dayjs from "dayjs"; | |||
| export default { | |||
| name: "AppletOrderDetail", | |||
| dicts: ['applet_order_status', 'applet_order_type', 'order_check_status'], | |||
| components: { | |||
| CheckinDialog | |||
| }, | |||
| data() { | |||
| return { | |||
| loading: false, | |||
| tableLoading: false, | |||
| orderDetail: {}, | |||
| dateFrequencyList: [], | |||
| appUsersList: [], | |||
| active: 1, | |||
| checkinDialogVisible: false, | |||
| currentOrderData: {}, | |||
| id: null, | |||
| serviceItems: [], | |||
| } | |||
| }, | |||
| created() { | |||
| this.id = this.$route.query.id; | |||
| this.getDetail(this.id); | |||
| this.listAppUsers(); | |||
| }, | |||
| methods: { | |||
| getDetail() { | |||
| this.loading = true; | |||
| getAppletOrder(this.id).then(res => { | |||
| this.orderDetail = res.data; | |||
| this.getDateFrequencyList(); | |||
| this.getOmsOrder(); | |||
| if (this.orderDetail.status <= 3) { | |||
| this.active = this.orderDetail.status + 1; | |||
| } else { | |||
| this.active = 1; | |||
| } | |||
| this.loading = false; | |||
| }); | |||
| }, | |||
| getOmsOrder() { | |||
| getAppletOrderDetail(this.orderDetail.orderId).then(res => { | |||
| //=====================服务项目以及费用的计算开始===================== | |||
| let data = res.data; | |||
| let items = [] | |||
| //1、找出有哪些日期 | |||
| let days = [...new Set(data.orderServiceList.map(item => item.serviceDate))] | |||
| days.forEach(day => { | |||
| let price = 0; | |||
| let itemsText = [] | |||
| //2、找出每个日期对应的服务对象 | |||
| let dayItems = data.orderServiceList.filter(item => item.serviceDate === day) | |||
| //3、找出每个服务对象对应的宠物 | |||
| let pets = data.petVOList.filter(item => dayItems.some(dayItem => dayItem.petId === item.id)) | |||
| //深度拷贝pets | |||
| pets = JSON.parse(JSON.stringify(pets)) | |||
| //4、将每个服务对象添加进对应的宠物 | |||
| pets.forEach(pet => { | |||
| pet.serviceList = dayItems.filter(item => item.petId === pet.id) | |||
| let itemList = [] | |||
| //5、将每个服务对象中添加对应的项目 | |||
| pet.serviceList.forEach(item => { | |||
| itemList.push(...(data.orderItemList.filter(n => n.orderServiceId == item.id))) | |||
| }) | |||
| //倒叙 | |||
| itemList = itemList.reverse(); | |||
| itemList.forEach(p => { | |||
| price += p.salePrice * p.quantity | |||
| itemsText = [...new Set([...itemsText, p.productName])] | |||
| }) | |||
| pet.itemList = itemList | |||
| }) | |||
| //6、将每个宠物添加进items | |||
| items.push({ | |||
| price, | |||
| pets, | |||
| day, | |||
| itemsText, | |||
| }) | |||
| }) | |||
| //根据日期排序 | |||
| items = items.sort((a, b) => dayjs(a.day).valueOf() - dayjs(b.day).valueOf()) | |||
| items.forEach(n => { | |||
| n.day = dayjs(n.day).format('MM-DD') | |||
| }) | |||
| console.log(items); | |||
| this.serviceItems = items; | |||
| //=====================服务项目以及费用的计算结束===================== | |||
| }); | |||
| }, | |||
| getDateFrequencyList() { | |||
| this.tableLoading = true; | |||
| listAppletOrderDateFrequency({ | |||
| orderId: this.orderDetail.orderId | |||
| }).then(response => { | |||
| this.dateFrequencyList = response.rows; | |||
| this.tableLoading = false; | |||
| }); | |||
| }, | |||
| listAppUsers() { | |||
| listAppUsers({ | |||
| pageNum: 1, | |||
| pageSize: 99999999, | |||
| userBcs: 1, | |||
| }).then(response => { | |||
| this.appUsersList = response.rows; | |||
| }); | |||
| }, | |||
| getAppUsersPhone(userId) { | |||
| let data = this.appUsersList.find(item => item.userId == userId); | |||
| if (data) { | |||
| return data.userTelephone; | |||
| } else { | |||
| return ''; | |||
| } | |||
| }, | |||
| handleCheckin(row) { | |||
| this.currentOrderData = row; | |||
| this.checkinDialogVisible = true; | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .order_detail_wrapper { | |||
| >.el-card+.el-card { | |||
| margin-top: 1rem; | |||
| } | |||
| .el-form-item { | |||
| margin-bottom: 0; | |||
| .el-form-item__content, | |||
| .el-form-item__label { | |||
| line-height: 2; | |||
| } | |||
| } | |||
| } | |||
| .my-label { | |||
| width: 100px; | |||
| } | |||
| .my-content { | |||
| width: 400px; | |||
| } | |||
| .service-items { | |||
| padding: 0 20px; | |||
| display: flex; | |||
| flex-wrap: wrap; | |||
| gap: 20px; | |||
| .service-item { | |||
| padding: 20px; | |||
| min-width: 280px; | |||
| width: 30%; | |||
| background-color: #f9f9f9; | |||
| border-radius: 10px; | |||
| box-sizing: border-box; | |||
| &:last-child { | |||
| border-bottom: none; | |||
| } | |||
| .service-item-header { | |||
| display: flex; | |||
| align-items: center; | |||
| margin-bottom: 15px; | |||
| .service-date { | |||
| font-size: 16px; | |||
| color: #000; | |||
| margin-right: 10px; | |||
| min-width: 100px; | |||
| font-weight: 900; | |||
| } | |||
| .service-name { | |||
| flex: 1; | |||
| font-size: 14px; | |||
| color: #303133; | |||
| margin: 0 20px; | |||
| } | |||
| .service-price { | |||
| font-size: 16px; | |||
| font-weight: bold; | |||
| color: #303133; | |||
| min-width: 100px; | |||
| text-align: right; | |||
| } | |||
| } | |||
| .service-pets { | |||
| padding: 15px; | |||
| background-color: #F5F7FA; | |||
| border-radius: 4px; | |||
| .pet-info { | |||
| margin-bottom: 15px; | |||
| &:last-child { | |||
| margin-bottom: 0; | |||
| } | |||
| .pet-header { | |||
| display: flex; | |||
| align-items: center; | |||
| margin-bottom: 10px; | |||
| .pet-name { | |||
| margin-left: 10px; | |||
| font-size: 14px; | |||
| font-weight: bold; | |||
| color: #303133; | |||
| } | |||
| } | |||
| .pet-services { | |||
| padding-left: 50px; | |||
| .service-detail { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| margin-bottom: 8px; | |||
| padding: 8px 0; | |||
| border-bottom: 1px dashed #E4E7ED; | |||
| &:last-child { | |||
| margin-bottom: 0; | |||
| border-bottom: none; | |||
| } | |||
| .service-detail-name { | |||
| font-size: 13px; | |||
| color: #606266; | |||
| } | |||
| .service-detail-price { | |||
| font-size: 13px; | |||
| color: #909399; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| </style> | |||