交办、整改责任人修改

This commit is contained in:
王利强
2026-06-30 09:47:10 +08:00
parent d4897284e8
commit 455fd4fc07
638 changed files with 5153 additions and 2572 deletions

View File

@@ -165,11 +165,12 @@
<scroll-view class="cascader-col user-col" scroll-y :key="'dept-users-' + activeDeptIndex">
<view v-if="currentDeptUsers.length === 0" class="empty-tip">该部门暂无人员</view>
<view v-else>
<view class="user-item" v-for="user in currentDeptUsers" :key="'user-' + user.userId">
<view class="user-item" v-for="user in currentDeptUsers" :key="'user-' + user.userId" :class="{ 'user-item-locked': isLockedUser(user.userId) }">
<up-checkbox
usedAlone
:checked="userPickerSelectedSet.has(String(user.userId))"
:label="formatUserDisplayName(user)"
:label="formatUserPickerLabel(user)"
:disabled="isLockedUser(user.userId)"
activeColor="#2667E9"
shape="square"
@change="(checked) => onUserCheckChange(user.userId, checked)"
@@ -199,7 +200,40 @@
:height="canvasHeight"
:style="{ width: canvasWidth + 'px', height: canvasHeight + 'px', position: 'fixed', left: '-9999px', top: '-9999px' }"
></canvas>
<!-- 电子签名 -->
<canvas
v-if="!showUserPopup && !showManagerPopup && !showRectifyTimePicker"
canvas-id="watermarkCanvas"
:width="canvasWidth"
:height="canvasHeight"
:style="{ width: canvasWidth + 'px', height: canvasHeight + 'px', position: 'fixed', left: '-9999px', top: '-9999px' }"
></canvas>
<view class="form-label margin-bottom margin-top">
<view class="text-gray">下一步流程</view>
<view class="text-red">*</view>
</view>
<view class="static-field">隐患验收</view>
<view class="form-label margin-bottom margin-top">
<view class="text-gray">下一步处理人</view>
<view class="text-red">*</view>
</view>
<view class="static-field">企业管理员</view>
<view class="form-label margin-bottom margin-top">
<view class="text-gray">短信提醒</view>
<view class="text-red">*</view>
</view>
<up-radio-group v-model="sendMsgFlagRadio" placement="row" activeColor="#2667e9">
<up-radio
label="是"
name="yes"
:customStyle="{ marginRight: '48rpx' }"
></up-radio>
<up-radio label="否" name="no"></up-radio>
</up-radio-group>
<!-- 电子签名表单最底部 -->
<view class="form-label margin-bottom margin-top flex justify-between align-center" style="width: 100%;">
<view class="flex align-center">
<view class="text-gray">电子签名</view>
@@ -253,7 +287,15 @@
<script setup>
import {ref,reactive,computed,nextTick,getCurrentInstance} from 'vue'
import {onLoad, onHide} from '@dcloudio/uni-app'
import {submitRectification,getDepartmentPersonUsers,getRectifyDetail,getDeptUsersWithSubordinates,getHiddenDangerDetail,generateRectifyPlan} from '@/request/api.js'
import {
submitRectification,
// getDepartmentPersonUsers,
// getDeptUsersWithSubordinates,
getRelatedDeptUsers,
getRectifyDetail,
getHiddenDangerDetail,
generateRectifyPlan
} from '@/request/api.js'
import { buildDraftKey, buildDraftKeyCompact, DRAFT_NS } from '@/utils/draftCache.js';
import { useDraftCache } from '@/utils/useDraftCache.js';
import {
@@ -415,6 +457,10 @@
const rectifyTimeValue = ref(Date.now());
const selectedRectifyTime = ref('');
// 短信提醒
const sendMsgFlagRadio = ref('yes');
const sendMsgFlag = computed(() => sendMsgFlagRadio.value === 'yes');
const formatDateValue = (timestamp) => {
if (!timestamp) return '';
const date = new Date(timestamp);
@@ -458,7 +504,18 @@
deptName: ''
});
}
selectedUserIds.value = [id];
if (!lockedUserIds.value.includes(id)) {
lockedUserIds.value = [...lockedUserIds.value, id];
}
selectedUserIds.value = mergeLockedUserIds([id]);
syncSelectedUsersFromIds(selectedUserIds.value);
};
const setLockedDefaultUsers = (ids) => {
const normalized = parseIdList(ids);
if (!normalized.length) return;
lockedUserIds.value = normalized;
selectedUserIds.value = mergeLockedUserIds(selectedUserIds.value);
syncSelectedUsersFromIds(selectedUserIds.value);
};
@@ -529,7 +586,7 @@
showRectifyTimePicker.value = false;
};
// 人员列表(安全管理人员:本部门及上级;整改责任人:隐患关联部门)
// 人员列表(安全管理人员整改责任人:关联部门及人员type=2
const managerDeptList = ref([])
const deptList = ref([])
const detailPersonPool = ref([])
@@ -541,9 +598,25 @@
const showUserPopup = ref(false)
const selectedUserIds = ref([])
const selectedUsers = ref([])
const lockedUserIds = ref([])
const activeDeptIndex = ref(0)
const userPickerSelectedIds = ref([])
const isLockedUser = (userId) => lockedUserIds.value.includes(String(userId));
const mergeLockedUserIds = (ids) => {
const merged = new Set([
...(ids || []).map((id) => String(id)),
...lockedUserIds.value.map((id) => String(id))
]);
return [...merged];
};
const formatUserPickerLabel = (user) => {
const name = formatUserDisplayName(user);
return isLockedUser(user.userId) ? `${name}(默认)` : name;
};
const formatUserDisplayName = (user) => {
if (user.postName) {
return `${user.nickName}_${user.postName}`;
@@ -647,6 +720,10 @@
function onUserCheckChange(userId, checked) {
const id = String(userId);
if (!checked && isLockedUser(id)) {
uni.showToast({ title: '默认整改责任人不可取消', icon: 'none' });
return;
}
if (checked) {
if (!userPickerSelectedSet.value.has(id)) {
userPickerSelectedIds.value = [...userPickerSelectedIds.value, id];
@@ -668,7 +745,7 @@
};
const openUserPopup = () => {
userPickerSelectedIds.value = [...selectedUserIds.value];
userPickerSelectedIds.value = mergeLockedUserIds(selectedUserIds.value);
const firstDeptWithUsers = deptList.value.findIndex((dept) => dept.users?.length > 0);
activeDeptIndex.value = firstDeptWithUsers >= 0 ? firstDeptWithUsers : 0;
showUserPopup.value = true;
@@ -687,45 +764,65 @@
// 确认选择整改责任人
const confirmUserSelect = () => {
userPickerSelectedIds.value = mergeLockedUserIds(userPickerSelectedIds.value);
selectedUserIds.value = userPickerSelectedIds.value.map((id) => String(id));
syncSelectedUsersFromIds(selectedUserIds.value);
showUserPopup.value = false;
};
// 获取安全管理人员候选列表(本部门及上级部门)
const fetchManagerDeptUsers = async () => {
// 获取关联部门及人员列表(全部上级部门、本部门、全部下级部门)
const fetchRelatedDeptUsers = async () => {
try {
const res = await getDepartmentPersonUsers();
const res = await getRelatedDeptUsers({ type: 2 });
if (res.code === 0 && res.data) {
managerDeptList.value = res.data;
deptList.value = res.data;
if (selectedManagerIds.value.length > 0) {
syncSelectedManagersFromIds(selectedManagerIds.value);
}
}
} catch (error) {
console.error('获取安全管理人员列表失败:', error);
}
};
// 获取整改责任人候选列表(隐患关联部门人员)
const fetchRectifyDeptUsers = async () => {
console.log('当前hazardId:', hazardId.value);
try {
const res = await getDeptUsersWithSubordinates({ hazardId: hazardId.value });
if (res.code === 0 && res.data) {
deptList.value = res.data;
if (selectedUserIds.value.length > 0) {
syncSelectedUsersFromIds(selectedUserIds.value);
}
console.log('整改责任人部门树:', deptList.value);
}
} catch (error) {
console.error('获取整改责任人列表失败:', error);
console.error('获取关联部门人员列表失败:', error);
}
};
// 获取安全管理人员候选列表(本部门及上级部门)
// const fetchManagerDeptUsers = async () => {
// try {
// const res = await getDepartmentPersonUsers();
// if (res.code === 0 && res.data) {
// managerDeptList.value = res.data;
// if (selectedManagerIds.value.length > 0) {
// syncSelectedManagersFromIds(selectedManagerIds.value);
// }
// }
// } catch (error) {
// console.error('获取安全管理人员列表失败:', error);
// }
// };
// 获取整改责任人候选列表(隐患关联部门人员)
// const fetchRectifyDeptUsers = async () => {
// console.log('当前hazardId:', hazardId.value);
// try {
// const res = await getDeptUsersWithSubordinates({ hazardId: hazardId.value });
// if (res.code === 0 && res.data) {
// deptList.value = res.data;
// if (selectedUserIds.value.length > 0) {
// syncSelectedUsersFromIds(selectedUserIds.value);
// }
// console.log('整改责任人部门树:', deptList.value);
// }
// } catch (error) {
// console.error('获取整改责任人列表失败:', error);
// }
// };
const fetchPersonnelLists = async () => {
await Promise.all([fetchManagerDeptUsers(), fetchRectifyDeptUsers()]);
await fetchRelatedDeptUsers();
if (selectedManagerIds.value.length > 0) {
syncSelectedManagersFromIds(selectedManagerIds.value);
}
@@ -763,7 +860,8 @@
manageIds: selectedManagerIds.value.map((id) => Number(id)),
memberIds: selectedUserIds.value.map((id) => Number(id)),
rectifyTime: selectedRectifyTime.value || formatDateValue(rectifyTimeValue.value),
signPath: signatureServerPath.value || ''
signPath: signatureServerPath.value || '',
sendMsgFlag: sendMsgFlag.value
};
// 编辑模式需要传递rectifyId
@@ -1037,6 +1135,11 @@
} else if (data.rectifierId) {
selectedUserIds.value = [String(data.rectifierId)];
}
if (data.assigneeId) {
setLockedDefaultUsers(data.assigneeId);
} else if (data.rectifierId) {
setLockedDefaultUsers(data.rectifierId);
}
await fetchPersonnelLists();
// 回显附件
@@ -1138,7 +1241,8 @@
signatureUrl: signatureUrl.value,
signatureLocalPath: signatureLocalPath.value,
showCanvas: showCanvas.value,
signaturePaths: signaturePaths.value
signaturePaths: signaturePaths.value,
sendMsgFlagRadio: sendMsgFlagRadio.value
}),
hasContent: rectifyDraftHasContent,
applyPayload: (data) => {
@@ -1158,6 +1262,7 @@
} else if (data.showCanvas === false) {
showCanvas.value = false;
}
sendMsgFlagRadio.value = data.sendMsgFlagRadio === 'no' ? 'no' : 'yes';
},
clearForm: () => {
formData.rectifyPlan = '';
@@ -1175,6 +1280,7 @@
if (signatureRef.value) {
signatureRef.value.clear();
}
sendMsgFlagRadio.value = 'yes';
},
canSave: () => !!(hazardId.value || rectifyId.value),
onAfterRestore: (data) => {
@@ -1203,7 +1309,8 @@
signatureUrl.value,
signatureLocalPath.value,
showCanvas.value,
signaturePaths.value
signaturePaths.value,
sendMsgFlagRadio.value
]);
onHide(() => {
@@ -1328,6 +1435,17 @@
font-size: 28rpx;
color: #333;
}
.static-field {
background: #fff;
border: 1rpx solid #dcdfe6;
border-radius: 8rpx;
padding: 20rpx 24rpx;
margin-bottom: 20rpx;
font-size: 28rpx;
color: #333;
line-height: 1.5;
}
// 选择触发器样式
.select-trigger {
@@ -1479,6 +1597,10 @@
border-bottom: none;
}
}
.user-item-locked {
opacity: 0.85;
}
.popup-footer {
display: flex;