1
This commit is contained in:
parent
4022a1ebcd
commit
9f052c8cc8
@ -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: {
|
||||
// 上传图片到服务器
|
||||
uploadImage() {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
success: async (res) => {
|
||||
const tempFilePaths = res.tempFilePaths[0];
|
||||
this.tempImagePath = tempFilePaths;
|
||||
this.workOrderImg = tempFilePaths;
|
||||
uni.showToast({
|
||||
title: '图片已更换',
|
||||
icon: 'success'
|
||||
// 预览图片
|
||||
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: 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,6 +389,57 @@
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 图片区域优化 */
|
||||
.image-area {
|
||||
@include card;
|
||||
padding: 24rpx;
|
||||
|
||||
.img-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
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: 200rpx;
|
||||
height: 200rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.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;
|
||||
@ -333,129 +456,21 @@
|
||||
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;
|
||||
.upload-btn-container {
|
||||
margin-top: 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
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 {
|
||||
@include card;
|
||||
padding: 24rpx;
|
||||
|
||||
.img-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
border-radius: 8rpx;
|
||||
overflow: hidden;
|
||||
background-color: $bg-color;
|
||||
}
|
||||
|
||||
.work-order-img {
|
||||
width: 100%;
|
||||
border-radius: 8rpx;
|
||||
transition: $transition;
|
||||
// 加载占位效果
|
||||
&:empty {
|
||||
height: 300rpx;
|
||||
background-color: $bg-color;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: $light-text;
|
||||
}
|
||||
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>
|
||||
Loading…
x
Reference in New Issue
Block a user