This commit is contained in:
Teo
2025-09-04 11:06:45 +08:00
parent 9d1f96309f
commit 910b24019e
83 changed files with 8390 additions and 834 deletions

View File

@ -5,7 +5,11 @@
<el-form :model="param" ref="queryRef" :inline="true" label-width="100px">
<el-row>
<el-col>
<el-button type="success" v-hasPermi="['project:project:remove']" :disabled="multiple" @click="onRecyclingStation(null)"
<el-button
type="success"
v-auth="'api/v1/system/documentCompletion/completionDataRecyclingStation'"
:disabled="multiple"
@click="onRecyclingStation(null, true)"
><el-icon><RefreshRight /></el-icon>批量恢复</el-button
>
</el-col>
@ -15,42 +19,43 @@
<el-table v-loading="loading" :data="tableData" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" align="center" type="index" min-width="30px" />
<el-table-column label="文件名称" align="center" prop="fileName" min-width="100px" />
<el-table-column label="文件类型" align="center" prop="fileType" min-width="100px">
<el-table-column label="文件名称" align="center" prop="name" min-width="100px" />
<el-table-column label="文件类型" align="center" prop="type" min-width="100px">
<template #default="scope">
<span>{{ scope.row.fileType == '1' ? '文件' : '文件夹' }}</span>
<span>{{ scope.row.type == 1 ? '文件' : '文件夹' }}</span>
</template> </el-table-column
><el-table-column label="文件路径" align="center" min-width="100px">
<template #default="scope">
<span>{{ scope.row.filePath }}</span>
<span>{{ scope.row.filenPath }}</span>
</template>
</el-table-column>
<el-table-column label="删除时间" align="center" prop="deletedAt" min-width="100px"> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding" min-width="100px" fixed="right">
<template #default="scope">
<el-button type="success" v-hasPermi="['project:project:remove']" link @click="onRecyclingStation(scope.row)"
<el-button
type="success"
v-auth="'api/v1/system/documentCompletion/completionDataRecyclingStation'"
link
@click="onRecyclingStation(scope.row)"
><el-icon><RefreshRight /></el-icon>恢复</el-button
>
</template>
</el-table-column>
</el-table>
<!-- <pagination v-show="total > 0" :total="total" v-model:page="param.pageNum" v-model:limit="param.pageSize" @pagination="getDocumentDataList" /> -->
<pagination v-show="total > 0" :total="total" v-model:page="param.pageNum" v-model:limit="param.pageSize" @pagination="documentList" />
</el-card>
</div>
</template>
<script lang="ts">
import { toRefs, reactive, ref, defineComponent, getCurrentInstance } from 'vue';
import { ElMessageBox, ElMessage, ElLoading } from 'element-plus';
import { useUserStoreHook } from '@/store/modules/user';
// 获取用户 store
const userStore = useUserStoreHook();
// 从 store 中获取项目列表和当前选中的项目
const currentProject = computed(() => userStore.selectedProject);
import { documentRecycleBinList, completionDataRecyclingStation } from '@/api/safety/documentSafetyMeeting';
import { useUserStoreHook } from '@/store/modules/user';
export default defineComponent({
name: 'index',
setup() {
const stores = useUserStoreHook();
const { proxy } = <any>getCurrentInstance();
const loading = ref(false);
const queryRef = ref();
@ -60,7 +65,7 @@ export default defineComponent({
tableData: [],
param: {
type: 2,
projectId: currentProject.value?.id
projectId: stores.selectedProject.goId
},
total: 0,
ids: [] //所选择的文件
@ -69,11 +74,9 @@ export default defineComponent({
const getDocumentDataList = () => {
loading.value = true;
documentRecycleBinList(state.param).then((res: any) => {
let list = res.rows ?? [];
let list = res.data.list ?? [];
state.tableData = list;
console.log('🚀 ~ documentRecycleBinList ~ state.tableData:', state.tableData);
state.total = res.total;
state.total = res.data.total;
loading.value = false;
});
};
@ -101,13 +104,16 @@ export default defineComponent({
text: '正在恢复中……',
background: 'rgba(0, 0, 0, 0.7)'
});
completionDataRecyclingStation(ids).then((res) => {
completionDataRecyclingStation({
ids,
type: 1
}).then((res) => {
loading.close();
if (res.code == 200) {
if (res.code == 0) {
getDocumentDataList();
ElMessage.success('操作成功');
} else {
ElMessage.error(res.msg);
ElMessage.error(res.message);
}
});
})

View File

@ -1,23 +1,35 @@
<template>
<div class="documentCompletion-data">
<el-tabs v-model="activeName" class="p-4" @tab-click="handleClick">
<div class="documentCompletion-data p-2">
<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
<el-tab-pane label="文件夹" name="first">
<el-button type="success" :disabled="toolStart" @click="handleFile(3)"
><el-icon><Plus /></el-icon>新建文件夹</el-button
>
<el-button type="primary" :disabled="toolStart" @click="handleFile(2)"
><el-icon><Upload /></el-icon>上传文件</el-button
>
<el-card>
<el-row>
<el-col :span="2" class="colBlock">
<el-button
type="success"
v-auth="'api/v1/system/documentSafetyMeeting/safetyNewFolderData'"
:disabled="toolStart"
@click="handleFile(3)"
><el-icon><Plus /></el-icon>新建文件夹</el-button
>
</el-col>
<el-col :span="2" class="colBlock">
<el-button type="primary" v-auth="'api/v1/system/documentSafetyMeeting/add'" :disabled="toolStart" @click="handleFile(2)"
><el-icon><Upload /></el-icon>上传文件</el-button
>
</el-col>
</el-row>
</el-card>
<el-card style="margin-top: 10px">
<div class="breadcrumb-img">
<el-breadcrumb>
<el-breadcrumb-item @click="onBreadcrumb(item)" v-for="(item, i) of breadcrumbList" :key="i">
<span title="点击打开文件夹" style="cursor: pointer">{{ item.fileName }}</span>
<span title="点击打开文件夹" style="cursor: pointer">{{ item.name }}</span>
</el-breadcrumb-item>
</el-breadcrumb>
<div class="tool-All">
<div v-if="!toolStart">
<el-button type="primary" v-hasPermi="['project:project:remove']" @click="onBatchAll">
<el-button type="primary" v-auth="'api/v1/system/documentSafetyMeeting/delete'" @click="onBatchAll">
<el-icon><Menu /></el-icon>批量操作</el-button
>
</div>
@ -38,12 +50,12 @@
<el-col :span="2" v-for="(item, i) of fileList" :key="i">
<div :class="{ file_style: true }">
<div @click="onNav(item)" title="点击打开文件" @contextmenu="onContextmenu($event, item, i)">
<img src="../../../assets/icons/svg/file1.png" v-if="item.fileType == '2'" alt="" />
<img src="../../../assets/icons/svg/file.png" v-else-if="item.fileType == '1'" alt="" />
<img src="@/assets/icons/file1.png" v-if="item.suffix == 'folder'" alt="" />
<img src="@/assets/icons/file.png" v-else-if="item.suffix == 'file'" alt="" />
<el-image
v-else-if="item.fileType == '3'"
v-else-if="item.suffix == 'image'"
style="width: 100%; height: 100%"
:src="item.filePath"
:src="item.filenPathCoding"
:zoom-rate="1.2"
:max-scale="7"
:min-scale="0.2"
@ -51,9 +63,9 @@
:preview-src-list="[item.filenPathCoding]"
fit="cover"
/>
<img :src="'/icon/' + item.fileType + '.png'" v-else />
<img :src="'/image/' + item.suffix.replace('.', '').toUpperCase() + '.png'" v-else />
</div>
<span @click="onFileName(item)" title="点击重命名">{{ item.fileName }}</span>
<span @click="onFileName(item)" title="点击重命名">{{ item.name }}</span>
<div :class="{ fileActive: toolStart }" v-if="toolStart" @click="onToolAll(item)"></div>
<div class="checkbox-box" v-if="toolStart">
<el-checkbox v-model="item.checkbox" size="large" />
@ -63,7 +75,7 @@
</el-row>
<el-empty :image-size="200" description="暂无文件" v-else />
<div class="right_box" id="right_box">
<div v-for="(item, i) of list" :key="i" @click="item.callback($event)">
<div v-for="(item, i) of list" :key="i" v-auth="item.auth" @click="item.callback($event)">
{{ item.name }}
</div>
</div>
@ -86,15 +98,12 @@ import {
documentCompletionEdit,
newFolder,
uniFileDownload
} from '@/api/safety/documentSafetyMeeting/index';
import { useUserStoreHook } from '@/store/modules/user';
} from '@/api/safety/documentSafetyMeeting';
// 获取用户 store
const userStore = useUserStoreHook();
// 从 store 中获取项目列表和当前选中的项目
const currentProject = computed(() => userStore.selectedProject);
// 回收站
import RecyclingStation from '@/views/safety/documentSafetyMeeting/RecyclingStation/index.vue';
import RecyclingStation from './RecyclingStation/index.vue';
import { useUserStoreHook } from '@/store/modules/user';
const stores = useUserStoreHook();
export default defineComponent({
name: 'index',
components: {
@ -106,29 +115,29 @@ export default defineComponent({
// 字典选项数据
const {} = proxy.useDict();
// 文件下载
const onExport = (event) => {
const onExport = (event, item) => {
event.stopPropagation();
// 文件下载 state.typeFile: 2、文件夹 1、文件
if (state.typeFile == '2') {
// 文件下载 state.typeFile: 1、文件夹 2、文件
if (state.typeFile == 1) {
window.open(state.relativePath, '_black');
} else {
uniFileDownload({ relativePath: state.relativePath, type: state.typeFile }).then((res) => {
if (res.code == 200) {
if (res.code == 0) {
window.open(res.data.Path, '_black');
}
});
}
};
// 文件删除
const onDeleteFile = (event) => {
const onDeleteFile = (event, item) => {
event.stopPropagation();
setDel([state.delId]);
};
const state = reactive({
fileList: [],
activeName: 'first',
breadcrumbList: [{ id: 0, fileName: '目录' }], //菜单列表
projectId: currentProject.value?.id,
breadcrumbList: [{ id: 0, name: '目录' }], //菜单列表
projectId: stores.selectedProject.goId,
parentPid: '0', //父级的id 默认为0
fileType: 0, //文件 或压缩文件
list: [
@ -156,7 +165,6 @@ export default defineComponent({
// 默认第一级 父级pid为0
getdocumentCompletionTreeStructure();
// 压缩文件上传
proxy.mittBus.on('bigUploader.uploadFileSuccess' + 1010, (res: any) => {
const { filename, totalSize, url, identifier, fileType } = res;
let arr = filename.split('.');
@ -174,10 +182,12 @@ export default defineComponent({
size: totalSize,
fileType: '.' + fileType1 //后缀名
},
file: ''
fileType: state.fileType,
pid: state.parentPid == 0 ? '' : state.parentPid,
projectId: state.projectId
};
documentCompletionAdd(obj).then((res: any) => {
if (res.code == 200) {
if (res.code == 0) {
ElMessage({
type: 'success',
message: '上传成功'
@ -202,16 +212,32 @@ export default defineComponent({
text: '正在查询文件……',
background: 'rgba(0, 0, 0, 0.7)'
});
documentCompletionTreeStructure({ projectId: currentProject.value?.id, pid: state.parentPid }).then((res: any) => {
documentCompletionTreeStructure({ projectId: state.projectId, pid: state.parentPid }).then((res: any) => {
loading.close();
if (res.code == 200) {
state.fileList = res.data || [];
if (res.code == 0) {
state.fileList = res.data.list || [];
if (state.fileList.length) {
state.fileList.map((item) => {
return {
...item,
checkbox: false
};
item.checkbox = false;
item.name = item.name + item.suffix;
item.suffix = item.suffix.slice(1).toUpperCase();
// 截取后缀
if (item.filenPathCoding.indexOf('.') != -1) {
let str = item.filenPathCoding.slice(item.filenPathCoding.indexOf('.') + 1);
if (state.imageType.includes(str)) {
// 图片文件格式
item.suffix = 'image';
} else {
if (!window['$ICONLIST'].includes(item.suffix)) {
item.suffix = 'file';
}
}
} else {
// 当没得后缀的时候 默认未文件夹
item.suffix = 'folder';
}
return item;
});
}
}
@ -227,8 +253,8 @@ export default defineComponent({
})
.then(({ value }) => {
// pid 父级
newFolder({ fileName: value, pid: state.parentPid == '0' ? '' : state.parentPid, projectId: state.projectId }).then((res: any) => {
if (res.code == 200) {
newFolder({ fileName: value, pid: state.parentPid == 0 ? '' : state.parentPid, projectId: state.projectId }).then((res: any) => {
if (res.code == 0) {
getdocumentCompletionTreeStructure();
ElMessage({
type: 'success',
@ -237,7 +263,7 @@ export default defineComponent({
} else {
ElMessage({
type: 'error',
message: res.data
message: res.message
});
}
});
@ -255,12 +281,12 @@ export default defineComponent({
// 图片格式 jpg、png、jpeg、
// word文档格式:docx、doc、pdf、xls、xlsx、pptx、ppt
// 其他全文件夹
if (item.fileType == '3') {
if (item.suffix == 'image') {
// 可以预览图片
return;
} else if (item.fileType == '2') {
} else if (item.suffix == 'folder') {
// 打开文件夹
state.parentPid = item.id;
state.parentPid = item.idStr;
state.breadcrumbList.push(item); //路径设置
state.fileList = [];
// 获取对应文件夹的数据
@ -280,7 +306,7 @@ export default defineComponent({
.then(({ value }) => {
// 确定
documentCompletionEdit({ id: item.id, name: value, type: item.type }).then((res: any) => {
if (res.code == 200) {
if (res.code == 0) {
item.name = value;
getdocumentCompletionTreeStructure();
ElMessage({
@ -305,9 +331,9 @@ export default defineComponent({
}
};
const onBreadcrumb = (item) => {
if (item.fileName == '目录') {
if (item.name == '目录') {
state.parentPid = '0';
state.breadcrumbList = [{ id: 0, fileName: '目录' }]; //菜单列表
state.breadcrumbList = [{ id: 0, name: '目录' }]; //菜单列表
// 最初目录
getdocumentCompletionTreeStructure();
} else {
@ -315,15 +341,15 @@ export default defineComponent({
let array = state.breadcrumbList;
for (let index = 0; index < array.length; index++) {
arr.push(array[index]);
if (array[index].fileName == item.fileName) {
if (array[index].name == item.name) {
break;
}
}
state.breadcrumbList = arr;
// 通过 当前点击的文件进行获取数据
// 重复点击不用再次获取
if (item.id == state.parentPid) return;
state.parentPid = item.id;
if (item.idStr == state.parentPid) return;
state.parentPid = item.idStr;
getdocumentCompletionTreeStructure();
}
};
@ -343,16 +369,14 @@ export default defineComponent({
type: 'warning'
})
.then(() => {
console.log(ids);
documentCompletionDelete(ids).then((res) => {
if (res.code == 200) {
documentCompletionDelete({ ids }).then((res) => {
if (res.code == 0) {
let box = document.getElementById('right_box');
box.style.display = 'none'; //显示div盒子
ElMessage.success('删除成功');
getdocumentCompletionTreeStructure();
} else {
ElMessage.error(res.msg);
ElMessage.error(res.message);
}
});
})
@ -380,7 +404,7 @@ export default defineComponent({
row.checkbox = !row.checkbox;
};
const onContextmenu = (event, item, i) => {
state.typeFile = item.fileType;
state.typeFile = item.type;
state.relativePath = item.filenPath;
state.delId = item.id;
let len = (100 / 12) * (i % 12) + 4 + '%';

View File

@ -27,6 +27,11 @@
</transition>
<el-card shadow="never">
<el-row :gutter="10" class="mb8">
<el-button type="danger" @click="handleDelete()" plain icon="Delete" :disabled="multiple">删除</el-button>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="recognizeRecordList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="设备名称" align="center" prop="sxtName" />
@ -47,6 +52,11 @@
</el-table-column>
<el-table-column label="故障描述" align="center" prop="describe" />
<el-table-column label="创建时间" align="center" prop="createdAt" width="180"> </el-table-column>
<el-table-column label="操作" align="center" width="100">
<template #default="scope">
<el-button type="danger" link icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>

View File

@ -24,6 +24,24 @@
</transition>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['safety:safetyInspection:add']"> 新增 </el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['safety:safetyInspection:remove']">
删除
</el-button>
</el-col>
<!-- <el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" :disabled="multiple" v-hasPermi="['safety:safetyInspection:export']"
>导出
</el-button>
</el-col> -->
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" :data="safetyInspectionList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" type="index" width="60" align="center" />
@ -76,6 +94,9 @@
<el-button link type="primary" icon="View" @click="handleShowDialog(scope.row)" v-hasPermi="['safety:safetyInspection:query']">
详情
</el-button>
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['safety:safetyInspection:remove']">
删除
</el-button>
</el-space>
</template>
</el-table-column>
@ -85,51 +106,35 @@
<!-- 添加或修改安全巡检工单对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" append-to-body>
<el-form ref="safetyInspectionFormRef" :model="form" :rules="rules" label-width="120px">
<el-form-item label="检查类型" prop="checkType">
<el-select v-model="form.checkType" placeholder="请选择检查类型">
<el-option v-for="dict in safety_inspection_check_type" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
<el-form-item label="检查类型" prop="studyType">
<el-select v-model="form.studyType" placeholder="请选择检查类型">
<el-option v-for="dict in safety_inspection_check_type" :key="dict.key" :label="dict.value" :value="dict.key"></el-option>
</el-select>
</el-form-item>
<el-form-item label="违章类型" prop="violationType">
<el-select v-model="form.violationType" placeholder="请选择违章类型">
<el-option v-for="dict in safety_inspection_violation_type" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
<el-form-item label="违章类型" prop="tourType">
<el-select v-model="form.tourType" placeholder="请选择违章类型">
<el-option v-for="dict in safety_inspection_violation_type" :key="dict.key" :label="dict.value" :value="dict.key"></el-option>
</el-select>
</el-form-item>
<el-form-item label="巡检结果" prop="inspectionResult">
<el-input v-model="form.inspectionResult" placeholder="请输入巡检结果" />
</el-form-item>
<el-form-item label="工单整改单位" prop="rectificationUnit">
<el-select v-model="form.rectificationUnit" placeholder="请选择整改单位类型">
<el-option v-for="dict in rectification_unit_type" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
<el-form-item label="整改人" prop="corrector">
<el-select v-model="form.corrector" placeholder="请选择整改人">
<el-option v-for="dict in foremanOpt" :key="dict.openid" :label="dict.userName" :value="dict.openid"></el-option>
</el-select>
</el-form-item>
<el-form-item label="整改班组" prop="teamId">
<el-select v-model="form.teamId" placeholder="选择整改班组">
<el-option v-for="item in teamOpt" :key="item.value" :label="item.label" :value="item.value" @click="changeForeman(item.value)" />
</el-select>
</el-form-item>
<el-form-item label="整改人" prop="correctorId">
<el-select v-model="form.correctorId" placeholder="请选择整改人" :disabled="!form.teamId">
<el-option v-for="item in foremanOpt" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="问题隐患" prop="hiddenDanger">
<el-input v-model="form.hiddenDanger" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="整改措施" prop="measure">
<el-input v-model="form.measure" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="要求整改期限" prop="checkTime">
<el-date-picker clearable v-model="form.rectificationDeadline" type="date" value-format="YYYY-MM-DD" placeholder="选择要求整改期限" />
</el-form-item>
<el-form-item label="检查附件" prop="checkFile">
<file-upload v-model="form.checkFile" :file-size="20" :file-type="['doc', 'docx', 'pdf', 'png', 'jpg', 'jpeg']" />
<el-form-item label="要求整改期限" prop="replyDate">
<el-date-picker clearable v-model="form.replyDate" type="date" value-format="YYYY-MM-DD" placeholder="选择要求整改期限" />
</el-form-item>
<el-form-item label="整改附件" prop="rectificationFile">
<file-upload v-model="form.rectificationFile" :file-size="20" :file-type="['doc', 'docx', 'pdf', 'png', 'jpg', 'jpeg']" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
<file-upload
ref="uploadRef"
v-model="form.inspectionFile"
isGo
upload-url="/zm/api/v1/system/busHseManagement/add"
:auto-upload="false"
show-file-list
:data="form"
:accept="['doc', 'docx', 'pdf', 'png', 'jpg', 'jpeg']"
/>
</el-form-item>
</el-form>
<template #footer>
@ -159,6 +164,7 @@ import SafetyInspectionDetailDialog from '@/views/safety/safetyInspection/compon
import { listProjectTeamForeman } from '@/api/project/projectTeam';
import { foremanQuery, ProjectTeamForemanResp } from '@/api/project/projectTeam/types';
import { getDictData } from '@/api/project/goUser/index';
import { acquisitionOfCorrectivePersonnel } from '@/api/quality/qualityInspection';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { review_type } = toRefs<any>(proxy?.useDict('review_type', 'safety_inspection_type'));
@ -184,31 +190,13 @@ const dialog = reactive<DialogOption>({
title: ''
});
const initFormData: SafetyInspectionForm = {
id: undefined,
pid: undefined,
const initFormData: any = {
projectId: currentProject.value.goId,
checkType: undefined,
violationType: undefined,
inspectionResult: undefined,
teamId: undefined,
correctorId: undefined,
rectificationDeadline: undefined,
isReply: undefined,
replyDate: undefined,
status: undefined,
hiddenDanger: undefined,
measure: undefined,
review: undefined,
reviewType: undefined,
checkTime: undefined,
rectificationTime: undefined,
rectificationUnit: undefined,
reviewTime: undefined,
checkFile: undefined,
rectificationFile: undefined,
remark: undefined
studyType: undefined,
tourType: undefined,
corrector: undefined,
teamName: 'undefined'
};
const data = reactive<PageData<SafetyInspectionForm, SafetyInspectionQuery>>({
form: { ...initFormData },
@ -303,20 +291,42 @@ const handleSelectionChange = (selection: SafetyInspectionVO[]) => {
single.value = selection.length != 1;
multiple.value = !selection.length;
};
//删除
const handleDelete = async (row?: SafetyInspectionVO) => {
const _ids = row?.id || ids.value;
await proxy?.$modal.confirm('是否确认删除安全巡检工单编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
await delSafetyInspection(_ids);
proxy?.$modal.msgSuccess('删除成功');
await getList();
};
/** 新增按钮操作 */
const handleAdd = async () => {
reset();
await getPeople();
dialog.visible = true;
dialog.title = '添加安全巡检工单';
};
const getPeople = async () => {
await acquisitionOfCorrectivePersonnel(currentProject.value?.goId).then((res) => {
foremanOpt.value = res.data.list;
});
};
/** 提交按钮 */
const uploadRef = ref(null);
const submitForm = () => {
safetyInspectionFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
form.value.projectId = currentProject.value?.id;
if (form.value.id) {
await updateSafetyInspection(form.value).finally(() => (buttonLoading.value = false));
} else {
await addSafetyInspection(form.value).finally(() => (buttonLoading.value = false));
}
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
await getList();
uploadRef.value.submitUpload().then((res) => {
if (res != 'noFile') {
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
getList();
buttonLoading.value = false;
}
});
}
});
};

View File

@ -2,52 +2,63 @@
<el-card v-loading="loading">
<h2 style="text-align: center; margin-top: 5px; font-weight: bold">安全日志</h2>
<el-row>
<el-col :span="12" style="text-align: left">记录人{{ safetyLogDetail?.creator?.name }}</el-col>
<el-col :span="12" style="text-align: right">记录时间{{ safetyLogDetail?.createTime }}</el-col>
<el-col :span="12" style="text-align: left">记录人{{ safetyLogDetail?.fill }}</el-col>
<el-col :span="12" style="text-align: right">记录时间{{ safetyLogDetail?.createdAt }}</el-col>
</el-row>
<el-descriptions :column="3" border style="margin-top: 8px">
<el-descriptions-item label-align="center" width="160px" label="项目名称" :span="3">{{ currentProject?.name }} </el-descriptions-item>
<el-descriptions-item label-align="center" label="发生日期">{{ safetyLogDetail?.dateOfOccurrence }} </el-descriptions-item>
<el-descriptions-item label-align="center" label="气温">
<el-descriptions-item label-align="center" width="160px" label="项目名称" :span="3">{{ safetyLogDetail?.projectName }} </el-descriptions-item>
<el-descriptions-item label-align="center" label="发生日期" :span="safetyLogDetail?.fileList ? 3 : 1"
>{{ safetyLogDetail?.dateOfOccurrence }}
</el-descriptions-item>
<el-descriptions-item label-align="center" label="气温" v-if="!safetyLogDetail?.fileList">
<span>最高{{ safetyLogDetail?.airTemperatureMax }}</span>
<span>最低{{ safetyLogDetail?.airTemperatureMin }}</span>
</el-descriptions-item>
<el-descriptions-item label-align="center" label="气候">
<dict-tag :value="safetyLogDetail?.weather" :options="weather_type" />
<el-descriptions-item label-align="center" label="气候" v-if="!safetyLogDetail?.fileList">
{{ safetyLogDetail?.climateName }}
</el-descriptions-item>
<el-descriptions-item label-align="center" label="工程施工部位及施工进展情况" :span="3">
<el-descriptions-item label-align="center" label="工程施工部位及施工进展情况" :span="3" v-if="!safetyLogDetail?.fileList">
{{ safetyLogDetail?.progress }}
</el-descriptions-item>
<el-descriptions-item label-align="center" label="当日主要危险性项目作业内容" :span="3">
<el-descriptions-item label-align="center" label="当日主要危险性项目作业内容" :span="3" v-if="!safetyLogDetail?.fileList">
{{ safetyLogDetail?.jobContent }}
</el-descriptions-item>
<el-descriptions-item label-align="center" label="施工项目安全教育与安全交底情况" :span="3">
{{ safetyLogDetail?.discloseCondition }}
<el-descriptions-item label-align="center" label="施工项目安全教育与安全交底情况" :span="3" v-if="!safetyLogDetail?.fileList">
{{ safetyLogDetail?.discloseTheFacts }}
</el-descriptions-item>
<el-descriptions-item label-align="center" label="施工作业队伍班前施工安全活动情况" :span="3">
{{ safetyLogDetail?.activityCondition }}
<el-descriptions-item label-align="center" label="施工作业队伍班前施工安全活动情况" :span="3" v-if="!safetyLogDetail?.fileList">
{{ safetyLogDetail?.progressOfActivity }}
</el-descriptions-item>
<el-descriptions-item label-align="center" label="现场施工安全巡视与检查情况" :span="3">
{{ safetyLogDetail?.examineCondition }}
<el-descriptions-item label-align="center" label="现场施工安全巡视与检查情况" :span="3" v-if="!safetyLogDetail?.fileList">
{{ safetyLogDetail?.examine }}
</el-descriptions-item>
<el-descriptions-item label-align="center" label="季节施工防寒、防暑等措施实施情况" :span="3">
{{ safetyLogDetail?.implementCondition }}
<el-descriptions-item label-align="center" label="季节施工防寒、防暑等措施实施情况" :span="3" v-if="!safetyLogDetail?.fileList">
{{ safetyLogDetail?.implementation }}
</el-descriptions-item>
<el-descriptions-item label-align="center" label="监理通知有关部门安全检查情况" :span="3">
{{ safetyLogDetail?.safetyInspectionCondition }}
<el-descriptions-item label-align="center" label="监理通知有关部门安全检查情况" :span="3" v-if="!safetyLogDetail?.fileList">
{{ safetyLogDetail?.safetyInspectionSituation }}
</el-descriptions-item>
<el-descriptions-item label-align="center" label="停工、加班情况" :span="3">{{ safetyLogDetail?.stoppageOrOvertime }} </el-descriptions-item>
<el-descriptions-item label-align="center" label="其他应记录的安全与文明施工事项" :span="3">
{{ safetyLogDetail?.otherCondition }}
<el-descriptions-item label-align="center" label="停工、加班情况" :span="3" v-if="!safetyLogDetail?.fileList"
>{{ safetyLogDetail?.stoppageOrOvertime }}
</el-descriptions-item>
<el-descriptions-item label-align="center" label="附件" :span="3">
<el-descriptions-item label-align="center" label="其他应记录的安全与文明施工事项" :span="3" v-if="!safetyLogDetail?.fileList">
{{ safetyLogDetail?.otherRecords }}
</el-descriptions-item>
<el-descriptions-item label-align="center" label="附件" :span="3" v-if="safetyLogDetail?.fileList">
<el-space direction="vertical">
<el-link v-for="item in fileList" :key="item.ossId" :href="`${item.url}`" type="primary" :underline="false" target="_blank">
<span> {{ item.originalName }} </span>
<el-link
v-for="item in safetyLogDetail?.fileList"
:key="item.id"
:href="`${BASE_URL}${item.path}`"
type="primary"
:underline="false"
target="_blank"
>
<span> {{ item.name }} </span>
</el-link>
</el-space>
</el-descriptions-item>
<el-descriptions-item label-align="center" label="备注" :span="3">{{ safetyLogDetail?.remark }} </el-descriptions-item>
<!-- <el-descriptions-item label-align="center" label="备注" :span="3">{{ safetyLogDetail?.remark }} </el-descriptions-item> -->
</el-descriptions>
</el-card>
</template>
@ -62,6 +73,8 @@ import { OssVO } from '@/api/system/oss/types';
interface Props {
safetyLogId?: string | number;
}
const BASE_URL = import.meta.env.VITE_APP_BASE_API_GO;
console.log('🚀 ~ BASE_URL:', BASE_URL);
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { weather_type } = toRefs<any>(proxy?.useDict('weather_type'));
@ -77,7 +90,7 @@ const fileList = ref<Array<OssVO>>([]);
const get = async () => {
loading.value = true;
const res = await getSafetyLog(props.safetyLogId);
if (res.data && res.code === 200) {
if (res.data && res.code === 0) {
safetyLogDetail.value = res.data;
if (res.data.fileId) {
const fileRes = await listByIds(res.data.fileId.split(','));

View File

@ -19,6 +19,12 @@
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['safety:safetyLog:add']">新增 </el-button>
</el-col>
<el-col :span="1.5">
<el-button type="primary" plain icon="Upload" @click="handleAdd('file')" v-hasPermi="['safety:safetyLog:add']">上传附件 </el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
@ -35,9 +41,8 @@
<span>{{ parseTime(scope.row.dateOfOccurrence, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="录入时间" align="center" prop="createTime" />
<el-table-column label="录入人" align="center" prop="creatorName" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="录入时间" align="center" prop="updatedAt" />
<el-table-column label="录入人" align="center" prop="fill" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-space>
@ -55,54 +60,115 @@
</el-card>
<!-- 添加或修改安全日志对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="950px" append-to-body>
<el-form ref="safetyLogFormRef" :model="form" :rules="rules" label-width="250px">
<el-form ref="safetyLogFormRef" :model="form" :rules="rules" label-width="210px">
<el-form-item label="发生日期" prop="dateOfOccurrence">
<el-date-picker clearable v-model="form.dateOfOccurrence" type="date" value-format="YYYY-MM-DD" placeholder="请选择发生日期">
</el-date-picker>
<el-date-picker
clearable
style="width: 200px"
v-model="form.dateOfOccurrence"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
type="date"
placeholder="选择发生日期"
></el-date-picker>
</el-form-item>
<el-form-item label="最高气温" prop="airTemperatureMax">
<el-input v-model="form.airTemperatureMax" placeholder="请输入最高气温" />
<el-form-item label="最高气温" prop="airTemperatureMax" v-if="!fileStatus">
<el-input v-model="form.airTemperatureMax" placeholder="请输入最高气温" type="number">
<template #append></template>
</el-input>
</el-form-item>
<el-form-item label="最低气温" prop="airTemperatureMin">
<el-input v-model="form.airTemperatureMin" placeholder="请输入最低气温" />
<el-form-item label="最低气温" prop="airTemperatureMin" v-if="!fileStatus">
<el-input v-model="form.airTemperatureMin" :min="-275" :max="form.airTemperatureMax" placeholder="请输入最低气温" type="number">
<template #append></template>
</el-input>
</el-form-item>
<el-form-item label="气候" prop="weather">
<el-select v-model="form.weather" placeholder="请选择气候">
<el-form-item label="气候" prop="climate" v-if="!fileStatus">
<el-select v-model="form.climate" placeholder="请选择气候">
<el-option v-for="dict in weather_type" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="工程施工部位及施工进展情况" prop="progress">
<el-input v-model="form.progress" type="textarea" placeholder="请输入内容" />
<el-form-item label="工程施工部位及施工进展情况" prop="progress" v-if="!fileStatus">
<el-input v-model="form.progress" placeholder="请输入工程施工部位及施工进展情况" autosize maxlength="300" show-word-limit type="textarea" />
</el-form-item>
<el-form-item label="当日主要危险性项目作业内容">
<editor v-model="form.jobContent" :min-height="192" />
<el-form-item label="当日主要危险性项目作业内容" prop="jobContent" v-if="!fileStatus">
<el-input
v-model="form.jobContent"
placeholder="请输入当日主要危险性项目作业内容"
autosize
maxlength="300"
show-word-limit
type="textarea"
/>
</el-form-item>
<el-form-item label="施工项目安全教育与安全交底情况">
<editor v-model="form.discloseCondition" :min-height="192" />
<el-form-item label="施工项目安全教育与安全交底情况" prop="discloseTheFacts" v-if="!fileStatus">
<el-input
v-model="form.discloseTheFacts"
placeholder="请输入施工项目安全教育与安全交底情况"
autosize
maxlength="300"
show-word-limit
type="textarea"
/>
</el-form-item>
<el-form-item label="施工作业队伍班前施工安全活动情况">
<editor v-model="form.activityCondition" :min-height="192" />
<el-form-item label="施工作业队伍班前施工安全活动情况" prop="progressOfActivity" v-if="!fileStatus">
<el-input
v-model="form.progressOfActivity"
placeholder="请输入施工作业队伍班前施工安全活动情况"
autosize
maxlength="300"
show-word-limit
type="textarea"
/>
</el-form-item>
<el-form-item label="现场施工安全巡视与检查情况">
<editor v-model="form.examineCondition" :min-height="192" />
<el-form-item label="现场施工安全巡视与检查情况" prop="examine" v-if="!fileStatus">
<el-input v-model="form.examine" placeholder="请输入现场施工安全巡视与检查情况" autosize maxlength="300" show-word-limit type="textarea" />
</el-form-item>
<el-form-item label="季节施工防寒、防等措施实施情况">
<editor v-model="form.implementCondition" :min-height="192" />
<el-form-item label="季节施工防寒、防等措施实施情况" prop="implementation" v-if="!fileStatus">
<el-input
v-model="form.implementation"
placeholder="请输入季节施工防寒、防署等措施实施情况"
autosize
maxlength="300"
show-word-limit
type="textarea"
/>
</el-form-item>
<el-form-item label="监理通知有关部门安全检查情况">
<editor v-model="form.safetyInspectionCondition" :min-height="192" />
<el-form-item label="监理通知有关部门安全检查情况" prop="safetyInspectionSituation" v-if="!fileStatus">
<el-input
v-model="form.safetyInspectionSituation"
placeholder="请输入监理通知或有关部门安全检查情况"
autosize
maxlength="300"
show-word-limit
type="textarea"
/>
</el-form-item>
<el-form-item label="停工、加班情况">
<editor v-model="form.stoppageOrOvertime" :min-height="192" />
<el-form-item label="停工、加班情况" prop="stoppageOrOvertime" v-if="!fileStatus">
<el-input v-model="form.stoppageOrOvertime" placeholder="请输入停工、加班情况" autosize maxlength="300" show-word-limit type="textarea" />
</el-form-item>
<el-form-item label="其他应记录的安全与文明施工事项">
<editor v-model="form.otherCondition" :min-height="192" />
<el-form-item label="其他应记录的安全与文明施工事项" prop="otherRecords" v-if="!fileStatus">
<el-input
v-model="form.otherRecords"
placeholder="请输入其他应记录的安全与文明施工事项"
autosize
maxlength="300"
show-word-limit
type="textarea"
/>
</el-form-item>
<el-form-item label="附件" prop="fileId">
<file-upload v-model="form.fileId" />
<el-form-item label="文件上传" v-if="fileStatus">
<file-upload
v-model="form.file"
:auto-upload="false"
ref="uploadRef"
upload-url="/zm/api/v1/system/busHseSecurityLog/addFile"
isGo
:data="form"
show-file-list
/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
<el-input type="textarea" v-model="form.remark" maxlength="300" placeholder="请输入备注" />
</el-form-item>
</el-form>
<template #footer>
@ -112,6 +178,7 @@
</div>
</template>
</el-dialog>
<el-dialog title="安全日志详情" v-model="showDetailDialog">
<safety-log-detail-dialog :safety-log-id="currentSafetyLogId" />
</el-dialog>
@ -129,6 +196,7 @@ import SafetyLogDetailDialog from '@/views/safety/safetyLog/component/SafetyLogD
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { weather_type } = toRefs<any>(proxy?.useDict('weather_type'));
// 获取用户 store
const userStore = useUserStoreHook();
// 从 store 中获取项目列表和当前选中的项目
@ -149,9 +217,10 @@ const dialog = reactive<DialogOption>({
title: ''
});
const initFormData: SafetyLogForm = {
const initFormData: any = {
id: undefined,
projectId: currentProject.value.goId,
file: undefined,
dateOfOccurrence: undefined,
airTemperatureMax: undefined,
airTemperatureMin: undefined,
@ -248,13 +317,16 @@ const handleShowDialog = (row?: SafetyLogVO) => {
showDetailDialog.value = true;
};
/** 提交按钮 */
const uploadRef = ref();
const submitForm = () => {
safetyLogFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
form.value.projectId = currentProject.value?.id;
if (form.value.id) {
await updateSafetyLog(form.value).finally(() => (buttonLoading.value = false));
form.value.projectId = currentProject.value?.goId;
if (fileStatus.value) {
await uploadRef.value.submitUpload().finally((res) => {
buttonLoading.value = false;
});
} else {
await addSafetyLog(form.value).finally(() => (buttonLoading.value = false));
}
@ -274,6 +346,25 @@ const handleDelete = async (row?: SafetyLogVO) => {
await getList();
};
/** 新增按钮操作 */
const fileStatus = ref<boolean>(false);
const handleAdd = (type?: string) => {
reset();
if (weather_type.value.length == 5) {
weather_type.value = weather_type.value.filter((item) => item.value != '3');
weather_type.value[2].value = '3';
}
console.log('🚀 ~ handleAdd ~ type:', type);
if (type == 'file') {
fileStatus.value = true;
} else {
fileStatus.value = false;
}
dialog.visible = true;
dialog.title = '添加安全日志';
};
//监听项目id刷新数据
const listeningProject = watch(
() => currentProject.value.goId,

View File

@ -43,9 +43,6 @@
批量删除
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['safety:safetyWeeklyReport:export']">导出 </el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
@ -59,8 +56,8 @@
<span>{{ parseTime(scope.row.scope, '{y}-{m}-{d}') }} {{ parseTime(scope.row.scopeEnd, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="创建时间" align="center" prop="createdAt" />
<!-- <el-table-column label="备注" align="center" prop="remark" /> -->
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-space>
@ -80,20 +77,15 @@
<!-- 添加或修改安全周报对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="safetyWeeklyReportFormRef" :model="form" :rules="rules" label-width="120px">
<el-form-item label="周期" prop="week">
<el-input v-model="form.week" placeholder="请输入周期" />
</el-form-item>
<el-form-item label="周期开始范围" prop="scope">
<el-date-picker clearable v-model="form.scope" type="date" value-format="YYYY-MM-DD" placeholder="请选择周期范围" />
</el-form-item>
<el-form-item label="周期范围结束" prop="scopeEnd">
<el-date-picker clearable v-model="form.scopeEnd" type="date" value-format="YYYY-MM-DD" placeholder="请选择周期范围结束" />
</el-form-item>
<el-form-item label="文件位置" prop="path">
<div><file-upload v-model="form.path" :file-size="20" :limit="1" :file-type="['doc', 'docx']" /></div>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
<el-form-item label="周期范围" prop="timeRange">
<el-date-picker
v-model="form.timeRange"
type="daterange"
range-separator=""
format="YYYY-MM-DD"
start-placeholder="开始时间"
end-placeholder="结束时间"
/>
</el-form-item>
</el-form>
<template #footer>
@ -116,6 +108,7 @@ import {
} from '@/api/safety/safetyWeeklyReport';
import { SafetyWeeklyReportForm, SafetyWeeklyReportQuery, SafetyWeeklyReportVO } from '@/api/safety/safetyWeeklyReport/types';
import { useUserStoreHook } from '@/store/modules/user';
import { dayjs } from 'element-plus';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@ -142,7 +135,7 @@ const dialog = reactive<DialogOption>({
const initFormData: SafetyWeeklyReportForm = {
id: undefined,
projectId: currentProject.value?.id,
projectId: currentProject.value?.goId,
week: undefined,
scope: undefined,
scopeEnd: undefined,
@ -155,7 +148,7 @@ const data = reactive<PageData<SafetyWeeklyReportForm, SafetyWeeklyReportQuery>>
pageNum: 1,
pageSize: 10,
id: undefined,
projectId: currentProject.value?.id,
projectId: currentProject.value?.goId,
week: undefined,
scopeDate: undefined,
remark: undefined,
@ -163,7 +156,8 @@ const data = reactive<PageData<SafetyWeeklyReportForm, SafetyWeeklyReportQuery>>
},
rules: {
id: [{ required: true, message: '主键id不能为空', trigger: 'blur' }],
projectId: [{ required: true, message: '项目id不能为空', trigger: 'blur' }]
projectId: [{ required: true, message: '项目id不能为空', trigger: 'blur' }],
timeRange: [{ required: true, message: '周期范围不能为空', trigger: 'blur' }]
}
});
@ -173,8 +167,8 @@ const { queryParams, form, rules } = toRefs(data);
const getList = async () => {
loading.value = true;
const res = await listSafetyWeeklyReport(queryParams.value);
safetyWeeklyReportList.value = res.rows;
total.value = res.total;
safetyWeeklyReportList.value = res.data.list;
total.value = res.data.total;
loading.value = false;
};
@ -218,10 +212,11 @@ const handleAdd = () => {
/** 修改按钮操作 */
const handleUpdate = async (row?: SafetyWeeklyReportVO) => {
return;
reset();
const _id = row?.id || ids.value[0];
const res = await getSafetyWeeklyReport(_id);
Object.assign(form.value, res.data);
// const res = await getSafetyWeeklyReport(_id);
// Object.assign(form.value, res.data);
dialog.visible = true;
dialog.title = '修改安全周报';
};
@ -231,10 +226,11 @@ const submitForm = () => {
safetyWeeklyReportFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
form.value.projectId = currentProject.value?.id;
form.value.projectId = currentProject.value?.goId;
if (form.value.id) {
await updateSafetyWeeklyReport(form.value).finally(() => (buttonLoading.value = false));
} else {
form.value.timeRange = form.value.timeRange.map((d) => dayjs(d).format('YYYY-MM-DD')).join(',');
await addSafetyWeeklyReport(form.value).finally(() => (buttonLoading.value = false));
}
proxy?.$modal.msgSuccess('操作成功');
@ -266,7 +262,7 @@ const handleExport = () => {
//监听项目id刷新数据
const listeningProject = watch(
() => currentProject.value?.id,
() => currentProject.value?.goId,
(nid, oid) => {
queryParams.value.projectId = nid;
form.value.projectId = nid;

View File

@ -46,6 +46,9 @@
<el-button link type="primary" icon="View" @click="handleShowDrawer(scope.row)" v-hasPermi="['safety:teamMeeting:query']">
详情
</el-button>
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['safety:teamMeeting:remove']">
删除
</el-button>
</el-space>
</template>
</el-table-column>
@ -192,6 +195,14 @@ const handleAdd = () => {
dialog.visible = true;
dialog.title = '添加站班会';
};
/** 删除按钮操作 */
const handleDelete = async (row: TeamMeetingVO) => {
proxy?.$modal.confirm('确定删除选中数据吗?').then(async () => {
await delTeamMeeting(row.id);
proxy?.$modal.msgSuccess('删除成功');
await getList();
});
};
/** 展开站班会详情抽屉操作 */
const showDetailDrawer = ref<boolean>(false);

View File

@ -7,8 +7,8 @@
<el-form ref="formRef" size="large" :model="formData" :rules="rules" label-width="90px">
<el-row>
<el-col :span="12">
<el-form-item label="违章等级" prop="violationLevel">
<el-input v-model="formData.violationLevel" placeholder="请输入违章等级" />
<el-form-item label="违章等级" prop="grade">
<el-input v-model="formData.grade" placeholder="请输入违章等级" />
</el-form-item>
</el-col>
<el-col :span="12">
@ -17,43 +17,23 @@
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="风险等级" prop="riskType">
<el-select v-model="formData.riskType" placeholder="请选择风险等级">
<el-option v-for="dict in risxList" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" :offset="0" prop="dept">
<el-form-item label="部门">
<el-cascader
:options="postListAll"
v-model="formData.dept"
clearable
filterable
:show-all-levels="false"
placeholder="请选择部门"
:props="{ expandTrigger: 'hover', checkStrictly: true, value: 'id', emitPath: false, multiple: true }"
@change="changeDept"
>
</el-cascader>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="岗位" prop="postIdList">
<el-select v-model="formData.postIdList" placeholder="请选择岗位" multiple :disabled="!formData.dept">
<el-option
v-for="dict in formData.postWorkList"
:key="dict.postId"
:label="dict.deptName + '/' + dict.postName"
:value="dict.postId"
/>
<el-form-item label="风险等级" prop="risx">
<el-select v-model="formData.risx" placeholder="请选择风险等级">
<el-option v-for="dict in risxList" :key="dict.key" :label="dict.value" :value="dict.key" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="违章类型" prop="violationType">
<el-select v-model="formData.violationType" placeholder="请选择违章类型" multiple>
<el-option v-for="dict in tourTypeOptions" :key="dict.value" :label="dict.label" :value="dict.value" />
<el-form-item label="岗位" prop="posts">
<el-select v-model="formData.posts" placeholder="请选择岗位" multiple>
<el-option v-for="dict in postListAll" :key="dict.postId" :label="dict.postName" :value="dict.postId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="违章类型" prop="tourType">
<el-select v-model="formData.tourType" placeholder="请选择违章类型" multiple>
<el-option v-for="dict in tourTypeOptions" :key="dict.key" :label="dict.value" :value="dict.key" />
</el-select>
</el-form-item>
</el-col>
@ -166,16 +146,14 @@ const resetForm = () => {
// 提交操作
const onSubmit = () => {
if (!formRef.value) return;
formRef.value.validate((valid: boolean) => {
if (valid) {
loading.value = true;
const param = JSON.parse(JSON.stringify(formData));
if (param.violationType?.length) {
param.violationType = param.violationType.join(',');
if (param.tourType?.length) {
param.tourType = param.tourType.join(',');
}
addViolationLevel(param)
.then(() => {
ElMessage.success('添加成功');
@ -189,32 +167,6 @@ const onSubmit = () => {
});
};
const changeDept = (val: any) => {
formData.postWorkList = getPostVoListByIds(props.postListAll, val);
formData.postIdList = [];
console.log(formData.postWorkList, val);
};
function getPostVoListByIds(tree: any[], idList: (string | number)[]): any[] {
const idSet = new Set(idList.map(String)); // 用于快速匹配 ID统一为字符串比较
const result: any[] = [];
function dfs(nodes: any[]) {
for (const node of nodes) {
if (idSet.has(String(node.id))) {
result.push(...(node.postVoList || []));
}
if (node.children && node.children.length > 0) {
dfs(node.children);
}
}
}
dfs(tree);
return result;
}
defineExpose({
openDialog,
closeDialog

View File

@ -1,16 +1,14 @@
<template>
<div class="system-busViolationLevel-edit">
<el-dialog v-model="isShowDialog" width="550px" :close-on-click-modal="false" :destroy-on-close="true" custom-class="busViolationLevel_edit">
<el-dialog v-model="isShowDialog" width="550px" :close-on-click-modal="false" :destroy-on-close="true">
<template #header>
<div v-drag="['.system-busViolationLevel-edit .el-dialog', '.system-busViolationLevel-edit .el-dialog__header']">
{{ (!formData.id || formData.id == 0 ? '添加' : '修改') + '违章等级' }}
</div>
<div v-drag="['.system-busViolationLevel-add .el-dialog', '.system-busViolationLevel-add .el-dialog__header']">修改违章等级</div>
</template>
<el-form ref="formRef" size="large" :model="formData" :rules="rules" label-width="90px">
<el-row>
<el-col :span="12">
<el-form-item label="违章等级" prop="violationLevel">
<el-input v-model="formData.violationLevel" placeholder="请输入违章等级" />
<el-form-item label="违章等级" prop="grade">
<el-input v-model="formData.grade" placeholder="请输入违章等级" />
</el-form-item>
</el-col>
<el-col :span="12">
@ -19,43 +17,23 @@
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="风险等级" prop="riskType">
<el-select v-model="formData.riskType" placeholder="请选择风险等级">
<el-option v-for="dict in risxList" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" :offset="0" prop="dept">
<el-form-item label="部门">
<el-cascader
:options="postListAll"
v-model="formData.dept"
clearable
filterable
:show-all-levels="false"
placeholder="请选择部门"
:props="{ expandTrigger: 'hover', checkStrictly: true, value: 'id', emitPath: false, multiple: true }"
@change="changeDept"
>
</el-cascader>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="岗位" prop="postIdList">
<el-select v-model="formData.postIdList" placeholder="请选择岗位" multiple :disabled="!formData.dept">
<el-option
v-for="dict in formData.postWorkList"
:key="dict.postId"
:label="dict.deptName + '/' + dict.postName"
:value="dict.postId"
/>
<el-form-item label="风险等级" prop="risx">
<el-select v-model="formData.risx" placeholder="请选择风险等级">
<el-option v-for="dict in risxList" :key="dict.key" :label="dict.value" :value="dict.key" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="违章类型" prop="violationType">
<el-select v-model="formData.violationType" placeholder="请选择违章类型" multiple>
<el-option v-for="dict in tourTypeOptions" :key="dict.value" :label="dict.label" :value="dict.value" />
<el-form-item label="岗位" prop="posts">
<el-select v-model="formData.posts" placeholder="请选择岗位" multiple>
<el-option v-for="dict in postListAll" :key="dict.postId" :label="dict.postName" :value="dict.postId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="违章类型" prop="tourType">
<el-select v-model="formData.tourType" placeholder="请选择违章类型" multiple>
<el-option v-for="dict in tourTypeOptions" :key="dict.key" :label="dict.value" :value="dict.key" />
</el-select>
</el-form-item>
</el-col>
@ -138,11 +116,10 @@ const openDialog = (row?: ViolationLevelVO) => {
getViolationLevel(row.id as string).then((res) => {
loadingInstance.close();
const data = res.data;
data.postIdList = (data.postList || []).map((item: any) => item.postId);
data.violationType = data.violationType ? (data.violationType as string).split(',') : [];
formData.dept = (data.postList || []).map((item: any) => item.deptId);
formData.postWorkList = getPostVoListByIds(props.postListAll, formData.dept);
data.posts = (data.postEntity || []).map((item: any) => item.postId);
data.tourType = data.tourType ? (data.tourType as string).split(',') : [];
Object.assign(formData, data);
console.log(formData);
});
});
}
@ -167,11 +144,8 @@ const onSubmit = () => {
loading.value = true;
const param = JSON.parse(JSON.stringify(formData));
if (Array.isArray(param.violationType)) {
param.violationType = param.violationType.join(',');
}
if (Array.isArray(param.riskType)) {
param.riskType = param.riskType.join(',');
if (Array.isArray(param.tourType)) {
param.tourType = param.tourType.join(',');
}
const action = !param.id || param.id === 0 ? addViolationLevel : updateViolationLevel;

View File

@ -23,6 +23,23 @@
</el-col>
</el-row>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" @click="handleAdd" v-auth="'api/v1/system/busViolationLevel/add'">
<el-icon><Plus /></el-icon>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" :disabled="single" @click="handleUpdate(null)" v-auth="'api/v1/system/busViolationLevel/edit'">
<el-icon><Edit /></el-icon>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" :disabled="multiple" @click="handleDelete(null)" v-auth="'api/v1/system/busViolationLevel/delete'">
<el-icon><Delete /></el-icon>删除
</el-button>
</el-col>
</el-row>
</div>
<el-table v-loading="loading" :data="state.tableData.data" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
@ -44,6 +61,16 @@
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createdAt"> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding" width="160px" fixed="right">
<template #default="scope">
<el-button type="success" link @click="handleUpdate(scope.row)" v-auth="'api/v1/system/busViolationLevel/edit'">
<el-icon><EditPen /></el-icon>修改
</el-button>
<el-button type="danger" link @click="handleDelete(scope.row)" v-auth="'api/v1/system/busViolationLevel/delete'">
<el-icon><DeleteFilled /></el-icon>删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="state.tableData.total > 0"
@ -56,15 +83,15 @@
<apiV1SystemBusViolationLevelAdd
ref="addRef"
:tourTypeOptions="violation_level_type"
:risxList="risk_level_type"
:tourTypeOptions="safety_inspection_violation_type"
:risxList="risx"
@busViolationLevelList="busViolationLevelList"
:postListAll="state.postListAll"
/>
<apiV1SystemBusViolationLevelEdit
ref="editRef"
:tourTypeOptions="violation_level_type"
:risxList="risk_level_type"
:tourTypeOptions="safety_inspection_violation_type"
:risxList="risx"
:postListAll="state.postListAll"
@busViolationLevelList="busViolationLevelList"
/>
@ -123,7 +150,7 @@ const state = reactive<any>({
const postList = () => {
listTreeByProject().then((res) => {
console.log('🚀 ~ listTreeByProject ~ res:', res);
state.postListAll = res.data ?? [];
state.postListAll = res.data.postList ?? [];
});
};

View File

@ -23,6 +23,7 @@
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-button type="danger" @click="handleDelete()" plain icon="Delete" :disabled="multiple">删除</el-button>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
@ -66,60 +67,94 @@
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
<template #default="scope">
<el-tooltip content="详情" placement="top">
<el-button
link
type="primary"
icon="View"
@click="handleShowDialog(scope.row)"
v-hasPermi="['safety:violationRecord:view']"
></el-button>
</el-tooltip>
<el-button link type="primary" icon="View" @click="handleShowDialog(scope.row)" v-hasPermi="['safety:violationRecord:view']"
>详情</el-button
>
<el-button
link
type="primary"
icon="User"
v-if="!scope.row.openid"
@click="handleEdit(scope.row)"
v-hasPermi="['safety:violationRecord:view']"
>违章处理人</el-button
>
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['safety:violationRecord:view']">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
<!-- 添加或修改违规记录对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="violationRecordFormRef" :model="form" :rules="rules" label-width="90px">
<el-form-item label="违章处理人" prop="handlerId">
<el-input v-model="form.handlerId" placeholder="请输入违章处理人" />
</el-form-item>
<el-form-item label="处理期限" prop="disposeDeadline">
<el-date-picker clearable v-model="form.disposeDeadline" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择处理期限">
</el-date-picker>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
<el-dialog title="违规记录详情" v-model="showDetailDialog" width="60vw">
<ViolationRecordDetailDialog
:violation-record-id="currentViolationRecordId"
:safety_inspection_violation_type="safety_inspection_violation_type"
/>
</el-dialog>
<el-dialog v-model="isShowDialog" width="450px" :close-on-click-modal="false" :destroy-on-close="true">
<template #header>
<div v-drag="['.system-busViolationRecord-add .el-dialog', '.system-busViolationRecord-add .el-dialog__header']">选择违章处理人</div>
</template>
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
<el-row>
<el-col :span="24">
<el-form-item label="处理人" prop="openid">
<el-select v-model="form.openid" :filter-method="filterMethod" filterable placeholder="请选择处理人">
<el-option
v-for="(item, i) of userQuery.userList"
:key="item.openid"
:label="item.userName ? item.userName : item.nickName"
:value="item.openid"
/>
<pagination
v-show="userQuery.total > 0"
:total="userQuery.total"
v-model:page="userQuery.param.pageNum"
v-model:limit="userQuery.param.pageSize"
@pagination="busConstructionUserList"
:layout="'total, prev, pager, next'"
:isSmall="true"
style="padding: 5px 10px"
/>
</el-select>
</el-form-item>
<el-form-item label="要求处理期限" prop="processingPeriod">
<el-date-picker format="YYYY-MM-DD" value-format="YYYY-MM-DD" v-model="form.processingPeriod" type="date" placeholder="要求处理期限" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="onSubmit" :loading="loading"> </el-button>
<el-button @click="isShowDialog = false"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="ViolationRecord" lang="ts">
import { listViolationRecord, getViolationRecord, delViolationRecord, addViolationRecord, updateViolationRecord } from '@/api/safety/violationRecord';
import {
listViolationRecord,
getViolationRecord,
delViolationRecord,
addViolationRecord,
updateViolationRecord,
listBusConstructionUser
} from '@/api/safety/violationRecord';
import { ViolationRecordVO, ViolationRecordQuery, ViolationRecordForm } from '@/api/safety/violationRecord/types';
import ViolationRecordDetailDialog from './component/violationRecordDetailDialog.vue';
import { useUserStoreHook } from '@/store/modules/user';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
import { getDictData } from '@/api/project/goUser/index';
import { disable } from 'ol/rotationconstraint';
const { violation_level_type, risk_level_type, safety_inspection_type } = toRefs<any>(
proxy?.useDict('violation_level_type', 'risk_level_type', 'safety_inspection_type')
);
@ -127,6 +162,17 @@ const { violation_level_type, risk_level_type, safety_inspection_type } = toRefs
const userStore = useUserStoreHook();
// 从 store 中获取项目列表和当前选中的项目
const currentProject = computed(() => userStore.selectedProject);
const userQuery = reactive({
userList: [],
total: 0,
param: {
pageNum: 1,
pageSize: 10,
userName: undefined,
phone: undefined,
projectId: currentProject.value.goId
}
});
const violationRecordList = ref<ViolationRecordVO[]>([]);
const buttonLoading = ref(false);
@ -138,6 +184,7 @@ const multiple = ref(true);
const total = ref(0);
const currentViolationRecordId = ref<string | number>(undefined);
const showDetailDialog = ref(false);
const isShowDialog = ref(false);
const queryFormRef = ref<ElFormInstance>();
const violationRecordFormRef = ref<ElFormInstance>();
@ -194,12 +241,29 @@ const data = reactive<PageData<ViolationRecordForm, ViolationRecordQuery>>({
levelId: [{ required: true, message: '违章等级id不能为空', trigger: 'blur' }],
recognizeId: [{ required: true, message: '识别记录id不能为空', trigger: 'blur' }],
processType: [{ required: true, message: '处理流程类型(0仅通知 1通知整改复查)不能为空', trigger: 'change' }],
status: [{ required: true, message: '工单状态不能为空', trigger: 'change' }]
status: [{ required: true, message: '工单状态不能为空', trigger: 'change' }],
openid: [{ required: true, message: '处理人不能为空', trigger: 'change' }],
processingPeriod: [{ required: true, message: '要求处理期限不能为空', trigger: 'change' }]
}
});
const { queryParams, form, rules } = toRefs(data);
const filterMethod = (val) => {
userQuery.param.userName = val;
busConstructionUserList();
};
const busConstructionUserList = () => {
listBusConstructionUser(userQuery.param).then((res: any) => {
if (res.code === 0) {
userQuery.userList = [];
userQuery.userList = res.data.list;
userQuery.total = res.data.total;
}
});
};
/** 查询违规记录列表 */
const getList = async () => {
loading.value = true;
@ -247,6 +311,14 @@ const handleAdd = () => {
dialog.title = '添加违规记录';
};
const handleEdit = async (row: any) => {
reset();
busConstructionUserList();
const res = await getViolationRecord(row.id);
form.value.id = res.data.id;
isShowDialog.value = true;
};
/** 修改按钮操作 */
const handleUpdate = async (row?: ViolationRecordVO) => {
reset();
@ -261,11 +333,11 @@ const handleShowDialog = (row?: ViolationRecordVO) => {
};
/** 提交按钮 */
const submitForm = () => {
const onSubmit = () => {
violationRecordFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
await addViolationRecord(form.value).finally(() => (buttonLoading.value = false));
loading.value = true;
await addViolationRecord(form.value).finally(() => (loading.value = false));
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
await getList();