2025-04-18 17:23:27 +08:00

743 lines
17 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="containers">
<view class="flex justify-center bg-white" style="padding: 5px;">
<!-- 审核处理 -->
<view class="text-center" style="width: 50%;">
<view class="wztitle" :class="{ active: selectedTab === 'consume' }" @click="selectTab('consume')">
审核处理
</view>
<view class="selectTop" v-if="selectedTab === 'consume'"></view>
</view>
<!-- 上报记录 -->
<view class="text-center" style="width: 50%;">
<view class="wztitle" :class="{ active: selectedTab === 'report' }" @click="selectTab('report')">
上报记录
</view>
<view class="selectTop" v-if="selectedTab === 'report'"></view>
</view>
</view>
<!-- 切换的页面内容 -->
<view>
<view v-show="selectedTab === 'consume'">
<!-- 审核处理的具体内容 -->
<scroll-view scroll-y="true" :style="{ height: (scrollHeight - 190) + 'px', marginTop: '10px' }">
<view class="content">
<view class="card">
<view class="card-header">
<span class="text-red"> *</span>审核结果
</view>
<view class="card-info">
<uni-data-checkbox v-model="baseFormData.result" :localdata="results" />
</view>
</view>
<view class="card">
<view class="card-header flex justify-between">
<view>
<span class="text-red"> *</span>确认故障部件
</view>
<view class="addclass" @click="addFaultyPart">
+添加
</view>
</view>
<view class="card-textart flex flex-wrap">
<view v-for="(part, index) in faultyParts" :key="index" class="">
<view class="card-tag">
{{ part }}
</view>
<view class="close-btn" @click="removeFaultyPart(index)">X</view>
</view>
</view>
</view>
<view class="card">
<view class="card-header">
<span class="text-red"> *</span>选择报修图片
</view>
<view class="card-info">
<view class="example-body">
<uni-file-picker limit="9" @select="selectImg" @delete="delChangeImg"
:value="fileLists"></uni-file-picker>
</view>
</view>
</view>
<view class="card">
<view class="card-header">
<span class="text-red"> *</span>审核备注
</view>
<view class="card-info">
<uni-easyinput type="textarea" v-model="baseFormData.remark" placeholder="请输入备注内容" />
</view>
</view>
</view>
</scroll-view>
<view class="nav-panel">
<view class="warning-message">
<uni-icons type="info" color="#c1c1c1" size="20"></uni-icons>
<span>故障上报属实后车辆不可被用户租用</span>
</view>
<uni-goods-nav :fill="true" :options="[]" :buttonGroup="navButtonGroup"
@buttonClick="navButtonClick" />
</view>
</view>
<view v-show="selectedTab === 'report'">
<view class="">
<view class="query-selector">
<view class="query-option" :class="{ 'query-select': selectedOption === option }"
v-for="(option, index) in options" :key="index" @click="selectOption(option)">
{{ option }}
</view>
</view>
<scroll-view scroll-y="true" :style="{ height: scrollHeight-170 + 'px' }">
<view v-for="(item,index) in dataList" :key="index">
<view style=" margin: 8px; background: #fff; border-radius: 10px; padding: 5px 10px;">
<uni-forms>
<view class="flex justify-between" style="margin: 10px 0px;">
<view class="label">
用户姓名
</view>
<view class="flex justify-between" style="width: 75%;">
<view class="deepBlackBoldText">
{{ item.reportUser }}
</view>
<view v-if="item.mobile" @click="makeACall(item.mobile)">
<text style="font-size: 18px; color: orange;"
class="cuIcon-phone"></text>
</view>
</view>
</view>
<view class="flex justify-between" style="margin: 10px 0px;">
<view class="label">
上报来源
</view>
<view class="deepBlackBoldText" style="width: 75%;">
{{ item.reportSource }}
</view>
</view>
<view class="flex justify-between" style="margin: 10px 0px;">
<view class="label">
订单编号
</view>
<view v-if="item.orderCode" class="flex justify-between" style="width: 75%;">
<view class="deepBlackBoldText">
{{ item.orderCode }}
</view>
<view @click="copyOrderCode(item.orderCode)">
<text style="font-size: 18px; color: orange;"
class="cuIcon-copy"></text>
</view>
</view>
</view>
<view class="flex justify-between" style="margin: 10px 0px;">
<view class="label">
上报时间
</view>
<view class="deepBlackBoldText" style="width: 75%;">
{{ item.reportAt }}
</view>
</view>
<view class="flex justify-between" style="margin: 10px 0px;">
<view class="label">
故障部件
</view>
<view class="deepBlackBoldText" style="width: 75%;">
{{ item.faultPart }}
</view>
</view>
<view class="flex justify-between" style="margin: 10px 0px;">
<view class="label">
故障原因
</view>
<view class="deepBlackBoldText" style="width: 75%;">
{{ item.faultDescription }}
</view>
</view>
<view class="flex justify-between" style="margin: 10px 0px;">
<view class="label">
上报图片
</view>
<view class="deepBlackBoldText" style="width: 75%;">
<uni-file-picker readonly="true" limit="9"
:value="item.reportAttachments"></uni-file-picker>
</view>
</view>
</uni-forms>
</view>
</view>
<view style="height: 10px;">
</view>
</scroll-view>
</view>
</view>
</view>
</view>
<view>
<uni-popup ref="popup" background-color="#fff" :mask-click="false">
<view class="fault-parts-container">
<view class="fault-parts-title">
故障部件
</view>
<view class="flex flex-wrap">
<uni-data-checkbox mode="button" multiple v-model="selectedParts" :localdata="partsList">
</uni-data-checkbox>
</view>
<view class="options-description-title">
选项说明
</view>
<view class="options-description-text">
默认勾选上已经上报的故障部件您可取消勾选或者增加勾选故障部件
</view>
<view class="action-buttons-container flex justify-between">
<button @click="oncancel" style="border: solid 1px;"
class="cu-btn line-blue bg-white text-blue">取消</button>
<button @click="onOk" class="cu-btn bg-blue text-white">完成</button>
</view>
</view>
</uni-popup>
</view>
</template>
<script setup>
import {
ref,
onMounted
} from 'vue';
import * as api from '@/utils/api.js';
import config from '@/utils/config';
import {
onLoad
} from '@dcloudio/uni-app';
const imgPath = config.imgPath;
const selectedParts = ref([])
const options = ref(["全部"]);
const selectedOption = ref("全部");
const bikeCode = ref("")
const partsList = ref([{
text: '车轮',
value: '车轮'
},
{
text: '挡泥板',
value: '挡泥板'
},
{
text: '电池',
value: '电池'
}, {
text: '脚撑',
value: '脚撑'
}, {
text: '开关锁',
value: '开关锁'
}, {
text: '链条',
value: '链条'
}, {
text: '前蹬',
value: '前蹬'
}, {
text: '刹车',
value: '刹车'
}, {
text: '转把',
value: '转把'
}
]) // 用于显示的部件列表)
// 使用ref来声明选中的标签
const selectedTab = ref('consume');
// 切换选中的标签
const selectTab = (tab) => {
selectedTab.value = tab;
};
const popup = ref(null)
// 数据模型
const baseFormData = ref([]);
const results = ref([{
text: '属实',
value: 1
},
{
text: '虚假',
value: 0
}
]);
const navButtonGroup = [{
text: '提交',
backgroundColor: 'rgb(0,120,212)',
color: '#fff'
}];
// 故障部件
const faultyParts = ref([]);
// 获取设备信息
const scrollHeight = ref(null);
const selectOption = (option) => {
selectedOption.value = option;
if (option == "全部") {
dataList.value = dataListAll.value;
} else {
dataList.value = dataListAll.value.filter(item => item.faultPart.includes(option));
}
};
const fileLists = ref([]);
const selectImg = (data) => {
const file = data.tempFiles[0];
api.fileUpload(file).then(res => {
if (res.code == 200) {
fileLists.value.push(res.data)
} else {
if (fileLists.value.length > 0) {
fileLists.value.pop();
} else {
fileLists.value = [];
}
}
});
}
const delChangeImg = (res) => {
const fileUniqueKey = fileLists.value[res.index].fileUniqueKey;
if (!fileLists.value[res.index].nodelete) {
api.callEbikeInfo("deletedFile?fileUniqueKey=" + fileUniqueKey, {}, "get");
}
fileLists.value.splice(res.index, 1);
}
const userInfo = ref(null);
onLoad((options) => {
const systemInfo = uni.getSystemInfoSync();
userInfo.value = uni.getStorageSync('userInfo');
const screenHeight = systemInfo.screenHeight;
const statusBarHeight = systemInfo.statusBarHeight;
scrollHeight.value = screenHeight - statusBarHeight;
bikeCode.value = "250306001002";
showInfo();
})
onMounted(() => {
// 获取设备信息
});
const showInfo = () => {
api.callMaintenanceApi("ebikeFaultreportReview/getInfo?bikeCode=" + bikeCode.value, {}, 'get').then((
res) => {
if (res.code == 200) {
workorderId.value = res.data.reviewId;
loadMoreData();
} else {
loadMoreData();
}
});
}
const workorderId = ref("")
const reportfaults = ref(null);
const dataList = ref([])
const dataListAll = ref([]);
const loadMoreData = () => {
// 组装参数
let params = {}
if (workorderId.value) {
params = {
"bikeCode": bikeCode.value,
"workorderId": workorderId.value
}
} else {
params = {
"bikeCode": bikeCode.value
}
}
api.callMaintenanceApi("ebikeFaultreportReview/userFaultreports", params).then((
res) => {
if (res.code == 200) {
dataListAll.value = res.data;
updateOptions(res.data, options.value);
dataList.value = res.data;
if (!workorderId.value) {
updateOptions(res.data, faultyParts.value);
collectAndSaveImages(res.data);
}
}
});
};
const collectAndSaveImages = (data) => {
data.forEach(res => {
res.reportAttachments.forEach(s => {
s.nodelete = true; // 给每个附件加上 nodelete 属性
});
fileLists.value = fileLists.value.concat(res.reportAttachments); // 合并数组,避免重复赋值
});
}
function updateOptions(dataList, options) {
dataList.forEach(res => {
// 判断 faultPart 是否包含 "|"
if (res.faultPart.includes("|")) {
// 如果包含 "|", 则拆分成数组
const components = res.faultPart.split("|");
// 循环数组
components.forEach(component => {
// 判断 options 数组中是否存在该 component
if (!options.includes(component)) {
// 如果不存在,则添加
options.push(component);
}
});
} else {
// 如果没有 "|", 直接判断是否存在于 options 数组中
if (!options.includes(res.faultPart)) {
// 如果不存在,则添加
options.push(res.faultPart);
}
}
});
}
// 添加故障部件
const addFaultyPart = () => {
// 这里可以修改成你想要添加的部件内容
let data = faultyParts.value;
selectedParts.value = [];
data.forEach(res => {
selectedParts.value.push(res);
})
popup.value.open("center");
};
// 删除故障部件
const removeFaultyPart = (index) => {
faultyParts.value.splice(index, 1);
};
const oncancel = () => {
popup.value.close("center");
}
const navButtonClick = (index, content) => {
uni.showModal({
title: '确认提交',
content: '您确定要进行提交操作吗?',
success: (res) => {
if (res.confirm) {
const params = {
// "reviewId": "string",
"faultParts": faultyParts.value.join("|"),
"result": baseFormData.value.result,
"remark": baseFormData.value.remark,
"bikeCode": bikeCode.value,
// "reviewTime": "string",
"reviewer": userInfo.value.staffId,
// "isDelete": "string",
// "deleteTime": "string",
// "dealState": "string",
"attachmentFiles": fileLists.value,
"faultReports": dataListAll.value
}
api.callMaintenanceApi("ebikeFaultreportReview/save", params).then(res => {
if (res.code == 200) {
uni.showToast({
title: '提交成功',
icon: 'success',
duration: 500
});
setTimeout(() => {
uni.switchTab({
url: "/pages/user/mine/MePage"
})
}, 500);
}
})
} else if (res.cancel) {
console.log('用户取消出库');
}
}
});
}
const onOk = () => {
let data = selectedParts.value;
faultyParts.value = [];
data.forEach(res => {
faultyParts.value.push(res);
})
popup.value.close("center");
}
const maskPhoneNumber = (phoneNumber) => {
if (!phoneNumber) return '';
const firstPart = phoneNumber.substring(0, 3);
const lastPart = phoneNumber.substring(phoneNumber.length - 4);
const maskedPart = '*'.repeat(phoneNumber.length - 7);
return firstPart + maskedPart + lastPart;
}
const makeACall = (phoneNumber) => {
uni.makePhoneCall({
phoneNumber: phoneNumber,
success: () => {},
fail() {}
})
}
const copyOrderCode = (orderCode) => {
uni.setClipboardData({
data: orderCode,
success: () => {
uni.showToast({
title: '复制成功',
icon: 'success'
});
},
fail: (error) => {
uni.showToast({
title: '复制失败',
icon: 'none'
});
}
});
}
</script>
<style scoped>
.containers {
background-color: rgb(241, 241, 241);
}
.selectTop {
width: 20px;
height: 2px;
background-color: rgb(0, 132, 255);
margin-left: 43%;
margin-top: 5px;
border-radius: 2px;
}
.separator {
color: rgb(202, 202, 202);
}
.wztitle {
font-size: 14px;
font-weight: bold;
cursor: pointer;
}
.active {
color: rgb(0, 132, 255);
}
.card-header {
font-size: 14px;
color: #333;
letter-spacing: 2px;
padding: 10px 2px;
}
.card-info {
width: 100%;
margin-top: 2px;
font-size: 16px;
}
.card-info .ride-info {
color: rgb(15, 27, 38);
font-size: 15px;
}
.card-info .ride-info image {
width: 15px;
height: 15px;
margin-right: 5px;
}
.status-tag {
margin-top: 2px;
}
.corui-ride-in-progress {
background-color: rgb(0, 132, 255);
color: #fff;
padding: 4px 10px;
font-size: 12px;
border-radius: 5px;
}
.corui-completed {
background-color: rgb(195, 198, 203);
color: #fff;
padding: 4px 10px;
font-size: 12px;
border-radius: 5px;
}
.corui-processing {
background-color: rgb(218, 102, 17);
color: #fff;
padding: 4px 10px;
font-size: 12px;
border-radius: 5px;
}
.content {
padding-bottom: 70px;
padding: 10px;
background-color: #fff;
}
.card-textart {
padding: 15px 10px;
background-color: rgb(245, 245, 245);
border-radius: 5px;
min-height: 100px;
}
.card-tag {
line-height: 20px;
text-align: center;
margin: -3px 7px;
background-color: white;
border-radius: 5px;
font-size: 12px;
}
.close-btn {
background-color: #000000;
color: white;
border: none;
border-radius: 50%;
width: 12px;
font-size: 8px;
line-height: 12px;
text-align: center;
height: 12px;
cursor: pointer;
margin-left: 58px;
margin-top: -26px;
}
.addclass {
width: 60px;
text-align: center;
font-size: 12px;
height: 24px;
color: rgb(0, 132, 255);
background-color: rgb(239, 248, 255);
line-height: 24px;
border-radius: 5px;
border: solid 1px rgb(0, 132, 255);
letter-spacing: 1px;
}
.fault-parts-container {
width: 280px;
padding: 10px 10px;
border-radius: 10px;
height: auto;
}
.fault-parts-title {
line-height: 30px;
font-weight: bold;
letter-spacing: 2px;
font-size: 15px;
}
.options-description-title {
font-size: 12px;
color: black;
line-height: 30px;
margin-top: 20px;
}
.options-description-text {
color: rgb(122 122 122);
font-size: 10px;
letter-spacing: 1px;
line-height: 16px;
}
.action-buttons-container {
margin-top: 30px;
}
.action-buttons-container button {
width: 48%;
}
.nav-panel {
position: fixed;
bottom: 0rpx;
width: 100%;
padding-bottom: 20px;
background-color: #fff;
z-index: 105;
}
.deepBlackBoldText {
color: rgb(134 134 134);
overflow-wrap: break-word;
font-size: 14px;
line-height: 20px;
}
.uni-card__header {
font-weight: bold;
color: #000000;
font-size: 16px;
}
.label {
width: 25%;
font-size: 14px;
color: black;
}
.query-selector {
margin: 15px 7px 0px 10px;
display: flex;
flex-wrap: wrap;
}
.query-option {
padding: 5px 15px;
font-size: 13px;
font-weight: 400;
background: white;
margin: 5px 5px;
border-radius: 3px;
color: #000000;
}
.query-select {
color: #ffffff;
background: rgb(0, 132, 255);
}
.uni-popup .uni-popup__wrapper {
border-radius: 10px;
}
/* 警告信息样式 */
.warning-message {
display: flex;
align-items: center;
font-size: 12px;
letter-spacing: 1px;
gap: 8px;
color: #c1c1c1;
padding-left: 20px;
padding-top: 10px;
}
</style>