Files
threeonecheck_web/pages/hiddendanger/assignment.vue
2026-06-03 10:16:37 +08:00

308 lines
8.5 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="padding page">
<view class="padding radius bg-white">
<!-- 草稿恢复提示 -->
<view v-if="showRestoreBanner" class="bg-orange-light text-orange padding-sm radius margin-bottom flex justify-between align-center" style="font-size: 24rpx; background-color: #FFF7EB; border: 1rpx solid #FFE4CC; width: 100%; box-sizing: border-box; display: flex; flex-direction: row; justify-content: space-between; align-items: center; margin-bottom: 20rpx;">
<view class="flex align-center" style="display: flex; flex-direction: row; align-items: center;">
<text class="cuIcon-info margin-right-xs" style="margin-right: 10rpx;"></text>
<text>已自动恢复您上次未提交的内容</text>
</view>
<text class="text-blue text-bold" style="cursor: pointer; padding: 0 10rpx; color: #2667E9; font-weight: bold;" @click="clearDraft(true)">清空草稿</text>
</view>
<view class="flex margin-bottom">
<view class="text-gray">整改人员</view>
<view class="text-red">*</view>
</view>
<view class="picker-input" @click="showUserPicker = true">
<text :class="selectedUser ? '' : 'text-gray'">{{ selectedUser || '请选择整改人员' }}</text>
</view>
<up-picker
:show="showUserPicker"
:columns="userColumns"
@confirm="onUserConfirm"
@cancel="showUserPicker = false"
@close="showUserPicker = false"
></up-picker>
<view class="flex margin-bottom margin-top">
<view class="text-gray">整改期限</view>
<view class="text-red">*</view>
</view>
<view class="picker-input" @click="showDatePicker = true">
<text :class="selectedDate ? '' : 'text-gray'">{{ selectedDate || '请选择整改期限' }}</text>
</view>
<up-datetime-picker
:show="showDatePicker"
v-model="dateValue"
mode="datetime"
@confirm="onDateConfirm"
@cancel="showDatePicker = false"
@close="showDatePicker = false"
></up-datetime-picker>
<view class="btn-group margin-top-xl">
<button class="btn-cancel" @click="handleCancel">取消</button>
<button class="btn-confirm bg-blue" @click="handleSubmit">确认</button>
</view>
</view>
</view>
</template>
<script setup>
import { ref, reactive, watch, nextTick } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { getDepartmentPersonUsers,assignHiddenDanger } from '@/request/api.js';
// 页面参数
const hazardId = ref('');
const assignId = ref('');
// 整改人员选择
const showUserPicker = ref(false);
const selectedUser = ref('');
const selectedUserId = ref('');
const userColumns = ref([['暂无数据']]);
const userList = ref([]); // 存储完整用户数据
// 整改期限选择
const showDatePicker = ref(false);
const dateValue = ref(Date.now());
const selectedDate = ref('');
// 获取部门人员列表
const fetchDeptUsers = async () => {
try {
const res = await getDepartmentPersonUsers();
if (res.code === 0 && res.data) {
const users = [];
res.data.forEach(dept => {
if (dept.users && dept.users.length > 0) {
dept.users.forEach(user => {
users.push({
id: String(user.userId),
name: `${user.nickName}${dept.deptName}`
});
});
}
});
userList.value = users;
// 转换为 picker 需要的格式
userColumns.value = [users.map(u => u.name)];
console.log('整改人员列表:', users);
}
} catch (error) {
console.error('获取部门人员失败:', error);
}
};
// 人员选择确认
const onUserConfirm = (e) => {
console.log('选择的人员:', e);
if (e.value && e.value.length > 0) {
selectedUser.value = e.value[0];
// 找到对应的用户ID
const user = userList.value.find(u => u.name === e.value[0]);
if (user) {
selectedUserId.value = user.id;
}
}
showUserPicker.value = false;
};
// 日期时间选择确认
const onDateConfirm = (e) => {
console.log('选择的日期时间:', e);
const date = new Date(e.value);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
selectedDate.value = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
showDatePicker.value = false;
};
// 取消
const handleCancel = () => {
uni.navigateBack();
};
// 确认提交
const handleSubmit = async () => {
if (!selectedUserId.value) {
uni.showToast({ title: '请选择整改人员', icon: 'none' });
return;
}
if (!selectedDate.value) {
uni.showToast({ title: '请选择整改期限', icon: 'none' });
return;
}
// 构建请求参数
const params = {
hazardId: Number(hazardId.value), // 隐患ID
assigneeId: Number(selectedUserId.value), // 被指派人ID
deadline: selectedDate.value, // 处理期限
assignRemark: '' // 交办备注(可选)
};
console.log('提交数据:', params);
try {
const res = await assignHiddenDanger(params);
if (res.code === 0) {
clearDraft(false);
uni.showToast({ title: '交办成功', icon: 'success' });
setTimeout(() => {
uni.navigateBack();
}, 1500);
} else {
uni.showToast({ title: res.msg || '交办失败', icon: 'none' });
}
} catch (error) {
console.error('交办失败:', error);
uni.showToast({ title: '请求失败', icon: 'none' });
}
};
// 草稿缓存与恢复逻辑 (移至底部以确保 formData 等响应式状态已被正常定义)
const hasDraft = ref(false);
const showRestoreBanner = ref(false); // 独立控制提示 Banner仅在初次确实从本地恢复了内容时才显示
const isRestoring = ref(false); // 正在恢复标志避免触发冗余watch
const getDraftKey = () => `draft_assign_${hazardId.value || ''}`;
// 保存草稿 (排除选择器人员缓存,仅缓存整改期限日期值)
const saveDraft = () => {
if (isRestoring.value) return;
const key = getDraftKey();
const hasContent = selectedDate.value;
if (!hasContent) {
uni.removeStorageSync(key);
hasDraft.value = false;
return;
}
const data = {
selectedDate: selectedDate.value,
dateValue: dateValue.value
};
uni.setStorageSync(key, JSON.stringify(data));
hasDraft.value = true;
};
// 清空草稿
const clearDraft = (showToast = true) => {
const key = getDraftKey();
uni.removeStorageSync(key);
hasDraft.value = false;
showRestoreBanner.value = false;
isRestoring.value = true;
selectedDate.value = '';
dateValue.value = Date.now();
nextTick(() => {
isRestoring.value = false;
});
if (showToast) {
uni.showToast({ title: '草稿已清空', icon: 'none' });
}
};
// 恢复草稿
const restoreDraft = () => {
const key = getDraftKey();
const cached = uni.getStorageSync(key);
if (cached) {
try {
const data = JSON.parse(cached);
const hasContent = data.selectedDate;
if (!hasContent) return;
isRestoring.value = true;
selectedDate.value = data.selectedDate || '';
dateValue.value = data.dateValue || Date.now();
hasDraft.value = true;
showRestoreBanner.value = true; // 确实存在内容并恢复了,才亮起提示 Banner
nextTick(() => {
isRestoring.value = false;
});
uni.showToast({
title: '已自动恢复您上次未提交的内容',
icon: 'none',
duration: 2500
});
} catch (e) {
console.error('解析草稿失败:', e);
isRestoring.value = false;
}
}
};
// 监听变量变化,自动保存草稿
watch(
() => [selectedDate.value],
() => {
if (hazardId.value) {
saveDraft();
}
}
);
onLoad((options) => {
if (options.hazardId) hazardId.value = options.hazardId;
if (options.assignId) assignId.value = options.assignId;
fetchDeptUsers();
// 恢复草稿 (不恢复任何人员选择器数据)
restoreDraft();
});
</script>
<style lang="scss" scoped>
.page {
min-height: 100vh;
background: #EBF2FC;
}
.picker-input {
background: #fff;
border-radius: 8rpx;
padding: 24rpx 20rpx;
margin-bottom: 20rpx;
border: 1rpx solid #F6F6F6;
text {
font-size: 28rpx;
color: #333;
}
}
.btn-group {
display: flex;
gap: 30rpx;
}
.btn-cancel {
flex: 1;
height: 80rpx;
line-height: 80rpx;
border: 2rpx solid #2667E9;
border-radius: 40rpx;
background: #fff;
color: #2667E9;
font-size: 30rpx;
}
.btn-confirm {
flex: 1;
height: 80rpx;
line-height: 80rpx;
border-radius: 40rpx;
color: #fff;
font-size: 30rpx;
}
</style>