一单四制优化及加入工作流
This commit is contained in:
@@ -16,21 +16,12 @@
|
||||
<text>分派单位</text>
|
||||
<text class="required">*</text>
|
||||
</view>
|
||||
<view class="picker-input" @click="showDeptPicker = true">
|
||||
<view class="picker-input" @click="openDeptPopup">
|
||||
<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>
|
||||
|
||||
<!-- 补充说明 -->
|
||||
@@ -377,6 +368,42 @@
|
||||
</view>
|
||||
</u-popup>
|
||||
|
||||
<!-- 分派单位选择弹窗 -->
|
||||
<u-popup :show="showDeptPicker" mode="center" round="20" :safeAreaInsetBottom="false" @close="cancelDeptSelect">
|
||||
<view class="dept-popup">
|
||||
<view class="popup-header">
|
||||
<view class="popup-title">选择分派单位</view>
|
||||
<view class="popup-close" @click="cancelDeptSelect">×</view>
|
||||
</view>
|
||||
|
||||
<view v-if="showDeptPicker" class="dept-tree-body">
|
||||
<xq-tree
|
||||
v-if="deptTree.length"
|
||||
ref="deptTreeRef"
|
||||
:data="deptTree"
|
||||
node-key="deptId"
|
||||
label-key="deptName"
|
||||
children-key="children"
|
||||
show-checkbox
|
||||
check-strictly
|
||||
default-expand-all
|
||||
:height="500"
|
||||
:width="560"
|
||||
:default-checked-keys="deptDefaultCheckedKeys"
|
||||
empty-text="暂无部门数据"
|
||||
@check="onDeptCheck"
|
||||
@node-click="onDeptNodeClick"
|
||||
/>
|
||||
<view v-else class="empty-tip">暂无部门数据</view>
|
||||
</view>
|
||||
|
||||
<view class="popup-footer">
|
||||
<button class="btn-cancel" @click="cancelDeptSelect">取消</button>
|
||||
<button class="btn-confirm" @click="confirmDeptSelect">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
|
||||
<!-- 执行人员选择弹窗 -->
|
||||
<u-popup :show="showExecutorPopup" mode="center" round="20" @close="showExecutorPopup = false">
|
||||
<view class="executor-popup">
|
||||
@@ -413,9 +440,8 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
import { ref, reactive, computed, onMounted, nextTick } from 'vue';
|
||||
import { getRegulationList, addCheckPoint, detailcheckPoint, deleteCheckPoint, getCheckItemList, getCheckItemListDetail, getDeptUsers, getDeptChildren, addCheckTable } from '@/request/api.js';
|
||||
import { onMounted } from 'vue';
|
||||
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
@@ -560,13 +586,11 @@ const endDateValue = ref(getTodayTimestamp());
|
||||
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([['每天一次', '每周一次', '每月一次', '每季度一次']]);
|
||||
@@ -576,23 +600,84 @@ const showExecutorPopup = ref(false);
|
||||
const executorList = ref([]);
|
||||
const selectedExecutorId = ref(null);
|
||||
|
||||
// 分派单位级联选择器
|
||||
// 分派单位树形选择器
|
||||
const deptTree = ref([]);
|
||||
const deptCascaderColumns = ref([]);
|
||||
const deptCascaderIndexs = ref([0]);
|
||||
const selectedDeptPath = ref([]); // 选中的路径
|
||||
const deptTreeRef = ref(null);
|
||||
const selectedDeptId = ref(null);
|
||||
const deptDefaultCheckedKeys = ref([]);
|
||||
|
||||
// 选择器确认回调
|
||||
const onDeptConfirm = () => {
|
||||
const lastSelected = selectedDeptPath.value[selectedDeptPath.value.length - 1]
|
||||
if (lastSelected) {
|
||||
formData.deptId = lastSelected.deptId
|
||||
formData.deptName = selectedDeptPath.value.map(d => d.deptName).join(' / ')
|
||||
clearExecutorSelection()
|
||||
fetchDeptUsers(lastSelected.deptId)
|
||||
const getDeptNodeId = (node) => node?.deptId ?? node?.raw?.deptId ?? null;
|
||||
|
||||
const syncDeptTreeChecked = (deptId) => {
|
||||
nextTick(() => {
|
||||
if (deptId) {
|
||||
deptTreeRef.value?.setCheckedKeys?.([deptId]);
|
||||
} else {
|
||||
deptTreeRef.value?.clearChecked?.();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const findDeptPath = (tree, targetId, path = []) => {
|
||||
for (const node of tree) {
|
||||
const currentPath = [...path, node];
|
||||
if (String(node.deptId) === String(targetId)) {
|
||||
return currentPath;
|
||||
}
|
||||
if (node.children?.length) {
|
||||
const found = findDeptPath(node.children, targetId, currentPath);
|
||||
if (found) return found;
|
||||
}
|
||||
}
|
||||
showDeptPicker.value = false
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const openDeptPopup = () => {
|
||||
selectedDeptId.value = formData.deptId || null;
|
||||
deptDefaultCheckedKeys.value = formData.deptId ? [formData.deptId] : [];
|
||||
showDeptPicker.value = true;
|
||||
syncDeptTreeChecked(formData.deptId);
|
||||
};
|
||||
|
||||
const onDeptNodeClick = (node) => {
|
||||
const deptId = getDeptNodeId(node);
|
||||
selectedDeptId.value = deptId;
|
||||
syncDeptTreeChecked(deptId);
|
||||
};
|
||||
|
||||
const onDeptCheck = (node, { checkedKeys = [] } = {}) => {
|
||||
const deptId = getDeptNodeId(node);
|
||||
const isChecked = checkedKeys.some((key) => String(key) === String(deptId));
|
||||
if (isChecked) {
|
||||
selectedDeptId.value = deptId;
|
||||
syncDeptTreeChecked(deptId);
|
||||
return;
|
||||
}
|
||||
selectedDeptId.value = null;
|
||||
syncDeptTreeChecked(null);
|
||||
};
|
||||
|
||||
const cancelDeptSelect = () => {
|
||||
showDeptPicker.value = false;
|
||||
};
|
||||
|
||||
const confirmDeptSelect = () => {
|
||||
if (!selectedDeptId.value) {
|
||||
uni.showToast({ title: '请选择分派单位', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
const path = findDeptPath(deptTree.value, selectedDeptId.value);
|
||||
if (!path?.length) {
|
||||
uni.showToast({ title: '请选择分派单位', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
const selected = path[path.length - 1];
|
||||
formData.deptId = selected.deptId;
|
||||
formData.deptName = path.map((d) => d.deptName).join(' / ');
|
||||
clearExecutorSelection();
|
||||
fetchDeptUsers(selected.deptId);
|
||||
showDeptPicker.value = false;
|
||||
};
|
||||
|
||||
// 检查表类型映射:日常检查->1, 专项检查->2, 设备检查->3
|
||||
const typeMap = {
|
||||
@@ -674,72 +759,12 @@ const fetchDeptChildren = async () => {
|
||||
if (res.code === 0 && res.data) {
|
||||
const list = Array.isArray(res.data) ? res.data : []
|
||||
deptTree.value = handleTree(list, 'deptId')
|
||||
initDeptCascader(deptTree.value)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取部门树失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化部门级联选择器
|
||||
const initDeptCascader = (treeData) => {
|
||||
const roots = Array.isArray(treeData) ? treeData : (treeData ? [treeData] : [])
|
||||
if (roots.length === 0) return
|
||||
|
||||
const firstColumn = roots.map(item => ({ text: item.deptName, ...item }))
|
||||
deptCascaderColumns.value = [firstColumn]
|
||||
deptCascaderIndexs.value = [0]
|
||||
selectedDeptPath.value = [roots[0]]
|
||||
|
||||
let current = roots[0]
|
||||
while (current.children && current.children.length > 0) {
|
||||
const nextColumn = current.children.map(item => ({ text: item.deptName, ...item }))
|
||||
deptCascaderColumns.value.push(nextColumn)
|
||||
deptCascaderIndexs.value.push(0)
|
||||
selectedDeptPath.value.push(current.children[0])
|
||||
current = current.children[0]
|
||||
}
|
||||
}
|
||||
|
||||
// 部门级联选择器列改变
|
||||
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];
|
||||
@@ -1857,6 +1882,31 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
// 分派单位弹窗样式
|
||||
.dept-popup {
|
||||
width: 600rpx;
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.popup-footer {
|
||||
button {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dept-tree-body {
|
||||
height: 500rpx;
|
||||
overflow: hidden;
|
||||
|
||||
:deep(.checkbox-custom.checked),
|
||||
:deep(.checkbox-custom.indeterminate) {
|
||||
background-color: #2667E9;
|
||||
border-color: #2667E9;
|
||||
}
|
||||
}
|
||||
|
||||
// 执行人员弹窗样式
|
||||
.executor-popup {
|
||||
width: 600rpx;
|
||||
|
||||
Reference in New Issue
Block a user