| @ -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> | |||||