基本功能都已完成

This commit is contained in:
王利强
2026-02-08 09:30:43 +08:00
parent 1ad538f351
commit 721ef0ad54
494 changed files with 6837 additions and 42302 deletions

View File

@@ -25,18 +25,27 @@
<view class="flex justify-end" style="gap: 10rpx;">
<!-- 所有状态都显示查看详情 -->
<button class="round cu-btn lg light bg-blue" @click="details(item)">查看详情</button>
<!-- 待整改待验收显示立即整改 -->
<button v-if="item.statusName === '待整改' || item.statusName === '待验收'"
class="round cu-btn lg light bg-blue" @click="Rectification(item)">立即整改</button>
<!-- 待验收显示立即验收 -->
<button v-if="item.statusName === '待验收'"
<!-- 待整改状态canEdit为true时显示隐患交办和立即整改为false时不显示 -->
<button v-if="item.statusName === '待整改' && item.canEdit"
class="round cu-btn lg light bg-blue" @click="assignHazard(item)">隐患交办</button>
<button v-if="item.statusName === '待整改' && item.canEdit"
class="round cu-btn lg bg-blue" @click="Rectification(item)">立即整改</button>
<!-- 待验收显示编辑整改信息和立即验收 -->
<button v-if="item.statusName === '待验收' && item.canEdit"
class="round cu-btn lg light bg-blue" @click="editRectification(item)">编辑整改信息</button>
<button v-if="item.statusName === '待验收' && canAcceptance"
class="round cu-btn lg bg-blue" @click="acceptance(item)">立即验收</button>
<!-- 待交办显示隐患交办 -->
<button v-if="item.statusName === '待交办'"
class="round cu-btn lg bg-blue" @click="assignHazard(item)">隐患交办</button>
</view>
</view>
<button class="cuIcon-add round bg-blue margin-top-xl" @click="showAddPopup = true">新增</button>
<!-- 固定在底部的悬浮新增按钮 -->
<view class="fixed-add-btn" @click="showAddPopup = true">
<text class="cuIcon-add"></text>
<text>新增</text>
</view>
<!-- 新增弹窗 -->
<u-popup :show="showAddPopup" mode="center" round="20" @close="showAddPopup = false">
@@ -45,7 +54,7 @@
<view class="popup-title text-bold">新增隐患排查</view>
<view class="popup-close" @click="showAddPopup = false">×</view>
</view>
<view class="popup-body">
<scroll-view class="popup-body" scroll-y>
<view class="flex margin-bottom">
<view class="text-gray">隐患图片/视频</view>
<view class="text-red">*</view>
@@ -77,12 +86,22 @@
</view>
<view class="address-box">
<view class="address-input" @tap.stop="chooseLocation">
<text :class="selectedAddress ? '' : 'text-gray'">{{ selectedAddress || '请选择地址' }}</text>
</view>
<up-input class="address-input-wrapper" v-model="selectedAddress" placeholder="请输入地址" border="surround"></up-input>
<button class="btn-address bg-blue" @tap.stop="chooseLocation">选择地址</button>
</view>
<view class="text-gray text-sm margin-top-xs">办公楼3层东侧消防通道生产车间A区设备旁等或点击"选择地址"按钮在地图上选择</view>
<!-- 隐患区域选择 -->
<view class="flex margin-bottom margin-top">
<view class="text-gray">隐患区域</view>
</view>
<view class="select-trigger" @click="showAreaPicker = true">
<view class="select-value" :class="{ 'placeholder': !selectedAreaName }">
{{ selectedAreaName || '请选择隐患区域' }}
</view>
<text class="cuIcon-unfold"></text>
</view>
<view class="flex margin-bottom margin-top">
<view class="text-gray">隐患描述</view>
<view class="text-red">*</view>
@@ -92,13 +111,42 @@
<view class="text-gray margin-bottom margin-top">隐患标签</view>
<up-choose v-model="formData.tagIndex" :options="tagOptions"></up-choose>
<view class="text-gray text-sm">可选择多个相关标签对隐患进行分类</view>
</view>
</scroll-view>
<view class="popup-footer">
<button class="btn-cancel" @click="showAddPopup = false">取消</button>
<button class="btn-confirm bg-blue" @click="handleAdd">确定</button>
</view>
</view>
</u-popup>
<!-- 区域选择弹窗 -->
<u-popup :show="showAreaPicker" mode="bottom" round="20" @close="showAreaPicker = false">
<view class="picker-popup">
<view class="picker-header">
<view class="picker-cancel" @click="showAreaPicker = false">取消</view>
<view class="picker-title">选择隐患区域</view>
<view class="picker-confirm" @click="confirmAreaSelect">确定</view>
</view>
<scroll-view class="picker-body" scroll-y>
<view
v-for="item in areaList"
:key="item.id"
class="picker-item"
:class="{ 'picker-item-active': tempAreaId === item.id }"
@click="tempAreaId = item.id"
>
<view class="flex align-center">
<view class="area-color-dot" :style="{ backgroundColor: item.color }"></view>
<text>{{ item.name }}</text>
</view>
<text v-if="tempAreaId === item.id" class="cuIcon-check text-blue"></text>
</view>
<view v-if="areaList.length === 0" class="text-gray text-center padding">
暂无区域数据
</view>
</scroll-view>
</view>
</u-popup>
</view>
</template>
@@ -120,6 +168,7 @@
getMyHiddenDangerList,
getHiddenDangerLabelList
} from '@/request/api.js'
import { getAreaList } from '@/request/three_one_api/area.js'
import {
baseUrl,
getToken
@@ -127,6 +176,27 @@
// 弹窗控制
const showAddPopup = ref(false);
// 获取用户角色判断是否有验收权限admin或manage才能验收
const userRole = ref('');
const canAcceptance = computed(() => {
return userRole.value === 'admin' || userRole.value === 'manage';
});
// 从storage获取用户信息
const getUserRole = () => {
try {
const userInfoStr = uni.getStorageSync('userInfo');
if (userInfoStr) {
const userInfo = JSON.parse(userInfoStr);
userRole.value = userInfo.role || '';
console.log('当前用户角色:', userRole.value);
}
} catch (error) {
console.error('获取用户信息失败:', error);
}
};
getUserRole();
// 任务相关ID从接口获取
const taskId = ref('');
@@ -173,6 +243,36 @@
// 地址选择 - 调用腾讯地图
const selectedAddress = ref('');
// 区域选择相关
const showAreaPicker = ref(false);
const areaList = ref([]);
const selectedAreaId = ref('');
const selectedAreaName = ref('');
const tempAreaId = ref('');
// 获取区域列表
const fetchAreaList = async () => {
try {
const res = await getAreaList();
if (res.code === 0 && res.data && res.data.records) {
areaList.value = res.data.records;
}
} catch (error) {
console.error('获取区域列表失败:', error);
}
};
fetchAreaList();
// 确认区域选择
const confirmAreaSelect = () => {
if (tempAreaId.value) {
selectedAreaId.value = tempAreaId.value;
const selected = areaList.value.find(item => item.id === tempAreaId.value);
selectedAreaName.value = selected ? selected.name : '';
}
showAreaPicker.value = false;
};
const chooseLocation = () => {
console.log('chooseLocation called');
@@ -180,27 +280,60 @@
showAddPopup.value = false;
setTimeout(() => {
uni.chooseLocation({
success: (res) => {
console.log('选择位置成功:', res);
// 获取选择的位置信息
selectedAddress.value = res.address + (res.name ? `(${res.name})` : '');
lng.value = res.longitude;
lat.value = res.latitude;
// 重新打开弹窗
showAddPopup.value = true;
// 先获取当前位置,再打开地图选择
uni.getLocation({
type: 'gcj02', // 使用国测局坐标系(腾讯地图使用)
success: (locationRes) => {
console.log('获取当前位置成功:', locationRes);
// 使用当前位置作为地图初始中心点
uni.chooseLocation({
latitude: locationRes.latitude,
longitude: locationRes.longitude,
success: (res) => {
console.log('选择位置成功:', res);
// 获取选择的位置信息
selectedAddress.value = res.address + (res.name ? `(${res.name})` : '');
lng.value = res.longitude;
lat.value = res.latitude;
// 重新打开弹窗
showAddPopup.value = true;
},
fail: (err) => {
console.error('选择位置失败:', err);
// 重新打开弹窗
showAddPopup.value = true;
// 用户取消选择不提示
if (err.errMsg && err.errMsg.indexOf('cancel') === -1) {
uni.showToast({
title: '选择位置失败',
icon: 'none'
});
}
}
});
},
fail: (err) => {
console.error('选择位置失败:', err);
// 重新打开弹窗
showAddPopup.value = true;
// 用户取消选择不提示
if (err.errMsg && err.errMsg.indexOf('cancel') === -1) {
uni.showToast({
title: '选择位置失败',
icon: 'none'
});
}
console.error('获取当前位置失败:', err);
// 即使获取位置失败,也打开地图选择(不带初始位置)
uni.chooseLocation({
success: (res) => {
console.log('选择位置成功:', res);
selectedAddress.value = res.address + (res.name ? `(${res.name})` : '');
lng.value = res.longitude;
lat.value = res.latitude;
showAddPopup.value = true;
},
fail: (chooseErr) => {
console.error('选择位置失败:', chooseErr);
showAddPopup.value = true;
if (chooseErr.errMsg && chooseErr.errMsg.indexOf('cancel') === -1) {
uni.showToast({
title: '选择位置失败',
icon: 'none'
});
}
}
});
}
});
}, 300);
@@ -250,19 +383,21 @@
// 构建请求参数
const params = {
title: formData.title, //标题
level: formData.level + 1, // 1.轻微隐患 2.一般隐患 3.重大隐患
lng: lng.value || 0, //经度
lat: lat.value || 0, //纬度
address: selectedAddress.value || '', //详细地址
areaId: selectedAreaId.value || null, //隐患区域ID
description: formData.description || '', //隐患描述
tagId: tagId, //隐患标签ID
taskId: taskId.value, //关联任务ID
checkPointId: checkPointId.value, //关联检查点ID
source: sourceOptions.value[formData.source]?.title || '', //隐患来源(随手拍、企业自查、行业互查、专家诊查)
attachments: attachments, //附件列表(图片/视频)
};
console.log('提交的参数:', params);
//
try {
const res = await addHiddenDanger(params);
@@ -278,6 +413,8 @@
formData.description = '';
formData.tagIndex = 0;
selectedAddress.value = '';
selectedAreaId.value = '';
selectedAreaName.value = '';
fileList1.value = [];
// 刷新隐患列表
fetchHiddenDangerList();
@@ -320,6 +457,7 @@
// 页面显示时刷新列表(从交办、验收页面返回时自动刷新)
onShow(() => {
fetchHiddenDangerList();
});
const details = (item) => {
@@ -332,6 +470,14 @@
url: `/pages/hiddendanger/rectification?hazardId=${item.hazardId}&assignId=${item.assignId}`
})
}
// 编辑整改信息(待验收状态)
const editRectification = (item) => {
uni.navigateTo({
url: `/pages/hiddendanger/rectification?rectifyId=${item.rectifyId}&isEdit=1`
})
}
const acceptance = (item) => {
uni.navigateTo({
url: `/pages/hiddendanger/acceptance?hazardId=${item.hazardId}&assignId=${item.assignId}&rectifyId=${item.rectifyId}`
@@ -476,6 +622,31 @@
.page {
min-height: 100vh;
background: #EBF2FC;
padding-bottom: 120rpx; // 给底部按钮留出空间
}
// 固定在底部的悬浮新增按钮
.fixed-add-btn {
position: fixed;
bottom: 40rpx;
left: 30rpx;
right: 30rpx;
height: 88rpx;
background: linear-gradient(135deg, #667eea 0%, #2668EA 100%);
border-radius: 44rpx;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 32rpx;
font-weight: 500;
box-shadow: 0 8rpx 24rpx rgba(38, 104, 234, 0.4);
z-index: 100;
.cuIcon-add {
margin-right: 10rpx;
font-size: 36rpx;
}
}
.list-list {
@@ -576,18 +747,8 @@
align-items: center;
gap: 20rpx;
.address-input {
.address-input-wrapper {
flex: 1;
background: #fff;
border: 1rpx solid #F6F6F6;
;
border-radius: 8rpx;
padding: 20rpx;
font-size: 26rpx;
color: #333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.btn-address {
@@ -605,6 +766,87 @@
}
}
// 选择器触发器样式
.select-trigger {
display: flex;
align-items: center;
justify-content: space-between;
background: #fff;
border: 1rpx solid #dcdfe6;
border-radius: 8rpx;
padding: 20rpx 24rpx;
.select-value {
flex: 1;
font-size: 28rpx;
color: #333;
&.placeholder {
color: #c0c4cc;
}
}
}
// 选择弹窗样式
.picker-popup {
background: #fff;
.picker-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #eee;
.picker-cancel {
font-size: 28rpx;
color: #999;
}
.picker-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.picker-confirm {
font-size: 28rpx;
color: #2667E9;
}
}
.picker-body {
max-height: 600rpx;
padding: 0 30rpx;
}
.picker-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx 0;
border-bottom: 1rpx solid #f5f5f5;
font-size: 30rpx;
color: #333;
&:last-child {
border-bottom: none;
}
&.picker-item-active {
color: #2667E9;
}
}
}
// 区域颜色圆点
.area-color-dot {
width: 24rpx;
height: 24rpx;
border-radius: 50%;
margin-right: 16rpx;
}
.address-popup {
width: 600rpx;
background: #fff;