linwenxin 6 ay önce
ebeveyn
işleme
c6e60a5613

+ 224 - 191
src/components/logistics/common-logistics.vue

@@ -1,199 +1,232 @@
 <template>
-	<view class="bg-white">
-		<view class="common-logistics">
-			<view class="logistic-item" v-for="(item,index) in logisticsData" :key="index">
-				<view class="total-wrap" :style="{marginTop: item.isFirstNode ? '22rpx' : '6rpx'}">
-					<view class="item-container">
-						<view class="item-container-left flex flex-direction align-center"
-							:class="[index == 0 ? 'text-1A1A1A' : 'text-808080']">
-							<text class="text-df">{{item.time | dateTommdd}}</text>
-							<text class="text-sm">{{item.time | dateToHHmmss}}</text>
-						</view>
-						<view class="item-container-center">
-							<view class="tag-container">
-								<image v-if="item.isFirstNode && String(item.state) != 'null'" :src="nodeIconUrl(item.state, index)" mode="scaleToFill"></image>
-								<view v-else class="item-tag-container">
-									<image class="item-tag" :src="[index == 0 ? '/static/mine/logistics/active-line-state.png' : '/static/mine/logistics/line-state.png']" mode="scaleToFill"></image>
-								</view>
-							</view>
-							<view class="line-container"
-								:style="{height: item.isFirstNode ? '145rpx' : '88rpx' , paddingTop: item.isFirstNode ? '22rpx': '8rpx'}">
-								<view v-if="index !== logisticsData.length - 1" class="line" :style="{height: item.isFirstNode ? '120rpx':'80rpx'}"></view>
-							</view>
-						</view>
-						<view class="item-container-right" :style="{paddingTop: item.isFirstNode?'0':'8rpx'}">
-							<view v-if="item.isFirstNode" class="item-title text-dm text-bold" :class="[index == 0 ? 'text-1A1A1A' : 'text-808080']">{{item.state | stateFilter}}</view>
-							<view class="item-desc text-dm" :class="[index == 0 ? 'text-1A1A1A' : 'text-999999']" :style="{marginTop: item.isFirstNode ? '10rpx' : '0'}">{{item.context}}</view>
-							<!-- <view class="item-time">{{item.createTime}}</view> -->
-						</view>
-					</view>
-				</view>
-			</view>
-		</view>
-	</view>
+  <view class="bg-white">
+    <view class="common-logistics">
+      <view class="logistic-item" v-for="(item, index) in logisticsData" :key="index">
+        <view class="total-wrap" :style="{ marginTop: item.isFirstNode ? '22rpx' : '6rpx' }">
+          <view class="item-container">
+            <view
+              class="item-container-left flex flex-direction align-center"
+              :class="[index == 0 ? 'text-1A1A1A' : 'text-808080']"
+            >
+              <text class="text-df">{{ item.time | dateTommdd }}</text>
+              <text class="text-sm">{{ item.time | dateToHHmmss }}</text>
+            </view>
+            <view class="item-container-center">
+              <view class="tag-container">
+                <image
+                  v-if="item.isFirstNode && String(item.state) != 'null'"
+                  :src="nodeIconUrl(item.state, index)"
+                  mode="scaleToFill"
+                ></image>
+                <view v-else class="item-tag-container">
+                  <image
+                    class="item-tag"
+                    :src="[
+                      index == 0
+                        ? '/static/mine/logistics/active-line-state.png'
+                        : '/static/mine/logistics/line-state.png'
+                    ]"
+                    mode="scaleToFill"
+                  ></image>
+                </view>
+              </view>
+              <view
+                class="line-container"
+                :style="{
+                  height: item.isFirstNode ? '145rpx' : '88rpx',
+                  paddingTop: item.isFirstNode ? '22rpx' : '8rpx'
+                }"
+              >
+                <view
+                  v-if="index !== logisticsData.length - 1"
+                  class="line"
+                  :style="{ height: item.isFirstNode ? '120rpx' : '80rpx' }"
+                ></view>
+              </view>
+            </view>
+            <view class="item-container-right" :style="{ paddingTop: item.isFirstNode ? '0' : '8rpx' }">
+              <view
+                v-if="item.isFirstNode"
+                class="item-title text-dm text-bold"
+                :class="[index == 0 ? 'text-1A1A1A' : 'text-808080']"
+                >{{ item.state | stateFilter }}</view
+              >
+              <view
+                class="item-desc text-dm"
+                :class="[index == 0 ? 'text-1A1A1A' : 'text-999999']"
+                :style="{ marginTop: item.isFirstNode ? '10rpx' : '0' }"
+                >{{ item.context }}</view
+              >
+              <!-- <view class="item-time">{{item.createTime}}</view> -->
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
 </template>
 
 <script>
-	export default {
-		props: {
-			logisticsData: {
-				type: [Object, Array]
-			}
-		},
-		filters: {
-			stateFilter(val) {
-				const stateMap = {
-					0: '在途',
-					1: '揽收',
-					2: '疑难',
-					3: '签收',
-					4: '退签',
-					5: '派件',
-					6: '退回',
-				}
-				return stateMap[val]
-			},
-		},
-		computed: {
-			nodeIconUrl() {
-				return function(data, isFirstIndex) {
-					// 物流状:0在途,1揽收,2疑难,3签收,4退签,5派件,6退回
-					if (data == 0) {
-						return isFirstIndex === 0 ? '/static/icon/select_1.png' : '/static/icon/select_1.png'
-					} else if (data == 1) {
-						return isFirstIndex === 0 ? '/static/icon/select_1.png' : '/static/icon/select_1.png'
-					} else if (data == 2) {
-						return isFirstIndex === 0 ? '/static/icon/select_1.png' : '/static/icon/select_1.png'
-					} else if (data == 3) {
-						return isFirstIndex === 0 ? '/static/icon/select_1.png' : '/static/icon/select_1.png'
-					} else if (data == 4) {
-						return isFirstIndex === 0 ? '/static/icon/select_1.png' : '/static/icon/select_1.png'
-					} else if (data == 5) {
-						return isFirstIndex === 0 ? '/static/icon/select_1.png' : '/static/icon/select_1.png'
-					} else if (data == 6) {
-						return isFirstIndex === 0 ? '/static/icon/select_1.png' : '/static/icon/select_1.png'
-					}
-				}
-			}
-		}
-	}
+export default {
+  props: {
+    logisticsData: {
+      type: [Object, Array]
+    }
+  },
+  filters: {
+    stateFilter(val) {
+      const stateMap = {
+        0: '在途',
+        1: '揽收',
+        2: '疑难',
+        3: '签收',
+        4: '退签',
+        5: '派件',
+        6: '退回'
+      }
+      return stateMap[val]
+    }
+  },
+  computed: {
+    nodeIconUrl() {
+      return function (data, isFirstIndex) {
+        // 物流状:0在途,1揽收,2疑难,3签收,4退签,5派件,6退回
+        if (data == 0) {
+          return isFirstIndex === 0 ? '/static/icon/select_1.png' : '/static/icon/select_1.png'
+        } else if (data == 1) {
+          return isFirstIndex === 0 ? '/static/icon/select_1.png' : '/static/icon/select_1.png'
+        } else if (data == 2) {
+          return isFirstIndex === 0 ? '/static/icon/select_1.png' : '/static/icon/select_1.png'
+        } else if (data == 3) {
+          return isFirstIndex === 0 ? '/static/icon/select_1.png' : '/static/icon/select_1.png'
+        } else if (data == 4) {
+          return isFirstIndex === 0 ? '/static/icon/select_1.png' : '/static/icon/select_1.png'
+        } else if (data == 5) {
+          return isFirstIndex === 0 ? '/static/icon/select_1.png' : '/static/icon/select_1.png'
+        } else if (data == 6) {
+          return isFirstIndex === 0 ? '/static/icon/select_1.png' : '/static/icon/select_1.png'
+        }
+      }
+    }
+  }
+}
 </script>
 
 <style lang="scss" scoped>
-	@import url("@/components/logistics/main.css");
-	
-	.common-logistics {
-		height: auto;
-		box-sizing: border-box;
-		background: #FFFFFF;
-	}
-
-	.item-container {
-		width: 100%;
-		height: auto;
-		display: flex;
-
-		.item-container-left {
-			width: 120rpx;
-			max-width: 120rpx;
-		}
-
-		.item-container-center {
-			width: 44rpx;
-			height: auto;
-
-			.tag-container {
-				width: 44rpx;
-				height: 44rpx;
-
-				image {
-					width: 44rpx;
-					height: 44rpx;
-					border-radius: 50%;
-				}
-
-				.item-tag-container {
-					width: 44rpx;
-					height: 44rpx;
-					display: flex;
-					justify-content: center;
-					align-items: center;
-
-					.item-tag {
-						width: 14rpx;
-						height: 14rpx;
-						border-radius: 50%;
-					}
-				}
-			}
-
-			.line-container {
-				box-sizing: border-box;
-				width: 44rpx;
-				display: flex;
-				align-items: center;
-				justify-content: center;
-
-				.line {
-					width: 2rpx;
-					background-color: #dcdcdc;
-				}
-			}
-		}
-
-		.item-container-right {
-			width: 510rpx;
-			max-width: 510rpx;
-			box-sizing: border-box;
-			padding: 0 10rpx 0 24rpx;
-
-			.item-title {
-				width: 100%;
-				height: 40rpx;
-				line-height: 44rpx;
-				color: #222;
-				font-size: 28rpx;
-			}
-
-			.item-desc {
-				margin-top: 16rpx;
-				width: 100%;
-				min-height: 30rpx;
-				line-height: 30rpx;
-				word-wrap: break-word;
-				word-break: normal;
-			}
-
-			.item-time {
-				margin-top: 12rpx;
-				width: 100%;
-				height: 34rpx;
-				line-height: 34rpx;
-				font-size: 24rpx;
-			}
-		}
-	}
-
-	.line-state {
-		width: 20rpx;
-		height: 20rpx;
-		border-radius: 50%;
-	}
-
-	.take-space {
-		width: 100%;
-		height: 80rpx;
-	}
-
-	.text-1A1A1A {
-		color: #1A1A1A;
-	}
-
-	.text-999999 {
-		color: #999999;
-	}
-
-	.text-808080 {
-		color: #808080;
-	}
+@import url('@/components/logistics/main.css');
+
+.common-logistics {
+  height: auto;
+  box-sizing: border-box;
+  background: #ffffff;
+}
+
+.item-container {
+  width: 100%;
+  height: auto;
+  display: flex;
+
+  .item-container-left {
+    width: 120rpx;
+    max-width: 120rpx;
+  }
+
+  .item-container-center {
+    width: 44rpx;
+    height: auto;
+
+    .tag-container {
+      width: 44rpx;
+      height: 44rpx;
+
+      image {
+        width: 44rpx;
+        height: 44rpx;
+        border-radius: 50%;
+      }
+
+      .item-tag-container {
+        width: 44rpx;
+        height: 44rpx;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+
+        .item-tag {
+          width: 14rpx;
+          height: 14rpx;
+          border-radius: 50%;
+        }
+      }
+    }
+
+    .line-container {
+      box-sizing: border-box;
+      width: 44rpx;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+
+      .line {
+        width: 2rpx;
+        background-color: #dcdcdc;
+      }
+    }
+  }
+
+  .item-container-right {
+    width: 510rpx;
+    max-width: 510rpx;
+    box-sizing: border-box;
+    padding: 0 10rpx 0 24rpx;
+
+    .item-title {
+      width: 100%;
+      height: 40rpx;
+      line-height: 44rpx;
+      color: #222;
+      font-size: 28rpx;
+    }
+
+    .item-desc {
+      margin-top: 16rpx;
+      width: 100%;
+      min-height: 30rpx;
+      line-height: 30rpx;
+      word-wrap: break-word;
+      word-break: normal;
+    }
+
+    .item-time {
+      margin-top: 12rpx;
+      width: 100%;
+      height: 34rpx;
+      line-height: 34rpx;
+      font-size: 24rpx;
+    }
+  }
+}
+
+.line-state {
+  width: 20rpx;
+  height: 20rpx;
+  border-radius: 50%;
+}
+
+.take-space {
+  width: 100%;
+  height: 80rpx;
+}
+
+.text-1A1A1A {
+  color: #1a1a1a;
+}
+
+.text-999999 {
+  color: #999999;
+}
+
+.text-808080 {
+  color: #808080;
+}
 </style>

+ 232 - 163
src/components/logistics2/common-logistics.vue

@@ -1,173 +1,242 @@
 <template>
-	<view class="bg-white">
-		<view class="common-logistics">
-			<view class="logistic-item" v-for="(item,index) in logisticsData" :key="index">
-				<view class="total-wrap">
-					<view class="item-container">
-						<view class="item-container-center">
-							<view class="tag-container">
-								<view class="item-tag-container">
-									<image class="item-tag" :src="index == 0 ? '/static/mine/logistics/active-line-state.png' : '/static/mine/logistics/line-state.png'" mode="scaleToFill"></image>
-								</view>
-							</view>
-							<view class="line-container" v-if="index !== logisticsData.length - 1">
-								<view class="line"></view>
-							</view>
-						</view>
-						<view class="item-container-right">
-							<view class="item-title text-dm text-bold" :class="index == 0 ? 'text-1A1A1A' : 'text-808080'">{{item.title}}<text>{{item.time}}</text></view>
-							<view class="item-desc text-dm" :class="index == 0 ? 'text-1A1A1A' : 'text-999999'">{{item.content}}</view>
-						</view>
-					</view>
-				</view>
-			</view>
-		</view>
-	</view>
+  <view class="bg-white">
+    <view class="common-logistics">
+      <view class="logistic-item" v-for="(item, index) in logisticsData" :key="index">
+        <view class="total-wrap">
+          <view class="item-container">
+            <view class="item-container-center">
+              <view class="tag-container">
+                <view class="item-tag-container">
+                  <image
+                    class="item-tag"
+                    :src="
+                      index == 0
+                        ? '/static/mine/logistics/active-line-state.png'
+                        : '/static/mine/logistics/line-state.png'
+                    "
+                    mode="scaleToFill"
+                  ></image>
+                </view>
+              </view>
+              <view class="line-container" v-if="index !== logisticsData.length - 1">
+                <view class="line"></view>
+              </view>
+            </view>
+            <view class="item-container-right">
+              <view class="item-title text-dm text-bold" :class="index == 0 ? 'text-1A1A1A' : 'text-808080'"
+                >{{ item.title }}<text>{{ item.time }}</text></view
+              >
+              <view class="item-desc text-dm" :class="index == 0 ? 'text-1A1A1A' : 'text-999999'">
+                {{ item.content }}
+                <text
+                  v-for="(url, index_) in (item.imgSrc || '').split(',').filter(u => u != '')"
+                  :key="index_"
+                  style="margin-left: 10px; color: blue"
+                  @tap="downloadFile(url)"
+                  >{{ `附件${index_ + 1}` }}</text
+                >
+              </view>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
 </template>
 
 <script>
-	export default {
-		props: {
-			logisticsData: {
-				type: [Object, Array]
-			}
-		},
-		filters: {
-
-		},
-		computed: {
-
-		}
-	}
+export default {
+  props: {
+    logisticsData: {
+      type: [Object, Array]
+    }
+  },
+  filters: {},
+  computed: {},
+  methods: {
+    downloadFile(url) {
+      return new Promise((resolve, reject) => {
+        // 提取文件名和类型
+        const filename = url.split('/').pop().split('?')[0] // 获取文件名
+        const fileExtension = filename.split('.').pop().toLowerCase() // 获取文件扩展名
+        // 判断当前平台
+        const platform = uni.getSystemInfoSync().platform
+        // 使用uni.downloadFile进行文件下载
+        uni.downloadFile({
+          url: url,
+          success: res => {
+            if (res.statusCode === 200) {
+              const tempFilePath = res.tempFilePath
+              if (
+                fileExtension === 'jpg' ||
+                fileExtension === 'jpeg' ||
+                fileExtension === 'png' ||
+                fileExtension === 'gif' ||
+                fileExtension === 'mp4'
+              ) {
+                // 下载到相册
+                uni.saveImageToPhotosAlbum({
+                  filePath: tempFilePath,
+                  success: () => {
+                    resolve('Image saved to gallery.')
+                  },
+                  fail: err => {
+                    reject('Failed to save image: ' + err)
+                  }
+                })
+              } else {
+                // 其他类型文件保存到临时文件
+                uni.saveFile({
+                  tempFilePath: tempFilePath,
+                  success: saveRes => {
+                    resolve(saveRes.savedFilePath)
+                  },
+                  fail: err => {
+                    reject('Failed to save file: ' + err)
+                  }
+                })
+              }
+            } else {
+              reject('Download failed: ' + res.statusCode)
+            }
+          },
+          fail: err => {
+            reject('Download error: ' + err)
+          }
+        })
+      })
+    }
+  }
+}
 </script>
 
 <style lang="scss" scoped>
