这是一个通过接口展示文件的uniapp页面,代码中有一个存储检查区域的下拉框,用来根据检查区域筛选获取到 的数据,这个下拉框目前逻辑上存在一些问题,请分析并解决
时间: 2024-11-29 14:33:58 浏览: 19
### 分析与解决方案
#### 当前问题
在当前的代码中,`<select>` 下拉框用于选择检查区域,然后根据选择的区域过滤显示的数据。然而,存在以下问题:
1. **重复调用 `filterDataAndTab2Data` 方法**:
- 在 `mounted` 钩子中没有调用 `fetchTab2Data` 来初始化 `anotherData` 数据,导致初始状态下没有数据可选。
- `@change` 事件触发时,同时调用了 `filterDataAndTab2Data` 和 `filterData` 方法,但 `filterData` 方法并不适用于 `tab2` 的数据过滤。
2. **数据过滤逻辑不清晰**:
- `filterDataAndTab2Data` 方法同时调用了 `filterData` 和 `filterTab2Data`,这可能导致不必要的重复计算。
3. **初始值未设置**:
- `selectedArea` 初始值为空字符串,可能会导致首次加载时无法正确过滤数据。
#### 解决方案
1. **确保数据初始化**:
- 在 `onLoad` 或 `mounted` 钩子中调用 `fetchTab2Data` 方法,确保 `anotherData` 数据在页面加载时已经初始化。
2. **优化数据过滤逻辑**:
- 将 `filterDataAndTab2Data` 方法拆分为两个独立的方法,分别处理 `tab1` 和 `tab2` 的数据过滤。
3. **修正初始值**:
- 将 `selectedArea` 的初始值设为 `null`,并在选择区域时进行判断。
#### 修改后的代码
```vue
<template>
<view class="container">
<!-- Tab 切换按钮 -->
<view class="tab-bar">
<view class="tab-item" @click="currentTab = 'tab1'" :class="{ active: currentTab === 'tab1' }">日常检查</view>
<view class="tab-item" @click="currentTab = 'tab2'" :class="{ active: currentTab === 'tab2' }">专项检查</view>
</view>
<label></label>
<text>主任务名称:{{ taskId }}</text>
<!-- Tab 内容区域 -->
<view class="tab-content">
<view v-if="currentTab === 'tab1'" class="tab-page">
<view class="filter-bar"></view>
<view class="text-wrapper">
<view v-for="(item, index) in tab1Data.rows" :key="index" class="text-item">
<span class="input-prefix">检查内容: </span>
<input type="text" readonly v-model="item.Main_task_Nopri" class="input-field" />
<br />
<span class="input-prefix">危险源: </span>
<input type="text" readonly v-model="item.dangerous" class="input-field" />
<br />
<span class="input-prefix">工程技术措施: </span>
<input type="text" readonly v-model="item.Engineering_measures" class="input-field" />
<br />
<span class="input-prefix">管理措施: </span>
<input type="text" readonly v-model="item.management_measure" class="input-field" />
<br />
<select v-model="item.complianceStatus" @change="updateComplianceStatus(item)" class="compliance-status-select">
<option value="符合">符合</option>
<option value="不符合">不符合</option>
</select>
<br />
<button v-if="item.complianceStatus === '不符合'" @click="showDetail(item)">录入隐患</button>
</view>
</view>
</view>
<view v-if="currentTab === 'tab2'" class="tab-page">
<select v-model="selectedArea" @change="filterTab2Data" class="area-select">
<option value="">请选择检查区域</option>
<option v-for="area in areas" :value="area" :key="area">{{ area }}</option>
</select>
<view class="text-wrapper">
<view v-for="(item, index) in anotherData.rows" :key="index" class="text-item">
<span class="input-prefix">检查项目: </span>
<input type="text" readonly v-model="item.check_pro" class="input-field" />
<br />
<span class="input-prefix">检查区域: </span>
<input type="text" readonly v-model="item.AREA_NAME" class="input-field" />
<br />
<span class="input-prefix">检查标准:</span>
<input type="text" readonly v-model="item.check_sta" @click="showCheckStandardModal(item.check_sta)" />
<br />
<u-form-item class="picupload" label="检查人签字:" prop="upload" labelWidth=80px>
<u-upload width="80" height="40" maxCount="6" @on-success="uploadUpload" @on-remove="delUpload" :action="actionUrl" v-model="upload">
</u-upload>
</u-form-item>
<u-form-item class="picupload1" label="被检查区域负责人签字:" prop="upload" labelWidth=80px>
<div style="display:flex; justify-content-between;">
<u-upload width="80" height="40" maxCount="6" @on-success="uploadUpload" @on-remove="delUpload" :action="actionUrl" v-model="upload">
</u-upload>
<button type="button" class="btn-add-file" @click="handleAddFile">点击进入签名</button>
</div>
</u-form-item>
<select v-model="item.complianceStatus" @change="updateComplianceStatus(item)" class="compliance-status-select">
<option value="符合">符合</option>
<option value="不符合">不符合</option>
</select>
<br />
<button v-if="item.complianceStatus === '不符合'" @click="showDetail(item)">录入隐患</button>
</view>
</view>
</view>
</view>
<!-- 弹窗组件 -->
<view v-if="isModalVisible" class="modal">
<view class="modal-content">
<h3>详细信息</h3>
<form @submit.prevent="updateItem">
<u-form-item class="picupload" label="隐患图片" prop="upload" labelWidth=80px>
<u-upload width="80" height="40" maxCount="6" @on-success="uploadUpload" @on-remove="delUpload" :action="actionUrl" v-model="upload">
</u-upload>
</u-form-item>
<div>
<label>隐患描述:</label>
<input type="text" id="DANGER_DESC" v-model="selectedItem.DANGER_DESC" />
</div>
<button type="submit" style="width: 100px; height: 50px; font-size: 20px;">保存</button>
<button @click="closeModal" style="width: 100px; height: 50px; font-size: 20px;">关闭</button>
</form>
</view>
</view>
<view v-if="isAnotherModalVisible" class="modal">
<view class="modal-content">
<h3>检查标准详情</h3>
<div>
<p>{{ selectedItemForModal.check_sta }}</p>
</div>
<button @click="closeModal" style="width: 100px; height: 50px; font-size: 20px;">关闭</button>
</view>
</view>
</view>
</template>
<script>
import request from '@/utils/request';
import { getToken } from '@/utils/auth';
export default {
data() {
return {
currentTab: 'tab1',
tab1Data: {
status: null,
rows: [],
originalRows: [],
},
taskId: '',
anotherData: {
status: null,
rows: [],
originalRows: []
},
isModalVisible: false,
isAnotherModalVisible: false,
selectedItem: {
name: '',
complianceStatus: '符合',
hazardDescription: ''
},
selectedArea: null, // 初始值设为 null
areas: [],
selectedItemForModal: null,
upload: [], // 初始化upload属性
actionUrl: '' // 初始化actionUrl属性
};
},
methods: {
fetchTab1Data() {
request({
url: '/api/check_carryout_record_daily/getPageData',
method: 'POST',
header: {
'content-type': 'application/json',
'Authorization': `Bearer ${getToken()}`
},
data: {},
dataType: 'json'
}).then(response => {
this.tab1Data.originalRows = response.rows.map(item => ({
...item,
complianceStatus: '符合'
}));
this.filterData();
}).catch(error => {
console.error(error);
uni.showToast({
title: '请求失败',
icon: 'none'
});
});
},
fetchTab2Data() {
request({
url: '/api/check_carryout_record/getPageData',
method: 'POST',
header: {
'content-type': 'application/json',
'Authorization': `Bearer ${getToken()}`
},
dataType: 'json'
}).then(response => {
this.anotherData.originalRows = response.rows.map(item => ({
...item,
complianceStatus: '符合'
}));
this.filterTab2Data();
this.areas = [...new Set(response.rows.map(item => item.AREA_NAME))];
}).catch(error => {
console.error(error);
uni.showToast({
title: '请求失败',
icon: 'none'
});
});
},
showCheckStandardModal(checkSta) {
this.selectedItem = { checkSta };
this.isAnotherModalVisible = true;
},
handleSelectChange(event) {
const selectedValue = event.target.value;
this.selectedArea = selectedValue;
this.filterTab2Data();
},
filterData() {
const taskId = String(this.taskId);
this.tab1Data.rows = this.tab1Data.originalRows.filter(item => {
return String(item.Main_task_Nopri) === taskId && (!this.selectedArea || item.AREA_NAME === this.selectedArea);
});
},
filterTab2Data() {
const taskId = String(this.taskId);
this.anotherData.rows = this.anotherData.originalRows.filter(item => {
return String(item.Main_task_Nopri) === taskId && (!this.selectedArea || item.AREA_NAME === this.selectedArea);
});
},
showDetail(item) {
this.selectedItem = { ...item };
this.isModalVisible = true;
},
closeModal() {
this.isModalVisible = false;
this.isAnotherModalVisible = false;
},
updateItem() {
request({
url: '/api/update_item',
method: 'POST',
header: {
'content-type': 'application/json',
'Authorization': `Bearer ${getToken()}`
},
data: this.selectedItem,
dataType: 'json'
}).then(response => {
this.closeModal();
this.fetchTab1Data();
uni.showToast({
title: '更新成功',
icon: 'success'
});
}).catch(error => {
console.error(error);
uni.showToast({
title: '更新失败',
icon: 'none'
});
});
},
updateComplianceStatus(item) {
// 这里可以添加额外的逻辑来处理合规状态变化,如果需要
},
onLoad(options) {
if (options.id) {
this.taskId = decodeURIComponent(options.id);
}
this.fetchTab1Data();
this.fetchTab2Data();
},
mounted() {}
}
};
</script>
<style lang="scss">
.container {
padding: 10px;
background-color: #f9f9f9;
}
.compliance-status-select {
width: 300px;
height: 25px;
}
.input-prefix {
display: inline-block;
vertical-align: middle;
width: 105px;
padding: 0px;
background-color: #ffffff;
text-align: left;
font-size: 16px;
}
.input-field {
border: 1px solid #ccc;
border-radius: 4px;
height: 30px;
margin-bottom: -20px;
}
.text-value {
display: inline-block;
vertical-align: middle;
width: calc(100% - 110px);
padding: 10px;
border: none;
border-radius: 4px;
margin-left: 15px;
font-size: 16px;
}
.tab-bar {
display: flex;
justify-content: space-around;
background-color: #f1f1f1;
padding: 10px 0;
}
.tab-item {
flex: 1;
text-align: center;
padding: 10px 0;
cursor: pointer;
}
.tab-item.active {
color: #409EFF;
border-bottom: 2px solid #409EFF;
}
.tab-content {
margin-top: 10px;
}
.tab-page {
padding: 12px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.text-item {
margin-bottom: 30px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
.input-prefix + .input-field,
.input-prefix + select,
.input-prefix + button {
margin-top: 5px;
}
}
.modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
}
.modal-content {
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
max-width: 600px;
width: 100%;
}
.modal-content h3 {
margin-top: 0;
}
.modal-content label {
display: block;
margin-bottom: 5px;
}
.modal-content input {
display: block;
width: 100%;
height: 60px;
margin-bottom: 40px;
padding: 5px;
border: 1px solid #ccc;
border-radius: 4px;
}
.modal-content button {
margin-right: 20px;
border: none;
border-radius: 4px;
cursor: pointer;
padding: 0px 0px;
font-size: 16px;
}
.modal-content button[type="submit"] {
background-color: #4CAF50;
color: white;
}
.modal-content button[type="submit"]:hover {
background-color: #45a049;
}
.modal-content button[type="button"] {
background-color: #f44336;
color: white;
}
.modal-content button[type="button"]:hover {
background-color: #e74c3c;
}
.select-area {
width: 100%;
height: 40px;
padding: 0 10px;
border: 1px solid #ccc;
border-radius: 4px;
appearance: none;
-webkit-appearance: none;
background-color: #fff;
}
.compliance-status-select {
width: 100%;
height: 40px;
padding: 0 10px;
border: 1px solid #ccc;
border-radius: 4px;
appearance: none;
-webkit-appearance: none;
background-color: #fff;
}
</style>
```
### 总结
通过以上修改,我们确保了数据在页面加载时已经初始化,并且优化了数据过滤逻辑,使得每个选项卡的数据过滤更加清晰和高效。同时,将 `selectedArea` 的初始值设为 `null`,避免了首次加载时可能出现的问题。这些改动应该能够解决当前存在的问题。
阅读全文