Files
threeonecheck_web/pages/hiddendanger/rectification.vue
2026-02-08 09:30:43 +08:00

488 lines
13 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="page padding">
<view class="padding bg-white radius">
<view class="form-label margin-bottom">
<view class="text-gray">整改方案</view>
<view class="text-red">*</view>
</view>
<up-textarea v-model="formData.rectifyPlan" placeholder="请输入内容"></up-textarea>
<view class="form-label margin-bottom margin-top">
<view class="text-gray">整改完成情况</view>
<view class="text-red">*</view>
</view>
<up-textarea v-model="formData.rectifyResult" placeholder="请输入内容"></up-textarea>
<view class="form-label margin-bottom margin-top">
<view class="text-gray">投资资金(计划)</view>
<view class="text-red">*</view>
</view>
<up-input v-model="formData.planCost" placeholder="请输入内容" type="number"></up-input>
<view class="form-label margin-bottom margin-top">
<view class="text-gray">投资资金(实际)</view>
<view class="text-red">*</view>
</view>
<up-input v-model="formData.actualCost" placeholder="请输入内容" type="number"></up-input>
<view class="form-label margin-bottom margin-top">
<view class="text-gray">限定整改时间</view>
<view class="text-red">*</view>
</view>
<up-datetime-picker hasInput :show="show" v-model="value1" mode="date"></up-datetime-picker>
<view class="form-label margin-bottom margin-top">
<view class="text-gray">整改人员</view>
<view class="text-red">*</view>
</view>
<!-- 点击打开人员选择弹窗 -->
<view class="select-trigger" @click="showUserPopup = true">
<view class="select-content" :class="{ 'text-gray': selectedUsers.length === 0 }">
{{ selectedUsers.length > 0 ? selectedUsersText : '请选择整改人员(可多选)' }}
</view>
<text class="cuIcon-unfold"></text>
</view>
<!-- 人员多选弹窗 -->
<u-popup :show="showUserPopup" mode="bottom" round="20" @close="showUserPopup = false">
<view class="user-popup">
<view class="popup-header">
<view class="popup-title text-bold">选择整改人员</view>
<view class="popup-close" @click="showUserPopup = false">×</view>
</view>
<view class="popup-body">
<up-checkbox-group v-model="selectedUserIds" placement="column" @change="onUserChange">
<view class="user-item" v-for="item in cateList" :key="item.id">
<up-checkbox
:label="item.name"
:name="item.id"
activeColor="#2667E9"
shape="square"
></up-checkbox>
</view>
</up-checkbox-group>
</view>
<view class="popup-footer">
<button class="btn-cancel" @click="showUserPopup = false">取消</button>
<button class="btn-confirm bg-blue" @click="confirmUserSelect">确定</button>
</view>
</view>
</u-popup>
<view class="form-label margin-bottom margin-top">
<view class="text-gray">整改图片/视频</view>
<view class="text-red">*</view>
</view>
<up-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" multiple
:maxCount="10"></up-upload>
<button class="bg-blue round margin-top-xl" @click="handleSubmit">{{ isEdit ? '保存修改' : '提交整改' }}</button>
</view>
</view>
</template>
<script setup>
import {ref,reactive,computed} from 'vue'
import {onLoad} from '@dcloudio/uni-app'
import {submitRectification,getDepartmentPersonUsers,getRectifyDetail,getDeptUsersWithSubordinates} from '@/request/api.js'
import {baseUrl,getToken} from '@/request/request.js'
// 从页面参数获取的ID
const hazardId = ref('');
const assignId = ref('');
const rectifyId = ref(''); // 整改ID编辑模式时使用
const isEdit = ref(false); // 是否为编辑模式
// 表单数据
const formData = reactive({
rectifyPlan: '', // 整改方案
rectifyResult: '', // 整改完成情况
planCost: '', // 投资资金(计划)
actualCost: '' // 投资资金(实际)
});
const show = ref(false);
const value1 = ref(Date.now());
const radiovalue1 = ref('');
// 整改人员(多选)
const cateList = ref([])
const showUserPopup = ref(false) // 人员选择弹窗
const selectedUserIds = ref([]) // 选中的用户ID数组
const selectedUsers = ref([]) // 选中的用户对象数组
// 选中人员的显示文本
const selectedUsersText = computed(() => {
if (selectedUsers.value.length === 0) return '';
if (selectedUsers.value.length <= 2) {
return selectedUsers.value.map(u => u.name).join('、');
}
return `${selectedUsers.value[0].name}${selectedUsers.value.length}`;
});
// checkbox变化事件
const onUserChange = (ids) => {
console.log('选中的ID:', ids);
};
// 确认选择人员
const confirmUserSelect = () => {
// 根据选中的ID获取用户对象
selectedUsers.value = cateList.value.filter(item => selectedUserIds.value.includes(item.id));
showUserPopup.value = false;
console.log('选中的整改人员:', selectedUsers.value);
};
// 获取部门人员列表
const fetchDeptUsers = async () => {
console.log('当前hazardId:', hazardId.value);
try {
const res = await getDeptUsersWithSubordinates({hazardId:hazardId.value});
if (res.code === 0 && res.data) {
// 将部门下的用户数据扁平化
const userList = [];
res.data.forEach(dept => {
if (dept.users && dept.users.length > 0) {
dept.users.forEach(user => {
userList.push({
id: String(user.userId),
name: `${user.nickName}${dept.deptName}`
});
});
}
});
cateList.value = userList;
console.log('整改人员列表:', cateList.value);
}
} catch (error) {
console.error('获取部门人员失败:', error);
}
};
// 上传图片
const fileList1 = ref([]);
// 删除图片
const deletePic = (event) => {
fileList1.value.splice(event.index, 1);
};
// 新增图】片
const afterRead = async (event) => {
// 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file);
let fileListLen = fileList1.value.length;
lists.map((item) => {
fileList1.value.push({
...item,
status: 'uploading',
message: '上传中',
});
});
for (let i = 0; i < lists.length; i++) {
const result = await uploadFilePromise(lists[i].url);
let item = fileList1.value[fileListLen];
fileList1.value.splice(fileListLen, 1, {
...item,
status: 'success',
message: '',
url: result,
});
fileListLen++;
}
};
const uploadFilePromise = (filePath) => {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: baseUrl + '/frontend/attachment/upload',
filePath: filePath,
name: 'file',
header: {
'Authorization': getToken()
},
success: (res) => {
const data = JSON.parse(res.data);
if (data.code === 0) {
resolve(data.data);
} else {
reject(data.msg || '上传失败');
}
},
fail: (err) => {
console.error('上传失败:', err);
reject(err);
}
});
});
};
// 提交整改
const handleSubmit = async () => {
if (!formData.rectifyPlan) {
uni.showToast({
title: '请输入整改方案',
icon: 'none'
});
return;
}
if (!formData.rectifyResult) {
uni.showToast({
title: '请输入整改完成情况',
icon: 'none'
});
return;
}
if (selectedUsers.value.length === 0) {
uni.showToast({
title: '请选择整改人员',
icon: 'none'
});
return;
}
// 构建附件列表
const attachments = fileList1.value.map(file => {
let url = '';
if (typeof file.url === 'string') {
url = file.url;
} else if (file.url && typeof file.url === 'object') {
url = file.url.url || file.url.path || '';
}
const fileName = (typeof url === 'string' && url) ? url.split('/').pop() : (file.name || '');
return {
fileName: fileName || '',
filePath: url || '',
fileType: file.type || 'image/png',
fileSize: file.size || 0
};
});
const params = {
hazardId: hazardId.value,
assignId: assignId.value,
rectifyPlan: formData.rectifyPlan,
rectifyResult: formData.rectifyResult,
planCost: Number(formData.planCost) || 0,
actualCost: Number(formData.actualCost) || 0,
attachments: attachments,
// 整改人员ID数组
rectifyUserIds: selectedUserIds.value.map(id => Number(id))
};
// 编辑模式需要传递rectifyId
if (rectifyId.value) {
params.rectifyId = rectifyId.value;
}
try {
const res = await submitRectification(params);
if (res.code === 0) {
uni.showToast({
title: isEdit.value ? '保存成功' : '提交成功',
icon: 'success'
});
setTimeout(() => {
uni.navigateBack();
}, 1500);
} else {
uni.showToast({
title: res.msg || (isEdit.value ? '保存失败' : '提交失败'),
icon: 'none'
});
}
} catch (error) {
console.error('提交整改失败:', error);
uni.showToast({
title: '操作失败',
icon: 'none'
});
}
};
// 获取整改详情(编辑模式)
const fetchRectifyDetail = async () => {
try {
uni.showLoading({ title: '加载中...' });
const res = await getRectifyDetail({ rectifyId: rectifyId.value });
uni.hideLoading();
if (res.code === 0 && res.data) {
const data = res.data;
// 回显表单数据
formData.rectifyPlan = data.rectifyPlan || '';
formData.rectifyResult = data.rectifyResult || '';
formData.planCost = data.planCost ? String(data.planCost) : '';
formData.actualCost = data.actualCost ? String(data.actualCost) : '';
// 保存hazardId和assignId
hazardId.value = data.hazardId || '';
assignId.value = data.assignId || '';
// 回显附件
if (data.attachments && data.attachments.length > 0) {
fileList1.value = data.attachments.map(att => ({
url: att.filePath.startsWith('http') ? att.filePath : (baseUrl.replace('/api', '') + att.filePath),
status: 'success',
message: '',
name: att.fileName,
type: att.fileType,
filePath: att.filePath // 保存原始路径用于提交
}));
}
// 回显整改人员(如果有)
if (data.memberIds) {
const memberIdArr = data.memberIds.split(',').map(id => String(id.trim()));
selectedUserIds.value = memberIdArr;
// 等人员列表加载完成后再匹配
setTimeout(() => {
selectedUsers.value = cateList.value.filter(item => memberIdArr.includes(item.id));
}, 500);
} else if (data.rectifierId) {
// 如果没有memberIds使用rectifierId
selectedUserIds.value = [String(data.rectifierId)];
setTimeout(() => {
selectedUsers.value = cateList.value.filter(item => item.id === String(data.rectifierId));
}, 500);
}
// 设置页面标题
uni.setNavigationBarTitle({ title: '编辑整改信息' });
}
} catch (error) {
uni.hideLoading();
console.error('获取整改详情失败:', error);
uni.showToast({ title: '获取详情失败', icon: 'none' });
}
};
onLoad((options) => {
if (options.hazardId) {
hazardId.value = options.hazardId;
}
if (options.assignId) {
assignId.value = options.assignId;
}
// 在hazardId赋值后调用确保有值
fetchDeptUsers();
// 编辑模式
if (options.rectifyId) {
rectifyId.value = options.rectifyId;
isEdit.value = options.isEdit === '1';
// 获取整改详情
fetchRectifyDetail();
}
});
</script>
<style lang="scss" scoped>
.page {
min-height: 100vh;
background: #EBF2FC;
}
// 表单标签样式 - 让*号和文字对齐
.form-label {
display: flex;
align-items: center;
.text-red {
margin-left: 4rpx;
line-height: 1;
}
}
.date-input {
background: #fff;
border-radius: 8rpx;
padding: 24rpx 20rpx;
margin-bottom: 20rpx;
border: 1rpx solid #F6F6F6;
text {
font-size: 28rpx;
color: #333;
}
}
// 选择触发器样式
.select-trigger {
display: flex;
align-items: center;
justify-content: space-between;
background: #fff;
border: 1rpx solid #dcdfe6;
border-radius: 8rpx;
padding: 20rpx 24rpx;
margin-bottom: 20rpx;
.select-content {
flex: 1;
font-size: 28rpx;
color: #333;
}
}
// 人员选择弹窗
.user-popup {
background: #fff;
.popup-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #eee;
.popup-title {
font-size: 32rpx;
color: #333;
}
.popup-close {
font-size: 40rpx;
color: #999;
line-height: 1;
}
}
.popup-body {
padding: 20rpx 30rpx;
max-height: 600rpx;
overflow-y: auto;
}
.user-item {
padding: 24rpx 0;
border-bottom: 1rpx solid #f5f5f5;
&:last-child {
border-bottom: none;
}
}
.popup-footer {
display: flex;
border-top: 1rpx solid #eee;
button {
flex: 1;
height: 90rpx;
line-height: 90rpx;
border-radius: 0;
font-size: 30rpx;
&::after {
border: none;
}
}
.btn-cancel {
background: #fff;
color: #666;
}
.btn-confirm {
color: #fff;
}
}
}
</style>