|
|
|
@ -1,54 +1,30 @@ |
|
|
|
<template> |
|
|
|
<view class="checkout-detail-bg"> |
|
|
|
<!-- 房间图片 --> |
|
|
|
<image |
|
|
|
class="room-img" |
|
|
|
src="/static/img/login-top.png" |
|
|
|
mode="aspectFill" |
|
|
|
></image> |
|
|
|
<image class="room-img" :src="roomDetail.roomImg" mode="aspectFill"></image> |
|
|
|
<!-- 基本信息卡片 --> |
|
|
|
<view class="info-card"> |
|
|
|
<view class="info-header"> |
|
|
|
<view class="room-title">2号楼1单元101 房间1</view> |
|
|
|
<view class="room-title">{{ userInfo.roomNamePath }}</view> |
|
|
|
<view class="status-text">待释放</view> |
|
|
|
</view> |
|
|
|
<view class="checkout-date-row">退房日期:2025-05-16</view> |
|
|
|
<view class="checkout-date-row">退房日期:{{ userInfo.checkoutTime }}</view> |
|
|
|
</view> |
|
|
|
<view class="clean-card"> |
|
|
|
<text class="clean-label">房间卫生</text> |
|
|
|
<u-radio-group v-model="roomClean" class="clean-radio-group"> |
|
|
|
<u-radio |
|
|
|
v-for="item in cleanOptions" |
|
|
|
:key="item" |
|
|
|
:label="item" |
|
|
|
:name="item" |
|
|
|
activeColor="#0DC6C6" |
|
|
|
:custom-style="'margin-right: 40rpx;'" |
|
|
|
></u-radio> |
|
|
|
<text class="clean-label">房间卫生<text class="required">*</text></text> |
|
|
|
<u-radio-group v-model="cleaned" class="clean-radio-group"> |
|
|
|
<u-radio v-for="item in cleanOptions" :key="item.value" :label="item.label" :name="item.value" |
|
|
|
activeColor="#0DC6C6" :custom-style="'margin-right: 40rpx;'"></u-radio> |
|
|
|
</u-radio-group> |
|
|
|
</view> |
|
|
|
<!-- 设备检查 --> |
|
|
|
<view class="section-card"> |
|
|
|
<view class="section-title">设备检查</view> |
|
|
|
<view |
|
|
|
v-for="(item, idx) in deviceList" |
|
|
|
:key="item.name" |
|
|
|
class="device-row" |
|
|
|
> |
|
|
|
<text class="device-label">{{ item.name }}</text> |
|
|
|
<u-radio-group |
|
|
|
v-model="item.status" |
|
|
|
placement="row" |
|
|
|
@change="onDeviceChange(idx, $event)" |
|
|
|
> |
|
|
|
<u-radio |
|
|
|
:custom-style="'margin-right:36rpx;'" |
|
|
|
activeColor="#0DC6C6" |
|
|
|
v-for="opt in statusOptions" |
|
|
|
:key="opt" |
|
|
|
:label="opt" |
|
|
|
:name="opt" |
|
|
|
></u-radio> |
|
|
|
<view v-for="(item, idx) in roomDetail.facilitiesCheckResults" :key="item.name" class="device-row"> |
|
|
|
<text class="device-label">{{ item.facilityName }}</text> |
|
|
|
<u-radio-group v-model="item.checkResult" placement="row" @change="onDeviceChange(idx, $event)"> |
|
|
|
<u-radio :custom-style="'margin-right:36rpx;'" activeColor="#0DC6C6" v-for="opt in statusOptions" |
|
|
|
:key="opt.value" :label="opt.label" :name="opt.value"></u-radio> |
|
|
|
</u-radio-group> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
@ -56,48 +32,36 @@ |
|
|
|
<!-- 其他说明 --> |
|
|
|
<view class="section-card"> |
|
|
|
<view class="section-title">其他说明</view> |
|
|
|
<u-textarea |
|
|
|
v-model="value" |
|
|
|
:formatter="formatter" |
|
|
|
ref="textarea" |
|
|
|
placeholder="请输入内容(不超过500字)" |
|
|
|
maxlength="500" |
|
|
|
height="150" |
|
|
|
border="none" |
|
|
|
custom-style="background:#f7f7f7;border-radius:12rpx;padding:16rpx;" |
|
|
|
></u-textarea> |
|
|
|
|
|
|
|
<u-textarea v-model="value" :formatter="formatter" ref="textarea" placeholder="请输入内容(不超过500字)" maxlength="500" |
|
|
|
height="150" border="none" custom-style="background:#f7f7f7;border-radius:12rpx;padding:16rpx;"></u-textarea> |
|
|
|
|
|
|
|
</view> |
|
|
|
<!-- 图片/视频上传区域 --> |
|
|
|
<view class="section-card"> |
|
|
|
<view class="section-title">图片/视频</view> |
|
|
|
<u-upload |
|
|
|
:fileList="fileList" |
|
|
|
@afterRead="afterRead" |
|
|
|
@delete="deletePic" |
|
|
|
multiple |
|
|
|
:maxCount="10" |
|
|
|
accept="image,video" |
|
|
|
uploadIconColor="#12c3c3" |
|
|
|
uploadText="最多10个" |
|
|
|
> |
|
|
|
<!-- #ifdef MP-WEIXIN --> |
|
|
|
<u-upload :fileList="fileList" @afterRead="afterRead" @delete="deletePic" multiple :maxCount="10" |
|
|
|
uploadIconColor="#12c3c3" uploadText="点击上传" :previewImage="true" accept="media"> |
|
|
|
</u-upload> |
|
|
|
<!-- #endif --> |
|
|
|
<!-- #ifdef H5 --> |
|
|
|
<u-upload :fileList="fileList" @afterRead="afterRead" @delete="deletePic" multiple :maxCount="10" |
|
|
|
uploadIconColor="#12c3c3" uploadText="点击上传" :previewImage="true" accept="image/*,video/*"> |
|
|
|
</u-upload> |
|
|
|
<!-- #endif --> |
|
|
|
</view> |
|
|
|
<!-- 提交按钮 --> |
|
|
|
<view class="submit-btn-wrap"> |
|
|
|
<u-button |
|
|
|
type="primary" |
|
|
|
:custom-style="btnStyle" |
|
|
|
shape="circle" |
|
|
|
@click="onSubmit" |
|
|
|
>提交</u-button |
|
|
|
> |
|
|
|
<u-button type="primary" :custom-style="btnStyle" shape="circle" @click="onSubmit">提交</u-button> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
</template> |
|
|
|
|
|
|
|
<script> |
|
|
|
import {getRoomCheckRecDetail,submitCheckout} from "../../../common/api" |
|
|
|
import { getRoomCheckRecDetail, releaseRoom } from "../../../common/api" |
|
|
|
import { |
|
|
|
uploadImage, |
|
|
|
} from "../../../pages/api" |
|
|
|
export default { |
|
|
|
data() { |
|
|
|
return { |
|
|
|
@ -115,46 +79,86 @@ export default { |
|
|
|
{ name: "茶几", status: "完好" }, |
|
|
|
{ name: "桌椅", status: "完好" }, |
|
|
|
], |
|
|
|
statusOptions: ["完好", "破损", "丢失"], |
|
|
|
statusOptions: [{ label: "完好", value: 0 }, { label: "破损", value: 1 }, { label: "丢失", value: 2 }], |
|
|
|
waterMeter: 3245.1, |
|
|
|
electricMeter: 2672.6, |
|
|
|
remark: "", |
|
|
|
value: "", // 其他说明的文本内容 |
|
|
|
fileList: [], |
|
|
|
roomClean: "已打扫", |
|
|
|
cleanOptions: ["已打扫", "未打扫"], |
|
|
|
cleanOptions: [{ label: "已打扫", value: "1" }, { label: "未打扫", value: "0" }], |
|
|
|
cleaned: "1", |
|
|
|
}; |
|
|
|
}, |
|
|
|
onLoad(options) { |
|
|
|
// 获取路由参数 |
|
|
|
console.log(options); |
|
|
|
if (options.roomId) { |
|
|
|
this.roomId = options.roomId; |
|
|
|
this.roomId = Number(options.roomId); |
|
|
|
} |
|
|
|
if (options.userInfo) { |
|
|
|
try { |
|
|
|
this.userInfo = JSON.parse(decodeURIComponent(options.userInfo)); |
|
|
|
this.userInfo = JSON.parse(options.userInfo); |
|
|
|
} catch (e) { |
|
|
|
console.error('解析userInfo失败:', e); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 如果有roomId,则获取房间详情 |
|
|
|
if (this.roomId) { |
|
|
|
this.getRoomDetail(); |
|
|
|
} |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
// 删除文件 |
|
|
|
deletePic(event) { |
|
|
|
this[`fileList${event.name}`].splice(event.index, 1); |
|
|
|
var arry = []; |
|
|
|
this.fileList.filter((v, i) => { |
|
|
|
arry.push(v.url); |
|
|
|
}); |
|
|
|
this.fileList = arry; |
|
|
|
}, |
|
|
|
// 选择文件后上传 |
|
|
|
async afterRead(event) { |
|
|
|
let lists = [].concat(event.file); |
|
|
|
let fileListLen = this[`fileList${event.name}`].length; |
|
|
|
lists.map((item) => { |
|
|
|
this[`fileList${event.name}`].push({ |
|
|
|
...item, |
|
|
|
status: "uploading", |
|
|
|
message: "上传中", |
|
|
|
}); |
|
|
|
}); |
|
|
|
for (let i = 0; i < lists.length; i++) { |
|
|
|
const result = await uploadImage(lists[i].url); |
|
|
|
let item = this[`fileList${event.name}`][fileListLen]; |
|
|
|
|
|
|
|
this[`fileList${event.name}`].splice( |
|
|
|
fileListLen, |
|
|
|
1, |
|
|
|
Object.assign(item, { |
|
|
|
status: "success", |
|
|
|
message: "", |
|
|
|
url: result.url, |
|
|
|
}) |
|
|
|
); |
|
|
|
fileListLen++; |
|
|
|
} |
|
|
|
console.log(this.fileList); |
|
|
|
|
|
|
|
this.fileList = this.fileList.map(v => ({ url: v.url, name: v.name, type: v.type })); |
|
|
|
}, |
|
|
|
// 获取房间详情 |
|
|
|
async getRoomDetail() { |
|
|
|
try { |
|
|
|
uni.showLoading({ |
|
|
|
title: '加载中...' |
|
|
|
}); |
|
|
|
|
|
|
|
console.log(this.roomId); |
|
|
|
const res = await getRoomCheckRecDetail({ |
|
|
|
roomId: this.roomId |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
if (res && res.code === 200) { |
|
|
|
this.roomDetail = res.data || {}; |
|
|
|
// 根据返回的数据更新页面显示 |
|
|
|
@ -175,7 +179,7 @@ export default { |
|
|
|
uni.hideLoading(); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
// 更新页面数据 |
|
|
|
updatePageData() { |
|
|
|
// 根据roomDetail更新页面显示的数据 |
|
|
|
@ -186,26 +190,68 @@ export default { |
|
|
|
// 更新设备列表 |
|
|
|
this.deviceList = this.roomDetail.deviceList; |
|
|
|
} |
|
|
|
if (this.roomDetail.roomClean) { |
|
|
|
this.roomClean = this.roomDetail.roomClean; |
|
|
|
if (this.roomDetail.cleaned) { |
|
|
|
this.cleaned = this.roomDetail.cleaned; |
|
|
|
} |
|
|
|
if (this.roomDetail.remark) { |
|
|
|
this.value = this.roomDetail.remark; |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
onDeviceChange(idx, val) { |
|
|
|
this.deviceList[idx].status = val; |
|
|
|
}, |
|
|
|
afterRead(event) { |
|
|
|
let files = Array.isArray(event) ? event : [event]; |
|
|
|
this.fileList = this.fileList.concat(files); |
|
|
|
this.roomDetail.facilitiesCheckResults[idx].checkResult = val; |
|
|
|
}, |
|
|
|
deletePic(event) { |
|
|
|
this.fileList.splice(event.index, 1); |
|
|
|
}, |
|
|
|
onSubmit() { |
|
|
|
uni.showToast({ title: "提交成功", icon: "success" }); |
|
|
|
async onSubmit() { |
|
|
|
// 必填项验证 |
|
|
|
if (!this.cleaned) { |
|
|
|
uni.showToast({ title: "请选择房间卫生状态", icon: "none" }); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// if (!this.roomDetail.facilitiesCheckResults || this.roomDetail.facilitiesCheckResults.length === 0) { |
|
|
|
// uni.showToast({ title: "请完成设备检查", icon: "none" }); |
|
|
|
// return; |
|
|
|
// } |
|
|
|
|
|
|
|
// 检查设备检查是否都已完成 |
|
|
|
// const unfinishedDevices = this.roomDetail.facilitiesCheckResults.filter(item => |
|
|
|
// item.checkResult === undefined || item.checkResult === null |
|
|
|
// ); |
|
|
|
// if (unfinishedDevices.length > 0) { |
|
|
|
// uni.showToast({ title: "请完成所有设备检查", icon: "none" }); |
|
|
|
// return; |
|
|
|
// } |
|
|
|
|
|
|
|
// if (!this.value || this.value.trim() === '') { |
|
|
|
// uni.showToast({ title: "请输入其他说明", icon: "none" }); |
|
|
|
// return; |
|
|
|
// } |
|
|
|
|
|
|
|
// if (!this.fileList || this.fileList.length === 0) { |
|
|
|
// uni.showToast({ title: "请上传图片或视频", icon: "none" }); |
|
|
|
// return; |
|
|
|
// } |
|
|
|
|
|
|
|
let parm = { |
|
|
|
roomId: this.roomId, |
|
|
|
facilitiesCheckResults: this.roomDetail.facilitiesCheckResults, |
|
|
|
cleaned: this.cleaned, |
|
|
|
facilitiesCheckDesc: this.value, |
|
|
|
facilitiesCheckImages: this.fileList, |
|
|
|
} |
|
|
|
|
|
|
|
const res = await releaseRoom(parm) |
|
|
|
if (res.code === 200) { |
|
|
|
uni.showToast({ title: "提交成功", icon: "success" }); |
|
|
|
setTimeout(() => { |
|
|
|
uni.navigateBack() |
|
|
|
}, 1000); |
|
|
|
} else { |
|
|
|
uni.showToast({ title: res.msg, icon: "none" }); |
|
|
|
} |
|
|
|
}, |
|
|
|
// 文本格式化器 |
|
|
|
formatter(value) { |
|
|
|
@ -221,12 +267,14 @@ export default { |
|
|
|
min-height: 100vh; |
|
|
|
padding-bottom: 40rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.room-img { |
|
|
|
width: 100vw; |
|
|
|
height: 220rpx; |
|
|
|
object-fit: cover; |
|
|
|
display: block; |
|
|
|
} |
|
|
|
|
|
|
|
.info-card { |
|
|
|
background: #fff; |
|
|
|
border-radius: 20rpx; |
|
|
|
@ -234,37 +282,44 @@ export default { |
|
|
|
padding: 24rpx 24rpx 12rpx 24rpx; |
|
|
|
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04); |
|
|
|
} |
|
|
|
|
|
|
|
.info-header { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: space-between; |
|
|
|
} |
|
|
|
|
|
|
|
.room-title { |
|
|
|
font-weight: bold; |
|
|
|
font-size: 32rpx; |
|
|
|
color: #222; |
|
|
|
} |
|
|
|
|
|
|
|
.status-text { |
|
|
|
color: #ffb200; |
|
|
|
font-size: 28rpx; |
|
|
|
font-weight: bold; |
|
|
|
} |
|
|
|
|
|
|
|
.checkout-date-row { |
|
|
|
font-size: 28rpx; |
|
|
|
color: #222; |
|
|
|
margin-top: 18rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.section-card { |
|
|
|
background: #fff; |
|
|
|
border-radius: 20rpx; |
|
|
|
margin: 0 24rpx 16rpx 24rpx; |
|
|
|
padding: 24rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.section-title { |
|
|
|
font-weight: bold; |
|
|
|
font-size: 28rpx; |
|
|
|
margin-bottom: 18rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.device-row { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
@ -272,29 +327,35 @@ export default { |
|
|
|
min-height: 64rpx; |
|
|
|
border-bottom: 1px solid #f2f2f2; |
|
|
|
} |
|
|
|
|
|
|
|
.device-label { |
|
|
|
width: 160rpx; |
|
|
|
color: #222; |
|
|
|
font-size: 28rpx; |
|
|
|
margin-right: 24rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.meter-row { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
margin-bottom: 12rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.meter-label { |
|
|
|
width: 120rpx; |
|
|
|
color: #888; |
|
|
|
font-size: 28rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.u-radio { |
|
|
|
margin-right: 36rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.meter-value { |
|
|
|
color: #222; |
|
|
|
font-size: 28rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.custom-upload-btn { |
|
|
|
width: 160rpx; |
|
|
|
height: 160rpx; |
|
|
|
@ -307,28 +368,33 @@ export default { |
|
|
|
justify-content: center; |
|
|
|
margin: 0 16rpx 0 0; |
|
|
|
} |
|
|
|
|
|
|
|
.upload-tips { |
|
|
|
color: #bbb; |
|
|
|
font-size: 24rpx; |
|
|
|
margin-top: 8rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.u-upload__wrap { |
|
|
|
display: flex; |
|
|
|
flex-wrap: wrap; |
|
|
|
align-items: center; |
|
|
|
} |
|
|
|
|
|
|
|
.u-upload__preview { |
|
|
|
border-radius: 16rpx; |
|
|
|
overflow: hidden; |
|
|
|
margin-right: 16rpx; |
|
|
|
margin-bottom: 16rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.submit-btn-wrap { |
|
|
|
width: 100%; |
|
|
|
display: flex; |
|
|
|
justify-content: center; |
|
|
|
margin: 40rpx 0 0 0; |
|
|
|
} |
|
|
|
|
|
|
|
.clean-card { |
|
|
|
background: #fff; |
|
|
|
border-radius: 16rpx; |
|
|
|
@ -338,6 +404,7 @@ export default { |
|
|
|
margin: 24rpx 24rpx 24rpx 24rpx; |
|
|
|
padding: 24rpx 24rpx 24rpx 24rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.clean-label { |
|
|
|
color: #6a7fa3; |
|
|
|
font-size: 30rpx; |
|
|
|
@ -345,6 +412,12 @@ export default { |
|
|
|
margin-right: 32rpx; |
|
|
|
min-width: 180rpx; |
|
|
|
} |
|
|
|
.required { |
|
|
|
color: #ff4757; |
|
|
|
font-size: 28rpx; |
|
|
|
margin-left: 4rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.clean-radio-group { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
|