完善订单接口和流水明细接口

This commit is contained in:
wangxiaowei
2026-01-02 16:22:20 +08:00
parent e06be5531d
commit 58f59f1ee5
8 changed files with 336 additions and 203 deletions

2
env/.env vendored
View File

@ -12,8 +12,6 @@ VITE_LOGIN_URL = '/pages/login/login'
# 第一个请求地址
VITE_SERVER_BASEURL = 'https://cz.stnav.com'
VITE_UPLOAD_BASEURL = 'https://cz.stnav.com/upload'
# h5是否需要配置代理
VITE_APP_PROXY=true
VITE_APP_PROXY_PREFIX = '/storeapi'

View File

@ -50,6 +50,7 @@ export interface TeaSpecialistOrderListParams {
size: number
order_status?: string
search?: string
day_time?: string
}
export function getTeaSpecialistOrderList(data: TeaSpecialistOrderListParams) {
@ -101,3 +102,27 @@ export function arriveTeaSpecialistOrder(data: ArriveTeaSpecialistOrderParams) {
export function checkInTeaSpecialistOrder(id: number, img: string) {
return http.Post<any>('/teamapi/order/orderImage', { id, img })
}
/**
* 茶艺师完成订单
* @param id 订单ID
*/
export function completeTeaSpecialistOrder(id: number) {
return http.Post<any>('/teamapi/order/orderFinish', { id })
}
/**
* 茶艺师删除订单
* @param id 订单ID
*/
export function deleteTeaSpecialistOrder(id: number) {
return http.Post<any>('/teamapi/order/orderDel', { id })
}
/**
* 费用明细
* @param id 订单ID
*/
export function getTeaSpecialistCostDetails(id: number) {
return http.Post<any>('/teamapi/order/amountDetails', {id})
}

View File

@ -45,18 +45,18 @@ export function getUserInfo() {
export interface IGetUserTransactionDetailsParams {
page: number
size: number
end_time: string
times: string
}
export function getUserTransactionDetails(data: IGetUserTransactionDetailsParams) {
return http.Post<IOrderListResult>('/storeapi/user/balanceLogList', data)
return http.Post<IOrderListResult>('/teamapi/user/checkAccountList', data)
}
/**
* 获取流水明细详情(账单明细)
*/
export function getUserTransactionDetailsInfo(id: number) {
return http.Post<any>('/storeapi/user/balanceLogDetails', { id })
return http.Post<any>('/teamapi/user/balanceLogDetails', { id })
}
/**

View File

@ -36,7 +36,7 @@
<view class="mt-20rpx ml-68rpx mr-60rpx">
<view class="flex items-center justify-end" @click="Wallet.handleShowPrompt">
<view class="font-400 text-26rpx leading-36rpx text-[#909399] mr-16rpx">不可提现金额200</view>
<view class="font-400 text-26rpx leading-36rpx text-[#909399] mr-16rpx">不可提现金额{{ userInfo.no_reflect_amount }}</view>
<view class="">
<wd-img width="26rpx" height="26rpx" :src="`${OSS}icon/icon_prompt.png`"></wd-img>
</view>
@ -44,7 +44,7 @@
<view class="font-400 text-28rpx leading-40rpx text-[#303133]">可提现金额</view>
<view class="flex justify-between items-center mt-24rpx">
<view>
<price-format color="#000" :first-size="48" :second-size="48" :subscript-size="28" :price="userStore.userMoney"></price-format>
<price-format color="#000" :first-size="48" :second-size="48" :subscript-size="28" :price="userInfo.user_money"></price-format>
</view>
<view class="w-200rpx h-80rpx bg-[#4C9F44] rounded-8rpx font-bold text-28rpx leading-80rpx text-center text-[#fff]" @click="Wallet.handleToRecharge">
提现
@ -54,10 +54,10 @@
</view>
</view>
<!-- 提现明细 -->
<!-- 流水明细 -->
<view class="bg-white rounded-16rpx px-30rpx py-40rpx mt-20rpx mx-30rpx">
<view class="flex justify-between items-center">
<view class="text-32rpx leading-44rpx text-[#303133] mb-20rpx">提现明细</view>
<view class="text-32rpx leading-44rpx text-[#303133] mb-20rpx">流水明细</view>
<view class="border-2rpx border-solid border-[#E5E5E5] w-196rpx h-56rpx flex justify-center items-center rounded-8rpx">
<view class="text-24rpx leading-34rpx text-[#606266] wall-date">
<!-- 2019年5月 -->
@ -101,7 +101,7 @@
<view>
<view class="flex items-center h-50rpx">
<view class="mr-16rpx">
<text> {{ item.change_type == 3 ? '-' : '+' }}</text>
<text> {{ item.action === 2 ? '-' : '+' }}</text>
<price-format color="#000" :first-size="36" :second-size="36" :showSubscript="false" :price="item.amount"></price-format>
</view>
<view>
@ -135,6 +135,20 @@
// 消息提示框
const message = useMessage('wd-message-box-slot')
// 用户信息
const userInfo = ref({
avatar: '',
nickname: '',
account: '',
user_money: 0,
no_reflect_amount: 0,
work: '',
address: '',
work_time: '',
is_mileage: 0,
cert_id: 0,
})
/* mescroll */
const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom) // 调用mescroll的hook
const downOption = {
@ -149,7 +163,7 @@
const selectTime = ref<string>('')
onShow(() => {
Wallet.handleGetUserInfo()
})
const Wallet = {
@ -161,7 +175,7 @@
const filter = {
page: mescroll.num,
size: mescroll.size,
end_time: selectTime.value
times: selectTime.value
}
getUserTransactionDetails(filter).then((res) => {
@ -174,6 +188,14 @@
})
},
/**
* 获取个人信息
*/
handleGetUserInfo: async () => {
const res = await getUserInfo()
userInfo.value = res
},
/**
* 日期筛选
* @param date
@ -209,7 +231,7 @@
* @param id
*/
handleToBillDetail: (item: {id: number, change_type: number}) => {
// change_type: 1包间预定 2包间续订 3提现 4团购核销
// change_type: 1.预定2.续时3.续茶4.退款5.提现
if (item.change_type === 3) {
router.navigateTo(`/bundle/parten/pages/withdraw/progress?id=${item.id}`)
return
@ -224,10 +246,11 @@
*/
handleMapTransactionType: (type: number) => {
const typeMap: Record<number, string> = {
1: '包间预定',
2: '包间续费',
3: '提现',
4: '团购核销'
1: '茶艺师预约',
2: '加钟续费',
3: '续茶',
4: '退款',
5: '提现'
}
return typeMap[type] || '其他'
},
@ -238,7 +261,7 @@
handleShowPrompt: () => {
message.alert({
title: '温馨提示',
msg: '为保障您与平台的合作权益,我们将暂扣200元作为合作押金,感谢您的理解与支持。',
msg: `为保障您与平台的合作权益,我们将暂扣${userInfo.value.no_reflect_amount}作为合作押金,感谢您的理解与支持。`,
confirmButtonText: '我知道了',
confirmButtonProps: {
customClass: '!bg-[#4C9F44] !text-[#fff] !text-32rpx !leading-44rpx !rounded-8rpx',

View File

@ -1,5 +1,11 @@
import { router } from '@/utils/tools'
import { acceptTeaSpecialistOrder, departTeaSpecialistOrder, arriveTeaSpecialistOrder } from '@/api/tes-specialist'
import {
acceptTeaSpecialistOrder,
departTeaSpecialistOrder,
arriveTeaSpecialistOrder,
checkInTeaSpecialistOrder,
completeTeaSpecialistOrder,
deleteTeaSpecialistOrder } from '@/api/tes-specialist'
import { l } from 'vite/dist/node/types.d-aGj9QkWt'
@ -20,6 +26,7 @@ export async function handleReleaseOrderHooks(id: number) {
/**
* 茶艺师出发
* @param id 订单ID
*/
export async function handleDepartOrderHooks(id: number) {
try {
@ -33,6 +40,7 @@ export async function handleDepartOrderHooks(id: number) {
/**
* 茶艺师已到达
* @param data 订单ID和经纬度等参数
*/
export async function handleArriveOrderHooks(data: {id: number, longitude: number, latitude: number}) {
try {
@ -43,3 +51,46 @@ export async function handleArriveOrderHooks(data: {id: number, longitude: numbe
return false
}
}
/**
* 茶艺师打卡
* @param id 订单ID
* @param img 图片
*/
export async function handleTeaSpecialistClockInHooks(id: number, img: string) {
try {
await checkInTeaSpecialistOrder(id, img)
return true
}
catch (error) {
return false
}
}
/**
* 完成订单
* @param id 订单ID
*/
export async function handleCompleteOrderHooks(id: number) {
try {
await completeTeaSpecialistOrder(id)
return true
}
catch (error) {
return false
}
}
/**
* 删除订单
* @param id 订单ID
*/
export async function handleDeleteOrderHooks(id: number) {
try {
await deleteTeaSpecialistOrder(id)
return true
}
catch (error) {
return false
}
}

View File

@ -89,6 +89,7 @@
<view class="section-header" style="justify-content: flex-start;border-radius: 16rpx;">
<text class="section-title">今日行程</text>
<!-- <text class="section-tip">其他日期行程可至行程记录查看</text> -->
<text class="section-tip" @click="router.switchTab('/pages/order/order')">查看更多</text>
</view>
<view class="schedule-list">
<view v-if="todayOrders.length === 0" class="empty-schedule">
@ -103,46 +104,39 @@
class="schedule-item-wrapper">
<view class="schedule-header-row">
<text class="schedule-type">预约单</text>
<text class="schedule-status">{{ order.status || '待服务' }}</text>
<text class="schedule-status">{{ TeaSpecialistManageStatusTextValue[order.order_status].title }}</text>
</view>
<view class="schedule-item">
<view class="schedule-item" @click="router.navigateTo(`/pages/order/detail?orderId=${order.id}`)">
<view class="schedule-date">
<text class="date-day">{{ formatDate(order.date, 'day') }}</text>
<text class="date-month">{{ formatDate(order.date, 'month') }}月</text>
<text class="date-day">{{ day }}</text>
<text class="date-month">{{ month }}月</text>
</view>
<view class="schedule-content">
<view class="schedule-location-row">
<text class="schedule-location">
{{ order.location || order.store_name
}}
{{ order.title }}
</text>
<text class="schedule-service-type">
{{ order.service_type || '到店服务'
}}
{{ order.server_type == 1 ? '到店服务' : '上门服务'}}
</text>
</view>
<view class="schedule-time-row">
<wd-icon color="#8A94A3" name="time" size="22px" />
<text class="schedule-time">
{{ order.start_time }}-{{ order.end_time
}}
{{ order.start_time }}-{{ order.end_time }}
</text>
</view>
<view class="schedule-address-row">
<wd-icon color="#8A94A3" name="location" size="22px" />
<view class="schedule-address">
{{ order.address || order.store_address
}}
{{ order.address }}
</view>
<view class="schedule-navigate" @click="handleNavigate(order)">
<view class="schedule-navigate" @click.stop="Index.handleNavigate(order)">
<image class="navigate-icon"
:src="`${OSS}images/chayishi/send2.png`" mode="aspectFit" />
</view>
</view>
</view>
<!-- <view class="schedule-navigate" @click="handleNavigate(order)">
<image class="navigate-icon" :src="navigateIcon" mode="aspectFit" />
</view> -->
</view>
</view>
</view>
@ -158,8 +152,8 @@
<template v-else>
<view v-for="(order, index) in todayOrders" :key="order.id || index" class="schedule-item">
<view class="schedule-date">
<text class="date-day">{{ formatDate(order.date, 'day') }}</text>
<text class="date-month">{{ formatDate(order.date, 'month') }}月</text>
<text class="date-day">{{ day }}</text>
<text class="date-month">{{ month }}月</text>
</view>
<view class="schedule-content">
<view class="schedule-header-row">
@ -223,8 +217,11 @@
<script lang="ts" setup>
import { inject, onMounted, ref } from 'vue'
import { router } from '@/utils/tools'
import { router, getCurrentDate } from '@/utils/tools'
import { useUserStore } from '@/store'
import { getTeaSpecialistOrderList } from '@/api/tes-specialist'
import { TeaSpecialistManageStatusTextValue, TeaSpecialistOrderStatus } from '@/utils/teaSpecialistOrder'
const OSS = inject('OSS')
const navbarHeight = inject('navbarHeight')
@ -295,32 +292,7 @@
const levelInfo = computed(() => levelList.value[currentLevelIndex.value])
// 今日订单列表(模拟数据)
const todayOrders = ref<Array<any>>([
{
id: 1,
date: '2025-09-21',
start_time: '15:00',
end_time: '18:00',
location: '苓苑共享茶室空间',
address: '上海浦东新区新金桥路58号新银东大厦15楼F室',
service_type: '到店服务',
status: '待服务',
latitude: 31.2304,
longitude: 121.4737,
},
{
id: 2,
date: '2025-09-22',
start_time: '15:00',
end_time: '18:00',
location: '苓苑共享茶室空间',
address: '上海浦东新区新金桥路58号新银东大厦15楼F室',
service_type: '到店服务',
status: '待服务',
latitude: 31.2304,
longitude: 121.4737,
},
])
const todayOrders = ref<Array<any>>([])
// 公告列表(模拟数据)
const announcements = ref<Array<any>>([
@ -356,6 +328,7 @@
onLoad(() => {
calculateProgress()
Index.handleGetTodayOrder()
})
// 计算进度百分比
@ -366,11 +339,6 @@
})
}
// 页面加载时计算进度
onMounted(() => {
calculateProgress()
})
// 处理等级卡片滑动
function handleLevelScroll(e: any) {
// const scrollLeft = e.detail.scrollLeft
@ -386,33 +354,6 @@
// }
}
// 格式化日期
function formatDate(dateStr: string, type: 'day' | 'month') {
if (!dateStr)
return ''
// 处理格式如 "2025-09-21" 的日期字符串
const parts = dateStr.split('-')
if (parts.length >= 3) {
if (type === 'day') {
return Number.parseInt(parts[2]).toString()
}
else {
return Number.parseInt(parts[1]).toString()
}
}
// 如果不是标准格式尝试使用Date对象解析
const date = new Date(dateStr)
if (!Number.isNaN(date.getTime())) {
if (type === 'day') {
return date.getDate().toString()
}
else {
return (date.getMonth() + 1).toString()
}
}
return ''
}
// 菜单点击
function handleMenuClick() {
console.log('菜单点击')
@ -456,6 +397,47 @@
function handleAnnouncementClick(item: any) {
console.log('公告点击', item)
}
// 今日行程显示的月和日
const month = ref<number>(0)
const day = ref<number>(0)
const Index = {
/**
* 获取今日订单
*/
handleGetTodayOrder: async () => {
const date = getCurrentDate().split('-')
month.value = Number(date[1])
day.value = Number(date[2])
console.log("🚀 ~ date:", date)
// 获取今日日期
const filter = {
page: 1,
size: 10,
order_status: `${TeaSpecialistOrderStatus.Pending}, ${TeaSpecialistOrderStatus.Accepted}, ${TeaSpecialistOrderStatus.Departed}, ${TeaSpecialistOrderStatus.Arrived}, ${TeaSpecialistOrderStatus.Completed}`, // 只获取待服务、已接单和服务中的订单
day_time: getCurrentDate(), // 获取当前日期
}
const res = await getTeaSpecialistOrderList(filter)
todayOrders.value = res.list
},
/**
* 导航点击
*/
handleNavigate: (order: any) => {
if (order.latitude && order.longitude) {
uni.openLocation({
latitude: Number(order.latitude),
longitude: Number(order.longitude),
name: order.location,
address: order.address,
})
}
},
}
</script>
<style lang="scss">

View File

@ -59,8 +59,8 @@
</wd-step>
<wd-step title="茶艺师到达">
<template #description>
<view class="" v-if="order.image">
<wd-img width="120rpx" height='80rpx' :src="order.image" radius="8rpx"></wd-img>
<view class="" v-if="order.img" @click="Detail.handlePreviewPhoto">
<wd-img width="120rpx" height='80rpx' :src="order.img" radius="8rpx"></wd-img>
</view>
<view >{{ order.arrival_time }}</view>
</template>
@ -90,52 +90,52 @@
<!-- 订单总额 -->
<view class="cost-item">
<text class="cost-label">订单总额</text>
<text class="cost-value">¥ {{ order.team_income_price }}</text>
<text class="cost-value">¥ {{ costDetails.all_amount }}</text>
</view>
<view class="bg-[#FBFBFB] py-24rpx px-30rpx rounded-16rpx">
<!-- 服务费 -->
<view class="cost-item">
<text class="cost-label">服务费</text>
<text class="cost-value">¥ {{ costDetail.serviceFee.toFixed(2) }}</text>
<text class="cost-value">¥ {{ costDetails.server_all_price }}</text>
</view>
<view class="cost-sub-item">
<text class="cost-sub-label">服务费 (¥ {{ costDetail.serviceFeePerHour }}/小时)</text>
<text class="cost-sub-value">x{{ costDetail.serviceHours }}</text>
<text class="cost-sub-label">服务费 (¥ {{ costDetails.server_price }}/小时)</text>
<text class="cost-sub-value">x{{ costDetails.hours }}</text>
</view>
<!-- 车马费 -->
<view class="cost-item">
<text class="cost-label">车马费</text>
<text class="cost-value">¥ {{ costDetail.travelFee.toFixed(2) }}</text>
<text class="cost-value">¥ {{ costDetails.mileage_server_price }}</text>
</view>
<view class="cost-sub-item">
<text class="cost-sub-label">车马费 (¥ {{ costDetail.travelFeePerKm }}/公里)</text>
<text class="cost-sub-value">{{ costDetail.distance }}公里</text>
<text class="cost-sub-label">车马费 (¥ {{ costDetails.mileage_price }}/公里)</text>
<text class="cost-sub-value">{{ costDetails.distance }}公里</text>
</view>
<!-- 茶艺服务 -->
<view class="cost-item">
<text class="cost-label">茶艺服务</text>
<text class="cost-value">¥ {{ costDetail.teaServiceFee.toFixed(2) }}</text>
<text class="cost-value">¥ {{ costDetails.tea_all_price }}</text>
</view>
<view class="cost-sub-item">
<text class="cost-sub-label">{{ costDetail.teaName }}</text>
<text class="cost-sub-value">¥ {{ costDetail.teaPrice }}</text>
<text class="cost-sub-label">{{ order.leaf_name }}</text>
<text class="cost-sub-value">¥ {{ costDetails.tea_price }}</text>
</view>
<view class="cost-sub-item">
<text class="cost-sub-label">茶具使用</text>
<text class="cost-sub-value">¥ {{ costDetail.teawarePrice }}</text>
<text class="cost-sub-value">¥ {{ costDetails.teacup_price }}</text>
</view>
<!-- 优惠 -->
<view class="cost-item">
<text class="cost-label">优惠</text>
<text class="cost-value discount">- ¥ {{ costDetail.discount.toFixed(2) }}</text>
<text class="cost-value discount">- ¥ {{ costDetails.coupon_price }}</text>
</view>
<view class="cost-sub-item">
<text class="cost-sub-label">优惠券</text>
<text class="cost-sub-value discount">- ¥ {{ costDetail.couponDiscount }}</text>
<text class="cost-sub-value discount">- ¥ {{ costDetails.coupon_price }}</text>
</view>
</view>
@ -144,24 +144,23 @@
<view class="cost-divider" />
<!-- 扣除费用区域 -->
<view class="deduct-section rounded-16rpx">
<view class="cost-item">
<text class="cost-label">扣除费用</text>
<text class="cost-value">¥ {{ costDetail.deductFee.toFixed(2) }}</text>
</view>
<view class="cost-sub-item">
<text class="cost-sub-label">平台服务费</text>
<text class="cost-sub-value">¥ {{ costDetail.platformFee.toFixed(2) }}</text>
<!-- <view class="deduct-section rounded-16rpx">
<view class="flex items-center justify-between">
<view class="cost-label">平台服务费</view>
<view class="cost-value">¥ {{ costDetails.handling_fee }}</view>
</view>
</view> -->
<view class="cost-item">
<text class="cost-label">平台服务费</text>
<text class="cost-value">¥ {{ costDetails.handling_fee }}</text>
</view>
<!-- 分隔线 -->
<view class="cost-divider" />
<view class="deduct-section rounded-16rpx">
<view class="flex items-center justify-between">
<view class="cost-label">实际收入</view>
<view class="cost-value">¥ {{ costDetail.deductFee.toFixed(2) }}</view>
</view>
<view class="cost-item">
<text class="cost-label">实际收入</text>
<text class="cost-value">¥ {{ costDetails.team_income_price }}</text>
</view>
</scroll-view>
</view>
@ -230,7 +229,7 @@
<!-- 订单预约信息 -->
<view class="h-374rpx bg-white rounded-16rpx">
<view class="order-card relative">
<view class="price-btn" @click.stop="handlePriceClick">
<view class="price-btn" @click.stop="showCostDetailPopup = true">
<price-format color="#FFFFFF" :first-size="32" :second-size="32" :subscript-size="24"
:price="order.team_income_price" />
<wd-icon name="arrow-right" size="24rpx" color="#FFFFFF" class="ml-8rpx" />
@ -324,17 +323,17 @@
<!-- 拍照打卡 -->
<view class="bg-white rounded-16rpx px-30rpx py-20rpx mt-20rpx"
v-if="orderStatus === TeaSpecialistOrderStatus.Arrived || orderStatus === TeaSpecialistOrderStatus.Completed">
v-if="(orderStatus === TeaSpecialistOrderStatus.Arrived || orderStatus === TeaSpecialistOrderStatus.Completed) && Number(order.is_img) === 1">
<!-- TODO 暂时不做 -->
<!-- <view class="font-500 text-[#909399] text-24rpx">距离 5 km预计 <text class="text-[#303133]">20分钟</text> 请妥善安排好出行时间</view> -->
<view class="" v-if="order.is_image > 0">
<view class="" v-if="order.is_img > 0">
<view class="font-bold text-28rpx leading-48rpx text-[#303133]">拍照记录</view>
<view class="flex items-center mt-22rpx">
<view class="flex items-center">
<wd-img :src="`${OSS}icon/icon_checked.png`" width="36rpx" height="36rpx"></wd-img>
<view class="font-400 text-26rpx text-[#303133] leading-36rpx ml-8rpx">打卡成功</view>
</view>
<view class="flex items-center ml-82rpx">
<view class="flex items-center ml-82rpx" @click="Detail.handlePreviewPhoto">
<wd-img :src="`${OSS}icon/icon_photo.png`" width="36rpx" height="36rpx"></wd-img>
<view class="font-400 text-26rpx text-[#303133] leading-36rpx ml-8rpx">已拍照</view>
<wd-icon name="arrow-right" size="32rpx" color="#666666"></wd-icon>
@ -342,7 +341,7 @@
</view>
<view class="mt-12rpx flex items-center">
<wd-img :src="`${OSS}icon/icon_time2.png`" width="24rpx" height="24rpx"></wd-img>
<view class="font-400 text-24rpx text-[#8A94A3] leading-34rpx ml-8rpx">{{ order.image_time }}</view>
<view class="font-400 text-24rpx text-[#8A94A3] leading-34rpx ml-8rpx">{{ order.img_time }}</view>
</view>
<!-- TODO 打卡地址-暂时不做 -->
<!-- <view class="mt-12rpx flex items-center">
@ -395,9 +394,9 @@
<view class="copy-text" @click.stop="copy(order.order_sn)">| 复制</view>
</view>
</view>
<view class="info-item flex items-center justify-between" v-if="order.pay_title">
<view class="info-item flex items-center justify-between" v-if="order.pay_way_title">
<view class="info-label">交易方式</view>
<view class="info-value text-right">{{ order.pay_title }}</view>
<view class="info-value text-right">{{ order.pay_way_title }}</view>
</view>
<view class="info-item flex items-center justify-between">
<view class="info-label">创建时间</view>
@ -452,15 +451,23 @@
<script lang="ts" setup>
import { useMessage, useToast } from 'wot-design-uni'
import { useMessage, useToast, useUpload } from 'wot-design-uni'
import PriceFormat from '@/components/PriceFormat.vue'
import { copy } from '@/utils/tools'
import { router, copy } from '@/utils/tools'
import { TeaSpecialistOrderStatus, TeaSpecialistManageStatusTextValue } from '@/utils/teaSpecialistOrder'
import { getTeaSpecialistOrderDetails } from '@/api/tes-specialist'
import { handleReleaseOrderHooks, handleDepartOrderHooksm, handleDepartOrderHooks } from '@/hooks/useOrder'
import { getTeaSpecialistOrderDetails, getTeaSpecialistCostDetails } from '@/api/tes-specialist'
import {
handleReleaseOrderHooks,
handleDepartOrderHooks,
handleArriveOrderHooks,
handleTeaSpecialistClockInHooks,
handleCompleteOrderHooks,
handleDeleteOrderHooks
} from '@/hooks/useOrder'
const OSS = inject('OSS')
const toast = useToast()
const { startUpload, abort, chooseFile, UPLOAD_STATUS } = useUpload()
// navbar 标题
const title = ref<string>('')
@ -484,7 +491,8 @@
// 消息提示框
const message = useMessage('wd-message-box-slot')
// 费用明细弹窗
// 费用明细
const costDetails = ref<any>({})
const showCostDetailPopup = ref(false)
// 订单数据
@ -516,29 +524,12 @@
travel_time: '', // 出发时间
arrival_time: '', // 到达时间
take_order_time: '', // 接单时间
pay_title: '', // 交易方式
is_image: 0, //是否打卡 0未打卡 1已打卡
image: '', // 到达打卡拍照
image_time: '', // 到达打卡时间
pay_way_title: '', // 交易方式
is_img: 0, //是否打卡 0未打卡 1已打卡
img: '', // 到达打卡拍照
img_time: '', // 到达打卡时间
})
// 倒计时
const countdownTime = ref('09:30:48')
let countdownTimer: any = null
// 格式化倒计时
function formatCountdown(seconds: number) {
const hours = Math.floor(seconds / 3600)
const minutes = Math.floor((seconds % 3600) / 60)
const secs = seconds % 60
return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(secs).padStart(2, '0')}`
}
// 价格点击(查看详情)
function handlePriceClick() {
showCostDetailPopup.value = true
}
// 放弃接单
function handleDecline() {
message.confirm({
@ -570,30 +561,10 @@
})
}
// 立即接单
function handleAccept() {
// TODO: 调用接单的 API
console.log('立即接单')
uni.showToast({
title: '接单成功',
icon: 'success',
})
// 可以返回上一页
setTimeout(() => {
uni.navigateBack()
}, 1500)
}
onLoad((args) => {
onLoad(async (args) => {
orderId.value = args.orderId
Detail.handleInit()
})
onUnload(() => {
// 清理倒计时
if (countdownTimer) {
clearInterval(countdownTimer)
}
await Detail.handleInit()
await Detail.handleGetCostDetails()
})
const Detail = {
@ -606,6 +577,7 @@
orderStatus.value = res.order_status
title.value = TeaSpecialistManageStatusTextValue[order.value.order_status].pageTitle || '订单详情'
// 这里是显示订单记录步骤条
if (res.order_status === TeaSpecialistOrderStatus.Accepted) {
stepsActive.value = 1
} else if (res.order_status === TeaSpecialistOrderStatus.Departed) {
@ -617,6 +589,19 @@
} else {
stepsActive.value = 0
}
// 如果订单状态为已到达31提示需要打开拍照
if (res.order_status === TeaSpecialistOrderStatus.Arrived && !res.is_img) {
Detail.handleTakePhoto()
}
},
/**
* 获取订单费用明细
*/
handleGetCostDetails: async () => {
const res = await getTeaSpecialistCostDetails(order.value.id)
costDetails.value = res
},
/**
@ -741,15 +726,13 @@
/**
* 完成服务
*/
handleFinished: () => {
message.alert({
title: '服务未结束',
msg: '当前服务时长还未结束,暂无法完成服务',
confirmButtonText: '确定',
confirmButtonProps: {
customClass: '!bg-[#4C9F44] !text-[#fff] !text-32rpx !leading-44rpx !rounded-8rpx',
}
})
handleFinished: async () => {
toast.loading('加载中...')
const res = await handleCompleteOrderHooks(order.value.id)
toast.close()
if (res) {
Detail.handleInit()
}
},
/**
@ -767,10 +750,67 @@
confirmButtonProps: {
customClass: '!bg-[#4C9F44] !text-[#fff] !text-32rpx !leading-44rpx !rounded-8rpx',
}
}).then(async (res) => {
if (res.action == 'confirm') {
toast.loading('加载中...')
await handleDeleteOrderHooks(order.value.id)
toast.close()
router.navigateBack()
}
}).catch(() => {})
},
/**
* 拍照打卡
*/
handleTakePhoto: () => {
message.confirm({
title: '提示',
msg: '茶艺师到达目的地之后,需要打卡拍照',
confirmButtonText: '确定',
cancelButtonText: '取消',
cancelButtonProps: {
customClass: '!bg-[#F6F7F8] !text-[#303133] !text-32rpx !leading-44rpx !rounded-8rpx',
},
confirmButtonProps: {
customClass: '!bg-[#4C9F44] !text-[#fff] !text-32rpx !leading-44rpx !rounded-8rpx',
}
}).then((res) => {
if (res.action == 'confirm') {
// TODO 这里需要获取经纬度及拍照
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['camera'],
success: (chooseImageRes) => {
const file = {
url: chooseImageRes.tempFilePaths[0],
status: UPLOAD_STATUS.PENDING,
percent: 0
}
console.log("🚀 ~ file:", file)
// TODO 这里报错只是VScodeIDE报错源代码和文档中没有这个UID配置项
toast.loading('上传中...')
startUpload(file, {
action: import.meta.env.VITE_UPLOAD_BASEURL,
header: {'token': uni.getStorageSync('token')},
async onSuccess(res) {
const files = JSON.parse(res.data)
const fileUrl = files.data.url
await handleTeaSpecialistClockInHooks(order.value.id, fileUrl)
toast.close()
Detail.handleInit()
},
onError(err) {
toast.close()
toast.show('上传失败')
},
onProgress(progress) {
console.log('上传进度', progress)
}
})
}
})
}
}).catch(() => {
// 点击取消按钮回调事件
@ -787,6 +827,15 @@
name: order.value.title,
address: order.value.address,
})
},
/**
* 预览打卡照片
*/
handlePreviewPhoto: () => {
uni.previewImage({
urls: [order.value.img],
})
}
}
</script>

View File

@ -109,7 +109,7 @@
import { TeaSpecialistManageOrderStatusText, TeaSpecialistOrderStatus, TeaSpecialistManageStatusTextValue } from '@/utils/teaSpecialistOrder'
import { getTeaSpecialistOrderList } from '@/api/tes-specialist'
import { handleGetLocationFallback } from '@/hooks/useLocation'
import { handleReleaseOrderHooks, handleDepartOrderHooks, handleArriveOrderHooks } from '@/hooks/useOrder'
import { handleReleaseOrderHooks, handleDepartOrderHooks, handleArriveOrderHooks, handleCompleteOrderHooks, handleDeleteOrderHooks } from '@/hooks/useOrder'
const OSS = inject('OSS')
const toast = useToast()
@ -284,8 +284,8 @@
case 'navigate':
// 导航逻辑 - 显示地图选择弹窗
uni.openLocation({
latitude: order.latitude,
longitude: order.longitude,
latitude: Number(order.latitude),
longitude: Number(order.longitude),
name: order.title,
address: order.address,
})
@ -342,6 +342,7 @@
if (res) {
Order.handleSearch()
router.navigateTo(`/pages/order/detail?orderId=${order.id}`)
}
} else {
toast.show('获取位置信息失败,请检查定位权限是否开启')
@ -350,7 +351,12 @@
}).catch(() => {})
break
case 'complete':
// 完成服务逻辑
toast.loading('加载中...')
const res = await handleCompleteOrderHooks(order.value.id)
toast.close()
if (res) {
Order.handleSearch()
}
break
case 'delete':
// 删除订单逻辑
@ -365,15 +371,14 @@
confirmButtonProps: {
customClass: '!bg-[#4C9F44] !text-[#fff] !text-32rpx !leading-44rpx !rounded-8rpx',
},
}).then((res) => {
}).then(async (res) => {
if (res.action === 'confirm') {
// 确认删除订单的逻辑
console.log('确认删除订单', order)
// TODO: 调用删除订单的 API
uni.showToast({
title: '删除订单成功',
icon: 'success',
})
toast.loading('加载中...')
const res = await handleDeleteOrderHooks(order.value.id)
toast.close()
if (res) {
Order.handleSearch()
}
}
}).catch(() => {
// 点击取消按钮