1633 lines
41 KiB
Vue
1633 lines
41 KiB
Vue
<template>
|
||
<view class="page">
|
||
<view class="form-card">
|
||
<!-- 检查表名称 -->
|
||
<view class="form-item">
|
||
<view class="form-label">
|
||
<text>检查表名称</text>
|
||
<text class="required">*</text>
|
||
</view>
|
||
<up-input v-model="formData.name" placeholder="请输入检查表名称" border="surround"></up-input>
|
||
</view>
|
||
|
||
<!-- 分派单位 -->
|
||
<view class="form-item">
|
||
<view class="form-label">
|
||
<text>分派单位</text>
|
||
<text class="required">*</text>
|
||
</view>
|
||
<view class="picker-input" @click="showDeptPicker = true">
|
||
<text :class="formData.deptName ? 'picker-value' : 'picker-placeholder'">
|
||
{{ formData.deptName || '请选择分派单位' }}
|
||
</text>
|
||
<text class="cuIcon-unfold picker-arrow"></text>
|
||
</view>
|
||
<up-picker
|
||
:show="showDeptPicker"
|
||
:columns="deptCascaderColumns"
|
||
:defaultIndex="deptCascaderIndexs"
|
||
@confirm="onDeptConfirm"
|
||
@change="onDeptCascaderChange"
|
||
@cancel="showDeptPicker = false"
|
||
@close="showDeptPicker = false"
|
||
></up-picker>
|
||
</view>
|
||
|
||
<!-- 补充说明 -->
|
||
<view class="form-item">
|
||
<view class="form-label">
|
||
<text>补充说明</text>
|
||
</view>
|
||
<up-textarea v-model="formData.remark" placeholder="请输入补充说明"></up-textarea>
|
||
</view>
|
||
|
||
<!-- 检查表类型 -->
|
||
<view class="form-item">
|
||
<view class="form-label">
|
||
<text>检查表类型</text>
|
||
</view>
|
||
<view class="picker-input" @click="showTypePicker = true">
|
||
<text :class="formData.typeName ? 'picker-value' : 'picker-placeholder'">
|
||
{{ formData.typeName || '请选择检查表类型' }}
|
||
</text>
|
||
<text class="cuIcon-unfold picker-arrow"></text>
|
||
</view>
|
||
<up-picker
|
||
:show="showTypePicker"
|
||
:columns="typeColumns"
|
||
@confirm="onTypeConfirm"
|
||
@cancel="showTypePicker = false"
|
||
@close="showTypePicker = false"
|
||
></up-picker>
|
||
</view>
|
||
|
||
<!-- 运行模式 -->
|
||
<view class="form-item">
|
||
<view class="form-label">
|
||
<text>运行模式</text>
|
||
</view>
|
||
<view class="picker-input" @click="showModePicker = true">
|
||
<text :class="formData.modeName ? 'picker-value' : 'picker-placeholder'">
|
||
{{ formData.modeName || '请选择运行模式' }}
|
||
</text>
|
||
<text class="cuIcon-unfold picker-arrow"></text>
|
||
</view>
|
||
<up-picker
|
||
:show="showModePicker"
|
||
:columns="modeColumns"
|
||
@confirm="onModeConfirm"
|
||
@cancel="showModePicker = false"
|
||
@close="showModePicker = false"
|
||
></up-picker>
|
||
</view>
|
||
|
||
<!-- 执行人员(仅当运行模式为"指定人员"时显示) -->
|
||
<view class="form-item" v-if="formData.modeName === '指定人员'">
|
||
<view class="form-label">
|
||
<text>执行人员</text>
|
||
</view>
|
||
<view class="picker-input" @click="openExecutorPopup">
|
||
<text :class="formData.executorNames ? 'picker-value' : 'picker-placeholder'">
|
||
{{ formData.executorNames || '请选择执行人员' }}
|
||
</text>
|
||
<text class="cuIcon-unfold picker-arrow"></text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 周期 -->
|
||
<view class="form-item">
|
||
<view class="form-label">
|
||
<text>周期</text>
|
||
</view>
|
||
<view class="picker-input" @click="showCyclePicker = true">
|
||
<text :class="formData.cycleName ? 'picker-value' : 'picker-placeholder'">
|
||
{{ formData.cycleName || '请选择周期' }}
|
||
</text>
|
||
<text class="cuIcon-unfold picker-arrow"></text>
|
||
</view>
|
||
<up-picker
|
||
:show="showCyclePicker"
|
||
:columns="cycleColumns"
|
||
@confirm="onCycleConfirm"
|
||
@cancel="showCyclePicker = false"
|
||
@close="showCyclePicker = false"
|
||
></up-picker>
|
||
</view>
|
||
|
||
<!-- 工作日开关 -->
|
||
<view class="form-item">
|
||
<view class="form-label">
|
||
<text>工作日开关</text>
|
||
</view>
|
||
<view class="switch-row">
|
||
<switch :checked="workdaySwitch" @change="onSwitchChange" color="#07C160" />
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 开始时间 -->
|
||
<view class="form-item">
|
||
<view class="form-label">
|
||
<text>开始时间</text>
|
||
</view>
|
||
<view class="picker-input" @click="showStartDatePicker = true">
|
||
<text :class="formData.startDate ? 'picker-value' : 'picker-placeholder'">
|
||
{{ formData.startDate || '请选择开始时间' }}
|
||
</text>
|
||
<text class="cuIcon-unfold picker-arrow"></text>
|
||
</view>
|
||
<up-datetime-picker
|
||
:show="showStartDatePicker"
|
||
mode="datetime"
|
||
v-model="startDateValue"
|
||
@confirm="onStartDateConfirm"
|
||
@cancel="showStartDatePicker = false"
|
||
@close="showStartDatePicker = false"
|
||
></up-datetime-picker>
|
||
</view>
|
||
|
||
<!-- 结束时间 -->
|
||
<view class="form-item">
|
||
<view class="form-label">
|
||
<text>结束时间</text>
|
||
</view>
|
||
<view class="picker-input" @click="showEndDatePicker = true">
|
||
<text :class="formData.endDate ? 'picker-value' : 'picker-placeholder'">
|
||
{{ formData.endDate || '请选择结束时间' }}
|
||
</text>
|
||
<text class="cuIcon-unfold picker-arrow"></text>
|
||
</view>
|
||
<up-datetime-picker
|
||
:show="showEndDatePicker"
|
||
mode="datetime"
|
||
v-model="endDateValue"
|
||
@confirm="onEndDateConfirm"
|
||
@cancel="showEndDatePicker = false"
|
||
@close="showEndDatePicker = false"
|
||
></up-datetime-picker>
|
||
</view>
|
||
|
||
<!-- 已添加的检查项 -->
|
||
<view class="form-item">
|
||
<view class="form-label label-blue">
|
||
<text>已添加的检查项({{ checkItemCount }}项)</text>
|
||
</view>
|
||
|
||
<!-- 空状态提示 -->
|
||
<view v-if="checkItemCount === 0" class="empty-check-tip">
|
||
<text class="text-gray">暂无检查项目,请添加</text>
|
||
</view>
|
||
|
||
<!-- 手动添加的检查项卡片 -->
|
||
<view class="check-card manual-card" v-for="(item, index) in manualCheckItems" :key="'manual-' + index">
|
||
<view class="card-tag">第{{ index + 1 }}项</view>
|
||
<view class="check-info">
|
||
<view class="info-row">
|
||
<text class="info-label">检查项名称:</text>
|
||
<text class="info-value">{{ item.name }}</text>
|
||
</view>
|
||
<view class="info-row">
|
||
<text class="info-label">检查内容:</text>
|
||
<text class="info-value">{{ item.point }}</text>
|
||
</view>
|
||
<view class="info-row">
|
||
<text class="info-label">参考法规:</text>
|
||
<text class="info-value">{{ item.regulationName || '-' }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="check-action">
|
||
<button class="btn-delete" @click="deleteManualCheckItem(item, index)">删除</button>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 从检查库添加的检查项卡片 -->
|
||
<view class="check-card" v-for="(item, index) in checkItems" :key="'lib-' + index">
|
||
<view class="check-info">
|
||
<view class="info-row">
|
||
<text class="info-label">关联表名:</text>
|
||
<text class="info-value">{{ item.tableName }}</text>
|
||
</view>
|
||
<view class="info-row">
|
||
<text class="info-label">检查项数量:</text>
|
||
<text class="info-value">{{ item.count }}项</text>
|
||
</view>
|
||
</view>
|
||
<view class="check-action">
|
||
<button class="btn-delete" @click="deleteCheckItem(index)">删除</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 添加检查项 -->
|
||
<view class="form-item">
|
||
<view class="form-label label-blue">
|
||
<text>添加检查项</text>
|
||
</view>
|
||
<view class="add-btns">
|
||
<button class="btn-add" @click="showAddPopup = true">手动添加</button>
|
||
<button class="btn-add" @click="openLibraryPopup">从检查库添加</button>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- <view style="height: 20px;"></view> -->
|
||
</view>
|
||
|
||
<!-- 保存按钮 -->
|
||
<view class="footer-btn">
|
||
<button class="btn-save" @click="handleSave">保存</button>
|
||
</view>
|
||
|
||
<!-- 手动添加检查项弹出框 -->
|
||
<u-popup :show="showAddPopup" mode="center" round="20" @close="showAddPopup = false">
|
||
<view class="popup-content">
|
||
<view class="popup-header">
|
||
<view class="popup-title">手动添加检查项</view>
|
||
<view class="popup-close" @click="showAddPopup = false">×</view>
|
||
</view>
|
||
|
||
<view class="popup-body">
|
||
<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">
|
||
<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-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>
|
||
|
||
<view class="popup-footer">
|
||
<button class="btn-cancel" @click="showAddPopup = false">取消</button>
|
||
<button class="btn-confirm" @click="handleAddCheck">确定</button>
|
||
</view>
|
||
</view>
|
||
</u-popup>
|
||
|
||
<!-- 选择法规弹出框 -->
|
||
<u-popup :show="showLawPopup" mode="center" round="20" @close="showLawPopup = false">
|
||
<view class="law-popup">
|
||
<view class="popup-header">
|
||
<view class="popup-title">选择参考法规</view>
|
||
<view class="popup-close" @click="showLawPopup = false">×</view>
|
||
</view>
|
||
|
||
<view class="search-box">
|
||
<text class="cuIcon-search search-icon"></text>
|
||
<input class="search-input" v-model="lawKeyword" placeholder="请输入关键词搜索" @confirm="searchRegulation" />
|
||
<text class="search-btn" @click="searchRegulation">搜索</text>
|
||
</view>
|
||
|
||
<scroll-view class="law-list" scroll-y @scrolltolower="loadMoreLaw">
|
||
<view v-if="lawLoading && lawList.length === 0" class="loading-tip">加载中...</view>
|
||
<view v-else-if="!lawLoading && lawList.length === 0" class="empty-tip">暂无数据</view>
|
||
<template v-else>
|
||
<view
|
||
class="law-item"
|
||
:class="{ 'law-item-active': selectedLawId === item.id }"
|
||
v-for="item in lawList"
|
||
:key="item.id"
|
||
@click="selectLaw(item)"
|
||
>
|
||
<view class="law-title">{{ item.depict }}</view>
|
||
<view class="law-basis text-gray">{{ item.legalBasis }}</view>
|
||
</view>
|
||
<view v-if="lawLoading" class="loading-tip">加载中...</view>
|
||
</template>
|
||
</scroll-view>
|
||
|
||
<view class="popup-footer">
|
||
<button class="btn-cancel" @click="showLawPopup = false">取消</button>
|
||
<button class="btn-confirm" @click="confirmLaw">确定</button>
|
||
</view>
|
||
</view>
|
||
</u-popup>
|
||
|
||
<!-- 从检查库添加弹出框 -->
|
||
<u-popup :show="showLibraryPopup" mode="center" round="20" @close="closeLibraryPopup">
|
||
<view class="library-popup">
|
||
<view class="popup-header">
|
||
<view class="popup-title">选择检查库</view>
|
||
<view class="popup-close" @click="closeLibraryPopup">×</view>
|
||
</view>
|
||
|
||
<view class="search-box">
|
||
<text class="cuIcon-search search-icon"></text>
|
||
<input class="search-input" v-model="libraryKeyword" placeholder="请输入关键词搜索" @confirm="searchLibrary" />
|
||
<text class="search-btn" @click="searchLibrary">搜索</text>
|
||
</view>
|
||
|
||
<scroll-view class="library-list" scroll-y @scrolltolower="loadMoreLibrary">
|
||
<view v-if="libraryLoading && libraryList.length === 0" class="loading-tip">加载中...</view>
|
||
<view v-else-if="!libraryLoading && libraryList.length === 0" class="empty-tip">暂无数据</view>
|
||
<template v-else>
|
||
<view
|
||
class="library-item"
|
||
v-for="item in libraryList"
|
||
:key="item.id"
|
||
@click="toggleLibrarySelect(item)"
|
||
>
|
||
<view class="library-checkbox" :class="{ 'library-checkbox-active': selectedLibraries.includes(item.id) }">
|
||
<text v-if="selectedLibraries.includes(item.id)" class="cuIcon-check"></text>
|
||
</view>
|
||
<view class="library-info">
|
||
<view class="library-name">关联表名:{{ item.name }}</view>
|
||
<view class="library-count">共{{ item.pointCount }}项</view>
|
||
</view>
|
||
</view>
|
||
<view v-if="libraryLoading" class="loading-tip">加载中...</view>
|
||
</template>
|
||
</scroll-view>
|
||
|
||
<button class="btn-add-library" @click="addSelectedLibrary">添加选中项</button>
|
||
</view>
|
||
</u-popup>
|
||
|
||
<!-- 执行人员选择弹窗 -->
|
||
<u-popup :show="showExecutorPopup" mode="center" round="20" @close="showExecutorPopup = false">
|
||
<view class="executor-popup">
|
||
<view class="popup-header">
|
||
<view class="popup-title">选择执行人员</view>
|
||
<view class="popup-close" @click="showExecutorPopup = false">×</view>
|
||
</view>
|
||
|
||
<scroll-view class="executor-list" scroll-y>
|
||
<view v-if="executorList.length === 0" class="empty-tip">暂无人员数据</view>
|
||
<view
|
||
v-else
|
||
class="executor-item"
|
||
v-for="item in executorList"
|
||
:key="item.userId"
|
||
@click="toggleExecutorSelect(item)"
|
||
>
|
||
<view class="executor-checkbox" :class="{ 'executor-checkbox-active': selectedExecutorIds.includes(item.userId) }">
|
||
<text v-if="selectedExecutorIds.includes(item.userId)" class="cuIcon-check"></text>
|
||
</view>
|
||
<view class="executor-info">
|
||
<text class="executor-name">{{ item.nickName }}</text>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
|
||
<view class="popup-footer">
|
||
<button class="btn-cancel" @click="showExecutorPopup = false">取消</button>
|
||
<button class="btn-confirm" @click="confirmExecutorSelect">确定</button>
|
||
</view>
|
||
</view>
|
||
</u-popup>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, reactive, computed } from 'vue';
|
||
import { getRegulationList, addCheckPoint, detailcheckPoint, deleteCheckPoint, getCheckItemList, getCheckItemListDetail, getDeptUsers, getParentDepts, addCheckTable } from '@/request/api.js';
|
||
import { onMounted } from 'vue';
|
||
|
||
// 表单数据
|
||
const formData = reactive({
|
||
name: '',
|
||
deptId: '',
|
||
deptName: '',
|
||
remark: '',
|
||
type: '', // 检查表类型:1-日常检查,2-专项检查,3-设备检查
|
||
typeName: '',
|
||
modeId: '',
|
||
modeName: '',
|
||
selectDeptId: '',
|
||
selectDeptName: '',
|
||
executorIds: [], // 执行人员ID数组
|
||
executorNames: '', // 执行人员名称(显示用)
|
||
cycleId: '',
|
||
cycleName: '',
|
||
startDate: '',
|
||
endDate: ''
|
||
});
|
||
|
||
// 工作日开关(单独定义避免页面闪烁)
|
||
const workdaySwitch = ref(false);
|
||
const onSwitchChange = (e) => {
|
||
workdaySwitch.value = e.detail.value;
|
||
};
|
||
|
||
// 日期选择器值
|
||
const startDateValue = ref(Number(new Date()));
|
||
const endDateValue = ref(Number(new Date()));
|
||
|
||
// 选择器显示控制
|
||
const showDeptPicker = ref(false);
|
||
const showTypePicker = ref(false);
|
||
const showModePicker = ref(false);
|
||
const showDeptSelectPicker = ref(false);
|
||
const showCyclePicker = ref(false);
|
||
const showStartDatePicker = ref(false);
|
||
const showEndDatePicker = ref(false);
|
||
|
||
// 选择器数据
|
||
const deptColumns = ref([['湘西自治州和谐网络科技有限公司', '湘西自治州和谐云大数据科技有限公司', '湘西网络有限公司']]);
|
||
const typeColumns = ref([['日常检查', '专项检查', '设备检查']]);
|
||
const modeColumns = ref([['全员', '指定人员']]);
|
||
const cycleColumns = ref([['每天一次', '每周一次', '每月一次', '每季度一次']]);
|
||
|
||
// 执行人员选择器
|
||
const showExecutorPopup = ref(false);
|
||
const executorList = ref([]);
|
||
const selectedExecutorIds = ref([]);
|
||
|
||
// 分派单位级联选择器
|
||
const deptTree = ref([]);
|
||
const deptCascaderColumns = ref([]);
|
||
const deptCascaderIndexs = ref([0]);
|
||
const selectedDeptPath = ref([]); // 选中的路径
|
||
|
||
// 选择器确认回调
|
||
const onDeptConfirm = (e) => {
|
||
// 获取最后选中的部门
|
||
const lastSelected = selectedDeptPath.value[selectedDeptPath.value.length - 1];
|
||
if (lastSelected) {
|
||
formData.deptId = lastSelected.deptId;
|
||
formData.deptName = selectedDeptPath.value.map(d => d.deptName).join(' / ');
|
||
}
|
||
showDeptPicker.value = false;
|
||
};
|
||
|
||
// 检查表类型映射:日常检查->1, 专项检查->2, 设备检查->3
|
||
const typeMap = {
|
||
'日常检查': 1,
|
||
'专项检查': 2,
|
||
'设备检查': 3
|
||
};
|
||
|
||
const onTypeConfirm = (e) => {
|
||
if (e.value && e.value.length > 0) {
|
||
formData.typeName = e.value[0];
|
||
formData.type = typeMap[e.value[0]];
|
||
}
|
||
showTypePicker.value = false;
|
||
};
|
||
|
||
const onModeConfirm = (e) => {
|
||
if (e.value && e.value.length > 0) {
|
||
formData.modeName = e.value[0];
|
||
// 如果切换到全员,清空执行人员选择
|
||
if (e.value[0] === '全员') {
|
||
formData.executorIds = [];
|
||
formData.executorNames = '';
|
||
selectedExecutorIds.value = [];
|
||
}
|
||
}
|
||
showModePicker.value = false;
|
||
};
|
||
|
||
// 获取当前部门用户列表
|
||
const fetchDeptUsers = async () => {
|
||
try {
|
||
const res = await getDeptUsers();
|
||
if (res.code === 0 && res.data) {
|
||
executorList.value = res.data || [];
|
||
}
|
||
} catch (error) {
|
||
console.error('获取部门用户失败:', error);
|
||
}
|
||
};
|
||
|
||
// 切换执行人员选择
|
||
const toggleExecutorSelect = (item) => {
|
||
const index = selectedExecutorIds.value.indexOf(item.userId);
|
||
if (index > -1) {
|
||
selectedExecutorIds.value.splice(index, 1);
|
||
} else {
|
||
selectedExecutorIds.value.push(item.userId);
|
||
}
|
||
};
|
||
|
||
// 确认执行人员选择
|
||
const confirmExecutorSelect = () => {
|
||
formData.executorIds = [...selectedExecutorIds.value];
|
||
const selectedUsers = executorList.value.filter(u => selectedExecutorIds.value.includes(u.userId));
|
||
formData.executorNames = selectedUsers.map(u => u.nickName).join('、');
|
||
showExecutorPopup.value = false;
|
||
};
|
||
|
||
// 打开执行人员选择弹窗
|
||
const openExecutorPopup = () => {
|
||
selectedExecutorIds.value = [...formData.executorIds];
|
||
showExecutorPopup.value = true;
|
||
};
|
||
|
||
// 获取父级部门列表(树形结构)
|
||
const fetchParentDepts = async () => {
|
||
try {
|
||
const res = await getParentDepts();
|
||
if (res.code === 0 && res.data) {
|
||
deptTree.value = res.data;
|
||
// 初始化级联选择器第一列
|
||
initDeptCascader(res.data);
|
||
}
|
||
} catch (error) {
|
||
console.error('获取部门树失败:', error);
|
||
}
|
||
};
|
||
|
||
// 初始化部门级联选择器
|
||
const initDeptCascader = (data) => {
|
||
if (!data) return;
|
||
// 第一列数据
|
||
const firstColumn = buildDeptColumn(data);
|
||
deptCascaderColumns.value = [firstColumn];
|
||
deptCascaderIndexs.value = [0];
|
||
selectedDeptPath.value = [data];
|
||
// 如果有子级,添加下一列
|
||
if (data.children && data.children.length > 0) {
|
||
const secondColumn = data.children.map(item => ({ text: item.deptName, ...item }));
|
||
deptCascaderColumns.value.push(secondColumn);
|
||
deptCascaderIndexs.value.push(0);
|
||
selectedDeptPath.value.push(data.children[0]);
|
||
// 检查是否还有下一级
|
||
if (data.children[0].children && data.children[0].children.length > 0) {
|
||
const thirdColumn = data.children[0].children.map(item => ({ text: item.deptName, ...item }));
|
||
deptCascaderColumns.value.push(thirdColumn);
|
||
deptCascaderIndexs.value.push(0);
|
||
selectedDeptPath.value.push(data.children[0].children[0]);
|
||
}
|
||
}
|
||
};
|
||
|
||
// 构建部门列数据
|
||
const buildDeptColumn = (data) => {
|
||
return [{ text: data.deptName, ...data }];
|
||
};
|
||
|
||
// 部门级联选择器列改变
|
||
const onDeptCascaderChange = (e) => {
|
||
const { columnIndex, index, value } = e;
|
||
|
||
// 更新当前列的选中索引
|
||
deptCascaderIndexs.value[columnIndex] = index;
|
||
|
||
// 更新选中路径
|
||
selectedDeptPath.value[columnIndex] = value;
|
||
|
||
// 删除后续列
|
||
deptCascaderColumns.value = deptCascaderColumns.value.slice(0, columnIndex + 1);
|
||
deptCascaderIndexs.value = deptCascaderIndexs.value.slice(0, columnIndex + 1);
|
||
selectedDeptPath.value = selectedDeptPath.value.slice(0, columnIndex + 1);
|
||
|
||
// 如果有子级,添加新列
|
||
if (value.children && value.children.length > 0) {
|
||
const nextColumn = value.children.map(item => ({ text: item.deptName, ...item }));
|
||
deptCascaderColumns.value.push(nextColumn);
|
||
deptCascaderIndexs.value.push(0);
|
||
selectedDeptPath.value.push(value.children[0]);
|
||
|
||
// 继续检查是否有下下级
|
||
if (value.children[0].children && value.children[0].children.length > 0) {
|
||
const thirdColumn = value.children[0].children.map(item => ({ text: item.deptName, ...item }));
|
||
deptCascaderColumns.value.push(thirdColumn);
|
||
deptCascaderIndexs.value.push(0);
|
||
selectedDeptPath.value.push(value.children[0].children[0]);
|
||
}
|
||
}
|
||
};
|
||
|
||
const onDeptSelectConfirm = (e) => {
|
||
if (e.value && e.value.length > 0) {
|
||
formData.selectDeptName = e.value[0];
|
||
}
|
||
showDeptSelectPicker.value = false;
|
||
};
|
||
|
||
const onCycleConfirm = (e) => {
|
||
if (e.value && e.value.length > 0) {
|
||
formData.cycleName = e.value[0];
|
||
}
|
||
showCyclePicker.value = false;
|
||
};
|
||
|
||
// 日期时间格式化(精确到时分秒)
|
||
const formatDateTime = (timestamp) => {
|
||
const date = new Date(timestamp);
|
||
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');
|
||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||
};
|
||
|
||
const onStartDateConfirm = (e) => {
|
||
formData.startDate = formatDateTime(e.value);
|
||
showStartDatePicker.value = false;
|
||
};
|
||
|
||
const onEndDateConfirm = (e) => {
|
||
formData.endDate = formatDateTime(e.value);
|
||
showEndDatePicker.value = false;
|
||
};
|
||
|
||
// 手动添加的检查项列表
|
||
const manualCheckItems = ref([]);
|
||
|
||
// 从检查库添加的检查项
|
||
const checkItems = ref([]);
|
||
|
||
// 检查项数量(手动添加的数量 + 检查库的数量)
|
||
const checkItemCount = computed(() => {
|
||
const libraryCount = checkItems.value.reduce((sum, item) => sum + item.count, 0);
|
||
return manualCheckItems.value.length + libraryCount;
|
||
});
|
||
|
||
// 删除手动添加的检查项(调用接口删除)
|
||
const deleteManualCheckItem = (item, index) => {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '确定要删除该检查项吗?',
|
||
confirmColor: '#F56C6C',
|
||
success: async (res) => {
|
||
if (res.confirm) {
|
||
// 手动添加的检查项有id,需要调用接口删除
|
||
if (item.id) {
|
||
try {
|
||
uni.showLoading({ title: '删除中...' });
|
||
const result = await deleteCheckPoint({ id: item.id });
|
||
uni.hideLoading();
|
||
if (result.code === 0) {
|
||
manualCheckItems.value.splice(index, 1);
|
||
uni.showToast({ title: '删除成功', icon: 'success' });
|
||
} else {
|
||
uni.showToast({ title: result.msg || '删除失败', icon: 'none' });
|
||
}
|
||
} catch (error) {
|
||
uni.hideLoading();
|
||
console.error('删除检查项失败:', error);
|
||
uni.showToast({ title: '删除失败', icon: 'none' });
|
||
}
|
||
} else {
|
||
// 没有id的情况(理论上不应该出现),直接从本地移除
|
||
manualCheckItems.value.splice(index, 1);
|
||
uni.showToast({ title: '删除成功', icon: 'success' });
|
||
}
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
// 删除检查库中的检查项(只从本地暂存删除,不调用接口)
|
||
const deleteCheckItem = (index) => {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '确定要删除该检查项吗?',
|
||
confirmColor: '#F56C6C',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
checkItems.value.splice(index, 1);
|
||
uni.showToast({ title: '删除成功', icon: 'success' });
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
// 手动添加检查项弹窗
|
||
const showAddPopup = ref(false);
|
||
const checkForm = reactive({
|
||
name: '', // 检查名称
|
||
point: '', // 检查内容
|
||
regulationId: null, // 参考法规ID
|
||
regulationName: '' // 参考法规名称(显示用)
|
||
});
|
||
|
||
// 选择法规弹窗
|
||
const showLawPopup = ref(false);
|
||
const lawKeyword = ref('');
|
||
const selectedLawId = ref(null);
|
||
const selectedLawName = ref('');
|
||
const lawList = ref([]);
|
||
const lawLoading = ref(false);
|
||
const lawPageNum = ref(1);
|
||
const lawPageSize = ref(10);
|
||
const hasMoreLaw = ref(true);
|
||
|
||
// 打开法规选择弹窗
|
||
const openLawPopup = () => {
|
||
showLawPopup.value = true;
|
||
// 如果列表为空,加载数据
|
||
if (lawList.value.length === 0) {
|
||
fetchRegulationList();
|
||
}
|
||
};
|
||
|
||
// 获取法规列表
|
||
const fetchRegulationList = async (isLoadMore = false) => {
|
||
if (lawLoading.value) return;
|
||
|
||
lawLoading.value = true;
|
||
try {
|
||
// 构建参数,只传有值的字段
|
||
const params = {
|
||
pageNum: lawPageNum.value,
|
||
pageSize: lawPageSize.value,
|
||
status: 1 // 启用状态
|
||
};
|
||
// keyword 有值时才传
|
||
if (lawKeyword.value && lawKeyword.value.trim()) {
|
||
params.keyword = lawKeyword.value.trim();
|
||
}
|
||
|
||
const res = await getRegulationList(params);
|
||
if (res.code === 0) {
|
||
const records = res.data.records || res.data || [];
|
||
if (isLoadMore) {
|
||
lawList.value = [...lawList.value, ...records];
|
||
} else {
|
||
lawList.value = records;
|
||
}
|
||
// 判断是否还有更多
|
||
const total = res.data.total || 0;
|
||
hasMoreLaw.value = lawList.value.length < total;
|
||
}
|
||
} catch (error) {
|
||
console.error('获取法规列表失败:', error);
|
||
} finally {
|
||
lawLoading.value = false;
|
||
}
|
||
};
|
||
|
||
// 搜索法规
|
||
const searchRegulation = () => {
|
||
lawPageNum.value = 1;
|
||
lawList.value = [];
|
||
hasMoreLaw.value = true;
|
||
fetchRegulationList();
|
||
};
|
||
|
||
// 加载更多法规
|
||
const loadMoreLaw = () => {
|
||
if (!hasMoreLaw.value || lawLoading.value) return;
|
||
lawPageNum.value++;
|
||
fetchRegulationList(true);
|
||
};
|
||
|
||
// 选择法规
|
||
const selectLaw = (item) => {
|
||
selectedLawId.value = item.id;
|
||
// 用 depict(描述)作为显示名称
|
||
selectedLawName.value = item.depict || item.keyword || '';
|
||
};
|
||
|
||
// 确认选择法规
|
||
const confirmLaw = () => {
|
||
if (selectedLawId.value) {
|
||
checkForm.regulationId = selectedLawId.value;
|
||
checkForm.regulationName = selectedLawName.value;
|
||
}
|
||
showLawPopup.value = false;
|
||
};
|
||
|
||
// 提交手动添加的检查项
|
||
const handleAddCheck = async () => {
|
||
if (!checkForm.name) {
|
||
uni.showToast({ title: '请输入检查名称', icon: 'none' });
|
||
return;
|
||
}
|
||
if (!checkForm.point) {
|
||
uni.showToast({ title: '请输入检查内容', icon: 'none' });
|
||
return;
|
||
}
|
||
|
||
try {
|
||
uni.showLoading({ title: '添加中...' });
|
||
|
||
// 调用接口新增检查项
|
||
const params = {
|
||
name: checkForm.name,
|
||
point: checkForm.point,
|
||
regulationId: checkForm.regulationId || undefined
|
||
};
|
||
|
||
const res = await addCheckPoint(params);
|
||
|
||
if (res.code === 0) {
|
||
// 新增成功后,获取详情
|
||
const checkPointId = res.data?.id || res.data;
|
||
if (checkPointId) {
|
||
const detailRes = await detailcheckPoint(checkPointId);
|
||
if (detailRes.code === 0 && detailRes.data) {
|
||
// 添加到手动检查项列表
|
||
manualCheckItems.value.push({
|
||
id: detailRes.data.id,
|
||
name: detailRes.data.name,
|
||
point: detailRes.data.point,
|
||
regulationId: detailRes.data.regulationId,
|
||
regulationName: detailRes.data.regulationName || checkForm.regulationName
|
||
});
|
||
}
|
||
} else {
|
||
// 如果没有返回ID,直接用表单数据添加
|
||
manualCheckItems.value.push({
|
||
name: checkForm.name,
|
||
point: checkForm.point,
|
||
regulationId: checkForm.regulationId,
|
||
regulationName: checkForm.regulationName
|
||
});
|
||
}
|
||
|
||
uni.hideLoading();
|
||
uni.showToast({ title: '添加成功', icon: 'success' });
|
||
showAddPopup.value = false;
|
||
|
||
// 重置表单
|
||
checkForm.name = '';
|
||
checkForm.point = '';
|
||
checkForm.regulationId = null;
|
||
checkForm.regulationName = '';
|
||
} else {
|
||
uni.hideLoading();
|
||
uni.showToast({ title: res.msg || '添加失败', icon: 'none' });
|
||
}
|
||
} catch (error) {
|
||
uni.hideLoading();
|
||
console.error('添加检查项失败:', error);
|
||
uni.showToast({ title: '添加失败', icon: 'none' });
|
||
}
|
||
};
|
||
|
||
// 从检查库添加弹窗
|
||
const showLibraryPopup = ref(false);
|
||
const libraryKeyword = ref('');
|
||
const selectedLibraries = ref([]);
|
||
const libraryList = ref([]);
|
||
const libraryLoading = ref(false);
|
||
const libraryPageNum = ref(1);
|
||
const libraryPageSize = ref(10);
|
||
const hasMoreLibrary = ref(true);
|
||
|
||
// 打开检查库弹窗时获取数据
|
||
const openLibraryPopup = () => {
|
||
showLibraryPopup.value = true;
|
||
libraryKeyword.value = '';
|
||
libraryPageNum.value = 1;
|
||
libraryList.value = [];
|
||
hasMoreLibrary.value = true;
|
||
selectedLibraries.value = [];
|
||
fetchLibraryList();
|
||
};
|
||
|
||
// 关闭检查库弹窗
|
||
const closeLibraryPopup = () => {
|
||
showLibraryPopup.value = false;
|
||
selectedLibraries.value = [];
|
||
};
|
||
|
||
// 获取检查库列表
|
||
const fetchLibraryList = async (isLoadMore = false) => {
|
||
if (libraryLoading.value) return;
|
||
|
||
libraryLoading.value = true;
|
||
try {
|
||
const params = {
|
||
pageNum: libraryPageNum.value,
|
||
pageSize: libraryPageSize.value
|
||
};
|
||
// name 有值时才传
|
||
if (libraryKeyword.value && libraryKeyword.value.trim()) {
|
||
params.name = libraryKeyword.value.trim();
|
||
}
|
||
|
||
const res = await getCheckItemList(params);
|
||
if (res.code === 0) {
|
||
const records = res.data.records || [];
|
||
if (isLoadMore) {
|
||
libraryList.value = [...libraryList.value, ...records];
|
||
} else {
|
||
libraryList.value = records;
|
||
}
|
||
// 判断是否还有更多
|
||
const total = res.data.total || 0;
|
||
hasMoreLibrary.value = libraryList.value.length < total;
|
||
}
|
||
} catch (error) {
|
||
console.error('获取检查库列表失败:', error);
|
||
} finally {
|
||
libraryLoading.value = false;
|
||
}
|
||
};
|
||
|
||
// 搜索检查库
|
||
const searchLibrary = () => {
|
||
libraryPageNum.value = 1;
|
||
libraryList.value = [];
|
||
hasMoreLibrary.value = true;
|
||
fetchLibraryList();
|
||
};
|
||
|
||
// 加载更多检查库
|
||
const loadMoreLibrary = () => {
|
||
if (!hasMoreLibrary.value || libraryLoading.value) return;
|
||
libraryPageNum.value++;
|
||
fetchLibraryList(true);
|
||
};
|
||
|
||
const toggleLibrarySelect = (item) => {
|
||
const index = selectedLibraries.value.indexOf(item.id);
|
||
if (index > -1) {
|
||
selectedLibraries.value.splice(index, 1);
|
||
} else {
|
||
selectedLibraries.value.push(item.id);
|
||
}
|
||
};
|
||
|
||
// 添加选中的检查库
|
||
const addSelectedLibrary = async () => {
|
||
if (selectedLibraries.value.length === 0) {
|
||
uni.showToast({ title: '请选择检查库', icon: 'none' });
|
||
return;
|
||
}
|
||
|
||
uni.showLoading({ title: '加载中...' });
|
||
|
||
try {
|
||
// 遍历选中的检查库,获取详情
|
||
for (const id of selectedLibraries.value) {
|
||
const res = await getCheckItemListDetail({ itemId: id });
|
||
if (res.code === 0 && res.data) {
|
||
const records = res.data.records || [];
|
||
const total = res.data.total || 0;
|
||
// 获取关联表名(第一项的name)
|
||
const tableName = records.length > 0 ? records[0].name : '';
|
||
|
||
// 添加到检查项列表
|
||
checkItems.value.push({
|
||
itemId: id,
|
||
tableName: tableName,
|
||
count: total,
|
||
details: records // 保存详情数据,以便后续使用
|
||
});
|
||
}
|
||
}
|
||
|
||
uni.hideLoading();
|
||
uni.showToast({ title: '添加成功', icon: 'success' });
|
||
showLibraryPopup.value = false;
|
||
selectedLibraries.value = [];
|
||
} catch (error) {
|
||
uni.hideLoading();
|
||
console.error('获取检查库详情失败:', error);
|
||
uni.showToast({ title: '添加失败', icon: 'none' });
|
||
}
|
||
};
|
||
|
||
// 保存
|
||
const handleSave = async () => {
|
||
// 表单验证
|
||
if (!formData.name) {
|
||
uni.showToast({ title: '请输入检查表名称', icon: 'none' });
|
||
return;
|
||
}
|
||
if (!formData.deptId) {
|
||
uni.showToast({ title: '请选择分派单位', icon: 'none' });
|
||
return;
|
||
}
|
||
if (!formData.type) {
|
||
uni.showToast({ title: '请选择检查表类型', icon: 'none' });
|
||
return;
|
||
}
|
||
if (!formData.modeName) {
|
||
uni.showToast({ title: '请选择运行模式', icon: 'none' });
|
||
return;
|
||
}
|
||
// 如果选择指定人员,需要选择执行人员
|
||
if (formData.modeName === '指定人员' && formData.executorIds.length === 0) {
|
||
uni.showToast({ title: '请选择执行人员', icon: 'none' });
|
||
return;
|
||
}
|
||
if (!formData.cycleName) {
|
||
uni.showToast({ title: '请选择周期', icon: 'none' });
|
||
return;
|
||
}
|
||
if (!formData.startDate || !formData.endDate) {
|
||
uni.showToast({ title: '请选择计划时间', icon: 'none' });
|
||
return;
|
||
}
|
||
|
||
// 构建 items 数组(关联检查项id列表)
|
||
const items = [];
|
||
// 添加手动添加的检查项id
|
||
manualCheckItems.value.forEach(item => {
|
||
if (item.id) {
|
||
items.push(item.id );
|
||
}
|
||
});
|
||
// 添加从检查库选择的检查项详情中的所有项的 pointId
|
||
checkItems.value.forEach(lib => {
|
||
if (lib.details && lib.details.length > 0) {
|
||
lib.details.forEach(detail => {
|
||
if (detail.pointId) {
|
||
items.push(detail.pointId );
|
||
}
|
||
});
|
||
}
|
||
});
|
||
|
||
if (items.length === 0) {
|
||
uni.showToast({ title: '请添加检查项', icon: 'none' });
|
||
return;
|
||
}
|
||
|
||
// 运行模式映射:指定人员=1,全员=2
|
||
const runModeMap = {
|
||
'指定人员': 1,
|
||
'全员': 2
|
||
};
|
||
|
||
// 周期映射:每天=1,每周=2,每月=3,每季度=4
|
||
const cycleMap = {
|
||
'每天一次': 1,
|
||
'每周一次': 2,
|
||
'每月一次': 3,
|
||
'每季度一次': 4
|
||
};
|
||
|
||
// 构建 itemIds 数组(从检查库选择的检查库id列表)
|
||
const itemIds = [];
|
||
checkItems.value.forEach(lib => {
|
||
if (lib.itemId) {
|
||
itemIds.push(lib.itemId);
|
||
}
|
||
});
|
||
|
||
// 构建提交参数
|
||
const params = {
|
||
name: formData.name,
|
||
deptId: formData.deptId,
|
||
description: formData.remark || '',
|
||
type: formData.type, // 检查表类型:1-日常检查,2-专项检查,3-设备检查
|
||
runMode: runModeMap[formData.modeName] || 2,
|
||
checkPointIds: items,
|
||
itemIds: itemIds, // 从检查库选择的库id数组
|
||
cycle: cycleMap[formData.cycleName] || 1,
|
||
isWeekend: workdaySwitch.value ? 1 : 2,
|
||
planStartTime: formData.startDate,
|
||
planEndTime: formData.endDate
|
||
};
|
||
|
||
// 如果是指定人员模式,添加执行人员id
|
||
if (formData.modeName === '指定人员' && formData.executorIds.length > 0) {
|
||
params.executorId = formData.executorIds[0]; // 如果只能选一个执行人员
|
||
// 如果支持多个执行人员,可以改为:params.executorIds = formData.executorIds;
|
||
}
|
||
|
||
try {
|
||
uni.showLoading({ title: '保存中...' });
|
||
const res = await addCheckTable(params);
|
||
uni.hideLoading();
|
||
|
||
if (res.code === 0) {
|
||
uni.showToast({ title: '保存成功', icon: 'success' });
|
||
setTimeout(() => {
|
||
uni.navigateBack();
|
||
}, 1500);
|
||
} else {
|
||
uni.showToast({ title: res.msg || '保存失败', icon: 'none' });
|
||
}
|
||
} catch (error) {
|
||
uni.hideLoading();
|
||
console.error('保存失败:', error);
|
||
uni.showToast({ title: '保存失败', icon: 'none' });
|
||
}
|
||
};
|
||
|
||
// 页面加载时获取数据
|
||
onMounted(() => {
|
||
fetchDeptUsers();
|
||
fetchParentDepts();
|
||
});
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.page {
|
||
min-height: 100vh;
|
||
background: #EBF2FC;
|
||
padding: 24rpx;
|
||
padding-bottom: 140rpx;
|
||
}
|
||
|
||
// 表单卡片
|
||
.form-card {
|
||
background: #fff;
|
||
border-radius: 16rpx;
|
||
padding: 30rpx;
|
||
margin-bottom: 80rpx;
|
||
}
|
||
|
||
// 表单项
|
||
.form-item {
|
||
margin-bottom: 32rpx;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
|
||
// 表单标题
|
||
.form-label {
|
||
font-size: 28rpx;
|
||
color: #999;
|
||
margin-bottom: 16rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.required {
|
||
color: #F56C6C;
|
||
margin-left: 4rpx;
|
||
}
|
||
}
|
||
|
||
// 蓝色标题
|
||
.label-blue {
|
||
color: #2667E9;
|
||
}
|
||
|
||
// 选择器输入框
|
||
.picker-input {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
height: 88rpx;
|
||
background: #fff;
|
||
border: 2rpx solid #E5E5E5;
|
||
border-radius: 8rpx;
|
||
padding: 0 24rpx;
|
||
|
||
.picker-value {
|
||
color: #333;
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
.picker-placeholder {
|
||
color: #C0C4CC;
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
.picker-arrow {
|
||
color: #C0C4CC;
|
||
font-size: 24rpx;
|
||
}
|
||
}
|
||
|
||
// 开关行
|
||
.switch-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 30rpx;
|
||
}
|
||
|
||
// 空状态提示
|
||
.empty-check-tip {
|
||
text-align: center;
|
||
padding: 60rpx 0;
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
// 检查项卡片
|
||
.check-card {
|
||
background: #F8FAFF;
|
||
border-left: 6rpx solid #2667E9;
|
||
border-radius: 8rpx;
|
||
padding: 24rpx;
|
||
padding-bottom: 80rpx;
|
||
margin-bottom: 20rpx;
|
||
position: relative;
|
||
|
||
.check-info {
|
||
.info-row {
|
||
display: flex;
|
||
margin-bottom: 16rpx;
|
||
font-size: 26rpx;
|
||
line-height: 1.5;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.info-label {
|
||
color: #666;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.info-label-bold {
|
||
font-weight: bold;
|
||
}
|
||
|
||
.info-value {
|
||
color: #333;
|
||
flex: 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
.check-action {
|
||
position: absolute;
|
||
right: 20rpx;
|
||
bottom: 20rpx;
|
||
|
||
.btn-delete {
|
||
width: 120rpx;
|
||
height: 56rpx;
|
||
line-height: 56rpx;
|
||
background: #F56C6C;
|
||
color: #fff;
|
||
font-size: 26rpx;
|
||
border-radius: 8rpx;
|
||
padding: 0;
|
||
|
||
&::after {
|
||
border: none;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 手动添加的检查项卡片(带第x项标签)
|
||
.manual-card {
|
||
padding-top: 50rpx;
|
||
|
||
.card-tag {
|
||
position: absolute;
|
||
left: 0;
|
||
top: 0;
|
||
background: #2667E9;
|
||
color: #fff;
|
||
font-size: 24rpx;
|
||
padding: 6rpx 20rpx;
|
||
border-radius: 0 0 12rpx 0;
|
||
}
|
||
}
|
||
|
||
// 添加按钮组
|
||
.add-btns {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
gap: 24rpx;
|
||
|
||
.btn-add {
|
||
flex: 1;
|
||
height: 72rpx;
|
||
line-height: 72rpx;
|
||
background: #fff;
|
||
border: 2rpx solid #2667E9;
|
||
border-radius: 8rpx;
|
||
color: #2667E9;
|
||
font-size: 28rpx;
|
||
padding: 0;
|
||
|
||
&::after {
|
||
border: none;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 底部保存按钮
|
||
.footer-btn {
|
||
position: fixed;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
padding: 20rpx 40rpx;
|
||
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
||
background: #EBF2FC;
|
||
|
||
.btn-save {
|
||
width: 100%;
|
||
height: 88rpx;
|
||
line-height: 88rpx;
|
||
background: #2667E9;
|
||
color: #fff;
|
||
font-size: 32rpx;
|
||
border-radius: 44rpx;
|
||
|
||
&::after {
|
||
border: none;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 弹出框样式
|
||
.popup-content {
|
||
width: 600rpx;
|
||
background: #fff;
|
||
border-radius: 20rpx;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.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;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.popup-close {
|
||
font-size: 48rpx;
|
||
color: #999;
|
||
line-height: 1;
|
||
}
|
||
|
||
.popup-body {
|
||
padding: 30rpx;
|
||
max-height: 700rpx;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.popup-form-item {
|
||
margin-bottom: 24rpx;
|
||
}
|
||
|
||
.popup-form-label {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
margin-bottom: 12rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.required {
|
||
color: #F56C6C;
|
||
margin-left: 4rpx;
|
||
}
|
||
}
|
||
|
||
.popup-select {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
min-height: 80rpx;
|
||
border: 2rpx solid #E5E5E5;
|
||
border-radius: 8rpx;
|
||
padding: 0 24rpx;
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
.regulation-select {
|
||
align-items: flex-start;
|
||
padding: 20rpx 24rpx;
|
||
|
||
.regulation-text {
|
||
flex: 1;
|
||
line-height: 1.5;
|
||
word-break: break-all;
|
||
}
|
||
|
||
.select-icon {
|
||
flex-shrink: 0;
|
||
margin-left: 16rpx;
|
||
margin-top: 4rpx;
|
||
}
|
||
}
|
||
|
||
.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 {
|
||
background: #2667E9;
|
||
color: #fff;
|
||
}
|
||
}
|
||
|
||
// 选择法规弹窗
|
||
.law-popup {
|
||
width: 600rpx;
|
||
background: #fff;
|
||
border-radius: 20rpx;
|
||
overflow: hidden;
|
||
max-height: 80vh;
|
||
}
|
||
|
||
.search-box {
|
||
display: flex;
|
||
align-items: center;
|
||
background: #F5F5F5;
|
||
border-radius: 40rpx;
|
||
padding: 16rpx 24rpx;
|
||
margin: 20rpx 30rpx;
|
||
|
||
.search-icon {
|
||
font-size: 28rpx;
|
||
color: #999;
|
||
margin-right: 12rpx;
|
||
}
|
||
|
||
.search-input {
|
||
flex: 1;
|
||
font-size: 28rpx;
|
||
background: transparent;
|
||
}
|
||
|
||
.search-btn {
|
||
color: #2667E9;
|
||
font-size: 26rpx;
|
||
margin-left: 16rpx;
|
||
}
|
||
}
|
||
|
||
.loading-tip, .empty-tip {
|
||
text-align: center;
|
||
padding: 40rpx;
|
||
color: #999;
|
||
font-size: 26rpx;
|
||
}
|
||
|
||
.law-list {
|
||
max-height: 400rpx;
|
||
padding: 0 30rpx;
|
||
}
|
||
|
||
.law-item {
|
||
padding: 24rpx;
|
||
border: 2rpx solid #E5E5E5;
|
||
border-radius: 12rpx;
|
||
margin-bottom: 16rpx;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
|
||
.law-title {
|
||
line-height: 1.5;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.law-basis {
|
||
font-size: 24rpx;
|
||
line-height: 1.4;
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 2;
|
||
-webkit-box-orient: vertical;
|
||
overflow: hidden;
|
||
}
|
||
}
|
||
|
||
.law-item-active {
|
||
border-color: #2667E9;
|
||
background: #F0F6FF;
|
||
}
|
||
|
||
.load-more {
|
||
text-align: center;
|
||
padding: 20rpx;
|
||
margin: 0 30rpx;
|
||
border: 2rpx solid #2667E9;
|
||
border-radius: 40rpx;
|
||
}
|
||
|
||
// 检查库弹窗样式
|
||
.library-popup {
|
||
width: 600rpx;
|
||
background: #fff;
|
||
border-radius: 20rpx;
|
||
overflow: hidden;
|
||
max-height: 80vh;
|
||
}
|
||
|
||
.library-list {
|
||
max-height: 400rpx;
|
||
padding: 0 30rpx;
|
||
}
|
||
|
||
.library-item {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
padding: 24rpx;
|
||
border: 2rpx solid #E5E5E5;
|
||
border-radius: 12rpx;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.library-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;
|
||
margin-top: 4rpx;
|
||
font-size: 24rpx;
|
||
}
|
||
|
||
.library-checkbox-active {
|
||
background: #2667E9;
|
||
border-color: #2667E9;
|
||
color: #fff;
|
||
}
|
||
|
||
.library-info {
|
||
flex: 1;
|
||
}
|
||
|
||
.library-name {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.library-count {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
margin-top: 8rpx;
|
||
}
|
||
|
||
.btn-add-library {
|
||
width: calc(100% - 60rpx);
|
||
height: 80rpx;
|
||
line-height: 80rpx;
|
||
background: #2667E9;
|
||
border-radius: 40rpx;
|
||
color: #fff;
|
||
font-size: 30rpx;
|
||
margin: 20rpx 30rpx;
|
||
|
||
&::after {
|
||
border: none;
|
||
}
|
||
}
|
||
|
||
// 执行人员弹窗样式
|
||
.executor-popup {
|
||
width: 600rpx;
|
||
background: #fff;
|
||
border-radius: 20rpx;
|
||
overflow: hidden;
|
||
max-height: 80vh;
|
||
}
|
||
|
||
.executor-list {
|
||
max-height: 500rpx;
|
||
padding: 0 30rpx;
|
||
}
|
||
|
||
.executor-item {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 24rpx;
|
||
border-bottom: 1rpx solid #f0f0f0;
|
||
}
|
||
|
||
.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;
|
||
}
|
||
|
||
.executor-checkbox-active {
|
||
background: #2667E9;
|
||
border-color: #2667E9;
|
||
color: #fff;
|
||
}
|
||
|
||
.executor-info {
|
||
flex: 1;
|
||
}
|
||
|
||
.executor-name {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
}
|
||
</style>
|