检查表手动添加检查项时根据部门类型展示不一样

This commit is contained in:
王利强
2026-08-03 11:51:07 +08:00
parent 088ff356f2
commit ec76d588e2
50 changed files with 826 additions and 428 deletions

View File

@@ -1,4 +1,5 @@
<template>
<page-meta :page-style="pageScrollLockStyle" />
<view class="page">
<view class="form-card">
<!-- 检查表名称 -->
@@ -72,8 +73,8 @@
></up-picker>
</view>
<!-- 执行人员单人完成模式 -->
<view class="form-item" v-if="formData.modeName === '单人完成'">
<!-- 执行人员单人完成 / 排班模式 -->
<view class="form-item" v-if="formData.runMode === 1 || formData.runMode === 4">
<view class="form-label">
<text>执行人员</text>
<text class="required">*</text>
@@ -263,23 +264,63 @@
</view>
<view class="popup-body">
<view class="popup-form-item" v-if="showFullForm">
<view class="popup-form-label">行业类型<text class="required">*</text></view>
<view class="popup-select" @click="showIndustryPicker = true">
<text class="regulation-text" :class="checkForm.industryName ? '' : 'text-gray'">{{ checkForm.industryName || '请选择行业类型' }}</text>
<text class="cuIcon-unfold select-icon"></text>
</view>
<up-picker
:show="showIndustryPicker"
:columns="industryColumns"
@confirm="onIndustryConfirm"
@cancel="showIndustryPicker = false"
@close="showIndustryPicker = false"
></up-picker>
</view>
<view class="popup-form-item">
<view class="popup-form-label">检查名称<text class="required">*</text></view>
<up-input v-model="checkForm.name" placeholder="请输入检查名称" border="surround"></up-input>
</view>
<view class="popup-form-item" v-if="showFullForm">
<view class="popup-form-label">牵头部门<text class="required">*</text></view>
<up-input v-model="checkForm.leadDept" placeholder="请输入牵头部门名称" border="surround"></up-input>
</view>
<view class="popup-form-item">
<view class="popup-form-label">检查内容<text class="required">*</text></view>
<up-textarea v-model="checkForm.point" placeholder="请输入检查内容" :height="150"></up-textarea>
</view>
<view class="popup-form-item">
<view class="popup-form-item" v-if="showFullForm">
<view class="popup-form-label">参考法规</view>
<view class="popup-select regulation-select" @click="openLawPopup">
<text class="regulation-text" :class="checkForm.regulationName ? '' : 'text-gray'">{{ checkForm.regulationName || '选择法规' }}</text>
<text class="cuIcon-unfold select-icon"></text>
</view>
</view>
<view class="popup-form-item" v-if="showFullForm">
<view class="popup-form-label">常见隐患</view>
<up-textarea v-model="checkForm.commonProblem" placeholder="请输入常见隐患" :height="120"></up-textarea>
</view>
<view class="popup-form-item" v-if="showFullForm">
<view class="popup-form-label">重大隐患</view>
<view class="popup-select" @click="showSeriousPicker = true">
<text class="regulation-text">{{ seriousName }}</text>
<text class="cuIcon-unfold select-icon"></text>
</view>
<up-picker
:show="showSeriousPicker"
:columns="seriousColumns"
@confirm="onSeriousConfirm"
@cancel="showSeriousPicker = false"
@close="showSeriousPicker = false"
></up-picker>
</view>
</view>
<view class="popup-footer">
@@ -418,10 +459,21 @@
v-else
class="executor-item"
v-for="item in executorList"
:key="item.userId"
@click="selectExecutor(item)"
:key="item.identityId || item.userId"
@click="formData.runMode === 4 ? toggleRosterExecutor(item) : selectExecutor(item)"
>
<view class="executor-radio" :class="{ 'executor-radio-active': selectedExecutorId === item.userId }">
<view
v-if="formData.runMode === 4"
class="executor-checkbox"
:class="{ 'executor-checkbox-active': selectedRosterIdentityIds.includes(item.identityId) }"
>
<text v-if="selectedRosterIdentityIds.includes(item.identityId)" class="cuIcon-check"></text>
</view>
<view
v-else
class="executor-radio"
:class="{ 'executor-radio-active': selectedExecutorId === item.userId }"
>
<view v-if="selectedExecutorId === item.userId" class="executor-radio-dot"></view>
</view>
<view class="executor-info">
@@ -440,8 +492,22 @@
</template>
<script setup>
import { ref, reactive, computed, onMounted, nextTick } from 'vue';
import { getRegulationList, addCheckPoint, detailcheckPoint, deleteCheckPoint, getCheckItemList, getCheckItemListDetail, getDeptUsers, getDeptChildren, addCheckTable } from '@/request/api.js';
import { ref, reactive, computed, onMounted, nextTick, watch } from 'vue';
import { getRegulationList, addCheckPoint, detailcheckPoint, deleteCheckPoint, getCheckItemList, getCheckItemListDetail, getDeptUsers, getDeptChildren, addCheckTable, getindustry } from '@/request/api.js';
import { getCurrentIdentityFromStorage } from '@/utils/userInfo.js';
// organizationEntityType: 0/1 机关单位展示全部2/3 企业仅展示检查名称和检查内容
const showFullForm = computed(() => {
const identity = getCurrentIdentityFromStorage();
const type = Number(identity?.organizationEntityType);
return type === 0 || type === 1;
});
const MODE_OPTIONS = [
{ label: '单人完成', value: 1 },
{ label: '全员', value: 2 },
{ label: '排班模式', value: 4 }
]
// 表单数据
const formData = reactive({
@@ -451,12 +517,13 @@ const formData = reactive({
remark: '',
type: '', // 检查表类型1-日常检查2-专项检查3-设备检查
typeName: '',
modeId: '',
runMode: undefined,
modeName: '',
selectDeptId: '',
selectDeptName: '',
executorId: '',
executorNames: '',
rosterIdentityIds: [],
cycleId: '',
cycleName: '',
isWeekend: 1,
@@ -592,13 +659,21 @@ const showEndDatePicker = ref(false);
// 选择器数据
const typeColumns = ref([['日常检查', '专项检查', '设备检查']]);
const modeColumns = ref([['单人完成', '全员']]);
const modeColumns = ref([MODE_OPTIONS.map((item) => item.label)]);
const cycleColumns = ref([['每天一次', '每周一次', '每月一次', '每季度一次']]);
// 执行人员选择器
const showExecutorPopup = ref(false);
const executorList = ref([]);
const selectedExecutorId = ref(null);
const selectedRosterIdentityIds = ref([]);
const pageScrollLockStyle = computed(() => {
if (showDeptPicker.value || showExecutorPopup.value) {
return 'overflow: hidden; height: 100%;'
}
return ''
})
// 分派单位树形选择器
const deptTree = ref([]);
@@ -695,11 +770,17 @@ const onTypeConfirm = (e) => {
};
const onModeConfirm = (e) => {
if (e.value && e.value.length > 0) {
formData.modeName = e.value[0]
if (e.value[0] === '全员') {
clearExecutorSelection()
}
const index = Number(e.indexs?.[0] ?? 0)
const option = MODE_OPTIONS[index]
if (!option) {
showModePicker.value = false
return
}
formData.modeName = option.label
formData.runMode = option.value
clearExecutorSelection()
if (formData.deptId && option.value !== 2) {
fetchDeptUsers(formData.deptId)
}
showModePicker.value = false
}
@@ -707,7 +788,9 @@ const onModeConfirm = (e) => {
const clearExecutorSelection = () => {
formData.executorId = ''
formData.executorNames = ''
formData.rosterIdentityIds = []
selectedExecutorId.value = null
selectedRosterIdentityIds.value = []
}
const fetchDeptUsers = async (deptId) => {
@@ -716,7 +799,8 @@ const fetchDeptUsers = async (deptId) => {
return
}
try {
const res = await getDeptUsers(deptId)
const params = formData.runMode === 4 ? { type: 4 } : {}
const res = await getDeptUsers(deptId, params)
if (res.code === 0 && res.data) {
executorList.value = res.data || []
} else {
@@ -732,7 +816,31 @@ const selectExecutor = (item) => {
selectedExecutorId.value = item.userId
}
const toggleRosterExecutor = (item) => {
const identityId = item.identityId
if (identityId == null) return
const index = selectedRosterIdentityIds.value.indexOf(identityId)
if (index > -1) {
selectedRosterIdentityIds.value.splice(index, 1)
} else {
selectedRosterIdentityIds.value.push(identityId)
}
}
const confirmExecutorSelect = () => {
if (formData.runMode === 4) {
if (selectedRosterIdentityIds.value.length === 0) {
uni.showToast({ title: '请选择执行人员', icon: 'none' })
return
}
formData.rosterIdentityIds = [...selectedRosterIdentityIds.value]
const names = executorList.value
.filter((user) => selectedRosterIdentityIds.value.includes(user.identityId))
.map((user) => user.nickName || user.nickname)
formData.executorNames = names.join('、')
showExecutorPopup.value = false
return
}
if (!selectedExecutorId.value) {
uni.showToast({ title: '请选择执行人员', icon: 'none' })
return
@@ -748,7 +856,11 @@ const openExecutorPopup = () => {
uni.showToast({ title: '请先选择分派单位', icon: 'none' })
return
}
selectedExecutorId.value = formData.executorId || null
if (formData.runMode === 4) {
selectedRosterIdentityIds.value = [...(formData.rosterIdentityIds || [])]
} else {
selectedExecutorId.value = formData.executorId || null
}
fetchDeptUsers(formData.deptId)
showExecutorPopup.value = true
}
@@ -920,12 +1032,70 @@ const deleteLibraryCheckItem = (index) => {
// 手动添加检查项弹窗
const showAddPopup = ref(false);
const checkForm = reactive({
name: '', // 检查名称
point: '', // 检查内容
regulationId: null, // 参考法规ID
regulationName: '' // 参考法规名称(显示用)
name: '',
point: '',
industryId: null,
industryName: '',
leadDept: '',
commonProblem: '',
isSerious: 2,
regulationId: null,
regulationName: ''
});
const industryOptions = ref([]);
const showIndustryPicker = ref(false);
const industryColumns = computed(() => [industryOptions.value.map((item) => item.name || item.industryName || '')]);
const showSeriousPicker = ref(false);
const seriousColumns = ref([['是', '否']]);
const seriousName = computed(() => (checkForm.isSerious === 1 ? '是' : '否'));
const resetCheckForm = () => {
checkForm.name = '';
checkForm.point = '';
checkForm.industryId = null;
checkForm.industryName = '';
checkForm.leadDept = '';
checkForm.commonProblem = '';
checkForm.isSerious = 2;
checkForm.regulationId = null;
checkForm.regulationName = '';
};
const fetchIndustryOptions = async () => {
try {
const res = await getindustry();
if (res.code === 0) {
industryOptions.value = res.data || [];
}
} catch (error) {
console.error('获取行业类型失败:', error);
}
};
watch(showAddPopup, (val) => {
if (val && showFullForm.value) {
fetchIndustryOptions();
}
});
const onIndustryConfirm = (e) => {
const selectedName = e.value?.[0];
const selected = industryOptions.value.find((item) => (item.name || item.industryName) === selectedName);
if (selected) {
checkForm.industryId = selected.id;
checkForm.industryName = selected.name || selected.industryName || '';
}
showIndustryPicker.value = false;
};
const onSeriousConfirm = (e) => {
const selectedName = e.value?.[0];
checkForm.isSerious = selectedName === '是' ? 1 : 2;
showSeriousPicker.value = false;
};
// 选择法规弹窗
const showLawPopup = ref(false);
const lawKeyword = ref('');
@@ -939,6 +1109,9 @@ const hasMoreLaw = ref(true);
// 打开法规选择弹窗
const openLawPopup = () => {
if (!showFullForm.value) {
return;
}
showLawPopup.value = true;
// 如果列表为空,加载数据
if (lawList.value.length === 0) {
@@ -1023,16 +1196,34 @@ const handleAddCheck = async () => {
uni.showToast({ title: '请输入检查内容', icon: 'none' });
return;
}
if (showFullForm.value) {
if (!checkForm.industryId) {
uni.showToast({ title: '请选择行业类型', icon: 'none' });
return;
}
if (!checkForm.leadDept) {
uni.showToast({ title: '请输入牵头部门', icon: 'none' });
return;
}
}
try {
uni.showLoading({ title: '添加中...' });
// 调用接口新增检查项
const params = {
name: checkForm.name,
point: checkForm.point,
regulationId: checkForm.regulationId || undefined
};
const params = showFullForm.value
? {
name: checkForm.name,
point: checkForm.point,
industryId: checkForm.industryId,
leadDept: checkForm.leadDept,
regulationId: checkForm.regulationId || undefined,
commonProblem: checkForm.commonProblem || undefined,
isSerious: checkForm.isSerious
}
: {
name: checkForm.name,
point: checkForm.point
};
const res = await addCheckPoint(params);
@@ -1064,12 +1255,7 @@ const handleAddCheck = async () => {
uni.hideLoading();
uni.showToast({ title: '添加成功', icon: 'success' });
showAddPopup.value = false;
// 重置表单
checkForm.name = '';
checkForm.point = '';
checkForm.regulationId = null;
checkForm.regulationName = '';
resetCheckForm();
} else {
uni.hideLoading();
uni.showToast({ title: res.msg || '添加失败', icon: 'none' });
@@ -1276,11 +1462,15 @@ const handleSave = async () => {
uni.showToast({ title: '请选择检查表类型', icon: 'none' });
return;
}
if (!formData.modeName) {
if (!formData.runMode) {
uni.showToast({ title: '请选择模式', icon: 'none' });
return;
}
if (formData.modeName === '单人完成' && !formData.executorId) {
if (formData.runMode === 1 && !formData.executorId) {
uni.showToast({ title: '请选择执行人员', icon: 'none' });
return;
}
if (formData.runMode === 4 && (!formData.rosterIdentityIds || formData.rosterIdentityIds.length === 0)) {
uni.showToast({ title: '请选择执行人员', icon: 'none' });
return;
}
@@ -1315,12 +1505,6 @@ const handleSave = async () => {
return;
}
// 运行模式映射:单人完成=1全员=2
const runModeMap = {
'单人完成': 1,
'全员': 2
};
// 周期映射:每天=1每周=2每月=3每季度=4
const cycleMap = {
'每天一次': 1,
@@ -1343,7 +1527,7 @@ const handleSave = async () => {
deptId: formData.deptId,
description: formData.remark || '',
type: formData.type, // 检查表类型1-日常检查2-专项检查3-设备检查
runMode: runModeMap[formData.modeName] || 2,
runMode: formData.runMode,
checkPointIds: items,
itemIds: itemIds, // 从检查库选择的库id数组
cycle: cycleMap[formData.cycleName] || 1,
@@ -1352,9 +1536,13 @@ const handleSave = async () => {
planEndTime: `${formData.endDate} 00:00:00`
};
if (formData.modeName === '单人完成' && formData.executorId) {
if (formData.runMode === 1 && formData.executorId) {
params.executorId = formData.executorId;
}
if (formData.runMode === 4 && formData.rosterIdentityIds?.length) {
params.rosterIdentityIds = formData.rosterIdentityIds;
}
try {
uni.showLoading({ title: '保存中...' });
@@ -1951,6 +2139,25 @@ onMounted(() => {
background: #2667E9;
}
.executor-checkbox {
width: 40rpx;
height: 40rpx;
border: 2rpx solid #ccc;
border-radius: 8rpx;
margin-right: 20rpx;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
font-size: 24rpx;
}
.executor-checkbox-active {
background: #2667E9;
border-color: #2667E9;
color: #fff;
}
.executor-info {
flex: 1;
}