| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- <template>
- <view class="detail-page-container">
- <erp-nav-bar title="订单详情" />
- <!-- 2. 状态横幅区域:不再包含状态栏边距 -->
- <view class="status-banner-container" :class="order.statusType" id="nav-header">
- <view class="status-banner-content">
- <view class="header-main">
- <text class="status-title">{{ order.statusName }}</text>
- <text class="status-sub">{{ statusSubText }}</text>
- </view>
- <view class="header-icon-wrap">
- <view class="status-visual-icon"></view>
- </view>
- </view>
- </view>
- <!-- 2. 主内容滚动区:计算锁定高度以支持 100% 滚动 -->
- <scroll-view scroll-y class="main-content-scroll" :style="{ height: scrollHeight }" :show-scrollbar="false">
- <view class="detail-inner-box">
- <!-- 卡片:规格清单 (支持多个型号展现) -->
- <view class="model-item-card-inner" v-for="(model, mIdx) in (order.models || [order])" :key="mIdx">
- <view class="data-group-card" :class="{ 'first-card': mIdx === 0 }">
- <view class="card-head">规格清单 #{{ mIdx + 1 }}</view>
- <view class="data-item"><text class="l">产品型号</text><text class="v bold">{{ model.type }}</text>
- </view>
- <view class="data-item"><text class="l">型号名称</text><text class="v">{{ model.typeName ||
- '铝型材主料' }}</text></view>
- <view class="data-item"><text class="l">单据编号</text><text class="v">{{ model.docCode || '-' }}</text></view>
- <view class="data-item"><text class="l">项目号</text><text class="v">{{ model.itemNo || '-' }}</text></view>
- <view class="data-item"><text class="l">型材材质</text><text class="v">{{ model.material ||
- '6063-T5' }}</text></view>
- <view class="line-split"></view>
- <view class="data-item"><text class="l">表面处理</text><text class="v">{{ model.surface }}</text>
- </view>
- <view class="data-item"><text class="l">包装方式</text><text class="v">{{ model.package ||
- '普通包装' }}</text></view>
- <view class="line-split"></view>
- <view class="data-item"><text class="l">订单长度</text><text class="v">{{ model.length }} mm</text>
- </view>
- <view class="data-item"><text class="l">型材壁厚</text><text class="v">{{ model.wallThickness ||
- '1.2' }} mm</text></view>
- <view class="data-item"><text class="l">需求支数</text><text class="v highlight">{{ model.count }}
- 支</text></view>
- </view>
- </view>
- <!-- 卡片:订单详情 -->
- <view class="data-group-card shadow-less">
- <view class="card-head">订单详情</view>
- <view class="data-item"><text class="l">订单单号</text><text class="v selectable">{{ order.orderNo
- }}</text></view>
- <view class="data-item"><text class="l">单据编号</text><text class="v selectable">{{ order.docCode || '-' }}</text></view>
- <view class="data-item"><text class="l">下单日期</text><text class="v">{{ order.time }}</text></view>
- <view class="data-item"><text class="l">支付方式</text><text class="v">月结扣款</text></view>
- </view>
- <!-- 底部占位 -->
- <view class="list-bottom-placeholder"></view>
- </view>
- </scroll-view>
- <!-- 3. 底部固定操作栏 -->
- <view class="detail-action-bar-fixed" id="footer-bar">
- <view class="action-btn-wrap single" v-if="order.isConfirmed === 0">
- <button class="action-btn primary" @click="callSales">呼叫业务员</button>
- </view>
- <view class="action-btn-wrap single" v-else>
- <button class="action-btn primary" @click="goHome">再下一单</button>
- </view>
- <view class="safe-area-bottom-support"></view>
- </view>
- </view>
- </template>
- <script>
- import ErpNavBar from '@/components/erp-nav-bar.vue';
- import { getOrderDetail } from '@/api/erp/order.js';
- import { getPhone } from '@/api/system/phone.js';
- export default {
- components: { ErpNavBar },
- data() {
- return {
- footerHeight: 80, // px
- headerHeight: 120, // px
- rowId: '',
- loading: false,
- salesPhone: '',
- order: {
- orderNo: '-',
- docCode: '',
- isConfirmed: 1,
- statusName: '加载中',
- statusType: 'pending',
- models: [],
- erpNo: '',
- time: '-'
- }
- }
- },
- computed: {
- statusSubText() {
- const map = {
- pending: '您的订单已提交,正在等待管理端同步确认中...',
- finish: '订单已确认,并已成功同步到 ERP 系统中。',
- approved: '订单已在 ERP 系统中审核通过。',
- reviewed: '订单已由相关负责人签批。',
- exFinished: '订单关联的产品型材已挤压完成。',
- productionFinish: '订单所含产品型材已全部生产完成!',
- cancelled: '该订单已被撤销。'
- };
- return map[this.order.statusType] || '订单状态更新中';
- },
- scrollHeight() {
- const info = uni.getSystemInfoSync();
- const safeBottom = info.safeAreaInsets ? info.safeAreaInsets.bottom : 0;
- const statusBarHeight = info.statusBarHeight || 20;
- return `calc(100vh - ${statusBarHeight + 164}px - ${80 + safeBottom}px)`;
- }
- },
- onLoad(options) {
- if (options.rowId) {
- this.rowId = options.rowId;
- this.loadOrderDetail();
- this.loadPhone();
- }
- },
- methods: {
- async loadOrderDetail() {
- if (this.loading) return;
- this.loading = true;
- try {
- const res = await getOrderDetail(this.rowId);
- const data = res.data || res;
- if (!data) {
- uni.showToast({ title: '订单不存在', icon: 'none' });
- return;
- }
- // 状态展示映射
- const statusMap = {
- 0: { name: '待确认', type: 'pending' },
- 1: { name: '已确认', type: 'finish' },
- 2: { name: '已审核', type: 'approved' },
- 3: { name: '已签批', type: 'reviewed' },
- 4: { name: '挤压完成', type: 'exFinished' },
- 5: { name: '生产完成', type: 'productionFinish' },
- 6: { name: '已取消', type: 'cancelled' }
- };
- const s = statusMap[data.status] || { name: '待确认', type: 'pending' };
- this.order = {
- orderNo: data.code || '-',
- docCode: data.docCode || '',
- rowId: data.rowId,
- isConfirmed: data.isConfirmed,
- statusName: s.name,
- statusType: s.type,
- time: data.createTime || '-',
- totalCount: data.totalCount || 0,
- models: (data.details || []).map(d => ({
- type: d.modelNum || '未知型号',
- typeName: d.modelName || '铝型材主料',
- docCode: d.docCode || '',
- itemNo: d.itemNo || '',
- material: d.material || '6063-T5',
- surface: d.surfaceName || '无',
- package: d.packName || '普通包装',
- length: d.length ? Number(d.length).toFixed(4) : '0',
- wallThickness: d.wallThickness ? Number(d.wallThickness).toFixed(4) : '1.2',
- count: d.count || 0
- }))
- };
- } catch (e) {
- console.error('加载订单详情失败', e);
- uni.showToast({ title: e || '加载失败', icon: 'none' });
- } finally {
- this.loading = false;
- }
- },
- goBack() { uni.navigateBack(); },
- callSales() { uni.makePhoneCall({ phoneNumber: this.salesPhone }); },
- goHome() { uni.reLaunch({ url: '/pages/order/index' }); },
- async loadPhone() {
- try {
- const res = await getPhone();
- this.salesPhone = res.data.salesPhone || '13888888888';
- } catch (e) {
- console.error('加载联系电话失败', e);
- uni.showToast({ title: e || '加载联系电话失败', icon: 'none' });
- }
- }
- }
- }
- </script>
- <style scoped>
- /deep/ ::-webkit-scrollbar {
- display: none !important;
- width: 0 !important;
- height: 0 !important;
- -webkit-appearance: none;
- background: transparent;
- }
- .detail-page-container {
- width: 100vw;
- height: 100vh;
- background: #f8fbfd;
- display: flex;
- flex-direction: column;
- overflow: hidden;
- position: relative;
- }
- .status-banner-container {
- color: #fff;
- flex-shrink: 0;
- }
- .status-banner-container.pending {
- background: linear-gradient(135deg, #FF9900 0%, #FFB84D 100%);
- }
- .status-banner-container.finish {
- background: linear-gradient(135deg, #1890FF 0%, #69C0FF 100%);
- }
- .status-banner-container.approved {
- background: linear-gradient(135deg, #52C41A 0%, #95DE64 100%);
- }
- .status-banner-container.reviewed {
- background: linear-gradient(135deg, #722ED1 0%, #B37FEB 100%);
- }
- .status-banner-container.exFinished {
- background: linear-gradient(135deg, #13C2C2 0%, #5CDBD3 100%);
- }
- .status-banner-container.productionFinish {
- background: linear-gradient(135deg, #2F54EB 0%, #85A5FF 100%);
- }
- .status-banner-container.cancelled {
- background: linear-gradient(135deg, #F5222D 0%, #FF7875 100%);
- }
- /* 状态横幅内容 */
- .status-banner-content {
- padding: 40rpx;
- padding-bottom: 60rpx;
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- .header-main {
- flex: 1;
- }
- .status-title {
- font-size: 48rpx;
- font-weight: bold;
- display: block;
- margin-bottom: 12rpx;
- }
- .status-sub {
- font-size: 26rpx;
- opacity: 0.9;
- }
- .status-visual-icon {
- width: 60rpx;
- height: 60rpx;
- border: 4rpx solid rgba(255, 255, 255, 0.3);
- border-radius: 50%;
- opacity: 0.6;
- }
- /* 修正:移除负边距,并明确滚动方向 */
- .main-content-scroll {
- width: 100%;
- flex: 1;
- }
- .detail-inner-box {
- padding: 30rpx;
- padding-top: 10rpx;
- }
- .data-group-card {
- background: #fff;
- border-radius: 30rpx;
- padding: 40rpx;
- margin-bottom: 30rpx;
- box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.02);
- }
- /* 第一张卡片增加顶部间隔(红框1优化点) */
- .first-card {
- margin-top: 20rpx;
- }
- .card-head {
- font-size: 30rpx;
- font-weight: bold;
- color: #333;
- margin-bottom: 30rpx;
- border-left: 8rpx solid #C1001C;
- padding-left: 20rpx;
- }
- .line-split {
- height: 1rpx;
- background: #f5f5f5;
- margin: 24rpx 0;
- }
- .data-item {
- display: flex;
- justify-content: space-between;
- margin-bottom: 24rpx;
- font-size: 28rpx;
- align-items: center;
- }
- .l {
- color: #999;
- }
- .v {
- color: #333;
- font-weight: 500;
- }
- .v.bold {
- font-weight: bold;
- font-size: 30rpx;
- }
- .v.erp-no {
- color: #C1001C;
- font-weight: bold;
- }
- .v.highlight {
- color: #ff3b30;
- font-weight: bold;
- font-size: 34rpx;
- }
- .list-bottom-placeholder {
- height: 260rpx;
- }
- .detail-action-bar-fixed {
- position: fixed;
- bottom: 0;
- left: 0;
- right: 0;
- background: #fff;
- padding: 30rpx 40rpx;
- box-shadow: 0 -10rpx 40rpx rgba(0, 0, 0, 0.04);
- z-index: 999;
- flex-shrink: 0;
- }
- .action-btn-wrap {
- display: flex;
- gap: 24rpx;
- }
- .action-btn {
- flex: 1;
- height: 96rpx;
- border-radius: 48rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 32rpx;
- font-weight: bold;
- }
- .action-btn.primary {
- background: #C1001C;
- color: #fff;
- border: none;
- }
- .action-btn.cancel {
- background: #fff1f0;
- color: #ff3b30;
- border: 1rpx solid #ffccc7;
- font-weight: normal;
- }
- .safe-area-bottom-support {
- height: constant(safe-area-inset-bottom);
- height: env(safe-area-inset-bottom);
- }
- </style>
|