Commit e92440fc authored by knight's avatar knight

集运包裹详情

parent 64e10593
......@@ -30,6 +30,7 @@ const languageData = {
msgTitle:'title',
msgContent:'content',
warehouseTitle:'warehouseTitleZh',
companyName:'companyName',
},
'en': {
label: 'labelEn',
......@@ -51,6 +52,7 @@ const languageData = {
msgTitle:'titleEn',
msgContent:'contentEn',
warehouseTitle:'warehouseTitleEn',
companyName:'companyNameEn',
},
'fr': {
label: 'labelFr',
......@@ -72,6 +74,7 @@ const languageData = {
msgTitle:'titleFr',
msgContent:'contentFr',
warehouseTitle:'warehouseTitleFr',
companyName:'companyNameFr',
}
};
......
......@@ -350,6 +350,12 @@
"navigationStyle": "custom"
}
},
{
"path": "pages/cons/detail",
"style": {
"navigationStyle": "custom"
}
},
{
"path": "pages/cons/create",
"style": {
......
......@@ -50,7 +50,7 @@
<radio-group v-model="form.transportId" @change="radioChange">
<label class="from-item-radio" v-for="(item, index) in transportType">
<radio :value="item.value" :checked="parseInt(item.value) === parseInt(form.transportId)" color="#007AFF"/>
{{ item.label }}
{{ item[$lang.label] }}
</label>
</radio-group>
</view>
......@@ -544,9 +544,12 @@ export default {
})
}
// 用户点击确定,停留在当前页面并清空数据
this.form = {...this.initForm};
this.form.consItemVOList = [];
this.pickupPoint = '';
uni.navigateTo({
url: '../cons/create'
})
// this.form = {...this.initForm};
// this.form.consItemVOList = [];
// this.pickupPoint = '';
}
})
} else {
......@@ -568,7 +571,9 @@ export default {
navigateTo(page) {
// 这里添加页面跳转逻辑
uni.navigateTo({
url: '../cons/create'
})
}
},
......
<script setup>
<template>
<view>
<view class="header-toper">
<view class="start-bar"></view>
<view class="header-toper-title">
<image src="../../static/img/back.png" mode="" @click="handleBack"></image>
<text>{{ $lang.lang.cons.packageDetail }}</text>
</view>
</view>
</script>
<view class="container">
<!-- 快递信息 -->
<view class="express-card">
<view>
<text class="express-font">{{ info.express.companyName }}</text>
<text class="status-tag" :class="statusClass" v-if="consStatus">{{ consStatus[info.status].label }}</text>
</view>
<text class="express-no"><span>快递单号:</span>{{ info.expressNo }}</text>
</view>
<template>
<!-- 运输信息区块 -->
<view class="info-card">
<view class="section-title">
<uni-icons type="location" size="16" color="#666"></uni-icons>
<text class="title-text">运输</text>
</view>
<view class="info-item">
<text class="item-label">包裹编号:</text>
<text class="item-value">{{ info.consNum }}</text>
</view>
<view class="info-item">
<text class="item-label">集运仓库:</text>
<text class="item-value">{{ info.startWarehouse.titleZh }}</text>
</view>
<view class="info-item">
<text class="item-label">货运方式:</text>
<text class="item-value" v-if="transportType" >{{ transportType[info.transportId].label }}</text>
</view>
<view class="info-item">
<text class="item-label">提货网点:</text>
<text class="item-value">{{ info.endWarehouse.country.countryTitleZh }}-{{ info.endWarehouse.city.cityTitleZh }}-{{ info.endWarehouse.titleZh }}</text>
</view>
</view>
<!-- 商品信息区块 -->
<view class="info-card">
<view class="section-title">
<uni-icons type="cart" size="16" color="#666"></uni-icons>
<text class="title-text">商品</text>
</view>
<view class="info-item">
<text class="item-label">填单数据:</text>
<text class="item-value">{{ consProductString }}</text>
</view>
<view class="info-item">
<text class="item-label">验货数据:</text>
<text class="item-value" v-if="inspectionData">
{{ inspectionData.inspectionNum }}{{ inspectionData.inspectionWeight }}kg {{ inspectionData.inspectionVolume }}</text>
</view>
<view class="info-item">
<text class="item-label">订单货值:</text>
<text class="item-value highlight">¥{{ info.worth }}</text>
</view>
</view>
<!-- 其他信息区块 -->
<view class="info-card">
<view class="section-title">
<uni-icons type="info" size="16" color="#666"></uni-icons>
<text class="title-text">其他</text>
</view>
<view class="info-item">
<text class="item-label">创 建 人 :</text>
<text class="item-value">{{ info.creatorName }}</text>
</view>
<view class="info-item">
<text class="item-label">创建时间:</text>
<text class="item-value">{{ info.createTime|$parseTime }}</text>
</view>
<view class="info-item remark-item">
<text class="item-label">包裹备注:</text>
<text class="item-value">{{ info.remarks }}</text>
</view>
</view>
<!-- 选项卡 -->
<view class="info-card">
<view type="line">
<view class="uni-padding-wrap">
<uni-segmented-control :current="current" :values="items" style-type="text"
active-color="#007aff" @clickItem="handleSection"/>
</view>
<view class="content">
<view class="goods-table" v-if="current === 0">
<view class="table-header">
<text class="header-cell">序号</text>
<text class="header-cell">品名</text>
<text class="header-cell">验货数据</text>
</view>
<view class="table-row" v-for="(item, index) in info.consItem" :key="index">
<text class="cell">{{ index + 1 }}</text>
<view class="cell" style="width: 100%">
<text>{{item.product.titleZh}}</text>
</view>
<view class="cell">
{{item.quantity}}
</view>
</view>
</view>
<view class="time-line" v-if="current === 1">
<!-- 包裹动态 -->
<view class="step-container">
<view class="step-item active" v-for="(item,index) in info.trackingRecord">
<!-- 第一个节点显示选中 -->
<view class="step-icon" v-if="index === 0">
<uni-icons type="checkmarkempty" color="#fff" size="18"></uni-icons>
</view>
<view class="step-icon pending" v-else>
<uni-icons type="checkbox-filled" color="#999" size="18"></uni-icons>
</view>
<view class="step-content">
<text class="step-title">{{ consStatus[item.status].label }}</text>
<!-- 已转运显示订单号 -->
<text v-if="item.status === 2" style="margin-left: 20upx">订单号:<navigator :url="'/pages/orderInfo/orderInfo?id=' + info.orderId" class="order-link">
{{ info.orderNo }}</navigator></text>
<!-- 已签收显示签收图片按钮 -->
<text v-if="item.status === 1" class="image-link">签收图片</text>
<text class="step-time">{{ item.trackingTime | $parseTime }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<style scoped>
<script>
import {getCons} from "@/api/order/cons";
import lang from "@/common/lang";
export default {
data() {
return {
// 包裹详情数据
info: {
express: {},
endWarehouse: {
country: {},
city: {},
consItem: [], // 确保初始值为数组
},
startWarehouse: {},
},
// 填单数据字符串
consProductString: '',
// 验货数据
inspectionData: null,
// 状态样式(暂时不用)
statusClass: '',
// 集运状态字典值
consStatus: null,
// 运输方式字典值
transportType: null,
// 保存字典值
config:[],
// 选项卡选中值
current: 0,
// 选项卡标题
items: ['验货详情', '包裹动态'],
}
},
onLoad(option) {
// 初始化页面数据
this.initData(option.id);
},
methods: {
async initData(id) {
try {
// 并行请求接口
await Promise.all([
this.getConsData(id),
this.getConsStatus(),
this.getTransportType(),
]);
// 数据加载完成后处理
this.handleConsProduct();
this.handleInspectionData();
this.processConfigData('transportType' )
this.processConfigData('consStatus' )
} catch (error) {
console.error('初始化数据失败:', error);
}
},
/**
* 获取包裹详情
*/
async getConsData(id) {
const res = await getCons({ 'id' : id });
this.info = res.data;
},
/**
* 获取集运状态
*/
async getConsStatus() {
await this.$request.getConfig("cons_status").then(res => {
this.config['consStatus'] = res.data.list;
});
},
/**
* 获取运输方式
*/
async getTransportType() {
await this.$request.getConfig("transport_type").then(res => {
this.config['transportType'] = res.data.list;
});
},
/**
* 把字典值转为键值对形式
*/
processConfigData(target) {
const configMap = {};
this.config[target].forEach(item => {
configMap[item.value] = {
label: item.label || "",
labelEn: item.labelEn || "",
labelFr: item.labelFr || ""
};
});
this[target] = configMap;
},
/**
* 组装填单数据字符串
*/
handleConsProduct() {
const items = this.info?.consItem ?? [];
// 保存填单商品名称和数量
const productStrings = [];
items.forEach(item => {
const title = item.product?.titleZh || '';
const quantity = item.quantity || 0;
productStrings.push(`${title}*${quantity}`);
});
this.consProductString = productStrings.join(' ');
},
/**
* 计算汇总验货数据
*/
handleInspectionData(){
const items = this.info?.consItem || [];
this.inspectionData = items.reduce((acc, item) => {
acc.inspectionNum += item.inspectionNum || 0;
acc.inspectionVolume += item.inspectionVolume || 0;
acc.inspectionWeight += item.inspectionWeight || 0;
return acc;
}, {
inspectionNum: 0,
inspectionVolume: 0,
inspectionWeight: 0,
});
},
/**
* 返回按钮
*/
handleBack() {
uni.navigateTo({ url: '../cons/index' });
},
/**
* 选项卡切换事件
*/
handleSection(e) {
if (this.current !== e.currentIndex) {
this.current = e.currentIndex;
}
},
}
}
</script>
<style>
@import url(../../static/css/cons_detail.css);
</style>
/* 主体内容 */
.container {
margin: 100upx 0 ;
padding: 20rpx;
}
/* 快递信息卡片 */
.express-card {
background: #fff;
border-radius: 12rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.1);
}
/* 快递公司 */
.express-font {
font-size: 34rpx;
font-weight: 500;
color: #333;
}
.status-tag {
margin-left: 20upx;
padding: 8rpx 20rpx;
border-radius: 30rpx;
font-size: 24rpx;
background: #ff9900;
color: #fff;
}
.express-no {
display: block;
margin-top: 20rpx;
color: #666;
font-size: 28rpx;
}
.info-card {
background: #fff;
border-radius: 12rpx;
padding: 30rpx;
margin-bottom: 20rpx;
}
.section-title {
display: flex;
align-items: center;
padding-bottom: 20rpx;
margin-bottom: 20rpx;
border-bottom: 1rpx solid #eee;
}
.title-text {
margin-left: 10rpx;
font-size: 30rpx;
color: #333;
}
.info-item {
display: flex;
margin-bottom: 20rpx;
font-size: 28rpx;
}
.item-label {
width: 180rpx;
color: #666;
}
.item-value {
flex: 1;
color: #333;
}
.highlight {
color: #e4393c;
font-weight: 500;
}
.remark-text {
color: #e4393c;
background: #fff2f0;
padding: 10rpx;
border-radius: 8rpx;
}
/* 选项卡 */
.uni-padding-wrap {
border-bottom:1px solid var(--cdf);
}
.content {
display: flex;
width: 100%;
align-items: center;
/*height: 250upx;*/
text-align: center;
}
/* 选项卡-end */
/*table*/
.goods-table {
background-color: #fff;
width: 100%;
margin-top: 20upx;
border-radius: 10rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}
.table-header, .table-row {
display: flex;
margin-top: 20upx;
border-bottom: 1rpx solid #eee;
}
.header-cell {
flex: 1;
height: 50upx;
font-weight: bold;
text-align: center;
}
.cell {
flex: 1;
font-size: var(--f24);
text-align: center;
display: flex;
align-items: center;
height: 80upx;
justify-content: center;
}
/*table-end*/
/* 步骤条 */
.time-line{
width: 100%;
margin-top: 20upx;
padding-left: 20upx;
}
.card {
background: #fff;
border-radius: 16rpx;
padding: 30rpx;
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.05);
}
.header {
margin-bottom: 40rpx;
border-bottom: 1rpx solid #eee;
padding-bottom: 20rpx;
.order-number {
font-size: 32rpx;
font-weight: 500;
color: #333;
display: block;
margin-bottom: 12rpx;
}
.time {
font-size: 26rpx;
color: #999;
}
}
.step-container {
position: relative;
padding-left: 60rpx;
}
.step-item {
position: relative;
padding: 20rpx 0;
display: flex;
align-items: flex-start;
&::before {
content: '';
position: absolute;
left: 25rpx;
top: 62rpx;
height: calc(100% - 50rpx);
width: 2rpx;
background: #ebedf0;
}
&:last-child::before {
display: none;
}
}
.step-icon {
width: 48rpx;
height: 48rpx;
border-radius: 50%;
background: #07c160;
display: flex;
align-items: center;
justify-content: center;
position: relative;
z-index: 1;
margin-right: 30rpx;
&.pending {
background: #fff;
border: 2rpx solid #ddd;
}
}
.step-content {
text-align: left;
.step-title {
font-size: 30rpx;
color: #333;
/*display: block;*/
margin-bottom: 8rpx;
}
.image-link {
color: #007aff;
font-size: 26rpx;
margin-left: 10upx;
padding: 8rpx 16rpx;
border-radius: 8rpx;
background: rgba(0,122,255,0.1);
}
.order-link{
display: inline-block;
border-radius: 4px;
color: #007aff;
text-decoration: none;
transition: all 0.3s;
}
.step-time {
font-size: 26rpx;
color: #999;
display: block;
}
}
.extra-info {
display: flex;
align-items: center;
justify-content: space-between;
}
/* 步骤条-end */
export default {
"myCons": "我的集运",
"packageDetail": "包裹详情",
"myConsPackage": "我的集运包裹",
"address": "专属地址",
"turnOnWaitConfirm": "转运待确认",
......
## 1.2.3(2024-04-02)
- 修复 修复在微信小程序下inactiveColor失效bug
## 1.2.2(2024-03-28)
- 修复 在vue2下:style动态绑定导致编译失败的bug
## 1.2.1(2024-03-20)
- 新增 inActiveColor属性,可供配置未激活时的颜色
## 1.2.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-segmented-control](https://uniapp.dcloud.io/component/uniui/uni-segmented-control)
## 1.1.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.5(2021-05-12)
- 新增 项目示例地址
## 1.0.4(2021-02-05)
- 调整为uni_modules目录规范
<template>
<view :class="[styleType === 'text'?'segmented-control--text' : 'segmented-control--button' ]"
:style="{ borderColor: styleType === 'text' ? '' : activeColor }" class="segmented-control">
<view v-for="(item, index) in values" :class="[styleType === 'text' ? '' : 'segmented-control__item--button',
index === 0 && styleType === 'button' ? 'segmented-control__item--button--first' : '',
index === values.length - 1 && styleType === 'button' ? 'segmented-control__item--button--last':'']" :key="index"
:style="{backgroundColor: index === currentIndex && styleType === 'button' ? activeColor : styleType === 'button' ?inActiveColor:'transparent', borderColor: index === currentIndex && styleType === 'text' || styleType === 'button' ? activeColor : inActiveColor}"
class="segmented-control__item" @click="_onClick(index)">
<view>
<text
:style="{color:index === currentIndex? styleType === 'text'? activeColor: '#fff': styleType === 'text'? '#000': activeColor}"
class="segmented-control__text"
:class="styleType === 'text' && index === currentIndex ? 'segmented-control__item--text': ''">{{ item }}</text>
</view>
</view>
</view>
</template>
<script>
/**
* SegmentedControl 分段器
* @description 用作不同视图的显示
* @tutorial https://ext.dcloud.net.cn/plugin?id=54
* @property {Number} current 当前选中的tab索引值,从0计数
* @property {String} styleType = [button|text] 分段器样式类型
* @value button 按钮类型
* @value text 文字类型
* @property {String} activeColor 选中的标签背景色与边框颜色
* @property {String} inActiveColor 未选中的标签背景色与边框颜色
* @property {Array} values 选项数组
* @event {Function} clickItem 组件触发点击事件时触发,e={currentIndex}
*/
export default {
name: 'UniSegmentedControl',
emits: ['clickItem'],
props: {
current: {
type: Number,
default: 0
},
values: {
type: Array,
default () {
return []
}
},
activeColor: {
type: String,
default: '#2979FF'
},
inActiveColor: {
type: String,
default: 'transparent'
},
styleType: {
type: String,
default: 'button'
}
},
data() {
return {
currentIndex: 0
}
},
watch: {
current(val) {
if (val !== this.currentIndex) {
this.currentIndex = val
}
}
},
computed: {},
created() {
this.currentIndex = this.current
},
methods: {
_onClick(index) {
if (this.currentIndex !== index) {
this.currentIndex = index
this.$emit('clickItem', {
currentIndex: index
})
}
}
}
}
</script>
<style lang="scss" scoped>
.segmented-control {
/* #ifndef APP-NVUE */
display: flex;
box-sizing: border-box;
/* #endif */
flex-direction: row;
height: 36px;
overflow: hidden;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.segmented-control__item {
/* #ifndef APP-NVUE */
display: inline-flex;
box-sizing: border-box;
/* #endif */
position: relative;
flex: 1;
justify-content: center;
align-items: center;
}
.segmented-control__item--button {
border-style: solid;
border-top-width: 1px;
border-bottom-width: 1px;
border-right-width: 1px;
border-left-width: 0;
}
.segmented-control__item--button--first {
border-left-width: 1px;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
.segmented-control__item--button--last {
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
.segmented-control__item--text {
border-bottom-style: solid;
border-bottom-width: 2px;
padding: 6px 0;
}
.segmented-control__text {
font-size: 14px;
line-height: 20px;
text-align: center;
}
</style>
{
"id": "uni-segmented-control",
"displayName": "uni-segmented-control 分段器",
"version": "1.2.3",
"description": "分段器由至少 2 个分段控件组成,用作不同视图的显示",
"keywords": [
"uni-ui",
"uniui",
"分段器",
"segement",
"顶部选择"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
\ No newline at end of file
## SegmentedControl 分段器
> **组件名:uni-segmented-control**
> 代码块: `uSegmentedControl`
用作不同视图的显示
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-segmented-control)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment