This commit is contained in:
qiuyuan 2025-08-06 18:05:09 +08:00
parent 4022a1ebcd
commit 9f052c8cc8

View File

@ -1,41 +1,5 @@
<template>
<view class="work-order-detail">
<!-- 图片区域 - 编辑状态下可修改 -->
<view class="image-area card">
<view class="img-container">
<!-- 非编辑状态显示服务器图片 -->
<image
class="work-order-img"
:src="`${IMAGE_BASE_URL}${detailObj.images[0]}`"
mode="widthFix"
lazy-load="true"
v-if="!isEditing && detailObj.images && detailObj.images.length > 0"
></image>
<!-- 编辑状态显示本地选择的图片 -->
<image
class="work-order-img"
:src="workOrderImg"
mode="widthFix"
lazy-load="true"
v-if="isEditing && workOrderImg"
></image>
<!-- 没有图片时的占位 -->
<view class="empty-placeholder" v-if="(!detailObj.images || detailObj.images.length === 0) && !isEditing">
<u-icon name="photo" size="48" color="#c0c4cc"></u-icon>
<text class="empty-text">暂无图片</text>
</view>
<!-- 编辑状态的上传按钮 -->
<view class="upload-btn" @click="uploadImage" v-if="isEditing">
<u-icon name="camera" size="28" color="#fff"></u-icon>
<text class="upload-text">{{ workOrderImg ? '更换图片' : '上传图片' }}</text>
</view>
</view>
</view>
<!-- 标题与日期 -->
<view class="title-area card">
<view class="title-wrap">
@ -50,7 +14,6 @@
<view class="content card">
<view class="label">
<view class="label-name">
<!-- <u-icon name="map-marker" size="24" color="#409EFF"></u-icon> -->
<text>工单地点</text>
</view>
<text v-if="!isEditing" style="font-weight: normal;" :class="{empty: !detailObj.address}">{{detailObj.address || '未填写'}}</text>
@ -58,7 +21,6 @@
</view>
<view class="label">
<view class="label-name">
<!-- <u-icon name="user" size="24" color="#409EFF"></u-icon> -->
<text>联系人</text>
</view>
<text v-if="!isEditing" style="font-weight: normal;" :class="{empty: !detailObj.concatName}">{{detailObj.concatName || '未填写'}}</text>
@ -66,7 +28,6 @@
</view>
<view class="label">
<view class="label-name">
<!-- <u-icon name="phone" size="24" color="#409EFF"></u-icon> -->
<text>联系电话</text>
</view>
<text v-if="!isEditing" style="font-weight: normal;" :class="{empty: !detailObj.customerPhone}">{{detailObj.customerPhone || '未填写'}}</text>
@ -74,7 +35,6 @@
</view>
<view class="label label-content">
<view class="label-name">
<!-- <u-icon name="file-text" size="24" color="#409EFF"></u-icon> -->
<text>工单内容</text>
</view>
<text v-if="!isEditing" style="font-weight: normal; white-space: pre-line;" :class="{empty: !detailObj.title}">{{detailObj.title || '未填写'}}</text>
@ -87,6 +47,65 @@
/>
</view>
</view>
<!-- 图片区域 - 支持多张展示和编辑 -->
<view class="image-area card">
<view class="img-container">
<!-- 非编辑状态显示服务器图片 -->
<scroll-view
class="image-scroll"
scroll-x="true"
v-if="!isEditing && detailObj.images && detailObj.images.length > 0"
>
<view class="image-list">
<image
class="work-order-img"
v-for="(img, index) in detailObj.images"
:key="index"
:src="`${IMAGE_BASE_URL}${img}`"
mode="aspectFill"
lazy-load="true"
@click="previewImage(index)"
></image>
</view>
</scroll-view>
<!-- 编辑状态显示本地选择的图片 -->
<scroll-view
class="image-scroll"
scroll-x="true"
v-if="isEditing && localImages.length > 0"
>
<view class="image-list">
<view class="image-item" v-for="(img, index) in localImages" :key="index">
<image
class="work-order-img"
:src="img"
mode="aspectFill"
lazy-load="true"
></image>
<view class="delete-btn" @click="removeImage(index)">
<u-icon name="close" size="20" color="#fff"></u-icon>
</view>
</view>
</view>
</scroll-view>
<!-- 没有图片时的占位 -->
<view class="empty-placeholder" v-if="(!detailObj.images || detailObj.images.length === 0) && !isEditing">
<u-icon name="photo" size="48" color="#c0c4cc"></u-icon>
<text class="empty-text">暂无图片</text>
</view>
<!-- 编辑状态的上传按钮 -->
<view class="upload-btn-container" v-if="isEditing">
<view class="upload-btn" @click="uploadImage">
<u-icon name="camera" size="28" color="#fff"></u-icon>
<text class="upload-text">{{ localImages.length > 0 ? '添加更多' : '上传图片' }}</text>
</view>
<text class="upload-tip" v-if="localImages.length > 0">最多可上传9张</text>
</view>
</view>
</view>
<!-- 操作按钮 -->
<view class="btn-group">
@ -124,44 +143,85 @@
formatTime,
isEditing: false, //
isLoading: false, //
workOrderImg: '', //
localImages: [], //
//
editLabel: '',
editAddress: '',
editTitle: '',
editContactName: '', //
editContactPhone: '', //
editContactName: '',
editContactPhone: '',
detailObj: {},
tempImagePath: '' //
tempImagePaths: [] //
};
},
mounted() {
let obj = uni.getStorageSync("Detail");
this.detailObj = {...obj};
this.workOrderImg = `${IMAGE_BASE_URL}${this.detailObj.images[0]}`;
//
if (this.detailObj.images && this.detailObj.images.length > 0) {
this.localImages = this.detailObj.images.map(img => `${IMAGE_BASE_URL}${img}`);
}
//
this.editContactName = this.detailObj.concatName || '';
this.editContactPhone = this.detailObj.customerPhone || '';
},
methods: {
//
//
previewImage(index) {
uni.previewImage({
current: index,
urls: this.detailObj.images.map(img => `${IMAGE_BASE_URL}${img}`)
});
},
//
uploadImage() {
const maxCount = 9 - this.localImages.length;
if (maxCount <= 0) {
uni.showToast({
title: '最多只能上传9张图片',
icon: 'none'
});
return;
}
uni.chooseImage({
count: 1,
success: async (res) => {
const tempFilePaths = res.tempFilePaths[0];
this.tempImagePath = tempFilePaths;
this.workOrderImg = tempFilePaths;
uni.showToast({
title: '图片已更换',
icon: 'success'
});
count: maxCount,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
this.tempImagePaths = [...this.tempImagePaths, ...res.tempFilePaths];
this.localImages = [...this.localImages, ...res.tempFilePaths];
}
});
},
//
removeImage(index) {
this.localImages.splice(index, 1);
// tempImagePaths
if (index >= this.localImages.length - this.tempImagePaths.length) {
this.tempImagePaths.splice(index - (this.localImages.length - this.tempImagePaths.length), 1);
}
},
//
async uploadImageToServer(filePath) {
async uploadImagesToServer() {
const uploadedPaths = [];
for (const filePath of this.tempImagePaths) {
try {
const path = await this.uploadSingleImage(filePath);
uploadedPaths.push(path);
} catch (error) {
console.error('图片上传失败:', error);
throw error;
}
}
return uploadedPaths;
},
//
uploadSingleImage(filePath) {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: `${BASE_URL}/api/v1/upload`,
@ -174,7 +234,7 @@
try {
const res = JSON.parse(uploadRes.data);
if (res && res.success) {
resolve(res.data); //
resolve(res.data);
} else {
reject(new Error(res.message || '上传失败'));
}
@ -207,9 +267,16 @@
let images = this.detailObj.images;
//
if (this.tempImagePath) {
const uploadedPath = await this.uploadImageToServer(this.tempImagePath);
images = [uploadedPath]; //
if (this.tempImagePaths.length > 0) {
const uploadedPaths = await this.uploadImagesToServer();
//
const originalPaths = this.localImages
.filter(img => img.startsWith(IMAGE_BASE_URL))
.map(img => img.replace(IMAGE_BASE_URL, ''));
images = [...originalPaths, ...uploadedPaths];
} else if (this.localImages.length === 0) {
//
images = [];
}
const requestData = {
@ -218,8 +285,8 @@
title: this.editTitle,
images: images,
status: 1,
concatName: this.editContactName, //
customerPhone: this.editContactPhone //
concatName: this.editContactName,
customerPhone: this.editContactPhone
};
const res = await put(`/api/v1/app_auth/work-order/${this.detailObj.id}`, requestData);
@ -237,7 +304,7 @@
});
this.isEditing = false;
this.tempImagePath = ''; //
this.tempImagePaths = []; //
} else {
uni.showToast({
title: res.message || '修改失败',
@ -259,9 +326,14 @@
// /
async handleWithdraw() {
if (this.isEditing) {
//
//
this.isEditing = false;
this.tempImagePath = '';
this.tempImagePaths = [];
if (this.detailObj.images && this.detailObj.images.length > 0) {
this.localImages = this.detailObj.images.map(img => `${IMAGE_BASE_URL}${img}`);
} else {
this.localImages = [];
}
return;
}
@ -286,7 +358,7 @@
<style lang="scss" scoped>
/* 基础变量优化 */
$primary-color: #409EFF; //
$primary-color: #409EFF;
$success-color: #67C23A;
$warning-color: #F56C6C;
$text-color: #303133;
@ -317,102 +389,6 @@
margin-bottom: 0;
}
}
.empty-placeholder {
width: 100%;
height: 300rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #f5f7fa;
border-radius: 8rpx;
.empty-text {
margin-top: 16rpx;
font-size: 28rpx;
color: #909399;
}
}
/* 页面容器 */
.work-order-detail {
background-color: $bg-color;
min-height: 100vh;
padding: 0 30rpx 40rpx;
}
/* 导航栏 */
.navbar {
@include flex-center;
height: 100rpx;
width: 100%;
padding: 0 10rpx;
background: $card-bg;
border-bottom: 1px solid $border-color;
position: sticky;
top: 0;
z-index: 10;
margin-bottom: 24rpx;
.nav-title {
font-size: 36rpx;
color: $text-color;
font-weight: 500;
flex: 1;
text-align: center;
margin-left: -36rpx; //
}
}
/* 头部用户信息 */
.header {
@include card;
display: flex;
align-items: center;
padding: 24rpx 30rpx;
.avatar {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
background-color: $bg-color;
border: 2rpx solid #F0F2F5;
}
.user-info {
margin-left: 24rpx;
flex: 1;
}
.user-name-wrap {
@include flex-center;
margin-bottom: 8rpx;
}
.username {
font-size: 34rpx;
color: $text-color;
font-weight: 500;
}
.status-tag {
margin-left: 12rpx;
height: 40rpx;
line-height: 40rpx;
}
.contact-info {
@include flex-center;
font-size: 28rpx;
}
.info-icon {
margin-right: 6rpx;
}
.user-phone {
color: $subtext-color;
}
}
/* 图片区域优化 */
.image-area {
@ -425,37 +401,76 @@
border-radius: 8rpx;
overflow: hidden;
background-color: $bg-color;
min-height: 200rpx;
}
.image-scroll {
width: 100%;
white-space: nowrap;
}
.image-list {
display: inline-flex;
gap: 16rpx;
}
.image-item {
position: relative;
width: 200rpx;
height: 200rpx;
border-radius: 8rpx;
overflow: hidden;
}
.work-order-img {
width: 100%;
width: 200rpx;
height: 200rpx;
border-radius: 8rpx;
transition: $transition;
//
&:empty {
height: 300rpx;
background-color: $bg-color;
display: flex;
align-items: center;
justify-content: center;
color: $light-text;
}
.delete-btn {
position: absolute;
right: 8rpx;
top: 8rpx;
width: 36rpx;
height: 36rpx;
background: rgba(0, 0, 0, 0.5);
border-radius: 50%;
@include flex-center;
justify-content: center;
}
.empty-placeholder {
width: 100%;
height: 300rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #f5f7fa;
border-radius: 8rpx;
.empty-text {
margin-top: 16rpx;
font-size: 28rpx;
color: #909399;
}
}
.upload-btn-container {
margin-top: 20rpx;
display: flex;
flex-direction: column;
align-items: center;
gap: 10rpx;
}
.upload-btn {
position: absolute;
right: 16rpx;
bottom: 16rpx;
background: rgba(0, 0, 0, 0.5);
padding: 8rpx 16rpx;
background: $primary-color;
padding: 12rpx 24rpx;
border-radius: 24rpx;
@include flex-center;
transition: $transition;
cursor: pointer;
&:hover {
background: rgba(0, 0, 0, 0.7);
}
.upload-text {
color: #fff;
@ -463,9 +478,20 @@
margin-left: 6rpx;
}
}
.upload-tip {
font-size: 24rpx;
color: $light-text;
}
}
/* 其他样式保持不变 */
.work-order-detail {
background-color: $bg-color;
min-height: 100vh;
padding: 0 30rpx 40rpx;
}
/* 标题区域优化 */
.title-area {
@include card;
display: flex;
@ -477,11 +503,6 @@
width: 100%;
}
.title-icon {
margin-right: 12rpx;
flex-shrink: 0;
}
.title {
font-size: 34rpx;
color: $text-color;
@ -495,17 +516,12 @@
padding-top: 4rpx;
}
.date-icon {
margin-right: 6rpx;
}
.date {
font-size: 26rpx;
color: $light-text;
}
}
/* 内容区域优化 */
.content {
@include card;
@ -532,10 +548,6 @@
flex-shrink: 0;
}
.label-name u-icon {
margin-right: 8rpx;
}
& > text {
font-size: 28rpx;
color: $text-color;
@ -583,7 +595,6 @@
}
}
/* 按钮区域优化 */
.btn-group {
display: flex;
gap: 24rpx;
@ -608,28 +619,4 @@
}
}
}
/* 适配小屏幕 */
@media (max-width: 375px) {
$font-base: 28rpx;
.header {
padding: 18rpx;
.avatar {
width: 80rpx;
height: 80rpx;
}
}
.btn-group {
padding: 20rpx 5rpx;
.action-btn {
height: 80rpx;
line-height: 80rpx;
font-size: 28rpx;
}
}
}
</style>