|
|
@@ -1,66 +1,196 @@
|
|
|
<template>
|
|
|
<!-- #ifdef APP -->
|
|
|
<scroll-view class="page-scroll">
|
|
|
- <!-- #endif -->
|
|
|
+ <!-- #endif -->
|
|
|
<view class="page">
|
|
|
<view class="header-card">
|
|
|
- <text class="header-title">{{ detail.stateText }}</text>
|
|
|
- <text class="header-subtitle">订单编号:{{ detail.orderNo }}</text>
|
|
|
+ <view class="header-status">
|
|
|
+ <u-icon name="customerservice" :size="24" />
|
|
|
+ <text class="header-status-text">
|
|
|
+ {{ detail.stateText }}
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
|
|
|
- <view class="summary-row">
|
|
|
- <view class="summary-chip">
|
|
|
- <text class="summary-chip-label">项目金额</text>
|
|
|
- <text class="summary-chip-value">{{ detail.projectAmount }}</text>
|
|
|
+ <view class="section-card">
|
|
|
+ <view class="address-section">
|
|
|
+ <text class="address-label">
|
|
|
+ 服务地址
|
|
|
+ </text>
|
|
|
+ <text class="address-text">
|
|
|
+ {{ detail.address }}
|
|
|
+ </text>
|
|
|
+ <text class="phone-text">
|
|
|
+ {{ detail.customerPhone }}
|
|
|
+ </text>
|
|
|
</view>
|
|
|
- <view class="summary-chip">
|
|
|
- <text class="summary-chip-label">实付金额</text>
|
|
|
- <text class="summary-chip-value">{{ detail.payAmount }}</text>
|
|
|
+ <view class="time-section">
|
|
|
+ <text class="time-label">
|
|
|
+ 预约服务时间
|
|
|
+ </text>
|
|
|
+ <text class="time-value">
|
|
|
+ {{ detail.serviceTime }}
|
|
|
+ </text>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<view class="section-card">
|
|
|
- <text class="section-title">服务信息</text>
|
|
|
- <text class="section-line">服务地址:{{ detail.address }}</text>
|
|
|
- <text class="section-line">客户信息:{{ detail.customer }}</text>
|
|
|
- <text class="section-line">预约时间:{{ detail.serviceTime }}</text>
|
|
|
+ <view class="project-section">
|
|
|
+ <image class="project-image"
|
|
|
+ :src="detail.projectImage"
|
|
|
+ mode="aspectFill">
|
|
|
+ </image>
|
|
|
+ <view class="project-info">
|
|
|
+ <text class="project-title">
|
|
|
+ {{ detail.projectTitle }}
|
|
|
+ </text>
|
|
|
+ <text class="project-duration">
|
|
|
+ 服务时长: {{ detail.durationText }}
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
+ <text class="project-price">
|
|
|
+ {{ detail.projectAmount }}
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
|
|
|
<view class="section-card">
|
|
|
- <text class="section-title">项目收入</text>
|
|
|
- <text class="section-line">项目名称:{{ detail.projectTitle }}</text>
|
|
|
- <text class="section-line">项目时长:{{ detail.durationText }}</text>
|
|
|
- <text class="section-line">项目金额:{{ detail.projectAmount }}</text>
|
|
|
- <text class="section-line">配送费用:{{ detail.deliveryFee }}</text>
|
|
|
- <text class="section-line">实付金额:{{ detail.payAmount }}</text>
|
|
|
+ <text class="section-title">
|
|
|
+ 预估收入
|
|
|
+ </text>
|
|
|
+ <view class="income-row">
|
|
|
+ <text class="income-label">
|
|
|
+ 项目分成
|
|
|
+ </text>
|
|
|
+ <text class="income-value">
|
|
|
+ {{ detail.projectShare }}
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
+ <view class="income-row">
|
|
|
+ <text class="income-label">
|
|
|
+ 路费
|
|
|
+ </text>
|
|
|
+ <text class="income-value">
|
|
|
+ {{ detail.roadFee }}
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
+ <view class="income-total">
|
|
|
+ <text class="income-total-label">
|
|
|
+ 总收入
|
|
|
+ </text>
|
|
|
+ <text class="income-total-value">
|
|
|
+ {{ detail.totalIncome }}
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="section-card">
|
|
|
+ <view class="order-info-row">
|
|
|
+ <text class="order-info-label">
|
|
|
+ 订单编号
|
|
|
+ </text>
|
|
|
+ <view class="order-info-value">
|
|
|
+ <text>
|
|
|
+ {{ detail.orderNo }}
|
|
|
+ </text>
|
|
|
+ <text class="copy-button" @click="copyOrderNo">
|
|
|
+ 复制
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="order-info-row">
|
|
|
+ <text class="order-info-label">
|
|
|
+ 下单时间
|
|
|
+ </text>
|
|
|
+ <text class="order-info-value">
|
|
|
+ {{ detail.createdAt }}
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
+ <view class="order-info-row">
|
|
|
+ <text class="order-info-label">
|
|
|
+ 支付金额
|
|
|
+ </text>
|
|
|
+ <text class="order-info-value">
|
|
|
+ {{ detail.payAmount }}
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
+ <view class="order-info-row">
|
|
|
+ <text class="order-info-label">
|
|
|
+ 出行车费
|
|
|
+ </text>
|
|
|
+ <text class="order-info-value">
|
|
|
+ {{ detail.deliveryFee }}
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
+ <view class="order-info-row">
|
|
|
+ <text class="order-info-label">
|
|
|
+ 支付时间
|
|
|
+ </text>
|
|
|
+ <text class="order-info-value">
|
|
|
+ {{ detail.paymentTime }}
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
+ <view class="order-info-row">
|
|
|
+ <text class="order-info-label">
|
|
|
+ 备注
|
|
|
+ </text>
|
|
|
+ <text class="order-info-value">
|
|
|
+ {{ detail.remark }}
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
|
|
|
<view class="section-card">
|
|
|
- <text class="section-title">订单时间</text>
|
|
|
- <text class="section-line">下单时间:{{ detail.createdAt }}</text>
|
|
|
- <text class="section-line">支付时间:{{ detail.paymentTime }}</text>
|
|
|
- <text class="section-line">备注信息:{{ detail.remark }}</text>
|
|
|
+ <view v-for="(item, index) in detail.statusList" :key="index"
|
|
|
+ :class="['progress-item', item.active ? 'active' : '']">
|
|
|
+ <view class="progress-dot">
|
|
|
+ </view>
|
|
|
+ <view v-if="index < detail.statusList.length - 1"
|
|
|
+ :class="['progress-line', item.active ? 'active' : '']">
|
|
|
+ </view>
|
|
|
+ <view class="progress-content">
|
|
|
+ <text :class="['progress-text', item.active ? 'active' : '']">
|
|
|
+ {{ item.status }}
|
|
|
+ </text>
|
|
|
+ <text class="progress-time">
|
|
|
+ {{ item.time }}
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
|
|
|
<view class="button-row">
|
|
|
- <view class="secondary-button" @click="callCustomer">
|
|
|
- <text class="secondary-button-text">联系客户</text>
|
|
|
+ <view v-if="showSecondaryButton" class="secondary-button"
|
|
|
+ @click="detail.state == 2 ? handleTransfer : callCustomer">
|
|
|
+ <u-icon name="customerservice" :size="24" />
|
|
|
+ <text class="secondary-button-text">
|
|
|
+ {{ secondaryActionText }}
|
|
|
+ </text>
|
|
|
</view>
|
|
|
- <view class="primary-button" @click="handleAction">
|
|
|
- <text class="primary-button-text">{{ actionText }}</text>
|
|
|
+ <view v-if="showPrimaryButton" :class="['primary-button', { 'full-width': !showSecondaryButton }]"
|
|
|
+ @click="detail.state == 8 || detail.state == 9 ? contactService : handleAction">
|
|
|
+ <text class="primary-button-text">
|
|
|
+ {{ actionText }}
|
|
|
+ </text>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
- <!-- #ifdef APP -->
|
|
|
+ <!-- #ifdef APP -->
|
|
|
</scroll-view>
|
|
|
<!-- #endif -->
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="uts">
|
|
|
- import { computed, reactive, ref } from 'vue'
|
|
|
+ import { computed, reactive } from 'vue'
|
|
|
import { getCurrentLocation } from '@/utils/api/location.uts'
|
|
|
import { navigateToMobile } from '@/utils/api/tool.uts'
|
|
|
- import { getOrderDetaile, acceptOrder, departOrder, arriveOrder, leaveOrder } from '@/utils/api/order.uts'
|
|
|
+ import { getOrderDetaile, acceptOrder, departOrder, arriveOrder, leaveOrder, transferOrder } from '@/utils/api/order.uts'
|
|
|
+
|
|
|
+ type StatusItem = {
|
|
|
+ status : string
|
|
|
+ time : string
|
|
|
+ active : boolean
|
|
|
+ }
|
|
|
|
|
|
type DetailState = {
|
|
|
orderId : string
|
|
|
@@ -72,6 +202,7 @@
|
|
|
customerPhone : string
|
|
|
serviceTime : string
|
|
|
projectTitle : string
|
|
|
+ projectImage : string
|
|
|
durationText : string
|
|
|
projectAmount : string
|
|
|
deliveryFee : string
|
|
|
@@ -79,42 +210,80 @@
|
|
|
createdAt : string
|
|
|
paymentTime : string
|
|
|
remark : string
|
|
|
+ projectShare : string
|
|
|
+ roadFee : string
|
|
|
+ totalIncome : string
|
|
|
+ statusList : Array<StatusItem>
|
|
|
}
|
|
|
|
|
|
const detail = reactive<DetailState>({
|
|
|
- orderId: '',
|
|
|
- orderNo: '',
|
|
|
- state: 0,
|
|
|
- stateText: '订单详情',
|
|
|
- address: '',
|
|
|
- customer: '',
|
|
|
- customerPhone: '',
|
|
|
- serviceTime: '',
|
|
|
- projectTitle: '',
|
|
|
- durationText: '',
|
|
|
- projectAmount: '0',
|
|
|
- deliveryFee: '0',
|
|
|
- payAmount: '0',
|
|
|
- createdAt: '',
|
|
|
- paymentTime: '',
|
|
|
- remark: '',
|
|
|
- })
|
|
|
+ orderId: '',
|
|
|
+ orderNo: '',
|
|
|
+ state: 0,
|
|
|
+ stateText: '订单详情',
|
|
|
+ address: '',
|
|
|
+ customer: '',
|
|
|
+ customerPhone: '',
|
|
|
+ serviceTime: '',
|
|
|
+ projectTitle: '',
|
|
|
+ projectImage: '',
|
|
|
+ durationText: '',
|
|
|
+ projectAmount: '0',
|
|
|
+ deliveryFee: '0',
|
|
|
+ payAmount: '0',
|
|
|
+ createdAt: '',
|
|
|
+ paymentTime: '',
|
|
|
+ remark: '',
|
|
|
+ projectShare: '0',
|
|
|
+ roadFee: '0',
|
|
|
+ totalIncome: '0',
|
|
|
+ statusList: [
|
|
|
+ { status: '已接单', time: '', active: false },
|
|
|
+ { status: '已出发', time: '', active: false },
|
|
|
+ { status: '到达', time: '', active: false },
|
|
|
+ { status: '开始服务', time: '', active: false },
|
|
|
+ { status: '服务完成', time: '', active: false }]
|
|
|
+ })
|
|
|
|
|
|
const actionText = computed(() : string => {
|
|
|
- if (detail.state == 2) {
|
|
|
- return '确认接单'
|
|
|
- }
|
|
|
- if (detail.state == 4) {
|
|
|
- return '确认出发'
|
|
|
- }
|
|
|
- if (detail.state == 5) {
|
|
|
- return '确认到达'
|
|
|
- }
|
|
|
- if (detail.state == 10) {
|
|
|
- return '确认撤离'
|
|
|
- }
|
|
|
- return '刷新详情'
|
|
|
- })
|
|
|
+ if (detail.state == 2) { // 已支付
|
|
|
+ return '确认接单'
|
|
|
+ }
|
|
|
+ if (detail.state == 4) { // 已接单
|
|
|
+ return '已出发'
|
|
|
+ }
|
|
|
+ if (detail.state == 8 || detail.state == 9) { // 已退款或已取消
|
|
|
+ return '联系客服'
|
|
|
+ }
|
|
|
+ if (detail.state == 5) {
|
|
|
+ return '确认到达'
|
|
|
+ }
|
|
|
+ if (detail.state == 10) {
|
|
|
+ return '确认撤离'
|
|
|
+ }
|
|
|
+ return '刷新详情'
|
|
|
+ })
|
|
|
+
|
|
|
+ const secondaryActionText = computed(() : string => {
|
|
|
+ if (detail.state == 2) { // 已支付
|
|
|
+ return '我要转单'
|
|
|
+ }
|
|
|
+ if (detail.state == 4) { // 已接单
|
|
|
+ return '拨打电话'
|
|
|
+ }
|
|
|
+ if (detail.state == 8 || detail.state == 9) { // 已退款或已取消
|
|
|
+ return ''
|
|
|
+ }
|
|
|
+ return '拨打电话'
|
|
|
+ })
|
|
|
+
|
|
|
+ const showSecondaryButton = computed(() : boolean => {
|
|
|
+ return detail.state == 2 || detail.state == 4
|
|
|
+ })
|
|
|
+
|
|
|
+ const showPrimaryButton = computed(() : boolean => {
|
|
|
+ return detail.state == 2 || detail.state == 4 || detail.state == 8 || detail.state == 9
|
|
|
+ })
|
|
|
|
|
|
const toNumber = (value : any | null) : number => {
|
|
|
const numberValue = value as number | null
|
|
|
@@ -130,8 +299,8 @@
|
|
|
|
|
|
const getLocationPayload = async () : Promise<UTSJSONObject | null> => {
|
|
|
const response = await getCurrentLocation()
|
|
|
- const data = (response['data'] as UTSJSONObject | null)
|
|
|
- const location = (data?.['location'] as UTSJSONObject | null)
|
|
|
+ const data = response['data'] as UTSJSONObject | null
|
|
|
+ const location = data?.['location'] as UTSJSONObject | null
|
|
|
if (location == null) {
|
|
|
return null
|
|
|
}
|
|
|
@@ -141,6 +310,24 @@
|
|
|
} as UTSJSONObject
|
|
|
}
|
|
|
|
|
|
+ const getActiveStatusIndex = (state : number) : number => {
|
|
|
+ switch (state) {
|
|
|
+ case 2: // 待接单
|
|
|
+ return 0
|
|
|
+ case 4: // 已接单
|
|
|
+ return 1
|
|
|
+ case 5: // 已出发
|
|
|
+ return 2
|
|
|
+ case 6: // 已到达
|
|
|
+ return 3
|
|
|
+ case 7: // 服务中
|
|
|
+ case 8: // 服务完成
|
|
|
+ return 4
|
|
|
+ default:
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
const applyDetail = (data : UTSJSONObject) : void => {
|
|
|
const address = data['address'] as UTSJSONObject | null
|
|
|
const project = data['project'] as UTSJSONObject | null
|
|
|
@@ -148,22 +335,64 @@
|
|
|
const num = (data['num'] as number | null) ?? 1
|
|
|
detail.orderNo = (data['order_no'] as string | null) ?? ''
|
|
|
detail.state = state
|
|
|
- detail.stateText = (data['state_text'] as string | null) ?? '订单详情'
|
|
|
- detail.address = (address?.['location'] as string | null) ?? ''
|
|
|
+ detail.stateText = (data['state_text'] as string | null) ?? '已支付'
|
|
|
+
|
|
|
+ // 拼接完整地址
|
|
|
+ const province = (address?.['province'] as string | null) ?? ''
|
|
|
+ const city = (address?.['city'] as string | null) ?? ''
|
|
|
+ const district = (address?.['district'] as string | null) ?? ''
|
|
|
+ const detailAddr = (address?.['detail'] as string | null) ?? ''
|
|
|
+ detail.address = `${province}${city}${district}${detailAddr}`
|
|
|
+
|
|
|
const customerName = (address?.['name'] as string | null) ?? ''
|
|
|
const customerPhone = (address?.['phone'] as string | null) ?? ''
|
|
|
detail.customer = `${customerName} ${customerPhone}`
|
|
|
detail.customerPhone = customerPhone
|
|
|
- detail.serviceTime = (data['service_start_time'] as string | null) ?? ((data['service_time'] as string | null) ?? '')
|
|
|
+ detail.serviceTime = (data['service_time'] as string | null) ?? ''
|
|
|
detail.projectTitle = (project?.['title'] as string | null) ?? '服务项目'
|
|
|
+
|
|
|
+ // 获取项目图片
|
|
|
+ const coverUrls = project?.['cover_urls'] as Array<UTSJSONObject> | null
|
|
|
+ if (coverUrls != null && coverUrls.length > 0) {
|
|
|
+ detail.projectImage = (coverUrls[0]['medium_url'] as string | null) ?? ''
|
|
|
+ } else {
|
|
|
+ detail.projectImage = ''
|
|
|
+ }
|
|
|
+
|
|
|
const duration = (project?.['duration'] as number | null) ?? 0
|
|
|
detail.durationText = `${duration * num}分钟`
|
|
|
- detail.projectAmount = `${toNumber(data['project_amount']).toFixed(2)}元`
|
|
|
- detail.deliveryFee = `${toNumber(data['delivery_fee']).toFixed(2)}元`
|
|
|
- detail.payAmount = `${(toNumber(data['pay_amount']) + toNumber(data['balance_amount'])).toFixed(2)}元`
|
|
|
+ detail.projectAmount = `¥${toNumber(data['project_amount']).toFixed(2)}`
|
|
|
+ detail.deliveryFee = `¥${toNumber(data['delivery_fee']).toFixed(2)}`
|
|
|
+ detail.payAmount = `¥${(toNumber(data['pay_amount']) + toNumber(data['balance_amount'])).toFixed(2)}`
|
|
|
detail.createdAt = (data['created_at'] as string | null) ?? ''
|
|
|
detail.paymentTime = (data['payment_time'] as string | null) ?? ''
|
|
|
detail.remark = (data['remark'] as string | null) ?? '无'
|
|
|
+
|
|
|
+ // 预估收入相关字段(根据接口数据计算)
|
|
|
+ const commissionAmount = toNumber(data['commission_amount'])
|
|
|
+ const deliveryFee = toNumber(data['delivery_fee'])
|
|
|
+ detail.projectShare = `¥${commissionAmount.toFixed(2)}`
|
|
|
+ detail.roadFee = `¥${deliveryFee.toFixed(2)}`
|
|
|
+ detail.totalIncome = `¥${(commissionAmount + deliveryFee).toFixed(2)}`
|
|
|
+
|
|
|
+ // 更新状态列表
|
|
|
+ const statusList = data['status_list'] as Array<UTSJSONObject> | null
|
|
|
+ if (statusList != null && statusList.length > 0) {
|
|
|
+ for (let i = 0; i < statusList.length; i++) {
|
|
|
+ const item = statusList[i]
|
|
|
+ if (i < detail.statusList.length) {
|
|
|
+ detail.statusList[i].status = (item['status'] as string | null) ?? detail.statusList[i].status
|
|
|
+ detail.statusList[i].time = (item['time'] as string | null) ?? ''
|
|
|
+ detail.statusList[i].active = (item['active'] as boolean | null) ?? false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 根据订单状态设置默认激活状态
|
|
|
+ for (let i = 0; i < detail.statusList.length; i++) {
|
|
|
+ detail.statusList[i].active = i < getActiveStatusIndex(state)
|
|
|
+ detail.statusList[i].time = detail.createdAt
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
const loadDetail = async () : Promise<void> => {
|
|
|
@@ -193,6 +422,72 @@
|
|
|
navigateToMobile(detail.customerPhone)
|
|
|
}
|
|
|
|
|
|
+ const copyOrderNo = () : void => {
|
|
|
+ if (detail.orderNo.length == 0) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ uni.setClipboardData({
|
|
|
+ data: detail.orderNo,
|
|
|
+ success: function () {
|
|
|
+ uni.showToast({ title: '复制成功', icon: 'success' })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ // 商户转单
|
|
|
+ const httptransferOrder = async (orderId : number,) => {
|
|
|
+ try {
|
|
|
+ const res = await transferOrder({
|
|
|
+ order_id: orderId,
|
|
|
+ }) as UTSJSONObject;
|
|
|
+ if (res?.code === 200) {
|
|
|
+ uni.showToast({ title: '转单成功', icon: 'success' });
|
|
|
+ // await httpGetOrderList();
|
|
|
+ } else {
|
|
|
+ uni.showToast({
|
|
|
+ title: (res?.msg) as String ?? '转单失败',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ console.error('转单异常', err);
|
|
|
+ uni.showToast({
|
|
|
+ title: '转单失败,请重试',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const handleTransfer = () : void => {
|
|
|
+ // 转单逻辑
|
|
|
+ uni.showModal({
|
|
|
+ title: '转单确认',
|
|
|
+ content: '确定要将此订单转单吗?',
|
|
|
+ confirmText: '确定',
|
|
|
+ cancelText: '取消',
|
|
|
+ success: function (res) {
|
|
|
+ if (res.confirm) {
|
|
|
+ // 调用转单接口
|
|
|
+ httptransferOrder(toNumber(detail.orderId))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const contactService = () : void => {
|
|
|
+ // 联系客服逻辑
|
|
|
+ uni.showModal({
|
|
|
+ title: '联系客服',
|
|
|
+ content: '客服电话:400-123-4567',
|
|
|
+ confirmText: '拨打电话',
|
|
|
+ cancelText: '取消',
|
|
|
+ success: function (res) {
|
|
|
+ if (res.confirm) {
|
|
|
+ // 拨打电话
|
|
|
+ navigateToMobile('4001234567')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
const handleAction = async () : Promise<void> => {
|
|
|
if (detail.orderId.length == 0) {
|
|
|
return
|
|
|
@@ -208,7 +503,11 @@
|
|
|
}
|
|
|
try {
|
|
|
if (detail.state == 2) {
|
|
|
- await acceptOrder({ order_id: detail.orderId, latitude: locationPayload['latitude'], longitude: locationPayload['longitude'] } as UTSJSONObject)
|
|
|
+ await acceptOrder({
|
|
|
+ order_id: detail.orderId,
|
|
|
+ latitude: locationPayload['latitude'],
|
|
|
+ longitude: locationPayload['longitude']
|
|
|
+ } as UTSJSONObject)
|
|
|
} else if (detail.state == 4) {
|
|
|
await departOrder(detail.orderId, locationPayload)
|
|
|
} else if (detail.state == 5) {
|
|
|
@@ -224,9 +523,9 @@
|
|
|
}
|
|
|
|
|
|
onLoad((option : UTSJSONObject) => {
|
|
|
- detail.orderId = (option['order_id'] as string | null) ?? ''
|
|
|
- loadDetail()
|
|
|
- })
|
|
|
+ detail.orderId = (option['orderId'] as string | null) ?? ''
|
|
|
+ loadDetail()
|
|
|
+ })
|
|
|
</script>
|
|
|
|
|
|
<style>
|
|
|
@@ -236,83 +535,249 @@
|
|
|
|
|
|
.page {
|
|
|
min-height: 1000rpx;
|
|
|
- padding: 24rpx;
|
|
|
+ padding: 0;
|
|
|
box-sizing: border-box;
|
|
|
- background-color: #f5f2ea;
|
|
|
+ background-color: #f5f5f5;
|
|
|
flex-direction: column;
|
|
|
}
|
|
|
|
|
|
.header-card {
|
|
|
- padding: 28rpx;
|
|
|
- border-radius: 24rpx;
|
|
|
+ padding: 36rpx;
|
|
|
background-color: #ffdb5a;
|
|
|
flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .header-status {
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .header-status-icon {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #3a3330;
|
|
|
+ margin-right: 8rpx;
|
|
|
}
|
|
|
|
|
|
- .header-title {
|
|
|
- font-size: 38rpx;
|
|
|
+ .header-status-text {
|
|
|
+ font-size: 32rpx;
|
|
|
font-weight: 700;
|
|
|
color: #3a3330;
|
|
|
}
|
|
|
|
|
|
- .header-subtitle {
|
|
|
- margin-top: 10rpx;
|
|
|
+ .section-card {
|
|
|
+ margin-top: 12rpx;
|
|
|
+ padding: 24rpx;
|
|
|
+ background-color: #ffffff;
|
|
|
+ flex-direction: column;
|
|
|
+ }
|
|
|
+
|
|
|
+ .address-section {
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .address-label {
|
|
|
font-size: 24rpx;
|
|
|
- color: #5d5648;
|
|
|
+ color: #ff9500;
|
|
|
+ margin-bottom: 8rpx;
|
|
|
}
|
|
|
|
|
|
- .summary-row {
|
|
|
- margin-top: 18rpx;
|
|
|
+ .address-text {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #333333;
|
|
|
+ line-height: 36rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .phone-text {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #333333;
|
|
|
+ margin-top: 8rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .time-section {
|
|
|
flex-direction: row;
|
|
|
justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding-top: 16rpx;
|
|
|
+ border-top: 1rpx solid #f0f0f0;
|
|
|
}
|
|
|
|
|
|
- .summary-chip {
|
|
|
- width: 48%;
|
|
|
- padding: 20rpx;
|
|
|
- border-radius: 20rpx;
|
|
|
- background-color: #ffffff;
|
|
|
- flex-direction: column;
|
|
|
+ .time-label {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #666666;
|
|
|
}
|
|
|
|
|
|
- .summary-chip-label {
|
|
|
- font-size: 22rpx;
|
|
|
- color: #8b8376;
|
|
|
+ .time-value {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #333333;
|
|
|
}
|
|
|
|
|
|
- .summary-chip-value {
|
|
|
- margin-top: 8rpx;
|
|
|
- font-size: 30rpx;
|
|
|
- font-weight: 700;
|
|
|
- color: #3a3330;
|
|
|
+ .project-section {
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
}
|
|
|
|
|
|
- .section-card {
|
|
|
- margin-top: 18rpx;
|
|
|
- padding: 24rpx;
|
|
|
- border-radius: 20rpx;
|
|
|
- background-color: #ffffff;
|
|
|
- flex-direction: column;
|
|
|
- border-width: 1px;
|
|
|
- border-style: solid;
|
|
|
- border-color: #efe6d9;
|
|
|
+ .project-image {
|
|
|
+ width: 120rpx;
|
|
|
+ height: 120rpx;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ margin-right: 16rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .project-info {
|
|
|
+ flex: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ .project-title {
|
|
|
+ font-size: 28rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #333333;
|
|
|
+ margin-bottom: 8rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .project-duration {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #999999;
|
|
|
+ }
|
|
|
+
|
|
|
+ .project-price {
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: 700;
|
|
|
+ color: #ff3b30;
|
|
|
}
|
|
|
|
|
|
.section-title {
|
|
|
+ font-size: 28rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #333333;
|
|
|
+ margin-bottom: 16rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .income-row {
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-bottom: 12rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .income-label {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #666666;
|
|
|
+ }
|
|
|
+
|
|
|
+ .income-value {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #333333;
|
|
|
+ }
|
|
|
+
|
|
|
+ .income-total {
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-top: 16rpx;
|
|
|
+ padding-top: 16rpx;
|
|
|
+ border-top: 1rpx solid #f0f0f0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .income-total-label {
|
|
|
+ font-size: 26rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #333333;
|
|
|
+ }
|
|
|
+
|
|
|
+ .income-total-value {
|
|
|
font-size: 30rpx;
|
|
|
font-weight: 700;
|
|
|
- color: #3a3330;
|
|
|
+ color: #ff3b30;
|
|
|
}
|
|
|
|
|
|
- .section-line {
|
|
|
- margin-top: 12rpx;
|
|
|
+ .order-info-row {
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-bottom: 16rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .order-info-label {
|
|
|
font-size: 26rpx;
|
|
|
- line-height: 38rpx;
|
|
|
color: #666666;
|
|
|
}
|
|
|
|
|
|
+ .order-info-value {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #333333;
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .copy-button {
|
|
|
+ margin-left: 16rpx;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #007aff;
|
|
|
+ padding: 4rpx 12rpx;
|
|
|
+ border: 1rpx solid #e0e0e0;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .progress-item {
|
|
|
+ flex-direction: row;
|
|
|
+ position: relative;
|
|
|
+ padding-bottom: 32rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .progress-item:last-child {
|
|
|
+ padding-bottom: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .progress-dot {
|
|
|
+ width: 20rpx;
|
|
|
+ height: 20rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ background-color: #e0e0e0;
|
|
|
+ margin-right: 16rpx;
|
|
|
+ position: relative;
|
|
|
+ z-index: 2;
|
|
|
+ }
|
|
|
+
|
|
|
+ .progress-line {
|
|
|
+ position: absolute;
|
|
|
+ left: 9rpx;
|
|
|
+ top: 20rpx;
|
|
|
+ width: 2rpx;
|
|
|
+ height: 64rpx;
|
|
|
+ background-color: #e0e0e0;
|
|
|
+ z-index: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ .progress-item.active .progress-dot {
|
|
|
+ background-color: #ff9500;
|
|
|
+ }
|
|
|
+
|
|
|
+ .progress-item.active .progress-line {
|
|
|
+ background-color: #ff9500;
|
|
|
+ }
|
|
|
+
|
|
|
+ .progress-content {
|
|
|
+ flex: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ .progress-text {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #999999;
|
|
|
+ margin-bottom: 4rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .progress-text.active {
|
|
|
+ color: #333333;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+
|
|
|
+ .progress-time {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #999999;
|
|
|
+ }
|
|
|
+
|
|
|
.button-row {
|
|
|
- margin-top: 24rpx;
|
|
|
+ margin-top: 32rpx;
|
|
|
+ margin-bottom: 32rpx;
|
|
|
+ padding: 0 24rpx;
|
|
|
flex-direction: row;
|
|
|
justify-content: space-between;
|
|
|
}
|
|
|
@@ -320,13 +785,14 @@
|
|
|
.secondary-button {
|
|
|
width: 48%;
|
|
|
height: 88rpx;
|
|
|
- border-radius: 22rpx;
|
|
|
+ border-radius: 44rpx;
|
|
|
border-width: 2rpx;
|
|
|
border-style: solid;
|
|
|
border-color: #ffdb5a;
|
|
|
flex-direction: row;
|
|
|
justify-content: center;
|
|
|
align-items: center;
|
|
|
+ background-color: #ffffff;
|
|
|
}
|
|
|
|
|
|
.secondary-button-text {
|
|
|
@@ -337,7 +803,7 @@
|
|
|
.primary-button {
|
|
|
width: 48%;
|
|
|
height: 88rpx;
|
|
|
- border-radius: 22rpx;
|
|
|
+ border-radius: 44rpx;
|
|
|
background-color: #ffdb5a;
|
|
|
flex-direction: row;
|
|
|
justify-content: center;
|
|
|
@@ -349,4 +815,8 @@
|
|
|
font-weight: 700;
|
|
|
color: #3a3330;
|
|
|
}
|
|
|
+
|
|
|
+ .primary-button.full-width {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
</style>
|