-	@import url("@/components/logistics/main.css");
-
-	.common-logistics {
-		height: auto;
-		box-sizing: border-box;
-		background: #FFFFFF;
-	}
-
-	.item-container {
-		width: 100%;
-		height: auto;
-		display: flex;
-
-		.item-container-left {
-			width: 120rpx;
-			max-width: 120rpx;
-		}
-
-		.item-container-center {
-			width: 44rpx;
-			height: auto;
+@import url('@/components/logistics/main.css');
+
+.common-logistics {
+  height: auto;
+  box-sizing: border-box;
+  background: #ffffff;
+}
+
+.item-container {
+  width: 100%;
+  height: auto;
+  display: flex;
+
+  .item-container-left {
+    width: 120rpx;
+    max-width: 120rpx;
+  }
+
+  .item-container-center {
+    width: 44rpx;
+    height: auto;
+    display: flex;
+    flex-direction: column;
+
+    .tag-container {
+      width: 44rpx;
+      height: 44rpx;
+
+      image {
+        width: 44rpx;
+        height: 44rpx;
+        border-radius: 50%;
+      }
+
+      .item-tag-container {
+        width: 44rpx;
+        height: 44rpx;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+
+        .item-tag {
+          width: 14rpx;
+          height: 14rpx;
+          border-radius: 50%;
+        }
+      }
+    }
+
+    .line-container {
+      flex: 1;
+      box-sizing: border-box;
+      width: 44rpx;
+      height: 100%;
+      min-height: 88rpx;
+      padding-top: 8rpx;
       display: flex;
-      flex-direction: column;
-
-			.tag-container {
-				width: 44rpx;
-				height: 44rpx;
-
-				image {
-					width: 44rpx;
-					height: 44rpx;
-					border-radius: 50%;
-				}
-
-				.item-tag-container {
-					width: 44rpx;
-					height: 44rpx;
-					display: flex;
-					justify-content: center;
-					align-items: center;
-
-					.item-tag {
-						width: 14rpx;
-						height: 14rpx;
-						border-radius: 50%;
-					}
-				}
-			}
-
-			.line-container {
-        flex: 1;
-				box-sizing: border-box;
-				width: 44rpx;
+      align-items: center;
+      justify-content: center;
+
+      .line {
+        width: 2rpx;
         height: 100%;
-        min-height: 88rpx;
-        padding-top: 8rpx;
-				display: flex;
-				align-items: center;
-				justify-content: center;
-
-				.line {
-					width: 2rpx;
-          height: 100%;
-          min-height: 80rpx;
-					background-color: #dcdcdc;
-				}
-			}
-		}
-
-		.item-container-right {
-			flex: 1;
-			box-sizing: border-box;
-			padding: 0 10rpx 12rpx 24rpx;
-
-			.item-title {
-				width: 100%;
-				line-height: 44rpx;
-				color: #333333;
-				font-size: 28rpx;
-        text {
-          font-size: 24rpx;
-          color: $sec-font;
-          margin-left: 12rpx;
-          font-weight: normal;
-        }
-			}
-
-			.item-desc {
-				margin-top: 10rpx;
-				width: 100%;
-				min-height: 30rpx;
-				line-height: 32rpx;
-				word-wrap: break-word;
-				word-break: normal;
-			}
-
-			.item-time {
-				margin-top: 12rpx;
-				width: 100%;
-				height: 34rpx;
-				line-height: 34rpx;
-				font-size: 24rpx;
-			}
-		}
-	}
-
-	.line-state {
-		width: 20rpx;
-		height: 20rpx;
-		border-radius: 50%;
-	}
-
-	.take-space {
-		width: 100%;
-		height: 80rpx;
-	}
-
-	.text-1A1A1A {
-		color: #1A1A1A;
-	}
-
-	.text-999999 {
-		color: #999999;
-	}
-
-	.text-808080 {
-		color: #808080;
-	}
+        min-height: 80rpx;
+        background-color: #dcdcdc;
+      }
+    }
+  }
+
+  .item-container-right {
+    flex: 1;
+    box-sizing: border-box;
+    padding: 0 10rpx 12rpx 24rpx;
+
+    .item-title {
+      width: 100%;
+      line-height: 44rpx;
+      color: #333333;
+      font-size: 28rpx;
+      text {
+        font-size: 24rpx;
+        color: $sec-font;
+        margin-left: 12rpx;
+        font-weight: normal;
+      }
+    }
+
+    .item-desc {
+      margin-top: 10rpx;
+      width: 100%;
+      min-height: 30rpx;
+      line-height: 32rpx;
+      word-wrap: break-word;
+      word-break: normal;
+    }
+
+    .item-time {
+      margin-top: 12rpx;
+      width: 100%;
+      height: 34rpx;
+      line-height: 34rpx;
+      font-size: 24rpx;
+    }
+  }
+}
+
+.line-state {
+  width: 20rpx;
+  height: 20rpx;
+  border-radius: 50%;
+}
+
+.take-space {
+  width: 100%;
+  height: 80rpx;
+}
+
+.text-1A1A1A {
+  color: #1a1a1a;
+}
+
+.text-999999 {
+  color: #999999;
+}
+
+.text-808080 {
+  color: #808080;
+}
 </style>

+ 2 - 1
src/packageWorkorder/pages/orderDetail.vue

@@ -865,7 +865,8 @@ export default {
               return {
                 title: item.type,
                 time: item.createTime,
-                content: item.content
+                content: item.content,
+                imgSrc: item.imgSrc
               }
             })
             this.feedbackList = data