报错提示
message:Error: 非法的文件,错误信息:invalid file: pages/index/Order-Processing.js, 1:3179, SyntaxError: Unexpected token ?"use strict";const e=require("../../common/vendor.js"),t=require("../../utils/config.js"),s={data:()=>({keyword:"",searchType:"order_no",showTypePicker:!1,searchTypes:[{label:"订单号",key:"order_no"},{label:"客户姓名",key:"nickname"},{label:"手机号",key:"mobile"},{label:"商品名称",key:"goods_name"}],orderList:[],page:1,total:0,loading:!1,refreshing:!1,noMore:!1,currentStatus:-1,shipPopup:null,shipOrder:null,shipMode:1,shipGoodsList:[],shipping:!1,shipForm:{express_id:null,express_name:"",express_no:"",remark:""},expressList:[],expressLoading:!1,showExpressPicker:!1,logisticsPopup:null,logisticsPackages:[],logisticsPkgIndex:0,currentTrack:null,logisticsLoading:!1,showAfterSaleSheet:!1,afterSaleOrder:null,cancelPopup:null,cancelOrder:null,cancelGoodsList:[],cancelSelectedIds:[],tabList:[{name:"全部",status:-1,countKey:"total",count:0},{name:"待到货",status:1,countKey:"pending",count:0},{name:"待补款",status:2,countKey:"unpai... [20260408 17:27:55][wx3ea54ec4fa7cf43a]
appid: wx3ea54ec4fa7cf43a
openid: o6zAJs9Kr1RwvyYPUf4FQkAJn-pY
ideVersion: 2.01.2510260
osType: win32-x64
time: 2026-04-08 17:29:19
<template>
<view class="content">
<view class="search-box">
<view class="search-row">
<view class="search-select" @click="showTypePicker = true">
<text>{{currentTypeLabel}}</text>
<uv-icon name="arrow-down" size="22rpx" color="#666"></uv-icon>
</view>
<input class="search-input" v-model="keyword" :placeholder="currentPlaceholder"
confirm-type="search" @confirm="onSearch" />
<view class="search-btn" @click="onSearch">搜索</view>
</view>
</view>
<view class="type-mask" v-if="showTypePicker" @click="showTypePicker=false"></view>
<view class="type-sheet" :class="{show: showTypePicker}">
<view class="type-sheet-title">选择搜索类型</view>
<view class="type-sheet-item" v-for="t in searchTypes" :key="t.key"
:class="{active: searchType === t.key}"
@click="onSelectType(t)">
{{t.label}}
<uv-icon v-if="searchType === t.key" name="checkmark" color="#0D69EF" size="32rpx"></uv-icon>
</view>
<view class="type-sheet-cancel" @click="showTypePicker=false">取消</view>
</view>
<uv-sticky offset-top="0" bgColor="#fff">
<uv-tabs :list="tabListDisplay" lineWidth="70rpx" lineColor="#0D69EF" @click="changeTab"></uv-tabs>
</uv-sticky>
<scroll-view scroll-y class="order-scroll" @scrolltolower="loadMore"
refresher-enabled @refresherrefresh="onRefresh" :refresher-triggered="refreshing">
<view class="order-list">
<view class="order-card" v-for="order in orderList" :key="order.id"
@click="goDetail(order)">
<view class="order-head">
<view class="order-head-left">
<text class="order-member">{{order.member_info && order.member_info.nickname || '-'}}</text>
<text class="order-store" v-if="order.store_info">{{order.store_info.name}}</text>
</view>
<text class="order-status-tag" :class="'s'+order.order_status">
{{statusMap[order.order_status] || '-'}}
</text>
</view>
<view class="order-no-row">
<text class="order-no">{{order.order_id}}</text>
<text class="order-type-tag">{{orderTypeMap[order.order_type] || '普通订单'}}</text>
<text v-if="hasPartialCancelled(order.goods_list)" class="partial-cancel-tag">部分取消</text>
<text v-if="order.shipping_info && order.shipping_info.length > 0 && order.order_status === 3" class="partial-ship-tag">部分发货</text>
</view>
<view class="goods-row" v-for="(g, gi) in (order.goods_list || []).slice(0, 2)" :key="gi">
<uv-image :src="g.goods_image" radius="8rpx" width="100rpx" height="100rpx" mode="aspectFill"></uv-image>
<view class="goods-info">
<text class="goods-name ellipsis1">{{g.goods_name}}</text>
<text class="goods-spec" v-if="g.spec_data && typeof g.spec_data === 'object' && Object.keys(g.spec_data).length">
{{formatSpec(g.spec_data)}}
</text>
<view class="goods-price-row">
<text class="goods-price">¥{{g.goods_price}}</text>
<text class="goods-num">×{{g.goods_num}}</text>
</view>
</view>
</view>
<view class="more-goods" v-if="(order.goods_list || []).length > 2">
<text>共{{order.goods_list.length}}件商品</text>
</view>
<view class="order-foot">
<text class="order-time">{{order.order_time}}</text>
<view class="order-amount">
<text class="amount-label">实付</text>
<text class="amount-val">¥{{order.actual_payment}}</text>
</view>
</view>
<view class="order-actions" v-if="getActions(order).length" @click.stop>
<template v-for="(act, ai) in getActions(order)" :key="ai">
<view v-if="act.action === 'afterSale'" class="action-btn outline after-sale-btn"
@click="openAfterSaleSheet(order)">
售后操作
<uv-icon name="arrow-down" size="20rpx" color="#666" style="margin-left:4rpx"></uv-icon>
</view>
<view v-else class="action-btn" :class="act.type"
@click="handleAction(act, order)">
{{act.label}}
</view>
</template>
</view>
</view>
</view>
<view class="load-tip" v-if="orderList.length > 0">
<text v-if="loading">加载中...</text>
<text v-else-if="noMore">没有更多了</text>
</view>
<view class="empty-box" v-if="!loading && orderList.length === 0">
<uv-empty mode="order" text="暂无订单"></uv-empty>
</view>
</scroll-view>
<uv-popup ref="shipPopup" mode="bottom" round="20rpx" :safeAreaInsetBottom="true">
<view class="ship-popup">
<view class="ship-popup-header">
<view>
<text class="ship-popup-title">订单发货</text>
<text class="ship-popup-no">{{shipOrder && shipOrder.order_id}}</text>
</view>
<uv-icon name="close" size="36rpx" color="#999" @click="shipPopup.close()"></uv-icon>
</view>
<view class="ship-mode-row">
<view class="ship-mode-item" :class="{ active: shipMode === 1 }" @click="setShipMode(1)">
<view class="ship-mode-dot" :class="{ active: shipMode === 1 }"></view>
<text>整单发货</text>
</view>
<view class="ship-mode-item" :class="{ active: shipMode === 2, disabled: !canSplitShip }"
@click="canSplitShip && setShipMode(2)">
<view class="ship-mode-dot" :class="{ active: shipMode === 2 }"></view>
<text>多包裹发货</text>
</view>
</view>
<scroll-view scroll-y style="max-height: 60vh;">
<view v-if="shipMode === 2" class="split-goods-section">
<view class="split-tip">选择本次要发货的商品</view>
<view v-for="g in shipGoodsList" :key="g.id"
class="split-goods-item"
:class="{ selected: g._selected, disabled: g.status === 2 || g._availableQty <= 0 }"
@click="g.status !== 2 && g._availableQty > 0 && (g._selected = !g._selected)">
<view class="check-box" :class="{ checked: g._selected }">
<uv-icon v-if="g._selected" name="checkmark" size="22rpx" color="#fff"></uv-icon>
</view>
<uv-image :src="g.goods_image" width="88rpx" height="88rpx" radius="8rpx" mode="aspectFill" style="flex-shrink:0"></uv-image>
<view class="split-goods-info">
<view class="split-goods-name-row">
<text class="split-goods-name">{{g.goods_name}}</text>
<text v-if="g.status === 2" class="tag-cancelled">已取消</text>
<text v-else-if="g._shippedQty >= g.goods_num" class="tag-shipped">已发完</text>
<text v-else-if="g._shippedQty > 0" class="tag-partial">部分发货</text>
</view>
<text class="split-goods-spec" v-if="g.spec_data && Object.keys(g.spec_data).length">
{{Object.entries(g.spec_data).map(([k,v])=>k+':'+v).join(' ')}}
</text>
<view class="split-goods-qty-row" v-if="g._selected">
<text class="split-qty-label">发货数量</text>
<view class="qty-ctrl">
<view class="qty-btn" @click.stop="g.ship_qty > 1 && g.ship_qty--">-</view>
<text class="qty-num">{{g.ship_qty}}</text>
<view class="qty-btn" @click.stop="g.ship_qty < g._availableQty && g.ship_qty++">+</view>
</view>
<text class="qty-hint">可发 {{g._availableQty}}</text>
</view>
<view class="split-goods-qty-row" v-else>
<text class="qty-hint">总数 {{g.goods_num}},已发 {{g._shippedQty}},可发 {{g._availableQty}}</text>
</view>
</view>
</view>
</view>
<view v-else class="whole-goods-section">
<view v-for="g in shipGoodsList" :key="g.id"
class="whole-goods-item" :class="{ cancelled: g.status === 2, shipped: g._availableQty <= 0 && g.status !== 2 }">
<uv-image :src="g.goods_image" width="80rpx" height="80rpx" radius="8rpx" mode="aspectFill" style="flex-shrink:0"></uv-image>
<view class="whole-goods-info">
<view class="whole-goods-name-row">
<text class="whole-goods-name">{{g.goods_name}}</text>
<text v-if="g.status === 2" class="tag-cancelled">已取消</text>
<text v-else-if="g._availableQty <= 0" class="tag-shipped">已发完</text>
<text v-else-if="g._shippedQty > 0" class="tag-partial">部分发货</text>
</view>
<text class="whole-goods-spec" v-if="g.spec_data && Object.keys(g.spec_data).length">
{{Object.entries(g.spec_data).map(([k,v])=>k+':'+v).join(' ')}}
</text>
<view class="whole-goods-price-row">
<text class="whole-goods-price">¥{{g.goods_price}}</text>
<text class="whole-goods-qty">x{{g.goods_num}}</text>
<text class="whole-goods-shipped" v-if="g._shippedQty > 0">已发 {{g._shippedQty}}</text>
</view>
</view>
</view>
</view>
<view class="ship-form-section">
<view class="ship-form-item" @click="showExpressPicker = true">
<text class="ship-form-label">快递公司 <text class="req">*</text></text>
<view class="ship-form-input-row">
<text :class="shipForm.express_name ? 'ship-form-val' : 'ship-form-placeholder'">
{{shipForm.express_name || '请选择快递公司'}}
</text>
<uv-icon name="arrow-down" size="24rpx" color="#ccc"></uv-icon>
</view>
</view>
<view class="ship-form-item">
<text class="ship-form-label">快递单号 <text class="req">*</text></text>
<input class="ship-form-input" v-model="shipForm.express_no" placeholder="请输入快递单号" />
</view>
<view class="ship-form-item">
<text class="ship-form-label">发货备注</text>
<input class="ship-form-input" v-model="shipForm.remark" placeholder="选填" />
</view>
</view>
</scroll-view>
<view class="ship-popup-footer">
<view class="ship-cancel-btn" @click="shipPopup.close()">取消</view>
<view class="ship-confirm-btn" :class="{ loading: shipping }" @click="confirmShip">
{{shipping ? '发货中...' : '确认发货'}}
</view>
</view>
</view>
</uv-popup>
<view class="type-mask" v-if="showExpressPicker" @click="showExpressPicker = false"></view>
<view class="type-sheet" :class="{ show: showExpressPicker }">
<view class="type-sheet-title">选择快递公司</view>
<view v-if="expressLoading" class="type-sheet-loading">
<uv-loading-icon mode="circle" size="40rpx"></uv-loading-icon>
</view>
<view v-else class="type-sheet-item" v-for="e in expressList" :key="e.id"
:class="{ active: shipForm.express_id === e.id }"
@click="selectExpress(e)">
{{e.name}}
<uv-icon v-if="shipForm.express_id === e.id" name="checkmark" color="#0D69EF" size="32rpx"></uv-icon>
</view>
<view class="type-sheet-cancel" @click="showExpressPicker = false">取消</view>
</view>
<uv-popup ref="logisticsPopup" mode="bottom" round="20rpx" :safeAreaInsetBottom="true">
<view class="cancel-popup">
<view class="cancel-popup-header">
<view>
<text class="cancel-popup-title">查看物流</text>
<text class="cancel-popup-no" v-if="logisticsPackages.length">共 {{logisticsPackages.length}} 个包裹</text>
</view>
<uv-icon name="close" size="36rpx" color="#999" @click="logisticsPopup.close()"></uv-icon>
</view>
<scroll-view v-if="logisticsPackages.length > 1" scroll-x class="pkg-scroll">
<view class="pkg-list">
<view v-for="(pkg, pi) in logisticsPackages" :key="pi"
class="pkg-card" :class="{ active: logisticsPkgIndex === pi }"
@click="selectPackage(pi)">
<text class="pkg-company">{{pkg.express_company_name}}</text>
<text class="pkg-no">{{pkg.express_code}}</text>
<text class="pkg-time" v-if="pkg.shipping_time">{{pkg.shipping_time}}</text>
</view>
</view>
</scroll-view>
<view v-else-if="logisticsPackages.length === 1" class="single-pkg-info">
<text class="single-pkg-company">{{logisticsPackages[0].express_company_name}}</text>
<text class="single-pkg-no">{{logisticsPackages[0].express_code}}</text>
</view>
<scroll-view scroll-y style="max-height: 55vh;">
<view v-if="logisticsLoading" class="loading-row">
<uv-loading-icon mode="circle" size="40rpx"></uv-loading-icon>
</view>
<view v-else-if="currentTrack && currentTrack.data && currentTrack.data.length">
<view class="logistics-list">
<view class="logistics-item" v-for="(item, i) in currentTrack.data" :key="i"
:class="{ first: i === 0 }">
<view class="logistics-dot-wrap">
<view class="logistics-dot" :class="{ active: i === 0 }"></view>
<view class="logistics-line" v-if="i < currentTrack.data.length - 1"></view>
</view>
<view class="logistics-content">
<text class="logistics-time">{{item.time || item.ftime}}</text>
<text class="logistics-context">{{item.context}}</text>
</view>
</view>
</view>
</view>
<view v-else class="logistics-empty">
<view v-if="currentTrack">
<text class="logistics-no">快递单号:{{currentTrack.nu}}</text>
<text class="logistics-company">快递公司:{{currentTrack.company}}</text>
<text class="logistics-msg">{{currentTrack.message || '暂无物流信息'}}</text>
</view>
<uv-empty v-else-if="!logisticsLoading" mode="search" text="暂无物流信息" iconSize="120rpx"></uv-empty>
</view>
</scroll-view>
</view>
</uv-popup>
<view class="type-mask" v-if="showAfterSaleSheet" @click="showAfterSaleSheet=false"></view>
<view class="type-sheet" :class="{ show: showAfterSaleSheet }">
<view class="type-sheet-title">售后操作</view>
<view class="type-sheet-item" @click="doAfterSale('refundWithReturn')">退货退款</view>
<view class="type-sheet-item" @click="doAfterSale('refundOnly')">仅退款</view>
<view class="type-sheet-item" @click="doAfterSale('exchange')">换货</view>
<view class="type-sheet-cancel" @click="showAfterSaleSheet=false">取消</view>
</view>
<uv-popup ref="cancelPopup" mode="bottom" round="20rpx" :safeAreaInsetBottom="true">
<view class="cancel-popup">
<view class="cancel-popup-header">
<view>
<text class="cancel-popup-title">取消订单商品</text>
<text class="cancel-popup-no">{{cancelOrder && cancelOrder.order_id}}</text>
</view>
<uv-icon name="close" size="36rpx" color="#999" @click="cancelPopup.close()"></uv-icon>
</view>
<scroll-view scroll-y style="max-height: 55vh;">
<view class="cancel-goods-list">
<view v-for="g in cancelGoodsList" :key="g.id"
class="cancel-goods-item"
:class="{ selected: cancelSelectedIds.includes(g.id), disabled: g.status === 2 }"
@click="g.status !== 2 && toggleCancelGoods(g.id)">
<view class="check-box" :class="{ checked: cancelSelectedIds.includes(g.id) }">
<uv-icon v-if="cancelSelectedIds.includes(g.id)" name="checkmark" size="22rpx" color="#fff"></uv-icon>
</view>
<uv-image :src="g.goods_image" width="96rpx" height="96rpx" radius="8rpx" mode="aspectFill" style="flex-shrink:0"></uv-image>
<view class="cancel-goods-info">
<view class="cancel-goods-name-row">
<text class="cancel-goods-name">{{g.goods_name}}</text>
<text v-if="g.status === 2" class="cancelled-tag">已取消</text>
</view>
<text class="cancel-goods-spec" v-if="g.spec_data && Object.keys(g.spec_data).length">
{{Object.entries(g.spec_data).map(([k,v])=>k+':'+v).join(' ')}}
</text>
<view class="cancel-goods-price-row">
<text class="cancel-goods-price">¥{{g.goods_price}}</text>
<text class="cancel-goods-qty">x{{g.goods_num}}</text>
</view>
</view>
</view>
</view>
</scroll-view>
<view class="cancel-popup-footer">
<text class="cancel-selected-tip" v-if="cancelSelectedIds.length">已选 {{cancelSelectedIds.length}} 件</text>
<text class="cancel-selected-tip" v-else>请选择要取消的商品</text>
<view class="cancel-confirm-btn"
:class="{ disabled: !cancelSelectedIds.length }"
@click="confirmCancelOrder">
确认取消
</view>
</view>
</view>
</uv-popup>
</view>
</template>
<script>
import allConfig from "@/utils/config.js"
export default {
data() {
return {
keyword: '',
searchType: 'order_no',
showTypePicker: false,
searchTypes: [
{ label: '订单号', key: 'order_no' },
{ label: '客户姓名', key: 'nickname' },
{ label: '手机号', key: 'mobile' },
{ label: '商品名称', key: 'goods_name' },
],
orderList: [],
page: 1,
total: 0,
loading: false,
refreshing: false,
noMore: false,
currentStatus: -1,
shipPopup: null,
shipOrder: null,
shipMode: 1,
shipGoodsList: [],
shipping: false,
shipForm: { express_id: null, express_name: '', express_no: '', remark: '' },
expressList: [],
expressLoading: false,
showExpressPicker: false,
logisticsPopup: null,
logisticsPackages: [],
logisticsPkgIndex: 0,
currentTrack: null,
logisticsLoading: false,
showAfterSaleSheet: false,
afterSaleOrder: null,
cancelPopup: null,
cancelOrder: null,
cancelGoodsList: [],
cancelSelectedIds: [],
tabList: [
{ name: '全部', status: -1, countKey: 'total', count: 0 },
{ name: '待到货', status: 1, countKey: 'pending', count: 0 },
{ name: '待补款', status: 2, countKey: 'unpaid', count: 0 },
{ name: '待发货', status: 3, countKey: 'unshipped', count: 0 },
{ name: '已发货', status: 4, countKey: 'shipped', count: 0 },
{ name: '售后中', status: 5, countKey: 'aftersale', count: 0 },
{ name: '已完成', status: 6, countKey: 'completed', count: 0 },
{ name: '已退款', status: 7, countKey: 'refunded', count: 0 },
{ name: '已取消', status: 8, countKey: 'cancelled', count: 0 },
{ name: '已报损', status: 9, countKey: 'damaged', count: 0 },
{ name: '售后记录',status: 10, countKey: 'sales', count: 0 },
{ name: '售后订单',status: 11, countKey: 'sale', count: 0 },
],
statusMap: { 1:'待到货', 2:'待补款', 3:'待发货', 4:'已发货', 5:'售后中', 6:'已完成', 7:'已退款', 8:'已取消', 9:'已报损', 10:'售后记录', 11:'售后订单' },
orderTypeMap: { 1:'正常订单', 2:'售后订单', 3:'换货订单' },
CANCEL_ROLES: ['superAdmin', 'admin', 'dzAdmin', 'cw', 'hg'],
AFTERSALE_ROLES: ['superAdmin', 'admin', 'dzAdmin', 'cw'],
AUDIT_ROLES: ['superAdmin', 'admin', 'cw', 'ckxd', 'hg', 'sy', 'shsh'],
}
},
computed: {
currentTypeLabel() {
const t = this.searchTypes.find(item => item.key === this.searchType)
return t ? t.label : '订单号'
},
currentPlaceholder() {
return `请输入${this.currentTypeLabel}`
},
tabListDisplay() {
return this.tabList.map(t => ({ ...t, name: `${t.name}(${t.count})` }))
},
canSplitShip() {
const list = this.shipOrder?.goods_list || []
const available = list.filter(g => g.status !== 2)
if (available.length === 0) return false
if (available.length === 1 && available[0].goods_num === 1) return false
return true
},
},
onShow() {
this.fetchStatusCount()
this.resetAndLoad()
},
methods: {
baseUrl(path) {
return allConfig + path
return path
},
formatSpec(specData) {
if (!specData || typeof specData !== 'object') return ''
if (Array.isArray(specData)) return ''
return Object.entries(specData).map(([k, v]) => `${k}:${v}`).join(' ')
},
hasPartialCancelled(goodsList) {
if (!goodsList || !goodsList.length) return false
const cancelledCount = goodsList.filter(g => g.status === 2).length
return cancelledCount > 0 && cancelledCount < goodsList.length
},
onSelectType(t) {
this.searchType = t.key
this.keyword = ''
this.showTypePicker = false
},
onSearch() {
this.resetAndLoad()
},
onRefresh() {
this.refreshing = true
this.resetAndLoad()
},
loadMore() {
if (this.noMore || this.loading) return
this.page++
this.fetchOrders()
},
changeTab(e) {
this.currentStatus = this.tabList[e.index].status
this.resetAndLoad()
},
goDetail(order) {
uni.navigateTo({ url: `/pagesA/order/order-details?id=${order.id}` })
},
resetAndLoad() {
this.page = 1
this.noMore = false
this.orderList = []
this.fetchOrders()
},
fetchStatusCount() {
const token = uni.getStorageSync('TOKEN')
uni.request({
url: this.baseUrl('/prod/admin/order/Orders/statusCount'),
method: 'POST',
header: { 'authori-zation': token },
success: (res) => {
if (res.data.code === 200) {
const d = res.data.data
this.tabList.forEach(tab => {
tab.count = d[tab.countKey] ?? 0
})
}
}
})
},
fetchOrders() {
if (this.loading) return
this.loading = true
const token = uni.getStorageSync('TOKEN')
let url = this.baseUrl('/prod/admin/order/Orders/index')
url += `?page=${this.page}&limit=10&orderBy=id&orderType=desc`
url += `&order_status=${this.currentStatus}`
if (this.keyword) url += `&${this.searchType}=${encodeURIComponent(this.keyword)}`
uni.request({
url, method: 'GET',
header: { 'authori-zation': token },
success: (res) => {
if (res.data.code === 200) {
const d = res.data.data
const list = d.data || []
this.total = d.total || 0
this.orderList = this.page === 1 ? list : [...this.orderList, ...list]
this.noMore = this.orderList.length >= this.total
}
},
complete: () => { this.loading = false; this.refreshing = false }
})
},
getUserRoles() {
const info = uni.getStorageSync('userInfo')
if (!info) return []
const roleList = info.roleList || []
return roleList.map(r => r.code || r.name || r)
},
hasRole(roles) {
const userRoles = this.getUserRoles()
if (!userRoles.length) return false
return roles.some(r => userRoles.includes(r))
},
getActions(order) {
const s = order.order_status
const actions = []
actions.push({ label: '详情', type: 'outline', action: 'detail' })
if (s === 1) {
actions.push({ label: '立即补款', type: 'primary', action: 'payment' })
actions.push({ label: '预售退款', type: 'outline', action: 'presaleRefund' })
actions.push({ label: '信息修改', type: 'outline', action: 'edit' })
if (this.hasRole(this.CANCEL_ROLES))
actions.push({ label: '取消订单', type: 'danger', action: 'cancel' })
} else if (s === 2) {
actions.push({ label: '立即补款', type: 'primary', action: 'payment' })
actions.push({ label: '信息修改', type: 'outline', action: 'edit' })
if (this.hasRole(this.CANCEL_ROLES))
actions.push({ label: '取消订单', type: 'danger', action: 'cancel' })
} else if (s === 3) {
actions.push({ label: '信息修改', type: 'outline', action: 'edit' })
if (this.hasRole(this.CANCEL_ROLES))
actions.push({ label: '取消订单', type: 'danger', action: 'cancel' })
actions.push({ label: '立即发货', type: 'primary', action: 'ship' })
} else if (s === 4) {
actions.push({ label: '查看物流', type: 'outline', action: 'logistics' })
actions.push({ label: '确认收货', type: 'outline', action: 'confirmReceipt' })
if (this.hasRole(this.AFTERSALE_ROLES)) {
actions.push({ label: '售后操作', type: 'outline', action: 'afterSale' })
}
} else if (s === 5) {
actions.push({ label: '查看物流', type: 'outline', action: 'logistics' })
if (this.hasRole(this.AUDIT_ROLES))
actions.push({ label: '审核售后', type: 'primary', action: 'auditAfterSale' })
} else if (s === 6) {
actions.push({ label: '售后操作', type: 'outline', action: 'afterSale' })
}
return actions
},
handleAction(act, order) {
if (act.action === 'detail') {
uni.navigateTo({ url: `/pagesA/order/order-details?id=${order.id}` })
} else if (act.action === 'ship') {
this.openShipPopup(order)
} else if (act.action === 'cancel') {
this.cancelOrder = order
this.cancelGoodsList = order.goods_list || []
this.cancelSelectedIds = []
this.cancelPopup.open()
} else if (act.action === 'edit') {
uni.navigateTo({ url: `/pagesA/order/order-edit?id=${order.id}` })
} else if (act.action === 'payment') {
uni.navigateTo({ url: `/pagesA/order/order-payment?id=${order.id}` })
} else if (act.action === 'presaleRefund') {
uni.navigateTo({ url: `/pagesA/order/presale-refund?id=${order.id}` })
} else if (act.action === 'logistics') {
this.openLogisticsPopup(order)
} else if (act.action === 'confirmReceipt') {
uni.showModal({
title: '确认收货',
content: `确认订单 ${order.order_id} 已收货?`,
success: (res) => { if (res.confirm) this.doConfirmReceipt(order) }
})
} else if (act.action === 'refundWithReturn') {
uni.navigateTo({ url: `/pagesA/order/after-sale?id=${order.id}&type=refundWithReturn` })
} else if (act.action === 'refundOnly') {
uni.navigateTo({ url: `/pagesA/order/after-sale?id=${order.id}&type=refundOnly` })
} else if (act.action === 'exchange') {
uni.navigateTo({ url: `/pagesA/order/after-sale?id=${order.id}&type=exchange` })
} else if (act.action === 'auditAfterSale') {
uni.navigateTo({ url: `/pagesA/order/after-sale-audit?id=${order.id}` })
}
},
doConfirmReceipt(order) {
const token = uni.getStorageSync('TOKEN')
uni.request({
url: this.baseUrl(`/prod/admin/order/Orders/update?id=${order.id}`),
method: 'PUT',
header: { 'authori-zation': token, 'content-type': 'application/json' },
data: { order_status: 6 },
success: (res) => {
if (res.data.code === 200) {
uni.showToast({ title: '确认收货成功', icon: 'success' })
this.resetAndLoad()
} else {
uni.showToast({ title: res.data.message || '操作失败', icon: 'none' })
}
}
})
},
getShippedQty(g, shippingInfoItem) {
if (!shippingInfoItem) return 0
return shippingInfoItem
.filter(s => s.order_item_id === g.id)
.reduce((sum, s) => sum + (s.shipped_quantity || 0), 0)
},
fetchExpressList() {
if (this.expressList.length) return
this.expressLoading = true
const token = uni.getStorageSync('TOKEN')
uni.request({
url: this.baseUrl('/prod/admin/setting/ExpressCompany/index?page=1&pageSize=100'),
method: 'GET',
header: { 'authori-zation': token },
success: (res) => {
if (res.data.code === 200) this.expressList = res.data.data.data || []
},
complete: () => { this.expressLoading = false }
})
},
selectExpress(e) {
this.shipForm.express_id = e.id
this.shipForm.express_name = e.name
this.showExpressPicker = false
},
setShipMode(mode) {
this.shipMode = mode
this.shipGoodsList.forEach(g => { g._selected = false; g.ship_qty = 1 })
},
openShipPopup(order) {
this.shipOrder = order
this.shipMode = 1
this.shipForm = { express_id: null, express_name: '', express_no: '', remark: '' }
this.fetchExpressList()
const infoItem = order.shipping_info_item || []
this.shipGoodsList = (order.goods_list || []).map(g => {
const shipped = this.getShippedQty(g, infoItem)
const available = Math.max(0, g.goods_num - shipped)
return { ...g, _selected: false, ship_qty: Math.min(1, available), _shippedQty: shipped, _availableQty: available }
})
this.shipPopup.open()
},
confirmShip() {
if (!this.shipForm.express_name) return uni.showToast({ title: '请选择快递公司', icon: 'none' })
if (!this.shipForm.express_no.trim()) return uni.showToast({ title: '请输入快递单号', icon: 'none' })
if (this.shipMode === 2) {
const selected = this.shipGoodsList.filter(g => g._selected)
if (!selected.length) return uni.showToast({ title: '请选择要发货的商品', icon: 'none' })
}
this.shipping = true
const token = uni.getStorageSync('TOKEN')
const data = {
id: this.shipOrder.id,
express_company_id: this.shipForm.express_id,
express_company_name: this.shipForm.express_name,
express_code: this.shipForm.express_no,
remark: this.shipForm.remark,
shipping_mode: this.shipMode,
shipping_type: 1,
}
if (this.shipMode === 2) {
data.selected_goods = this.shipGoodsList
.filter(g => g._selected)
.map(g => ({ goods_id: g.goods_id, order_item_id: g.id, shipping_qty: g.ship_qty }))
}
uni.request({
url: this.baseUrl('/prod/admin/order/Orders/ship'),
method: 'POST',
header: { 'authori-zation': token, 'content-type': 'application/json' },
data,
success: (res) => {
if (res.data.code === 200) {
uni.showToast({ title: '发货成功', icon: 'success' })
this.shipPopup.close()
this.resetAndLoad()
} else {
uni.showToast({ title: res.data.message || '操作失败', icon: 'none' })
}
},
fail: () => uni.showToast({ title: '网络错误', icon: 'none' }),
complete: () => { this.shipping = false }
})
},
openLogisticsPopup(order) {
const pkgs = order.shipping_info || []
this.logisticsPackages = pkgs
this.logisticsPkgIndex = 0
this.currentTrack = null
this.logisticsPopup.open()
if (pkgs.length > 0) {
this.loadPackageTracks(0)
}
},
selectPackage(index) {
if (this.logisticsPkgIndex === index) return
this.logisticsPkgIndex = index
this.currentTrack = null
this.loadPackageTracks(index)
},
loadPackageTracks(index) {
const pkg = this.logisticsPackages[index]
if (!pkg) return
this.logisticsLoading = true
const token = uni.getStorageSync('TOKEN')
uni.request({
url: this.baseUrl(`/prod/admin/order/Orders/shippingInfo?order_id=${pkg.id}`),
method: 'GET',
header: { 'authori-zation': token },
success: (res) => {
if (res.data.code === 200) {
this.currentTrack = res.data.data
} else {
uni.showToast({ title: res.data.message || '获取失败', icon: 'none' })
}
},
fail: () => uni.showToast({ title: '网络错误', icon: 'none' }),
complete: () => { this.logisticsLoading = false }
})
},
openAfterSaleSheet(order) {
this.afterSaleOrder = order
this.showAfterSaleSheet = true
},
doAfterSale(type) {
this.showAfterSaleSheet = false
const order = this.afterSaleOrder
if (!order) return
uni.navigateTo({ url: `/pagesA/order/after-sale?id=${order.id}&type=${type}` })
},
toggleCancelGoods(id) {
const idx = this.cancelSelectedIds.indexOf(id)
if (idx > -1) this.cancelSelectedIds.splice(idx, 1)
else this.cancelSelectedIds.push(id)
},
confirmCancelOrder() {
if (!this.cancelSelectedIds.length) return uni.showToast({ title: '请选择要取消的商品', icon: 'none' })
uni.showModal({
title: '确认取消',
content: `确认取消选中的 ${this.cancelSelectedIds.length} 件商品?`,
success: (res) => {
if (!res.confirm) return
const token = uni.getStorageSync('TOKEN')
uni.request({
url: this.baseUrl('/prod/admin/order/Orders/cancelOrder'),
method: 'POST',
header: { 'authori-zation': token, 'content-type': 'application/json' },
data: {
order_id: this.cancelOrder.id,
goods_ids: this.cancelSelectedIds,
},
success: (r) => {
if (r.data.code === 200) {
uni.showToast({ title: '取消成功', icon: 'success' })
this.cancelPopup.close()
this.resetAndLoad()
} else {
uni.showToast({ title: r.data.message || '操作失败', icon: 'none' })
}
},
fail: () => uni.showToast({ title: '网络错误', icon: 'none' })
})
}
})
},
}
}
</script>
<style lang="scss" scoped>
page { background: #f7f8f8; }
.content { height: 100vh; display: flex; flex-direction: column; }
.search-box {
padding: 16rpx 24rpx; background: #fff;
.search-row {
display: flex; align-items: center; background: #f7f8f8;
border-radius: 12rpx; overflow: hidden; height: 80rpx;
}
.search-select {
display: flex; align-items: center; gap: 8rpx;
padding: 0 20rpx; height: 100%; white-space: nowrap;
font-size: 26rpx; color: #333; border-right: 1rpx solid #e5e5e5;
flex-shrink: 0;
}
.search-input {
flex: 1; height: 100%; padding: 0 16rpx;
font-size: 26rpx; color: #1a1a1a; background: transparent;
}
.search-btn {
padding: 0 28rpx; height: 100%; background: #0D69EF;
color: #fff; font-size: 26rpx;
display: flex; align-items: center; justify-content: center;
flex-shrink: 0;
}
}
.order-scroll { flex: 1; overflow: hidden; }
.order-list { padding: 0 24rpx; }
.order-card {
background: #fff; border-radius: 16rpx; margin-top: 20rpx; overflow: hidden;
.order-head {
display: flex; align-items: center; justify-content: space-between;
padding: 20rpx 24rpx; border-bottom: 1rpx solid #f5f5f5;
.order-head-left { display: flex; align-items: center; gap: 16rpx; }
.order-member { font-size: 28rpx; font-weight: 600; color: #1a1a1a; }
.order-store { font-size: 22rpx; color: #999; }
}
.order-no-row {
display: flex; align-items: center; gap: 16rpx;
padding: 12rpx 24rpx; border-bottom: 1rpx solid #f9f9f9;
.order-no { font-size: 22rpx; color: #999; flex: 1; }
.order-type-tag {
font-size: 20rpx; padding: 4rpx 12rpx; border-radius: 6rpx;
color: #0D69EF; background: rgba(13,105,239,0.08);
}
.partial-cancel-tag {
font-size: 20rpx; padding: 4rpx 12rpx; border-radius: 6rpx;
color: #ff7a00; background: rgba(255,122,0,0.1);
}
.partial-ship-tag {
font-size: 20rpx; padding: 4rpx 12rpx; border-radius: 6rpx;
color: #f53f3f; background: rgba(245,63,63,0.1);
}
}
.goods-row {
display: flex; gap: 20rpx; padding: 20rpx 24rpx;
border-bottom: 1rpx solid #f9f9f9;
.goods-info { flex: 1; display: flex; flex-direction: column; gap: 8rpx; }
.goods-name { font-size: 26rpx; color: #333; }
.goods-spec { font-size: 22rpx; color: #999; }
.goods-price-row { display: flex; align-items: center; justify-content: space-between; }
.goods-price { font-size: 26rpx; font-weight: 600; color: #333; }
.goods-num { font-size: 24rpx; color: #999; }
}
.more-goods {
padding: 8rpx 24rpx; font-size: 22rpx; color: #999;
border-bottom: 1rpx solid #f9f9f9;
}
.order-foot {
display: flex; align-items: center; justify-content: space-between;
padding: 16rpx 24rpx; background: #fafafa;
.order-time { font-size: 22rpx; color: #999; }
.order-amount { display: flex; align-items: baseline; gap: 6rpx; }
.amount-label { font-size: 22rpx; color: #999; }
.amount-val { font-size: 30rpx; font-weight: 700; color: #1a1a1a; }
}
.order-actions {
display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 12rpx;
padding: 16rpx 24rpx; border-top: 1rpx solid #f5f5f5;
.action-btn {
font-size: 24rpx; padding: 10rpx 24rpx; border-radius: 40rpx;
white-space: nowrap; flex-shrink: 0;
display: flex; align-items: center;
&.primary { color: #0D69EF; border: 1rpx solid #0D69EF; }
&.outline { color: #666; border: 1rpx solid #ccc; }
&.danger { color: #F56C6C; border: 1rpx solid #F56C6C; }
}
}
}
.order-status-tag {
font-size: 22rpx; padding: 4rpx 14rpx; border-radius: 20rpx;
&.s1 { color: #F7A600; background: rgba(247,166,0,0.1); } // 待到货
&.s2 { color: #F7A600; background: rgba(247,166,0,0.1); } // 待补款
&.s3 { color: #F56C6C; background: rgba(245,108,108,0.1); } // 售后订单
&.s4 { color: #0D69EF; background: rgba(13,105,239,0.1); } // 待发货
&.s5 { color: #0D69EF; background: rgba(13,105,239,0.1); } // 已发货
&.s6 { color: #F56C6C; background: rgba(245,108,108,0.1); } // 售后中
&.s7 { color: #0EB836; background: rgba(14,184,54,0.1); } // 已完成
&.s8 { color: #999; background: #f5f5f5; } // 已退款
&.s9 { color: #999; background: #f5f5f5; } // 已取消
&.s10 { color: #999; background: #f5f5f5; } // 已报损
&.s11 { color: #F56C6C; background: rgba(245,108,108,0.1); } // 售后记录
}
.load-tip { text-align: center; padding: 20rpx 0 40rpx; font-size: 24rpx; color: #999; }
.empty-box { padding-top: 200rpx; }
.tab-item {
display: flex; align-items: baseline; gap: 4rpx; white-space: nowrap;
.tab-count { font-size: 20rpx; color: #999; }
}
.ship-popup {
background: #fff; padding-bottom: env(safe-area-inset-bottom);
}
.ship-popup-header {
display: flex; align-items: flex-start; justify-content: space-between;
padding: 32rpx 32rpx 20rpx; border-bottom: 1rpx solid #f0f0f0;
.ship-popup-title { font-size: 30rpx; font-weight: 600; color: #1a1a1a; display: block; margin-bottom: 6rpx; }
.ship-popup-no { font-size: 22rpx; color: #999; display: block; }
}
.ship-mode-row {
display: flex; gap: 24rpx; padding: 20rpx 32rpx;
border-bottom: 1rpx solid #f5f5f5;
.ship-mode-item {
display: flex; align-items: center; gap: 10rpx;
font-size: 28rpx; color: #333;
&.active { color: #0D69EF; font-weight: 600; }
&.disabled { color: #ccc; }
}
.ship-mode-dot {
width: 32rpx; height: 32rpx; border-radius: 50%;
border: 2rpx solid #ccc; background: #fff; flex-shrink: 0;
display: flex; align-items: center; justify-content: center;
&.active { border-color: #0D69EF; background: #0D69EF; }
&.active::after { content: ''; width: 14rpx; height: 14rpx; border-radius: 50%; background: #fff; }
}
}
/* 整单商品预览 */
.whole-goods-section { padding: 16rpx 32rpx 0; }
.whole-goods-item {
display: flex; align-items: center; gap: 16rpx;
padding: 16rpx 0; border-bottom: 1rpx solid #f5f5f5;
&:last-child { border-bottom: none; }
&.cancelled { opacity: 0.45; }
&.shipped { opacity: 0.55; }
.whole-goods-info { flex: 1; display: flex; flex-direction: column; gap: 6rpx; }
.whole-goods-name-row { display: flex; align-items: center; gap: 10rpx; }
.whole-goods-name { font-size: 26rpx; color: #1a1a1a; font-weight: 500; flex: 1; }
.whole-goods-spec { font-size: 22rpx; color: #999; }
.whole-goods-price-row { display: flex; align-items: center; gap: 12rpx; }
.whole-goods-price { font-size: 26rpx; color: #F56C6C; font-weight: 600; }
.whole-goods-qty { font-size: 22rpx; color: #bbb; }
.whole-goods-shipped { font-size: 22rpx; color: #0EB836; margin-left: auto; }
}
/* 分单商品选择 */
.split-goods-section { padding: 16rpx 24rpx 0; }
.split-tip { font-size: 24rpx; color: #999; margin-bottom: 12rpx; padding: 0 8rpx; }
.split-goods-item {
display: flex; align-items: flex-start; gap: 16rpx;
padding: 20rpx; margin-bottom: 16rpx;
border-radius: 14rpx; border: 2rpx solid #f0f0f0; background: #fafafa;
&.selected { border-color: #0D69EF; background: rgba(13,105,239,0.04); }
&.disabled { opacity: 0.45; }
.check-box {
width: 40rpx; height: 40rpx; border-radius: 8rpx; flex-shrink: 0; margin-top: 4rpx;
border: 2rpx solid #ddd; background: #fff;
display: flex; align-items: center; justify-content: center;
&.checked { background: #0D69EF; border-color: #0D69EF; }
}
.split-goods-info { flex: 1; display: flex; flex-direction: column; gap: 8rpx; }
.split-goods-name-row { display: flex; align-items: center; gap: 10rpx; flex-wrap: wrap; }
.split-goods-name { font-size: 26rpx; font-weight: 500; color: #1a1a1a; flex: 1; }
.split-goods-spec { font-size: 22rpx; color: #999; }
.split-goods-qty-row { display: flex; align-items: center; gap: 16rpx; }
.split-qty-label { font-size: 24rpx; color: #555; }
.qty-ctrl { display: flex; align-items: center; gap: 12rpx; }
.qty-btn {
width: 48rpx; height: 48rpx; background: #f0f0f0; border-radius: 8rpx;
display: flex; align-items: center; justify-content: center;
font-size: 28rpx; color: #444;
}
.qty-num { font-size: 28rpx; font-weight: 600; color: #1a1a1a; min-width: 32rpx; text-align: center; }
.qty-hint { font-size: 22rpx; color: #999; }
}
/* 快递表单 */
.ship-form-section { padding: 20rpx 32rpx 0; }
.ship-form-item {
display: flex; align-items: center; padding: 24rpx 0;
border-bottom: 1rpx solid #f5f5f5;
&:last-child { border-bottom: none; }
.ship-form-label { font-size: 28rpx; color: #333; width: 160rpx; flex-shrink: 0; .req { color: #F56C6C; } }
.ship-form-input { flex: 1; font-size: 28rpx; color: #1a1a1a; }
.ship-form-input-row { flex: 1; display: flex; align-items: center; justify-content: flex-end; gap: 8rpx; }
.ship-form-val { font-size: 28rpx; color: #1a1a1a; text-align: right; }
.ship-form-placeholder { font-size: 28rpx; color: #c0c0c0; text-align: right; }
}
.type-sheet-loading { display: flex; justify-content: center; padding: 40rpx; }
/* 底部按钮 */
.ship-popup-footer {
display: flex; gap: 20rpx; padding: 20rpx 32rpx 32rpx;
border-top: 1rpx solid #f0f0f0;
.ship-cancel-btn {
flex: 1; height: 88rpx; border-radius: 44rpx; background: #f5f5f5; color: #666;
display: flex; align-items: center; justify-content: center; font-size: 30rpx;
}
.ship-confirm-btn {
flex: 2; height: 88rpx; border-radius: 44rpx;
background: linear-gradient(135deg, #1a7aff, #0D69EF); color: #fff;
display: flex; align-items: center; justify-content: center; font-size: 30rpx; font-weight: 600;
box-shadow: 0 4rpx 16rpx rgba(13,105,239,0.3);
&.loading { background: #a0c4ff; box-shadow: none; }
}
}
/* 状态标签 */
.tag-cancelled { font-size: 20rpx; color: #fff; background: #bbb; padding: 2rpx 10rpx; border-radius: 6rpx; flex-shrink: 0; }
.tag-shipped { font-size: 20rpx; color: #fff; background: #0EB836; padding: 2rpx 10rpx; border-radius: 6rpx; flex-shrink: 0; }
.tag-partial { font-size: 20rpx; color: #fff; background: #ff7a00; padding: 2rpx 10rpx; border-radius: 6rpx; flex-shrink: 0; }
/* 取消订单商品列表 */
.cancel-popup {
background: #fff;
padding-bottom: env(safe-area-inset-bottom);
}
.cancel-popup-header {
display: flex; align-items: flex-start; justify-content: space-between;
padding: 32rpx 32rpx 20rpx; border-bottom: 1rpx solid #f0f0f0;
.cancel-popup-title { font-size: 30rpx; font-weight: 600; color: #1a1a1a; display: block; margin-bottom: 6rpx; }
.cancel-popup-no { font-size: 22rpx; color: #999; display: block; }
}
.cancel-goods-list { padding: 16rpx 24rpx 8rpx; }
.cancel-goods-item {
display: flex; align-items: center; gap: 16rpx;
padding: 20rpx; margin-bottom: 16rpx;
border-radius: 14rpx; border: 2rpx solid #f0f0f0; background: #fafafa;
transition: all 0.15s;
&.selected { border-color: #0D69EF; background: rgba(13,105,239,0.04); }
&.disabled { opacity: 0.45; }
.check-box {
width: 40rpx; height: 40rpx; border-radius: 8rpx; flex-shrink: 0;
border: 2rpx solid #ddd; background: #fff;
display: flex; align-items: center; justify-content: center;
&.checked { background: #0D69EF; border-color: #0D69EF; }
}
.cancel-goods-info { flex: 1; display: flex; flex-direction: column; gap: 6rpx; overflow: hidden; }
.cancel-goods-name-row { display: flex; align-items: center; gap: 10rpx; flex-wrap: wrap; }
.cancel-goods-name { font-size: 26rpx; font-weight: 500; color: #1a1a1a; line-height: 1.4; flex: 1; }
.cancelled-tag {
font-size: 20rpx; color: #fff; background: #bbb;
padding: 2rpx 10rpx; border-radius: 6rpx; flex-shrink: 0;
}
.cancel-goods-spec { font-size: 22rpx; color: #999; }
.cancel-goods-price-row { display: flex; align-items: center; gap: 12rpx; }
.cancel-goods-price { font-size: 26rpx; color: #F56C6C; font-weight: 600; }
.cancel-goods-qty { font-size: 22rpx; color: #bbb; }
}
.cancel-popup-footer {
display: flex; align-items: center; justify-content: space-between;
padding: 20rpx 32rpx 32rpx; border-top: 1rpx solid #f0f0f0;
.cancel-selected-tip { font-size: 26rpx; color: #999; }
.cancel-confirm-btn {
background: #F56C6C; color: #fff;
height: 80rpx; padding: 0 48rpx; border-radius: 40rpx;
display: flex; align-items: center; justify-content: center;
font-size: 28rpx; font-weight: 500;
&.disabled { background: #ddd; color: #bbb; }
}
}
/* 物流 */
.loading-row { display: flex; align-items: center; justify-content: center; padding: 60rpx; }
.pkg-scroll { border-bottom: 1rpx solid #f0f0f0; }
.pkg-list { display: flex; gap: 16rpx; padding: 20rpx 24rpx; white-space: nowrap; }
.pkg-card {
display: inline-flex; flex-direction: column; gap: 6rpx;
padding: 16rpx 24rpx; border-radius: 12rpx;
border: 2rpx solid #eee; background: #fafafa; flex-shrink: 0;
&.active { border-color: #0D69EF; background: rgba(13,105,239,0.05); }
.pkg-company { font-size: 24rpx; color: #333; font-weight: 500; }
.pkg-no { font-size: 22rpx; color: #999; }
.pkg-time { font-size: 20rpx; color: #bbb; }
}
.single-pkg-info {
display: flex; align-items: center; gap: 16rpx;
padding: 16rpx 32rpx; border-bottom: 1rpx solid #f0f0f0;
.single-pkg-company { font-size: 26rpx; color: #333; font-weight: 500; }
.single-pkg-no { font-size: 24rpx; color: #999; }
}
.logistics-list { padding: 24rpx 32rpx; }
.logistics-item {
display: flex; gap: 20rpx; padding-bottom: 32rpx;
.logistics-dot-wrap { display: flex; flex-direction: column; align-items: center; flex-shrink: 0; }
.logistics-dot { width: 20rpx; height: 20rpx; border-radius: 50%; background: #ccc; flex-shrink: 0; margin-top: 6rpx; }
.logistics-line { flex: 1; width: 2rpx; background: #eee; margin-top: 8rpx; min-height: 40rpx; }
.logistics-content { flex: 1; display: flex; flex-direction: column; gap: 8rpx; }
.logistics-time { font-size: 22rpx; color: #999; }
.logistics-context { font-size: 26rpx; color: #333; line-height: 1.6; }
&.first .logistics-dot { background: #0D69EF; }
&.first .logistics-content { color: #1a1a1a; font-weight: 500; }
}
.logistics-empty {
padding: 40rpx 32rpx; display: flex; flex-direction: column; gap: 16rpx;
.logistics-no, .logistics-company { font-size: 26rpx; color: #555; }
.logistics-msg { font-size: 26rpx; color: #999; margin-top: 8rpx; }
}
.type-mask {
position: fixed; inset: 0; background: rgba(0,0,0,0.4); z-index: 9998;
}
.type-sheet {
position: fixed; bottom: 0; left: 0; width: 100%;
background: #fff; border-radius: 24rpx 24rpx 0 0;
z-index: 9999; padding-bottom: env(safe-area-inset-bottom);
transform: translateY(100%); transition: transform 0.25s ease;
&.show { transform: translateY(0); }
.type-sheet-title {
text-align: center; font-size: 28rpx; color: #999;
padding: 28rpx 0 16rpx; border-bottom: 1rpx solid #f5f5f5;
}
.type-sheet-item {
display: flex; align-items: center; justify-content: space-between;
padding: 32rpx 48rpx; font-size: 30rpx; color: #1a1a1a;
border-bottom: 1rpx solid #f9f9f9;
&.active { color: #0D69EF; font-weight: 600; }
}
.type-sheet-cancel {
text-align: center; padding: 32rpx; font-size: 30rpx; color: #999;
}
}
</style>
你好,提供下返回的rid