|
|
@@ -289,9 +289,6 @@
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
- </el-row>
|
|
|
-
|
|
|
- <el-row>
|
|
|
<el-col :span="8">
|
|
|
<el-form-item label="施工队伍" prop="deptIds">
|
|
|
<el-tree-select
|
|
|
@@ -313,6 +310,9 @@
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row>
|
|
|
<el-col :span="8">
|
|
|
<el-form-item label="施工设备" prop="deviceIds">
|
|
|
<el-button
|
|
|
@@ -338,25 +338,41 @@
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
|
- <el-form-item label="责任人" prop="responsiblePerson">
|
|
|
+ <el-form-item :label="isSpecialDept ? '带班干部' : '责任人'" prop="responsiblePerson">
|
|
|
<el-button
|
|
|
@click="openResponsiblePersonDialogForForm"
|
|
|
type="primary"
|
|
|
size="small"
|
|
|
>
|
|
|
- 选择责任人
|
|
|
+ 选择{{ isSpecialDept ? '带班干部' : '责任人' }}
|
|
|
</el-button>
|
|
|
- <!--
|
|
|
- <span v-if="currentTask.responsiblePerson && currentTask.responsiblePerson.length > 0" style="margin-left: 10px;">
|
|
|
- 已选 {{ currentTask.responsiblePerson.length }} 人
|
|
|
- </span> -->
|
|
|
<el-tooltip
|
|
|
v-if="currentTask.responsiblePerson && currentTask.responsiblePerson.length > 0"
|
|
|
:content="getAllResponsiblePersonNamesForForm(currentTask.responsiblePerson)"
|
|
|
placement="top"
|
|
|
+ >
|
|
|
+ <span style="margin-left: 10px;">
|
|
|
+ {{ formatResponsiblePersonsForForm(currentTask.responsiblePerson) }}
|
|
|
+ </span>
|
|
|
+ </el-tooltip>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8" v-if="isSpecialDept">
|
|
|
+ <el-form-item label="填报人" prop="submitter">
|
|
|
+ <el-button
|
|
|
+ @click="openSubmitterDialogForForm"
|
|
|
+ type="primary"
|
|
|
+ size="small"
|
|
|
+ >
|
|
|
+ 选择填报人
|
|
|
+ </el-button>
|
|
|
+ <el-tooltip
|
|
|
+ v-if="currentTask.submitter && currentTask.submitter.length > 0"
|
|
|
+ :content="getAllSubmitterNamesForForm(currentTask.submitter)"
|
|
|
+ placement="top"
|
|
|
>
|
|
|
<span style="margin-left: 10px;">
|
|
|
- {{ formatResponsiblePersonsForForm(currentTask.responsiblePerson) }}
|
|
|
+ {{ formatSubmittersForForm(currentTask.submitter) }}
|
|
|
</span>
|
|
|
</el-tooltip>
|
|
|
</el-form-item>
|
|
|
@@ -520,6 +536,44 @@
|
|
|
</span>
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
+
|
|
|
+ <!-- 填报人选择对话框 -->
|
|
|
+ <el-dialog
|
|
|
+ v-model="submitterDialogVisible"
|
|
|
+ title="选择填报人"
|
|
|
+ width="1000px"
|
|
|
+ :before-close="handleSubmitterDialogClose"
|
|
|
+ class="responsible-person-select-dialog"
|
|
|
+ >
|
|
|
+ <div class="transfer-container">
|
|
|
+ <el-transfer
|
|
|
+ v-model="selectedSubmitterIds"
|
|
|
+ :data="submitterList"
|
|
|
+ :titles="['可选人员', '已选人员']"
|
|
|
+ :props="{ key: 'id', label: 'nickname' }"
|
|
|
+ filterable
|
|
|
+ class="transfer-component"
|
|
|
+ >
|
|
|
+ <template #default="{ option }">
|
|
|
+ <el-tooltip
|
|
|
+ effect="dark"
|
|
|
+ placement="top"
|
|
|
+ :content="`${option.nickname} - ${option.deptName || '未分配部门'}`"
|
|
|
+ >
|
|
|
+ <span class="transfer-option-text">
|
|
|
+ {{ option.nickname }} - {{ option.deptName || '未分配部门' }}
|
|
|
+ </span>
|
|
|
+ </el-tooltip>
|
|
|
+ </template>
|
|
|
+ </el-transfer>
|
|
|
+ </div>
|
|
|
+ <template #footer>
|
|
|
+ <span class="dialog-footer">
|
|
|
+ <el-button @click="handleSubmitterDialogClose">取消</el-button>
|
|
|
+ <el-button type="primary" @click="confirmSubmitterSelection">确定</el-button>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
@@ -581,6 +635,10 @@ const responsiblePersonList = ref([]); // 所有责任人列表
|
|
|
const selectedResponsiblePersonIds = ref([]); // 选中的责任人ID
|
|
|
const currentEditingRowForResponsible = ref(null); // 当前正在编辑责任人的行
|
|
|
|
|
|
+const submitterDialogVisible = ref(false);
|
|
|
+const submitterList = ref([]); // 所有填报人列表
|
|
|
+const selectedSubmitterIds = ref([]); // 选中的日报填报人ID
|
|
|
+
|
|
|
// 动态属性相关变量
|
|
|
const dynamicAttrs = ref([]); // 存储动态属性列表
|
|
|
|
|
|
@@ -628,6 +686,11 @@ const close = () => {
|
|
|
push({ name: 'IotProjectTask', params:{}})
|
|
|
}
|
|
|
|
|
|
+// 添加计算属性来判断是否为特定部门
|
|
|
+const isSpecialDept = computed(() => {
|
|
|
+ return formData.value.deptId === 163;
|
|
|
+});
|
|
|
+
|
|
|
const getProjectInfo = async (contractId: number) => {
|
|
|
const project = projectList.value.find(item => item.id === contractId);
|
|
|
if (project) {
|
|
|
@@ -779,6 +842,7 @@ const currentTask = ref({
|
|
|
deptIds: [],
|
|
|
deviceIds: [],
|
|
|
responsiblePerson: [],
|
|
|
+ submitter: [],
|
|
|
remark: '',
|
|
|
projectId: ''
|
|
|
});
|
|
|
@@ -798,6 +862,10 @@ const taskFormRules = reactive({
|
|
|
deptIds: [{ required: true, message: '施工队伍不能为空', trigger: 'change' }],
|
|
|
deviceIds: [{ required: true, message: '施工设备不能为空', trigger: 'change' }],
|
|
|
responsiblePerson: [{ required: true, message: '责任人不能为空', trigger: 'change' }],
|
|
|
+ // 动态添加填报人验证规则
|
|
|
+ ...(isSpecialDept.value ? {
|
|
|
+ submitter: [{ required: true, message: '填报人不能为空', trigger: 'change' }]
|
|
|
+ } : {})
|
|
|
});
|
|
|
|
|
|
// 动态属性验证规则
|
|
|
@@ -858,6 +926,28 @@ const openResponsiblePersonDialogForForm = async () => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+// 打开工单人选择对话框(用于表单)
|
|
|
+const openSubmitterDialogForForm = async () => {
|
|
|
+ if (!currentTask.value.deptIds || currentTask.value.deptIds.length === 0) {
|
|
|
+ ElMessage.warning('请先选择施工队伍');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ selectedSubmitterIds.value = [...(currentTask.value.submitter || [])];
|
|
|
+
|
|
|
+ try {
|
|
|
+ const params = {
|
|
|
+ deptIds: currentTask.value.deptIds // 使用当前项目所属部门的deptId
|
|
|
+ };
|
|
|
+ const response = await UserApi.selectedDeptsEmployee(params);
|
|
|
+ submitterList.value = response;
|
|
|
+ submitterDialogVisible.value = true;
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('获取填报人列表失败');
|
|
|
+ console.error('获取填报人列表失败:', error);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
// 获取动态属性
|
|
|
const fetchDynamicAttrs = async () => {
|
|
|
// 如果已经通过任务数据获取了动态属性,则不再调用接口
|
|
|
@@ -936,6 +1026,12 @@ const confirmResponsiblePersonSelection = () => {
|
|
|
responsiblePersonDialogVisible.value = false;
|
|
|
};
|
|
|
|
|
|
+// 确认填报人选择(用于表单)
|
|
|
+const confirmSubmitterSelection = () => {
|
|
|
+ currentTask.value.submitter = [...selectedSubmitterIds.value];
|
|
|
+ submitterDialogVisible.value = false;
|
|
|
+};
|
|
|
+
|
|
|
// 关闭设备选择对话框
|
|
|
const handleDeviceDialogClose = () => {
|
|
|
deviceDialogVisible.value = false;
|
|
|
@@ -946,6 +1042,11 @@ const handleResponsiblePersonDialogClose = () => {
|
|
|
responsiblePersonDialogVisible.value = false;
|
|
|
};
|
|
|
|
|
|
+// 关闭填报人选择对话框
|
|
|
+const handleSubmitterDialogClose = () => {
|
|
|
+ submitterDialogVisible.value = false;
|
|
|
+};
|
|
|
+
|
|
|
// 获取井型标签的方法
|
|
|
const getWellTypeLabel = (value) => {
|
|
|
const options = getStrDictOptions(DICT_TYPE.PMS_PROJECT_WELL_TYPE)
|
|
|
@@ -1008,6 +1109,8 @@ const syncCurrentTaskToTable = () => {
|
|
|
return true;
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+
|
|
|
// 重置任务表单
|
|
|
const resetTaskForm = () => {
|
|
|
currentTask.value = {
|
|
|
@@ -1023,7 +1126,9 @@ const resetTaskForm = () => {
|
|
|
deviceIds: [],
|
|
|
responsiblePerson: [],
|
|
|
remark: '',
|
|
|
- projectId: formData.value.id
|
|
|
+ projectId: formData.value.id,
|
|
|
+ // 如果是特殊部门,初始化填报人字段
|
|
|
+ ...(isSpecialDept.value ? { submitter: [] } : {})
|
|
|
};
|
|
|
|
|
|
// 重新初始化动态属性
|
|
|
@@ -1164,10 +1269,12 @@ const open = async () => {
|
|
|
const data = await IotProjectTaskApi.getIotProjectTaskPage(queryParams);
|
|
|
tableData.value = data.list
|
|
|
|
|
|
- // 1. 收集所有设备ID
|
|
|
+ // 收集所有设备ID
|
|
|
const allDeviceIds = new Set<number>();
|
|
|
// 收集所有责任人ID
|
|
|
const allResponsiblePersonIds = new Set<number>();
|
|
|
+ // 收集所有填报人ID
|
|
|
+ const allSubmitterIds = new Set<number>();
|
|
|
|
|
|
data.list.forEach(item => {
|
|
|
if (item.deviceIds?.length) {
|
|
|
@@ -1176,16 +1283,19 @@ const open = async () => {
|
|
|
if (item.responsiblePerson?.length) {
|
|
|
item.responsiblePerson.forEach(id => allResponsiblePersonIds.add(id));
|
|
|
}
|
|
|
+ if (item.submitter?.length) {
|
|
|
+ item.submitter.forEach(id => allSubmitterIds.add(id));
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
- // 2. 批量获取设备信息
|
|
|
+ // 批量获取设备信息
|
|
|
if (allDeviceIds.size > 0) {
|
|
|
const deviceIdsArray = Array.from(allDeviceIds);
|
|
|
const devices = await IotDeviceApi.getDevicesByDepts({
|
|
|
deviceIds: deviceIdsArray
|
|
|
});
|
|
|
|
|
|
- // 3. 更新设备列表和映射表
|
|
|
+ // 更新设备列表和映射表
|
|
|
deviceList.value = devices;
|
|
|
deviceMap.value = {};
|
|
|
devices.forEach(device => {
|
|
|
@@ -1205,6 +1315,18 @@ const open = async () => {
|
|
|
responsiblePersonList.value = persons;
|
|
|
}
|
|
|
|
|
|
+ // 批量获取填报人信息
|
|
|
+ if (allSubmitterIds.size > 0) {
|
|
|
+ const personIdsArray = Array.from(allSubmitterIds);
|
|
|
+ const params = {
|
|
|
+ userIds: personIdsArray
|
|
|
+ };
|
|
|
+ const persons = await UserApi.companyDeptsEmployee(params);
|
|
|
+
|
|
|
+ // 更新责任人列表
|
|
|
+ submitterList.value = persons;
|
|
|
+ }
|
|
|
+
|
|
|
if (tableData.value && tableData.value.length > 0) {
|
|
|
// 使用深拷贝,避免修改表单时直接影响表格数据
|
|
|
currentTask.value = JSON.parse(JSON.stringify(tableData.value[0]));
|
|
|
@@ -1259,7 +1381,7 @@ const autoSelectContract = async (projectId: string) => {
|
|
|
|
|
|
/** 校验所有行数据 */
|
|
|
const validateAllRows = (): boolean => {
|
|
|
- // 新增检查:判断任务列表是否为空
|
|
|
+ // 判断任务列表是否为空
|
|
|
if (!tableData.value || tableData.value.length === 0) {
|
|
|
ElMessage.error('没有任务数据,无法保存');
|
|
|
return false;
|
|
|
@@ -1295,6 +1417,11 @@ const validateAllRows = (): boolean => {
|
|
|
if (!row.responsiblePerson || row.responsiblePerson.length === 0) {
|
|
|
allValid = false;
|
|
|
}
|
|
|
+
|
|
|
+ // 如果是特殊部门,验证填报人
|
|
|
+ if (isSpecialDept.value && (!row.submitter || row.submitter.length === 0)) {
|
|
|
+ allValid = false;
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
if (!allValid) {
|
|
|
@@ -1353,6 +1480,26 @@ const formatResponsiblePersonsForForm = (responsiblePersonIds: number[]) => {
|
|
|
return personNames.join(', ');
|
|
|
};
|
|
|
|
|
|
+// 格式化填报人显示(用于表单)
|
|
|
+const formatSubmittersForForm = (submitterIds: number[]) => {
|
|
|
+ if (!submitterIds || submitterIds.length === 0) return '';
|
|
|
+
|
|
|
+ const personNames = submitterIds
|
|
|
+ .map(id => {
|
|
|
+ const person = submitterList.value.find(p => p.id === id);
|
|
|
+ return person ? person.nickname : '';
|
|
|
+ })
|
|
|
+ .filter(name => name !== undefined && name !== '');
|
|
|
+
|
|
|
+ if (personNames.length === 0) return '';
|
|
|
+
|
|
|
+ if (personNames.length > 2) {
|
|
|
+ return `${personNames[0]}, ${personNames[1]}...`;
|
|
|
+ }
|
|
|
+
|
|
|
+ return personNames.join(', ');
|
|
|
+};
|
|
|
+
|
|
|
// 获取所有责任人名称(用于表单的tooltip)
|
|
|
const getAllResponsiblePersonNamesForForm = (responsiblePersonIds: number[]) => {
|
|
|
if (!responsiblePersonIds || responsiblePersonIds.length === 0) return '无责任人';
|
|
|
@@ -1367,6 +1514,20 @@ const getAllResponsiblePersonNamesForForm = (responsiblePersonIds: number[]) =>
|
|
|
return personNames.join(', ') || '无有效责任人';
|
|
|
};
|
|
|
|
|
|
+// 获取所有填报人名称(用于表单的tooltip)
|
|
|
+const getAllSubmitterNamesForForm = (submitterIds: number[]) => {
|
|
|
+ if (!submitterIds || submitterIds.length === 0) return '无填报人';
|
|
|
+
|
|
|
+ const personNames = submitterIds
|
|
|
+ .map(id => {
|
|
|
+ const person = submitterList.value.find(p => p.id === id);
|
|
|
+ return person ? person.nickname : '未知人员';
|
|
|
+ })
|
|
|
+ .filter(name => name !== '未知人员');
|
|
|
+
|
|
|
+ return personNames.join(', ') || '无有效填报人';
|
|
|
+};
|
|
|
+
|
|
|
/** 提交表单 */
|
|
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
|
|
|