| | |
| | | {
|
| | | "path": "pages/outbound/orderOut/orderList",
|
| | | "style": {
|
| | | "navigationBarTitleText": "单据列表"
|
| | | "navigationBarTitleText": "单据列表",
|
| | | "enablePullDownRefresh": true
|
| | | }
|
| | | },
|
| | | {
|
| | | "path": "pages/outbound/orderOut/orderDetlList",
|
| | | "style": {
|
| | | "navigationBarTitleText": "单据明细列表"
|
| | | }
|
| | | },
|
| | | {
|
| New file |
| | |
| | | <template> |
| | | <view class="page-container"> |
| | | <!-- 订单信息头部 --> |
| | | <view class="order-header" v-if="order"> |
| | | <view class="header-content"> |
| | | <view class="header-row"> |
| | | <text class="header-label">单据号</text> |
| | | <text class="header-value">{{order.code}}</text> |
| | | </view> |
| | | <view class="header-row"> |
| | | <text class="header-label">单据类型</text> |
| | | <text class="header-value">{{order.wkType$ || '-'}}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 搜索框 --> |
| | | <view class="search-bar"> |
| | | <uni-search-bar v-model="condition" placeholder=" 扫码 / 输入物料" bgColor="#F5F5F5" @confirm="search" @cancel="onCancelSearch" /> |
| | | </view> |
| | | |
| | | <!-- 明细列表 --> |
| | | <view class="detl-list"> |
| | | <view class="detl-card" v-for="(item, index) in filterList" :key="index" @click="chose(item)"> |
| | | <!-- 卡片头部 --> |
| | | <view class="card-header"> |
| | | <view class="mat-info"> |
| | | <text class="mat-code">{{item.matnrCode}}</text> |
| | | <text class="mat-name">{{item.maktx || '-'}}</text> |
| | | </view> |
| | | <view class="qty-badge" :class="item.enableQty > 0 ? 'badge-active' : 'badge-done'"> |
| | | <text class="qty-text">剩余 {{item.enableQty}}</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 卡片内容 --> |
| | | <view class="card-body"> |
| | | <view class="info-grid"> |
| | | <view class="info-item"> |
| | | <text class="info-label">规格</text> |
| | | <text class="info-value">{{item.specs || '-'}}</text> |
| | | </view> |
| | | <view class="info-item"> |
| | | <text class="info-label">批次</text> |
| | | <text class="info-value">{{item.batch || '-'}}</text> |
| | | </view> |
| | | <view class="info-item"> |
| | | <text class="info-label">订单数量</text> |
| | | <text class="info-value highlight">{{item.anfme}}</text> |
| | | </view> |
| | | <view class="info-item"> |
| | | <text class="info-label">已完成</text> |
| | | <text class="info-value">{{item.anfme - item.enableQty}}</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 进度条 --> |
| | | <view class="progress-wrap"> |
| | | <view class="progress-bar"> |
| | | <view class="progress-fill" :style="{width: getProgress(item) + '%'}"></view> |
| | | </view> |
| | | <text class="progress-text">{{getProgress(item)}}%</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 卡片底部 --> |
| | | <view class="card-footer" v-if="item.enableQty > 0"> |
| | | <text class="action-text">点击组托入库</text> |
| | | <uni-icons type="right" size="14" color="#0081ff"></uni-icons> |
| | | </view> |
| | | <view class="card-footer card-footer-done" v-else> |
| | | <text class="done-text">已完成</text> |
| | | <uni-icons type="checkmarkempty" size="14" color="#28a745"></uni-icons> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 空状态 --> |
| | | <view class="empty-state" v-if="filterList.length === 0 && !loading"> |
| | | <uni-icons type="info" size="60" color="#CCCCCC"></uni-icons> |
| | | <text class="empty-text">暂无明细数据</text> |
| | | </view> |
| | | |
| | | <!-- 统计信息 --> |
| | | <view class="stats-bar" v-if="menuList.length > 0"> |
| | | <view class="stats-item"> |
| | | <text class="stats-value">{{menuList.length}}</text> |
| | | <text class="stats-label">总明细</text> |
| | | </view> |
| | | <view class="stats-divider"></view> |
| | | <view class="stats-item"> |
| | | <text class="stats-value">{{pendingCount}}</text> |
| | | <text class="stats-label">待处理</text> |
| | | </view> |
| | | <view class="stats-divider"></view> |
| | | <view class="stats-item"> |
| | | <text class="stats-value">{{completedCount}}</text> |
| | | <text class="stats-label">已完成</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import { request } from '@/common/request.js' |
| | | export default { |
| | | data() { |
| | | return { |
| | | data: '', |
| | | condition: '', |
| | | menuList: [], |
| | | order: '', |
| | | loading: false, |
| | | } |
| | | }, |
| | | computed: { |
| | | // 过滤后的列表(优先显示有剩余数量的) |
| | | filterList() { |
| | | if (!this.condition.trim()) { |
| | | // 排序:有剩余数量的排前面 |
| | | return [...this.menuList].sort((a, b) => { |
| | | if (a.enableQty > 0 && b.enableQty <= 0) return -1; |
| | | if (a.enableQty <= 0 && b.enableQty > 0) return 1; |
| | | return 0; |
| | | }); |
| | | } |
| | | const keyword = this.condition.toLowerCase(); |
| | | return this.menuList.filter(item => { |
| | | return (item.matnr && item.matnr.toLowerCase().includes(keyword)) || |
| | | (item.maktx && item.maktx.toLowerCase().includes(keyword)) || |
| | | (item.batch && item.batch.toLowerCase().includes(keyword)); |
| | | }); |
| | | }, |
| | | // 待处理数量 |
| | | pendingCount() { |
| | | return this.menuList.filter(item => item.enableQty > 0).length; |
| | | }, |
| | | // 已完成数量 |
| | | completedCount() { |
| | | return this.menuList.filter(item => item.enableQty <= 0).length; |
| | | } |
| | | }, |
| | | onLoad() { |
| | | let that = this; |
| | | const eventChannel = this.getOpenerEventChannel(); |
| | | if (eventChannel) { |
| | | eventChannel.on('data', function(data) { |
| | | that.order = data.data; |
| | | that.getOrderNoList(that.order); |
| | | }); |
| | | } |
| | | }, |
| | | onShow() { |
| | | if (this.order) { |
| | | this.getOrderNoList(this.order); |
| | | } |
| | | }, |
| | | methods: { |
| | | // 计算进度 |
| | | getProgress(item) { |
| | | if (!item.anfme || item.anfme === 0) return 0; |
| | | const progress = ((item.anfme - item.enableQty) / item.anfme * 100).toFixed(0); |
| | | return Math.min(100, Math.max(0, progress)); |
| | | }, |
| | | // 搜索 |
| | | async search() { |
| | | if (!this.condition.trim()) { |
| | | this.getOrderNoList(this.order); |
| | | return; |
| | | } |
| | | this.loading = true; |
| | | try { |
| | | const res = await request('/orderDetl/search/pda/auth', { |
| | | condition: this.condition, |
| | | order: this.order.code |
| | | }, 'POST', true); |
| | | |
| | | if (res.code === 200) { |
| | | this.menuList = res.data || []; |
| | | } else if (res.code === 403) { |
| | | uni.showToast({ title: res.msg, icon: "none", position: 'top' }); |
| | | setTimeout(() => { |
| | | uni.reLaunch({ url: '../login/login' }); |
| | | }, 1000); |
| | | } else { |
| | | uni.showToast({ title: res.msg, icon: "none", position: 'top' }); |
| | | } |
| | | } catch (err) { |
| | | // request.js 已经处理了错误提示 |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | // 取消搜索 |
| | | onCancelSearch() { |
| | | this.condition = ''; |
| | | this.getOrderNoList(this.order); |
| | | }, |
| | | // 获取订单明细列表 |
| | | async getOrderNoList(order) { |
| | | if (!order || !order.code) return; |
| | | this.loading = true; |
| | | try { |
| | | const res = await request('/orderOut/detlList', { |
| | | orderNo: order.code |
| | | }, 'GET', true); |
| | | |
| | | if (res.code === 200) { |
| | | this.menuList = res.data || []; |
| | | } else { |
| | | this.menuList = res.data || []; |
| | | } |
| | | } catch (err) { |
| | | // request.js 已经处理了错误提示 |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | // 选择明细进行组托 |
| | | chose(item) { |
| | | if (item.enableQty <= 0) { |
| | | uni.showToast({ title: '该明细已完成', icon: "none", position: 'top' }); |
| | | return; |
| | | } |
| | | let that = this; |
| | | uni.navigateTo({ |
| | | url: "../order/orderPakin2", |
| | | success: function(res) { |
| | | res.eventChannel.emit('orderItem', { |
| | | item: item |
| | | }); |
| | | }, |
| | | events: { |
| | | acceptDataFromOpenedPage: function(data) { |
| | | // 返回后刷新数据 |
| | | }, |
| | | }, |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style> |
| | | /* 引入公共样式 */ |
| | | @import url('@/static/css/common.scss'); |
| | | |
| | | .page-container { |
| | | padding-bottom: 120rpx; |
| | | } |
| | | |
| | | /* 订单头部 */ |
| | | .order-header { |
| | | background: linear-gradient(135deg, #0081ff 0%, #1890ff 100%); |
| | | padding: 16rpx 20rpx; |
| | | } |
| | | |
| | | .header-content { |
| | | background: rgba(255, 255, 255, 0.15); |
| | | border-radius: 10rpx; |
| | | padding: 12rpx 16rpx; |
| | | } |
| | | |
| | | .header-row { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 4rpx 0; |
| | | } |
| | | |
| | | .header-label { |
| | | font-size: 24rpx; |
| | | color: rgba(255, 255, 255, 0.7); |
| | | } |
| | | |
| | | .header-value { |
| | | font-size: 26rpx; |
| | | color: #ffffff; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | /* 搜索栏 */ |
| | | .search-bar { |
| | | padding: 0rpx 8rpx; |
| | | background: #ffffff; |
| | | box-shadow: 0 2rpx 8rpx rgba(0, 129, 255, 0.08); |
| | | } |
| | | |
| | | /* 明细列表 */ |
| | | .detl-list { |
| | | padding: 0 20rpx; |
| | | } |
| | | |
| | | .detl-card { |
| | | background: #ffffff; |
| | | border-radius: 12rpx; |
| | | margin-top: 12rpx; |
| | | box-shadow: 0 2rpx 12rpx rgba(0, 129, 255, 0.08); |
| | | overflow: hidden; |
| | | transition: transform 0.2s ease; |
| | | border: 1rpx solid #e4e7ed; |
| | | } |
| | | |
| | | .detl-card:active { |
| | | transform: scale(0.98); |
| | | } |
| | | |
| | | /* 卡片头部 */ |
| | | .card-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: flex-start; |
| | | padding: 14rpx 16rpx; |
| | | border-bottom: 1rpx solid #f0f0f0; |
| | | } |
| | | |
| | | .mat-info { |
| | | flex: 1; |
| | | padding-right: 12rpx; |
| | | } |
| | | |
| | | .mat-code { |
| | | font-size: 26rpx; |
| | | color: #303133; |
| | | font-weight: 600; |
| | | display: block; |
| | | } |
| | | |
| | | .mat-name { |
| | | font-size: 22rpx; |
| | | color: #909399; |
| | | margin-top: 4rpx; |
| | | display: block; |
| | | } |
| | | |
| | | .qty-badge { |
| | | padding: 4rpx 12rpx; |
| | | border-radius: 16rpx; |
| | | flex-shrink: 0; |
| | | } |
| | | |
| | | .badge-active { |
| | | background: linear-gradient(135deg, #0081ff 0%, #1890ff 100%); |
| | | } |
| | | |
| | | .badge-done { |
| | | background: #e8f5e9; |
| | | } |
| | | |
| | | .qty-text { |
| | | font-size: 20rpx; |
| | | font-weight: 500; |
| | | color: #ffffff; |
| | | } |
| | | |
| | | .badge-done .qty-text { |
| | | color: #28a745; |
| | | } |
| | | |
| | | /* 卡片内容 */ |
| | | .card-body { |
| | | padding: 12rpx 16rpx; |
| | | } |
| | | |
| | | .info-grid { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .info-item { |
| | | width: 50%; |
| | | margin-bottom: 8rpx; |
| | | } |
| | | |
| | | .info-label { |
| | | font-size: 20rpx; |
| | | color: #909399; |
| | | display: block; |
| | | } |
| | | |
| | | .info-value { |
| | | font-size: 24rpx; |
| | | color: #303133; |
| | | font-weight: 500; |
| | | display: block; |
| | | margin-top: 2rpx; |
| | | } |
| | | |
| | | .info-value.highlight { |
| | | color: #0081ff; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | /* 进度条 */ |
| | | .progress-wrap { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-top: 8rpx; |
| | | } |
| | | |
| | | .progress-bar { |
| | | flex: 1; |
| | | height: 8rpx; |
| | | background: #e8e8e8; |
| | | border-radius: 4rpx; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .progress-fill { |
| | | height: 100%; |
| | | background: linear-gradient(90deg, #0081ff 0%, #1890ff 100%); |
| | | border-radius: 4rpx; |
| | | transition: width 0.3s ease; |
| | | } |
| | | |
| | | .progress-text { |
| | | font-size: 20rpx; |
| | | color: #909399; |
| | | margin-left: 12rpx; |
| | | min-width: 50rpx; |
| | | text-align: right; |
| | | } |
| | | |
| | | /* 卡片底部 */ |
| | | .card-footer { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: flex-end; |
| | | padding: 12rpx 16rpx; |
| | | border-top: 1rpx solid #f0f0f0; |
| | | background: #fafafa; |
| | | } |
| | | |
| | | .card-footer-done { |
| | | background: #f0fff4; |
| | | } |
| | | |
| | | .action-text { |
| | | font-size: 24rpx; |
| | | color: #0081ff; |
| | | margin-right: 6rpx; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .done-text { |
| | | font-size: 24rpx; |
| | | color: #28a745; |
| | | margin-right: 6rpx; |
| | | } |
| | | |
| | | /* 空状态 */ |
| | | .empty-state { |
| | | padding: 60rpx 0; |
| | | } |
| | | |
| | | .empty-text { |
| | | margin-top: 20rpx; |
| | | } |
| | | |
| | | /* 统计栏 */ |
| | | .stats-bar { |
| | | position: fixed; |
| | | bottom: 0; |
| | | left: 0; |
| | | right: 0; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-around; |
| | | background: #ffffff; |
| | | padding: 16rpx 0; |
| | | box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.06); |
| | | } |
| | | |
| | | .stats-item { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | flex: 1; |
| | | } |
| | | |
| | | .stats-value { |
| | | font-size: 32rpx; |
| | | color: #303133; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .stats-label { |
| | | font-size: 20rpx; |
| | | color: #909399; |
| | | margin-top: 4rpx; |
| | | } |
| | | |
| | | .stats-divider { |
| | | width: 1rpx; |
| | | height: 50rpx; |
| | | background: #e8e8e8; |
| | | } |
| | | </style> |
| | |
| | | <view class="order-card" v-for="(item,i) in matList" :key="i" @click="toPrint(item)"> |
| | | <!-- 卡片头部 --> |
| | | <view class="card-header"> |
| | | <view class="order-badge" :class="getSettleClass(item.settle)"> |
| | | <text class="badge-text">{{item.settle$ || '未知'}}</text> |
| | | <view class="order-badge" :class="getSettleClass(item.exceStatus)"> |
| | | <text class="badge-text">{{item.exceStatus$ || '未知'}}</text> |
| | | </view> |
| | | <view class="order-no"> |
| | | <text class="order-no-label">单据号</text> |
| | | <text class="order-no-value">{{item.orderNo}}</text> |
| | | <text class="order-no-value">{{item.code}}</text> |
| | | </view> |
| | | </view> |
| | | |
| | |
| | | <view class="info-row"> |
| | | <view class="info-item"> |
| | | <text class="info-label">单据类型</text> |
| | | <text class="info-value">{{item.docType$ || '-'}}</text> |
| | | <text class="info-value">{{item.wkType$ || '-'}}</text> |
| | | </view> |
| | | <!-- <view class="info-item"> |
| | | <text class="info-label">应出数量</text> |
| | | <text class="info-value">{{item.anfme || '-'}}</text> |
| | | </view> --> |
| | | </view> |
| | | <view class="info-row"> |
| | | <view class="info-item"> |
| | | <text class="info-label">应出数量</text> |
| | | <text class="info-value">{{item.anfme || '-'}}</text> |
| | | </view> |
| | | <view class="info-item"> |
| | | <text class="info-label">仓库</text> |
| | | <text class="info-value">{{item.itemName || '-'}}</text> |
| | | <text class="info-label">完成数量</text> |
| | | <text class="info-value">{{item.qty || '-'}}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | |
| | | <!-- 卡片底部 --> |
| | | <view class="card-footer"> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { request } from '@/common/request.js' |
| | | export default { |
| | | data() { |
| | | return { |
| | |
| | | condition: '', |
| | | loading: false, |
| | | curr: 1, |
| | | baseUrl: '', |
| | | token: '', |
| | | limit:5, |
| | | status: 'more', |
| | | contentText: { |
| | | contentdown: '上拉加载更多', |
| | |
| | | } |
| | | }, |
| | | onShow() { |
| | | this.baseUrl = uni.getStorageSync('baseUrl'); |
| | | this.token = uni.getStorageSync('token'); |
| | | // 每次进入页面重新加载 |
| | | this.refreshData(); |
| | | }, |
| | |
| | | this.fetchOrderList(false); |
| | | }, |
| | | // 获取订单列表 |
| | | fetchOrderList(isRefresh) { |
| | | let that = this; |
| | | uni.request({ |
| | | url: that.baseUrl + '/order/pakin/order/list/pda/page/auth', |
| | | data: { |
| | | curr: that.curr, |
| | | limit: 20, |
| | | tagId: that.tagIdNow |
| | | }, |
| | | method: "GET", |
| | | header: { |
| | | 'token': uni.getStorageSync('token'), |
| | | }, |
| | | success(result) { |
| | | var res = result.data; |
| | | if (res.code === 200) { |
| | | let records = res.data.records || []; |
| | | if (records.length > 0) { |
| | | if (isRefresh) { |
| | | that.matList = records; |
| | | } else { |
| | | that.matList = that.matList.concat(records); |
| | | } |
| | | that.curr = that.curr + 1; |
| | | that.status = 'more'; |
| | | async fetchOrderList(isRefresh) { |
| | | try { |
| | | const res = await request('/orderOut/list', { |
| | | curr: this.curr, |
| | | limit: this.limit, |
| | | orderNo: this.condition |
| | | }, 'GET', true); |
| | | |
| | | if (res.code === 200) { |
| | | let records = res.data.records || []; |
| | | if (records.length > 0) { |
| | | if (isRefresh) { |
| | | this.matList = records; |
| | | } else { |
| | | that.status = 'noMore'; |
| | | this.matList = this.matList.concat(records); |
| | | } |
| | | } else if (res.code === 403) { |
| | | uni.showToast({ title: res.msg, icon: "none", position: 'top' }); |
| | | setTimeout(() => { |
| | | uni.reLaunch({ url: '../login/login' }); |
| | | }, 1000); |
| | | this.curr = this.curr + 1; |
| | | this.status = 'more'; |
| | | } else { |
| | | uni.showToast({ title: res.msg, icon: "none", position: 'top' }); |
| | | this.status = 'noMore'; |
| | | } |
| | | }, |
| | | fail(err) { |
| | | uni.showToast({ title: '网络请求失败', icon: "none", position: 'top' }); |
| | | }, |
| | | complete() { |
| | | that.loading = false; |
| | | uni.stopPullDownRefresh(); |
| | | } else if (res.code === 403) { |
| | | uni.showToast({ title: res.msg, icon: "none", position: 'top' }); |
| | | setTimeout(() => { |
| | | uni.reLaunch({ url: '../login/login' }); |
| | | }, 1000); |
| | | } else { |
| | | uni.showToast({ title: res.msg, icon: "none", position: 'top' }); |
| | | } |
| | | }); |
| | | } catch (err) { |
| | | // request.js 已经处理了错误提示 |
| | | } finally { |
| | | this.loading = false; |
| | | uni.stopPullDownRefresh(); |
| | | } |
| | | }, |
| | | // 搜索 |
| | | search() { |
| | | async search() { |
| | | if (!this.condition.trim()) { |
| | | this.refreshData(); |
| | | return; |
| | | } |
| | | let that = this; |
| | | that.loading = true; |
| | | uni.request({ |
| | | url: that.baseUrl + '/order/search/pda/auth', |
| | | data: { |
| | | condition: that.condition |
| | | }, |
| | | method: "GET", |
| | | header: { |
| | | 'token': uni.getStorageSync('token'), |
| | | }, |
| | | success(result) { |
| | | var res = result.data; |
| | | if (res.code === 200) { |
| | | that.matList = res.data || []; |
| | | that.status = 'noMore'; |
| | | } else if (res.code === 403) { |
| | | uni.showToast({ title: res.msg, icon: "none", position: 'top' }); |
| | | setTimeout(() => { |
| | | uni.reLaunch({ url: '../login/login' }); |
| | | }, 1000); |
| | | } else { |
| | | uni.showToast({ title: res.msg, icon: "none", position: 'top' }); |
| | | } |
| | | }, |
| | | fail() { |
| | | uni.showToast({ title: '搜索请求失败', icon: "none", position: 'top' }); |
| | | }, |
| | | complete() { |
| | | that.loading = false; |
| | | this.loading = true; |
| | | try { |
| | | const res = await request('/orderOut/list', { |
| | | curr: this.curr, |
| | | limit: this.limit, |
| | | orderNo: this.condition |
| | | }, 'GET', true); |
| | | |
| | | if (res.code === 200) { |
| | | this.matList = res.data || []; |
| | | this.status = 'noMore'; |
| | | } else if (res.code === 403) { |
| | | uni.showToast({ title: res.msg, icon: "none", position: 'top' }); |
| | | setTimeout(() => { |
| | | uni.reLaunch({ url: '../login/login' }); |
| | | }, 1000); |
| | | } else { |
| | | uni.showToast({ title: res.msg, icon: "none", position: 'top' }); |
| | | } |
| | | }); |
| | | } catch (err) { |
| | | // request.js 已经处理了错误提示 |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | // 取消搜索 |
| | | onCancelSearch() { |
| | |
| | | toPrint(item) { |
| | | let that = this; |
| | | uni.navigateTo({ |
| | | url: "../order/orderDetlList", |
| | | url: "./orderDetlList", |
| | | success: function(res) { |
| | | res.eventChannel.emit('data', { |
| | | data: item |
| | |
| | | |
| | | .page-container { |
| | | min-height: 100vh; |
| | | background: linear-gradient(135deg, #f5f7fa 0%, #e4e8eb 100%); |
| | | background: #f5f7fa; |
| | | padding-bottom: 20rpx; |
| | | } |
| | | |
| | | .search-bar { |
| | | padding: 0rpx 14rpx; |
| | | padding: 0rpx 8rpx; |
| | | background: #ffffff; |
| | | box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08); |
| | | box-shadow: 0 2rpx 12rpx rgba(0, 129, 255, 0.08); |
| | | } |
| | | |
| | | .order-list { |
| | |
| | | background: #ffffff; |
| | | border-radius: 16rpx; |
| | | margin-top: 20rpx; |
| | | box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08); |
| | | box-shadow: 0 4rpx 20rpx rgba(0, 129, 255, 0.1); |
| | | overflow: hidden; |
| | | transition: transform 0.2s ease, box-shadow 0.2s ease; |
| | | border: 1rpx solid #e4e7ed; |
| | | } |
| | | |
| | | .order-card:active { |
| | | transform: scale(0.98); |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.12); |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 129, 255, 0.15); |
| | | } |
| | | |
| | | .card-header { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 24rpx 28rpx; |
| | | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| | | background: linear-gradient(135deg, #0081ff 0%, #1890ff 100%); |
| | | } |
| | | |
| | | .order-badge { |
| | |
| | | margin-bottom: 20upx; |
| | | } |
| | | }
|
| | | } |
| | | }
|
| | | /**
|
| | | * 公共样式 - 基于 agv_start.vue 抽离
|
| | | * 适用于:agv_start.vue, orderPakin2.vue, orderDetlList.vue 等页面
|
| | | */
|
| | |
|
| | | /* ==================== 页面基础样式 ==================== */
|
| | | page {
|
| | | height: 100%;
|
| | | background: #f5f7fa;
|
| | | }
|
| | |
|
| | | .page-container {
|
| | | min-height: 100vh;
|
| | | background: linear-gradient(135deg, #f5f7fa 0%, #e4e8eb 100%);
|
| | | padding-bottom: 110rpx;
|
| | | box-sizing: border-box;
|
| | | }
|
| | |
|
| | | /* ==================== 表单区域样式 ==================== */
|
| | | .form-section {
|
| | | background: #ffffff;
|
| | | padding: 12rpx 20rpx;
|
| | | box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
|
| | | }
|
| | |
|
| | | .form-item {
|
| | | display: flex;
|
| | | align-items: center;
|
| | | padding: 12rpx 0;
|
| | | border-bottom: 1rpx solid #f0f0f0;
|
| | | }
|
| | |
|
| | | .form-item:last-child {
|
| | | border-bottom: none;
|
| | | }
|
| | |
|
| | | .form-label {
|
| | | display: flex;
|
| | | align-items: center;
|
| | | flex-shrink: 0;
|
| | | white-space: nowrap;
|
| | | margin-right: 16rpx;
|
| | | }
|
| | |
|
| | | .label-text {
|
| | | font-size: 26rpx;
|
| | | color: #303133;
|
| | | margin-left: 6rpx;
|
| | | }
|
| | |
|
| | | .form-input-wrap {
|
| | | flex: 1;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | background: #f5f7fa;
|
| | | border-radius: 6rpx;
|
| | | padding: 0 16rpx;
|
| | | height: 60rpx;
|
| | | }
|
| | |
|
| | | .form-input {
|
| | | flex: 1;
|
| | | height: 60rpx;
|
| | | font-size: 26rpx;
|
| | | color: #303133;
|
| | | }
|
| | |
|
| | | /* Picker 样式 */
|
| | | .picker-full {
|
| | | flex: 1;
|
| | | width: 100%;
|
| | | }
|
| | |
|
| | | .picker-value {
|
| | | flex: 1;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | justify-content: space-between;
|
| | | height: 60rpx;
|
| | | font-size: 26rpx;
|
| | | color: #303133;
|
| | | }
|
| | |
|
| | | .picker-value text {
|
| | | flex: 1;
|
| | | }
|
| | |
|
| | | /* ==================== 列表头部样式 ==================== */
|
| | | .list-header {
|
| | | display: flex;
|
| | | justify-content: space-between;
|
| | | align-items: center;
|
| | | padding: 16rpx 20rpx;
|
| | | background: #ffffff;
|
| | | margin-top: 12rpx;
|
| | | box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
|
| | | }
|
| | |
|
| | | .header-left {
|
| | | display: flex;
|
| | | align-items: center;
|
| | | }
|
| | |
|
| | | .header-title {
|
| | | font-size: 28rpx;
|
| | | color: #303133;
|
| | | font-weight: 600;
|
| | | }
|
| | |
|
| | | .count-badge {
|
| | | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| | | border-radius: 16rpx;
|
| | | padding: 2rpx 12rpx;
|
| | | margin-left: 12rpx;
|
| | | }
|
| | |
|
| | | .count-text {
|
| | | font-size: 20rpx;
|
| | | color: #ffffff;
|
| | | font-weight: 500;
|
| | | }
|
| | |
|
| | | /* ==================== 商品卡片样式 ==================== */
|
| | | .list-container {
|
| | | padding: 0 20rpx;
|
| | | }
|
| | |
|
| | | .mat-card {
|
| | | background: #ffffff;
|
| | | border-radius: 12rpx;
|
| | | margin-top: 12rpx;
|
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
| | | overflow: hidden;
|
| | | }
|
| | |
|
| | | .card-top {
|
| | | display: flex;
|
| | | align-items: center;
|
| | | padding: 14rpx 16rpx;
|
| | | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| | | }
|
| | |
|
| | | .card-index {
|
| | | width: 36rpx;
|
| | | height: 36rpx;
|
| | | background: rgba(255, 255, 255, 0.25);
|
| | | border-radius: 50%;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | justify-content: center;
|
| | | font-size: 22rpx;
|
| | | color: #ffffff;
|
| | | font-weight: 600;
|
| | | margin-right: 12rpx;
|
| | | }
|
| | |
|
| | | .mat-code-wrap {
|
| | | flex: 1;
|
| | | }
|
| | |
|
| | | .mat-code {
|
| | | font-size: 26rpx;
|
| | | color: #ffffff;
|
| | | font-weight: 600;
|
| | | }
|
| | |
|
| | | .qty-badge {
|
| | | background: rgba(255, 255, 255, 0.3);
|
| | | padding: 4rpx 14rpx;
|
| | | border-radius: 16rpx;
|
| | | }
|
| | |
|
| | | .qty-text {
|
| | | font-size: 24rpx;
|
| | | color: #ffffff;
|
| | | font-weight: 600;
|
| | | }
|
| | |
|
| | | /* ==================== 卡片内容样式 ==================== */
|
| | | .card-content {
|
| | | padding: 12rpx 16rpx;
|
| | | }
|
| | |
|
| | | .info-row {
|
| | | display: flex;
|
| | | margin-bottom: 8rpx;
|
| | | }
|
| | |
|
| | | .info-row:last-child {
|
| | | margin-bottom: 0;
|
| | | }
|
| | |
|
| | | .info-col {
|
| | | flex: 1;
|
| | | }
|
| | |
|
| | | .info-col.half {
|
| | | width: 50%;
|
| | | flex: none;
|
| | | }
|
| | |
|
| | | .info-label {
|
| | | font-size: 20rpx;
|
| | | color: #909399;
|
| | | display: block;
|
| | | }
|
| | |
|
| | | .info-value {
|
| | | font-size: 24rpx;
|
| | | color: #303133;
|
| | | display: block;
|
| | | margin-top: 2rpx;
|
| | | }
|
| | |
|
| | | .info-value.highlight {
|
| | | color: #667eea;
|
| | | font-weight: 500;
|
| | | }
|
| | |
|
| | | .info-value.qty {
|
| | | font-size: 28rpx;
|
| | | color: #303133;
|
| | | font-weight: 600;
|
| | | }
|
| | |
|
| | | /* ==================== 卡片操作按钮样式 ==================== */
|
| | | .card-actions {
|
| | | display: flex;
|
| | | border-top: 1rpx solid #f0f0f0;
|
| | | }
|
| | |
|
| | | .action-btn {
|
| | | flex: 1;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | justify-content: center;
|
| | | padding: 14rpx 0;
|
| | | }
|
| | |
|
| | | .edit-btn {
|
| | | border-right: 1rpx solid #f0f0f0;
|
| | | }
|
| | |
|
| | | .action-text {
|
| | | font-size: 24rpx;
|
| | | color: #667eea;
|
| | | margin-left: 6rpx;
|
| | | }
|
| | |
|
| | | .delete-text {
|
| | | color: #f56c6c;
|
| | | }
|
| | |
|
| | | /* ==================== 空状态样式 ==================== */
|
| | | .empty-state {
|
| | | display: flex;
|
| | | flex-direction: column;
|
| | | align-items: center;
|
| | | justify-content: center;
|
| | | padding: 80rpx 0;
|
| | | }
|
| | |
|
| | | .empty-text {
|
| | | font-size: 26rpx;
|
| | | color: #909399;
|
| | | margin-top: 16rpx;
|
| | | }
|
| | |
|
| | | .empty-hint {
|
| | | font-size: 22rpx;
|
| | | color: #c0c4cc;
|
| | | margin-top: 8rpx;
|
| | | }
|
| | |
|
| | | .bottom-placeholder {
|
| | | height: 20rpx;
|
| | | }
|
| | |
|
| | | /* ==================== 底部操作栏样式 ==================== */
|
| | | .bottom-bar {
|
| | | position: fixed;
|
| | | bottom: 0;
|
| | | left: 0;
|
| | | right: 0;
|
| | | display: flex;
|
| | | padding: 16rpx 20rpx;
|
| | | background: #ffffff;
|
| | | box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.06);
|
| | | }
|
| | |
|
| | | .btn-reset {
|
| | | display: flex;
|
| | | align-items: center;
|
| | | justify-content: center;
|
| | | width: 160rpx;
|
| | | height: 72rpx;
|
| | | background: #f5f7fa;
|
| | | border-radius: 36rpx;
|
| | | margin-right: 16rpx;
|
| | | }
|
| | |
|
| | | .btn-reset .btn-text {
|
| | | font-size: 26rpx;
|
| | | color: #909399;
|
| | | margin-left: 6rpx;
|
| | | }
|
| | |
|
| | | .btn-submit {
|
| | | flex: 1;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | justify-content: center;
|
| | | height: 72rpx;
|
| | | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| | | border-radius: 36rpx;
|
| | | }
|
| | |
|
| | | .btn-submit .btn-text {
|
| | | font-size: 28rpx;
|
| | | color: #ffffff;
|
| | | font-weight: 500;
|
| | | margin-left: 6rpx;
|
| | | }
|
| | |
|
| | | .btn-disabled {
|
| | | background: #c0c4cc;
|
| | | opacity: 0.6;
|
| | | }
|
| | |
|
| | | /* ==================== 弹窗样式 ==================== */
|
| | | .popup-card {
|
| | | width: 600rpx;
|
| | | background: #ffffff;
|
| | | border-radius: 16rpx;
|
| | | overflow: hidden;
|
| | | }
|
| | |
|
| | | .popup-header {
|
| | | padding: 24rpx;
|
| | | text-align: center;
|
| | | border-bottom: 1rpx solid #f0f0f0;
|
| | | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| | | }
|
| | |
|
| | | .popup-title {
|
| | | font-size: 30rpx;
|
| | | color: #ffffff;
|
| | | font-weight: 600;
|
| | | }
|
| | |
|
| | | .popup-body {
|
| | | padding: 24rpx;
|
| | | }
|
| | |
|
| | | .popup-row {
|
| | | display: flex;
|
| | | align-items: center;
|
| | | margin-bottom: 20rpx;
|
| | | height: 70rpx;
|
| | | }
|
| | |
|
| | | .popup-row:last-child {
|
| | | margin-bottom: 0;
|
| | | }
|
| | |
|
| | | .popup-label {
|
| | | width: 80rpx;
|
| | | font-size: 26rpx;
|
| | | color: #606266;
|
| | | flex-shrink: 0;
|
| | | }
|
| | |
|
| | | .popup-value {
|
| | | flex: 1;
|
| | | height: 70rpx;
|
| | | background: #f5f7fa;
|
| | | border-radius: 8rpx;
|
| | | padding: 0 16rpx;
|
| | | font-size: 26rpx;
|
| | | color: #303133;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | box-sizing: border-box;
|
| | | }
|
| | |
|
| | | .popup-value.disabled {
|
| | | color: #909399;
|
| | | background: #f0f0f0;
|
| | | }
|
| | |
|
| | | .popup-value.input {
|
| | | padding: 0 16rpx;
|
| | | }
|
| | |
|
| | | .popup-value.number {
|
| | | justify-content: center;
|
| | | background: transparent;
|
| | | padding: 0;
|
| | | }
|
| | |
|
| | | .popup-footer {
|
| | | display: flex;
|
| | | border-top: 1rpx solid #f0f0f0;
|
| | | }
|
| | |
|
| | | .popup-btn {
|
| | | flex: 1;
|
| | | height: 90rpx;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | justify-content: center;
|
| | | font-size: 28rpx;
|
| | | }
|
| | |
|
| | | .popup-btn.cancel {
|
| | | color: #909399;
|
| | | border-right: 1rpx solid #f0f0f0;
|
| | | }
|
| | |
|
| | | .popup-btn.confirm {
|
| | | color: #667eea;
|
| | | font-weight: 600;
|
| | | }
|
| | | |