pull/1/head
z 2024-01-09 16:20:28 +08:00
parent faeb08ff24
commit f8b71eccbf
25 changed files with 1996 additions and 89 deletions

View File

@ -118,7 +118,7 @@
}
}
.el-select, .el-cascader, .el-date-editor.el-input, .el-date-editor.el-input__wrapper, .el-input__wrapper, .el-input-number {
.el-select, .el-cascader, .el-date-editor.el-input, .el-date-editor.el-input__wrapper, .el-input__wrapper, .el-input-number, .el-select-v2 {
width: 100% !important;
}
@ -380,7 +380,7 @@
color: var(--el-text-color-regular) !important;
}
.el-step__title {
.el-step__title, .el-select-dropdown__option-item {
font-size: 14px !important;
}

View File

@ -147,6 +147,63 @@ export default [
},
],
},
{
path: "/risk_control/identifying_parts",
meta: { title: "辨识部位", isSubMenu: false },
component: "children",
children: [
{
path: "",
component: "risk_control/identifying_parts/index",
},
{
path: "/risk_control/identifying_parts/resources_risk",
meta: {
title: "匹配资源存在风险",
activeMenu: "/risk_control/identifying_parts",
},
component: "risk_control/identifying_parts/resources_risk",
},
],
},
{
path: "/risk_control/ledger",
meta: { title: "风险管控台账", isSubMenu: false },
component: "children",
children: [
{
path: "",
component: "risk_control/ledger/index",
},
{
path: "/risk_control/ledger/allocation",
meta: {
title: "配置",
activeMenu: "/risk_control/ledger",
},
component: "risk_control/ledger/allocation",
},
],
},
],
},
{
path: "/hazard_investigation",
redirect: "/hazard_investigation/inventory_management",
meta: { title: "隐患排查", model: MODEL["1"] },
component: "children",
children: [
{
path: "/hazard_investigation/inventory_management",
meta: { title: "清单管理", isSubMenu: false },
component: "children",
children: [
{
path: "",
component: "hazard_investigation/inventory_management/index",
},
],
},
],
},
{

View File

@ -1,5 +1,5 @@
import {
getLearningTrainType,
getLevelsByParentId,
getLevels,
getLevelsAndChildrenNumber,
getRegulatoryType,
@ -36,25 +36,39 @@ export const layoutFnGetEnterpriseScale = async () => {
};
// 培训行业类型
export const layoutFnGetTrainingIndustryType = async () => {
const resData = await getLearningTrainType({
const resData = await getLevelsByParentId({
parentId: "052369aa22d242118236cde52d0c67ea",
});
return ref(JSON.parse(resData.zTreeNodes));
};
// 培训岗位类型
export const layoutFnGetTrainingPostType = async () => {
const resData = await getLearningTrainType({
const resData = await getLevelsByParentId({
parentId: "f6a7c4f5602f46e291d06b1390a3f820",
});
return ref(JSON.parse(resData.zTreeNodes));
};
// 培训板块类型
export const layoutFnGetTrainingPlateType = async () => {
const resData = await getLearningTrainType({
const resData = await getLevelsByParentId({
parentId: "d538d11e4eec409ab428f5d2f3c67c24",
});
return ref(JSON.parse(resData.zTreeNodes));
};
// 管控措施分类1
export const layoutFnGetControlMeasures1 = async () => {
const resData = await getLevelsByParentId({
parentId: "c61ff12d2e6e4040ad0dfd58d75275ae",
});
return ref(JSON.parse(resData.zTreeNodes));
};
// 管控措施分类2
export const layoutFnGetControlMeasures2 = async () => {
const resData = await getLevelsByParentId({
parentId: "1ca0ce441f8342cca57fd09079ad59b0",
});
return ref(JSON.parse(resData.zTreeNodes));
};
// 受限空间类型
export const layoutFnGetTypeOfConfinedSpace = async () => {
const resData = await getLevels({
@ -139,6 +153,20 @@ export const layoutFnGetEmploymentSituation = async () => {
});
return ref(resData.list);
};
// 事故类型
export const layoutFnGetAccidentType = async () => {
const resData = await getLevels({
DICTIONARIES_ID: "cee1190ea96a4ca9b7bca81e11f0d0f8",
});
return ref(resData.list);
};
// 风险分级
export const layoutFnGetRiskClassification = async () => {
const resData = await getLevels({
DICTIONARIES_ID: "5a81e63ec0e94d919b3138bc01dbef6b",
});
return ref(resData.list);
};
// 部门树
export const layoutFnGetDepartmentTree = async (params) => {
const resData = await getDepartmentTree(params);

View File

@ -4,12 +4,12 @@ import { getDataType } from "@/assets/js/utils.js";
/**
* @param api {Function} 接口函数
* @param options {Object?: {callbackFn, otherParams, immediate, usePagination, key}} 配置项
* @param options.callbackFn {Function?} 回调函数返回值为后台返回的所有数据
* @param options.callbackFn {Function?} 回调函数返回值第一个参数表格数据第二个参数后台返回的所有数据
* @param options.otherParams {Object?} 其它接口参数
* @param options.immediate {Boolean?} 是否立即执行接口函数默认是
* @param options.usePagination {Boolean?} 是否使用分页默认是
* @param options.key {String?} 返回的存放数组的key默认varList
* @return {Object} 返回对象包含以下属性list 表格数据pagination 分页数据searchForm 搜索表单数据tableRef 表格实例fnGetData 获取数据函数fnResetPagination 重置分页函数
* @return {Object} 返回对象包含以下属性list 表格数据pagination 分页数据searchForm 搜索表单数据tableRef 表格实例responseData 后台所有返回值fnGetData 获取数据函数fnResetPagination 重置分页函数
*/
export default function useListData(api, options = {}) {
@ -35,6 +35,7 @@ export default function useListData(api, options = {}) {
throw new Error("options.otherParams必须是一个对象");
if (options.callbackFn && getDataType(options.callbackFn) !== "Function")
throw new Error("options.callbackFn必须是一个函数");
const responseData = ref({});
const list = ref([]);
const pagination = ref({
currentPage: 1,
@ -57,7 +58,8 @@ export default function useListData(api, options = {}) {
});
list.value = resData[key];
pagination.value.total = resData.page.totalResult;
options.callbackFn && options.callbackFn(resData);
responseData.value = resData;
options.callbackFn && options.callbackFn(list.value, resData);
};
immediate && fnGetData().then();
const fnResetPagination = async (otherParams) => {
@ -76,6 +78,7 @@ export default function useListData(api, options = {}) {
pagination,
searchForm,
tableRef,
responseData,
fnGetData: async (otherParams) => await fnGetData(otherParams),
fnResetPagination: async (otherParams) =>
await fnResetPagination(otherParams),

View File

@ -0,0 +1,35 @@
<template>
<el-tooltip placement="top">
<template #content>
<template v-if="imgs.length > 0">
<img
v-for="item in imgs"
:key="item.IMGFILES_ID"
:src="VITE_FILE_URL + item.FILEPATH"
width="100"
height="100"
alt=""
class="ml-10"
/>
</template>
<span v-else></span>
</template>
<el-tag>预览</el-tag>
</el-tooltip>
</template>
<script setup>
defineOptions({
name: "LayoutTooltipImg",
});
const VITE_FILE_URL = import.meta.env.VITE_FILE_URL;
defineProps({
imgs: {
type: Array,
required: true,
default: () => [],
},
});
</script>
<style scoped lang="scss"></style>

View File

@ -3,7 +3,8 @@ import { post, upload } from "./axios";
export const Login = (params) => post("/admin/check", params); // 登录
export const logout = (params) => post("/main/logout", params); // 退出登录
export const getAsyncRouter = (params) => post("/main/index", params); // 获取动态路由
export const getHasMenu = (params) => post("/head/hasMenu", params); // 获取有没有权限访问路由
export const getHasMenu = (params) =>
post("/head/hasMenu", { loading: false, ...params }); // 获取有没有权限访问路由
export const getUserInfo = (params) => post("/user/goEditMyInfo", params); // 获取用户信息
export const setUserInfo = (params) => post("/user/editUserOwn", params); // 修改用户信息
export const getVerifyDuplicateEmail = (params) =>

View File

@ -12,6 +12,12 @@ export const getLevelsCorp = (params) =>
loading: false,
...params,
});
// 获取数据字典
export const getLevelsByParentId = (params) =>
post("/dictionaries/listDictToParId", {
loading: false,
...params,
});
// 获取数据字典包括子级数量
export const getLevelsAndChildrenNumber = (params) =>
post("/dictionaries/getLevelsAndSCount", {
@ -24,12 +30,6 @@ export const getRegulatoryType = (params) =>
loading: false,
...params,
});
// 获取在线学习培训类型
export const getLearningTrainType = (params) =>
post("/dictionaries/listDictToParId", {
loading: false,
...params,
});
// 获取用户
export const getUserListAllByCorp = (params) =>
post("/user/listUserByCorp", {

View File

@ -11,3 +11,55 @@ export const setRiskPointAdd = (params) => post("/riskunit/add", params); // 风
export const setRiskPointEdit = (params) => post("/riskunit/edit", params); // 风险点单元修改
export const getRiskPointInspectList = (params) =>
post("/riskunit/getRisByUnitId", params); // 风险点单元检查内容
export const getIdentifyingPartsList = (params) =>
post("/identificationparts/list", params); // 辨识部位列表
export const getIdentifyingPartsView = (params) =>
post("/identificationparts/goEdit", params); // 辨识部位查看
export const setIdentifyingPartsDelete = (params) =>
post("/identificationparts/delete", params); // 辨识部位删除
export const setIdentifyingPartsBatchDelete = (params) =>
post("/identificationparts/deleteAll", params); // 辨识部位批量删除
export const setIdentifyingPartsImport = (params) =>
upload("/identificationparts/readExcel", params); // 辨识部位导入
export const getRiskPointListAll = (params) =>
post("/identificationparts/getSelect", params); // 风险点单元列表所有
export const setIdentifyingPartsAdd = (params) =>
upload("/identificationparts/add", params); // 辨识部位添加
export const setIdentifyingPartsEdit = (params) =>
upload("/identificationparts/edit", params); // 辨识部位修改
export const getIdentifyingPartsResourcesRisk = (params) =>
post("/identificationparts/goEditRes", params); // 辨识部位匹配资源存在风险
export const getIdentifyingPartsRiskView1 = (params) =>
post("/riskpointTemporary/goRiskEdit", params); // 辨识部位风险查看
export const getIdentifyingPartsRiskView2 = (params) =>
post("/riskpointTemporary/goEdit", params); // 辨识部位风险查看
export const getIdentifyingPartsRiskView3 = (params) =>
post("/riskpointTemporary/goResEdit", params); // 辨识部位风险查看
export const setIdentifyingPartsRiskAdd = (params) =>
post("/riskpointTemporary/add", params); // 辨识部位风险添加
export const setIdentifyingPartsRiskEdit = (params) =>
post("/riskpointTemporary/edit", params); // 辨识部位风险修改
export const setIdentifyingPartsResourcesRiskSave = (params) =>
post("/identificationparts/resourceConfig", params); // 辨识部位匹配资源存在风险保存
export const getRiskControlLedgerList = (params) =>
post("/riskpoint/list", params); // 风险管控台账列表
export const setRiskControlLedgerDelete = (params) =>
post("/riskpoint/delete", params); // 风险管控台账删除
export const setRiskControlLedgerBatchDelete = (params) =>
post("/riskpoint/deleteAll", params); // 风险管控台账删除
export const setRiskControlLedgerImport = (params) =>
upload("/riskpoint/readExcel2", params); // 风险管控台账导入
export const getRiskControlLedgerView = (params) =>
post("/riskpoint/goEdit", params); // 风险管控台账查看
export const getRiskPointListAllById = (params) =>
post("/riskpoint/getPointSelect", params); // 风险点单元列表所有按部门查询
export const getIdentifyingPartsListAll = (params) =>
post("/identificationparts/listAll", params); // 辨识部位列表所有
export const setRiskControlLedgerAdd = (params) =>
post("/riskpoint/add", params); // 辨识部位添加
export const setRiskControlLedgerEdit = (params) =>
post("/riskpoint/edit", params); // 辨识部位修改
export const getRiskControlLedgerAllocationList = (params) =>
post("/riskcheckitem/list", params); // 辨识部位配置列表
export const setRiskControlLedgerAllocationEdit = (params) =>
post("/riskcheckitem/edit", params); // 辨识部位配置修改

View File

@ -55,23 +55,7 @@
<el-table-column label="证书编号" prop="NUMBER" />
<el-table-column label="照片">
<template v-slot="{ row }">
<el-tooltip placement="top">
<template #content>
<template v-if="row.imgs.length > 0">
<img
v-for="item in row.imgs"
:key="item.IMGFILES_ID"
:src="VITE_FILE_URL + item.FILEPATH"
width="100"
height="100"
alt=""
class="ml-10"
/>
</template>
<span v-else></span>
</template>
<el-tag>预览</el-tag>
</el-tooltip>
<layout-tooltip-img :imgs="row.imgs" />
</template>
</el-table-column>
<el-table-column label="操作" width="150">
@ -139,8 +123,8 @@ import {
} from "@/request/enterprise_management.js";
import { useRouter } from "vue-router";
import useListData from "@/assets/js/useListData.js";
import LayoutTooltipImg from "@/components/tooltip_img/index.vue";
const VITE_FILE_URL = import.meta.env.VITE_FILE_URL;
const router = useRouter();
const { list, pagination, searchForm, fnGetData, fnResetPagination } =
useListData(getIndustryQualificationsList);

View File

@ -37,23 +37,7 @@
</el-table-column>
<el-table-column label="照片">
<template v-slot="{ row }">
<el-tooltip placement="top">
<template #content>
<template v-if="row.imgs.length > 0">
<img
v-for="item in row.imgs"
:key="item.IMGFILES_ID"
:src="VITE_FILE_URL + item.FILEPATH"
width="100"
height="100"
alt=""
class="ml-10"
/>
</template>
<span v-else></span>
</template>
<el-tag>预览</el-tag>
</el-tooltip>
<layout-tooltip-img :imgs="row.imgs" />
</template>
</el-table-column>
<el-table-column label="操作" width="100">
@ -118,8 +102,8 @@ import { onBeforeRouteUpdate, useRoute, useRouter } from "vue-router";
import { debounce } from "throttle-debounce";
import { ElMessage, ElMessageBox } from "element-plus";
import Add from "./components/add.vue";
import LayoutTooltipImg from "@/components/tooltip_img/index.vue";
const VITE_FILE_URL = import.meta.env.VITE_FILE_URL;
const userStore = useUserStore();
const router = useRouter();
const route = useRoute();

View File

@ -721,9 +721,6 @@ const stop = watch(
fnGetLevels();
stop && stop();
}
},
{
immediate: true,
}
);
const fnSubmit = debounce(

View File

@ -83,9 +83,6 @@ watch(
() => props.visible,
(val) => {
if (val) fnGetWorkDate();
},
{
immediate: true,
}
);
</script>

View File

@ -130,6 +130,7 @@
type="primary"
text
link
@click="fnSchedule(row)"
>
排班表
</el-button>
@ -184,6 +185,11 @@
title="在线学习人员导入"
@submit="fnSubmitLearnersImport"
/>
<scheduling
v-model:visible="data.scheduleDialog.visible"
:info="data.scheduleDialog.info"
:id="data.scheduleDialog.id"
/>
</div>
</template>
@ -205,6 +211,7 @@ import { onBeforeRouteUpdate, useRoute, useRouter } from "vue-router";
import { debounce } from "throttle-debounce";
import { ElMessage, ElMessageBox } from "element-plus";
import LayoutImportFile from "@/components/import_file/index.vue";
import Scheduling from "./components/scheduling.vue";
const router = useRouter();
const route = useRoute();
@ -223,6 +230,11 @@ const data = reactive({
schedulingList1: [],
importDialogVisible: false,
importLearnersDialogVisible: false,
scheduleDialog: {
visible: false,
info: {},
id: "",
},
});
const fnGetUserScheduling = async (PARENTID, list) => {
const resData = await getUserScheduling({ PARENTID });
@ -286,6 +298,11 @@ const fnSubmitLearnersImport = async (formData) => {
fnImportLearnersDialogChangeShow();
fnResetPaginationTransfer();
};
const fnSchedule = (row) => {
data.scheduleDialog.visible = true;
data.scheduleDialog.info = row;
data.scheduleDialog.id = row.SHIFTDUTYTWO;
};
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,114 @@
<template>
<el-dialog
v-model="visible"
:title="type === 'edit' ? '修改' : '新增'"
:before-close="fnClose"
>
<el-form ref="formRef" :rules="rules" :model="form" label-width="150px">
<el-form-item label="风险点(单元)" prop="RISK_UNIT_ID">
<el-select v-model="form.RISK_UNIT_ID">
<el-option
v-for="item in unitList"
:key="item.RISKUNIT_ID"
:label="item.DEPT_NAME + '-' + item.RISKUNITNAME"
:value="item.RISKUNIT_ID"
/>
</el-select>
</el-form-item>
<el-form-item label="辨识部位名称" prop="PARTSNAME">
<el-input v-model="form.PARTSNAME" />
</el-form-item>
<el-form-item label="告知卡" prop="file">
<layout-upload
v-model:file-list="form.file"
accept=".jpg,.jpeg,.png"
list-type="picture-card"
delete-to-server
:limit="99"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="fnClose"></el-button>
<el-button type="primary" @click="fnSubmit"> </el-button>
</template>
</el-dialog>
</template>
<script setup>
import { ref } from "vue";
import { useVModels } from "@vueuse/core";
import { debounce } from "throttle-debounce";
import useFormValidate from "@/assets/js/useFormValidate.js";
import { ElMessage } from "element-plus";
import {
getRiskPointListAll,
setIdentifyingPartsAdd,
setIdentifyingPartsEdit,
} from "@/request/risk_control.js";
import LayoutUpload from "@/components/upload/index.vue";
const props = defineProps({
visible: {
type: Boolean,
required: true,
default: false,
},
form: {
type: Object,
required: true,
default: () => ({}),
},
type: {
type: String,
required: true,
default: "",
},
});
const emits = defineEmits(["update:visible", "update:form", "get-data"]);
const { visible, form } = useVModels(props, emits);
const rules = {
RISK_UNIT_ID: [
{ required: true, message: "风险点(单元)不能为空", trigger: "change" },
],
PARTSNAME: [
{ required: true, message: "辨识部位名称不能为空", trigger: "blur" },
],
};
const formRef = ref(null);
const unitList = ref([]);
const fnGetUnitList = async () => {
const resData = await getRiskPointListAll();
unitList.value = resData.unitList;
};
fnGetUnitList();
const fnClose = () => {
formRef.value.resetFields();
visible.value = false;
};
const fnSubmit = debounce(
1000,
async () => {
await useFormValidate(formRef);
const formData = new FormData();
for (let i = 0; i < form.value.file.length; i++) {
if (form.value.file[i].raw) {
formData.append("FFILE", form.value.file[i].raw);
}
}
Object.keys(form.value).forEach((key) => {
formData.append(key, form.value[key]);
});
formData.delete("file");
props.type === "add"
? await setIdentifyingPartsAdd(formData)
: await setIdentifyingPartsEdit(formData);
ElMessage.success("操作成功");
fnClose();
emits("get-data");
},
{ atBegin: true }
);
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,288 @@
<template>
<el-dialog v-model="visible" :title="title" :before-close="fnClose">
<el-form ref="formRef" :rules="rules" :model="form" label-width="240px">
<el-row>
<el-col :span="24">
<el-form-item label="管控部门" prop="DEPTNAME">
<el-input :model-value="info.DEPTNAME" disabled />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="管控责任人" prop="USER_ID">
<el-input v-model="form.USER_ID" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="风险点(单元)" prop="RISKUNITNAME">
<el-input :model-value="info.RISKUNITNAME" disabled />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="辨识部位" prop="PARTSNAME">
<el-input :model-value="info.PARTSNAME" disabled />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="存在风险" prop="RISK_DESCR">
<el-input
v-model="form.RISK_DESCR"
type="textarea"
:autosize="{
minRows: 3,
}"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="事故发生的可能性" prop="LIKELIHOOD">
<el-select v-model="form.LIKELIHOOD">
<el-option :value="10" label="完全可以预料" />
<el-option :value="6" label="相当可能" />
<el-option :value="3" label="可能,但不经常" />
<el-option :value="1" label="可能性小,完全意外" />
<el-option :value="0.5" label="很不可能,可以设想" />
<el-option :value="0.2" label="极不可能" />
<el-option :value="0.1" label="实际不可能" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="分值">
{{ form.LIKELIHOOD }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="人员暴露于危险环境中的频繁程度" prop="EXPOSURE">
<el-select v-model="form.EXPOSURE">
<el-option :value="10" label="连续暴露" />
<el-option :value="6" label="每天工作时间内暴露" />
<el-option :value="3" label="每周一次或偶然暴露" />
<el-option :value="2" label="每月一次暴露,完全意外" />
<el-option :value="1" label="每年几次暴露" />
<el-option :value="0.5" label="非常罕见暴露" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="分值">
{{ form.EXPOSURE }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="一旦发生事故可能造成的后果" prop="CONSEQUENCE">
<el-select v-model="form.CONSEQUENCE">
<el-option :value="100" label="10人以上死亡" />
<el-option :value="40" label="39人死亡" />
<el-option :value="15" label="12人死亡" />
<el-option :value="7" label="严重" />
<el-option :value="3" label="重大,伤残" />
<el-option :value="1" label="引人注意" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="分值">
{{ form.CONSEQUENCE }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="风险分级" prop="LEVEL_NAME">
{{ form.LEVEL_NAME }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="总分值" prop="DANGER">
{{ form.DANGER }}
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="管控措施" prop="MEASURES">
<el-input
v-model="form.MEASURES"
type="textarea"
:autosize="{
minRows: 3,
}"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="事故类型" prop="ACCIDENTS">
<el-select v-model="form.ACCIDENTS" multiple>
<el-option
v-for="item in accidentTypeList"
:key="item.BIANMA"
:label="item.NAME"
:value="item.BIANMA"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="应急处置措施" prop="EME_MEASURES">
<el-input
v-model="form.EME_MEASURES"
type="textarea"
:autosize="{
minRows: 3,
}"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<el-button @click="fnClose"></el-button>
<el-button type="primary" @click="fnSubmit"> </el-button>
</template>
</el-dialog>
</template>
<script setup>
import { ref, watch } from "vue";
import { useVModels } from "@vueuse/core";
import { debounce } from "throttle-debounce";
import useFormValidate from "@/assets/js/useFormValidate.js";
import { ElMessage } from "element-plus";
import { layoutFnGetAccidentType } from "@/assets/js/data_dictionary.js";
import {
setIdentifyingPartsRiskAdd,
setIdentifyingPartsRiskEdit,
} from "@/request/risk_control.js";
const props = defineProps({
visible: {
type: Boolean,
required: true,
default: false,
},
form: {
type: Object,
required: true,
default: () => ({}),
},
info: {
type: Object,
required: true,
default: () => ({}),
},
type: {
type: Number,
required: true,
default: 0,
},
title: {
type: String,
required: true,
default: "",
},
id: {
type: String,
required: true,
default: "",
},
time: {
type: Number,
required: true,
default: 0,
},
});
const emits = defineEmits(["update:visible", "update:form", "get-data"]);
const { visible, form } = useVModels(props, emits);
const rules = {
USER_ID: [{ required: true, message: "管控责任人不能为空", trigger: "blur" }],
RISK_DESCR: [
{ required: true, message: "存在风险不能为空", trigger: "blur" },
],
LIKELIHOOD: [
{ required: true, message: "事故发生的可能性不能为空", trigger: "change" },
],
EXPOSURE: [
{
required: true,
message: "人员暴露于危险环境中的频繁程度不能为空",
trigger: "change",
},
],
CONSEQUENCE: [
{
required: true,
message: "一旦发生事故可能造成的后果不能为空",
trigger: "change",
},
],
LEVEL_NAME: [
{ required: true, message: "风险分级不能为空", trigger: "change" },
],
MEASURES: [{ required: true, message: "管控措施不能为空", trigger: "blur" }],
EME_MEASURES: [
{ required: true, message: "应急处置措施不能为空", trigger: "blur" },
],
ACCIDENTS: [
{ required: true, message: "事故类型不能为空", trigger: "change" },
],
};
const formRef = ref(null);
const accidentTypeList = await layoutFnGetAccidentType();
const fnGetLevelName = (LIKELIHOOD, EXPOSURE, CONSEQUENCE) => {
const DANGER = (LIKELIHOOD * EXPOSURE * CONSEQUENCE).toFixed(2);
if (DANGER > 320) {
form.value.LEVELID = "levelA";
form.value.LEVEL_NAME = "重大风险/A级";
} else if (DANGER > 160) {
form.value.LEVELID = "levelB";
form.value.LEVEL_NAME = "较大风险/B级";
} else if (DANGER > 70) {
form.value.LEVELID = "levelC";
form.value.LEVEL_NAME = "一般风险/C级";
} else {
form.value.LEVELID = "levelD";
form.value.LEVEL_NAME = "低风险/D级";
}
form.value.DANGER = DANGER;
};
watch(
[
() => props.form.LIKELIHOOD,
() => props.form.EXPOSURE,
() => props.form.CONSEQUENCE,
],
([LIKELIHOOD, EXPOSURE, CONSEQUENCE]) => {
if (!LIKELIHOOD || !EXPOSURE || !CONSEQUENCE) return;
fnGetLevelName(LIKELIHOOD, EXPOSURE, CONSEQUENCE);
}
);
const fnClose = () => {
formRef.value.resetFields();
visible.value = false;
};
const fnSubmit = debounce(
1000,
async () => {
await useFormValidate(formRef);
const ACCIDENTS_NAME = accidentTypeList.value
.filter((item) => form.value.ACCIDENTS.includes(item.BIANMA))
.map((item) => item.NAME)
.join(",");
const params = {
...form.value,
RISK_UNIT_ID: props.info.RISK_UNIT_ID,
DEPARTMENT_ID: props.info.DEPARTMENT_ID,
IDENTIFICATION_ID: props.id,
CHECK_CONTENT: form.value.MEASURES,
ACCIDENTS: form.value.ACCIDENTS.join(","),
ACCIDENTS_NAME,
SETUPTIME: props.time,
TYPE: props.type,
};
if (!props.type) await setIdentifyingPartsRiskAdd(params);
else await setIdentifyingPartsRiskEdit(params);
ElMessage.success("操作成功");
fnClose();
emits("get-data");
},
{ atBegin: true }
);
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,51 @@
<template>
<el-dialog v-model="visible" title="打印">
<div id="printContent">
<div
v-for="item in list"
:key="item.IDENTIFICATIONPARTS_ID"
class="page_break"
>
<el-divider content-position="left">辨识部位信息</el-divider>
<el-descriptions :column="2" border>
<el-descriptions-item label="辨识部位" :span="2">
{{ item.PARTSNAME }}
</el-descriptions-item>
<el-descriptions-item label="风险点(单元)">
{{ item.RISKUNITNAME }}
</el-descriptions-item>
<el-descriptions-item label="管控部门">
{{ item.DEPT_NAME }}
</el-descriptions-item>
</el-descriptions>
<layout-qr-code :src="item.IDENTIFICATIONPARTS_ID + item.LEVELID" />
</div>
</div>
<template #footer>
<el-button @click="visible = false">关闭</el-button>
<el-button type="primary" v-print="'#printContent'"></el-button>
</template>
</el-dialog>
</template>
<script setup>
import { useVModel } from "@vueuse/core";
import LayoutQrCode from "@/components/qr_code/index.vue";
const props = defineProps({
visible: {
type: Boolean,
required: true,
default: false,
},
list: {
type: Array,
required: true,
default: () => [],
},
});
const emits = defineEmits(["update:visible"]);
const visible = useVModel(props, "visible", emits);
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,257 @@
<template>
<div>
<el-card>
<el-form
:model="searchForm"
label-width="60px"
@submit.prevent="fnResetPagination"
>
<el-row>
<el-col :span="6">
<el-form-item label="关键字" prop="KEYWORDS">
<el-input
v-model="searchForm.KEYWORDS"
placeholder="请输入关键字"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label-width="10px">
<el-button type="primary" native-type="submit">搜索</el-button>
<el-button native-type="reset" @click="fnResetPagination">
重置
</el-button>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label-width="10px" class="end">
<el-button @click="fnBatchPrint"></el-button>
<el-button @click="fnImportDialogChangeShow"> </el-button>
<el-button @click="fnExport"></el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<layout-card>
<layout-table
ref="tableRef"
:data="list"
v-model:pagination="pagination"
@get-data="fnGetData"
row-key="IDENTIFICATIONPARTS_ID"
>
<el-table-column reserve-selection type="selection" width="55" />
<el-table-column label="序号" width="70">
<template v-slot="{ $index }">
{{ serialNumber(pagination, $index) }}
</template>
</el-table-column>
<el-table-column prop="RISKUNITNAME" label="风险点(单元)" />
<el-table-column prop="PARTSNAME" label="辨识部位名称" />
<el-table-column label="告知卡">
<template v-slot="{ row }">
<layout-tooltip-img :imgs="row.imgs" />
</template>
</el-table-column>
<el-table-column label="操作" width="280">
<template v-slot="{ row }">
<el-button type="primary" text link @click="fnPrint(row)">
二维码
</el-button>
<el-button
v-if="buttonJurisdiction.edit"
type="primary"
text
link
@click="
router.push({
path: '/risk_control/identifying_parts/resources_risk',
query: {
IDENTIFICATIONPARTS_ID: row.IDENTIFICATIONPARTS_ID,
PARTSNAME: row.PARTSNAME,
RISKUNITNAME: row.RISKUNITNAME,
},
})
"
>
匹配资源存在风险
</el-button>
<el-button
v-if="buttonJurisdiction.edit"
type="primary"
text
link
@click="fnAddOrEdit(row.IDENTIFICATIONPARTS_ID, 'edit')"
>
编辑
</el-button>
<el-button
v-if="buttonJurisdiction.del"
type="primary"
text
link
@click="fnDelete(row.IDENTIFICATIONPARTS_ID)"
>
删除
</el-button>
</template>
</el-table-column>
<template #button>
<el-button
v-if="buttonJurisdiction.add"
type="primary"
@click="fnAddOrEdit('', 'add')"
>
新增
</el-button>
<el-button
v-if="buttonJurisdiction.del"
type="danger"
@click="fnBatchDelete"
>
批量删除
</el-button>
</template>
</layout-table>
</layout-card>
<layout-import-file
v-model:visible="data.importDialogVisible"
template-url="template/identificationpartsExcelTemplate.xls"
@submit="fnSubmitImport"
/>
<add
v-model:visible="data.addOrEditDialog.visible"
v-model:form="data.addOrEditDialog.form"
:type="data.addOrEditDialog.type"
@get-data="fnResetPagination"
/>
<print
v-model:visible="data.printDialog.visible"
:list="data.printDialog.list"
/>
</div>
</template>
<script setup>
import { addingPrefixToFile, serialNumber } from "@/assets/js/utils.js";
import useListData from "@/assets/js/useListData.js";
import {
getIdentifyingPartsList,
getIdentifyingPartsView,
setIdentifyingPartsBatchDelete,
setIdentifyingPartsDelete,
setIdentifyingPartsImport,
} from "@/request/risk_control.js";
import { debounce } from "throttle-debounce";
import { ElMessage, ElMessageBox } from "element-plus";
import { nextTick, reactive } from "vue";
import LayoutImportFile from "@/components/import_file/index.vue";
import Add from "./components/add.vue";
import { useRouter } from "vue-router";
import Print from "./components/print.vue";
import LayoutTooltipImg from "@/components/tooltip_img/index.vue";
import useButtonJurisdiction from "@/assets/js/useButtonJurisdiction.js";
const router = useRouter();
const { list, pagination, searchForm, fnGetData, fnResetPagination, tableRef } =
useListData(getIdentifyingPartsList);
const data = reactive({
importDialogVisible: false,
addOrEditDialog: {
visible: false,
type: "",
form: {
RISK_UNIT_ID: "",
PARTSNAME: "",
file: [],
},
},
printDialog: {
visible: false,
list: [],
},
});
const buttonJurisdiction = await useButtonJurisdiction("identificationparts");
const fnDelete = debounce(
1000,
async (IDENTIFICATIONPARTS_ID) => {
await ElMessageBox.confirm("确定要删除吗?", { type: "warning" });
await setIdentifyingPartsDelete({ IDENTIFICATIONPARTS_ID });
ElMessage.success("删除成功");
fnResetPagination();
},
{ atBegin: true }
);
const fnImportDialogChangeShow = () => {
data.importDialogVisible = !data.importDialogVisible;
};
const fnSubmitImport = async (formData) => {
const resData = await setIdentifyingPartsImport(formData);
if (resData.resultStr) {
ElMessage({
dangerouslyUseHTMLString: true,
message: resData.resultStr,
type: resData.resultType,
});
}
fnImportDialogChangeShow();
fnResetPagination();
};
const fnExport = async () => {
const selectionData = tableRef.value.getSelectionRows();
if (selectionData.length === 0) {
ElMessage.warning("请选择需要导出至excel报表的记录信息");
return;
}
await ElMessageBox.confirm("确定要导出到excel吗", { type: "warning" });
const DATA_IDS = selectionData
.map((item) => item.IDENTIFICATIONPARTS_ID)
.join(",");
window.location.href =
import.meta.env[import.meta.env.DEV ? "VITE_PROXY" : "VITE_BASE_URL"] +
"identificationparts/excel?" +
"&KEYWORDS=" +
searchForm.value.KEYWORDS +
"&DATA_IDS=" +
DATA_IDS;
};
const fnBatchDelete = async () => {
const selectionData = tableRef.value.getSelectionRows();
if (selectionData.length === 0) {
ElMessage.warning("请选中要删除的项");
return;
}
await ElMessageBox.confirm("确定要删除选中的数据吗?", { type: "warning" });
const DATA_IDS = selectionData
.map((item) => item.IDENTIFICATIONPARTS_ID)
.join(",");
await setIdentifyingPartsBatchDelete({ DATA_IDS });
ElMessage.success("删除成功");
fnResetPagination();
};
const fnAddOrEdit = async (IDENTIFICATIONPARTS_ID, type) => {
data.addOrEditDialog.visible = true;
await nextTick();
data.addOrEditDialog.type = type;
if (type === "edit") {
const resData = await getIdentifyingPartsView({ IDENTIFICATIONPARTS_ID });
data.addOrEditDialog.form = resData.pd;
data.addOrEditDialog.form.file = addingPrefixToFile(resData.imgs);
}
};
const fnPrint = (row) => {
data.printDialog.visible = true;
data.printDialog.list = [row];
};
const fnBatchPrint = () => {
const selectionData = tableRef.value.getSelectionRows();
if (selectionData.length === 0) {
ElMessage.warning("请选择需要打印的数据");
}
data.printDialog.list = selectionData;
data.printDialog.visible = true;
};
</script>
<style scoped></style>

View File

@ -0,0 +1,211 @@
<template>
<layout-card>
<el-divider content-position="left">辨识部位信息</el-divider>
<el-descriptions :column="2" border>
<el-descriptions-item label="管控部门" :span="2">
{{ data.info.DEPTNAME }}
</el-descriptions-item>
<el-descriptions-item label="风险点(单元)">
{{ data.info.RISKUNITNAME }}
</el-descriptions-item>
<el-descriptions-item label="辨识部位">
{{ data.info.PARTSNAME }}
</el-descriptions-item>
<el-descriptions-item label="风险分级">
<span v-if="data.info.LEVELID === 'levelD'" class="text-blue">
低风险/D级
</span>
<span v-else-if="data.info.LEVELID === 'levelC'" class="text-yellow">
一般风险/C级
</span>
<span v-else-if="data.info.LEVELID === 'levelB'" class="text-orange">
较大风险/B级
</span>
<span v-else-if="data.info.LEVELID === 'levelA'" class="text-red">
重大风险/A级
</span>
</el-descriptions-item>
<el-descriptions-item label="事故类型">
{{ data.info.ACCIDENTS_NAME }}
</el-descriptions-item>
</el-descriptions>
<el-divider content-position="left">资源库标准项</el-divider>
<layout-table
ref="tableRef"
:data="data.ideResList"
:show-pagination="false"
row-key="ID"
>
<el-table-column
:reserve-selection="true"
type="selection"
width="55"
align="center"
/>
<el-table-column type="index" label="序号" width="50" />
<el-table-column prop="RISK_DESCR" label="存在风险" />
<el-table-column prop="LEVELIDNAME" label="风险分级" />
<el-table-column prop="ACCIDENTS_NAME" label="事故类型" />
<el-table-column label="操作" width="80">
<template v-slot="{ row }">
<el-button type="primary" text link @click="fnAddOrEdit(row.ID, 3)">
选入
</el-button>
</template>
</el-table-column>
</layout-table>
<el-divider content-position="left">自定义项</el-divider>
<div class="tr mb-10">
<el-button type="primary" @click="fnAddOrEdit('', '')">
添加存在风险
</el-button>
</div>
<layout-table
:data="[...data.riskPointList, ...data.rpTimeList]"
:show-pagination="false"
>
<el-table-column type="index" label="序号" width="50" />
<el-table-column prop="RISK_DESCR" label="存在风险" />
<el-table-column prop="LEVELIDNAME" label="风险分级" />
<el-table-column prop="ACCIDENTS_NAME" label="事故类型" />
<el-table-column label="操作" width="80">
<template v-slot="{ row }">
<el-button
type="primary"
text
link
@click="
fnAddOrEdit(
row.asd ? row.RISKPOINT_ID : row.RISKPOINTTEMPORARY_ID,
row.asd ? 1 : 2
)
"
>
修改
</el-button>
</template>
</el-table-column>
</layout-table>
<div class="tc mt-10">
<el-button type="primary" @click="fnSubmit"></el-button>
</div>
<add-risk
v-model:visible="data.addDialog.visible"
v-model:form="data.addDialog.form"
:type="data.addDialog.type"
:title="data.addDialog.title"
:info="data.info"
:id="IDENTIFICATIONPARTS_ID"
:time="data.time"
@get-data="fnGetData"
/>
</layout-card>
</template>
<script setup>
import { nextTick, reactive, ref } from "vue";
import {
getIdentifyingPartsResourcesRisk,
setIdentifyingPartsResourcesRiskSave,
getIdentifyingPartsRiskView1,
getIdentifyingPartsRiskView2,
getIdentifyingPartsRiskView3,
} from "@/request/risk_control.js";
import { useRoute, useRouter } from "vue-router";
import AddRisk from "./components/add_risk.vue";
import { debounce } from "throttle-debounce";
import { ElMessage } from "element-plus";
const route = useRoute();
const router = useRouter();
const { IDENTIFICATIONPARTS_ID, PARTSNAME, RISKUNITNAME } = route.query;
const tableRef = ref(null);
const data = reactive({
time: new Date().getTime(),
info: {},
ideResList: [],
riskPointList: [],
rpTimeList: [],
addDialog: {
visible: false,
form: {
USER_ID: "",
RISK_DESCR: "",
LIKELIHOOD: "",
EXPOSURE: "",
CONSEQUENCE: "",
LEVEL_NAME: "",
DANGER: "",
MEASURES: "",
ACCIDENTS: [],
EME_MEASURES: "",
},
type: 0,
title: "",
},
});
const fnGetData = async () => {
const resData = await getIdentifyingPartsResourcesRisk({
IDENTIFICATIONPARTS_ID,
IDENTIFICATION: PARTSNAME,
RISKUNIT: RISKUNITNAME,
SETUPTIME: data.time,
});
for (let i = 0; i < resData.riskPointList.length; i++) {
resData.riskPointList[i].asd = "asd";
}
data.info = resData.pd;
data.ideResList = resData.ideResList;
data.riskPointList = resData.riskPointList;
data.rpTimeList = resData.rpTimeList;
};
fnGetData();
const fnAddOrEdit = async (RISKPOINT_ID, type) => {
data.addDialog.visible = true;
await nextTick();
data.addDialog.type = type;
const title = {
1: "修改",
2: "修改",
3: "选入",
};
data.addDialog.title = title[type] || "新增";
if (!type) return;
let resData = {};
if (type === 1)
resData = await getIdentifyingPartsRiskView1({ RISKPOINT_ID });
else if (type === 2)
resData = await getIdentifyingPartsRiskView2({ RISKPOINT_ID });
else if (type === 3)
resData = await getIdentifyingPartsRiskView3({ RISKPOINT_ID });
data.addDialog.form = resData.pd;
data.addDialog.form.ACCIDENTS = resData.pd.ACCIDENTS.split(",");
data.addDialog.form.DEPTNAME = resData.pd.DEPT_NAME;
data.addDialog.form.LEVEL_NAME = resData.pd.DNAME5;
if (type === 2)
data.addDialog.form.RISKPOINT_ID = resData.pd.RISKPOINTTEMPORARY_ID;
else if (type === 3)
data.addDialog.form.RISKPOINT_ID = resData.pd.IDEREPOSITORY_ID;
};
const fnSubmit = debounce(
1000,
async () => {
const selectionData = tableRef.value.getSelectionRows();
const DATA_IDS = selectionData.map((item) => item.ID).join(",");
await setIdentifyingPartsResourcesRiskSave({
IDENTIFICATION_ID: IDENTIFICATIONPARTS_ID,
DEPARTMENT_ID: data.info.DEPARTMENT_ID,
ISMATCHING: data.info.ISMATCHING,
RISK_UNIT_ID: data.info.RISK_UNIT_ID,
SETUPTIME: data.time,
USER_ID: data.info.USERNAME,
DATA_IDS,
});
ElMessage.success("保存成功");
router.back();
},
{ atBegin: true }
);
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,50 @@
<template>
<layout-card>
<layout-table :data="list" :show-pagination="false">
<el-table-column label="序号" width="70" type="index" />
<el-table-column prop="CHECK_CONTENT" label="检查内容" />
<el-table-column label="操作" width="80">
<template v-slot="{ row }">
<el-button type="primary" text link @click="fnEdit(row)">
修改
</el-button>
</template>
</el-table-column>
</layout-table>
<allocation-edit
v-model:visible="data.editDialog.visible"
v-model:form="data.editDialog.form"
@get-data="fnGetData"
/>
</layout-card>
</template>
<script setup>
import { useRoute } from "vue-router";
import useListData from "@/assets/js/useListData.js";
import { getRiskControlLedgerAllocationList } from "@/request/risk_control.js";
import { reactive } from "vue";
import { cloneDeep } from "lodash-es";
import AllocationEdit from "./components/allocation_edit.vue";
const route = useRoute();
const { RISKPOINT_ID } = route.query;
const { list, fnGetData } = useListData(getRiskControlLedgerAllocationList, {
otherParams: { RISKPOINT_ID },
usePagination: false,
});
const data = reactive({
editDialog: {
visible: false,
form: {
CHECK_CONTENT: "",
},
},
});
const fnEdit = (row) => {
data.editDialog.visible = true;
data.editDialog.form = cloneDeep(row);
};
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,384 @@
<template>
<el-dialog
v-model="visible"
:title="type === 'add' ? '新增' : '修改'"
:before-close="fnClose"
>
<el-form ref="formRef" :rules="rules" :model="form" label-width="240px">
<el-row>
<el-col :span="24">
<el-form-item label="管控部门" prop="DEPARTMENT_ID">
<layout-department
v-model="form.DEPARTMENT_ID"
@update:model-value="fnDepartmentChange"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="管控责任人" prop="USER_ID">
<el-input v-model="form.USER_ID" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="风险点(单元)" prop="RISK_UNIT_ID">
<el-select v-model="form.RISK_UNIT_ID" @change="fnRiskUnitChange">
<el-option
v-for="item in unitList"
:key="item.RISKUNIT_ID"
:label="item.DEPT_NAME + '-' + item.RISKUNITNAME"
:value="item.RISKUNIT_ID"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="辨识部位" prop="IDENTIFICATION_ID">
<el-select v-model="form.IDENTIFICATION_ID">
<el-option
v-for="item in partsList"
:key="item.IDENTIFICATIONPARTS_ID"
:label="item.PARTSNAME"
:value="item.IDENTIFICATIONPARTS_ID"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="存在风险" prop="RISK_DESCR">
<el-input
v-model="form.RISK_DESCR"
type="textarea"
:autosize="{
minRows: 3,
}"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="事故发生的可能性" prop="LIKELIHOOD">
<el-select v-model="form.LIKELIHOOD">
<el-option :value="10" label="完全可以预料" />
<el-option :value="6" label="相当可能" />
<el-option :value="3" label="可能,但不经常" />
<el-option :value="1" label="可能性小,完全意外" />
<el-option :value="0.5" label="很不可能,可以设想" />
<el-option :value="0.2" label="极不可能" />
<el-option :value="0.1" label="实际不可能" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="分值">
{{ form.LIKELIHOOD }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="人员暴露于危险环境中的频繁程度" prop="EXPOSURE">
<el-select v-model="form.EXPOSURE">
<el-option :value="10" label="连续暴露" />
<el-option :value="6" label="每天工作时间内暴露" />
<el-option :value="3" label="每周一次或偶然暴露" />
<el-option :value="2" label="每月一次暴露,完全意外" />
<el-option :value="1" label="每年几次暴露" />
<el-option :value="0.5" label="非常罕见暴露" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="分值">
{{ form.EXPOSURE }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="一旦发生事故可能造成的后果" prop="CONSEQUENCE">
<el-select v-model="form.CONSEQUENCE">
<el-option :value="100" label="10人以上死亡" />
<el-option :value="40" label="39人死亡" />
<el-option :value="15" label="12人死亡" />
<el-option :value="7" label="严重" />
<el-option :value="3" label="重大,伤残" />
<el-option :value="1" label="引人注意" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="分值">
{{ form.CONSEQUENCE }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="风险分级" prop="LEVEL_NAME">
{{ form.LEVEL_NAME }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="总分值" prop="DANGER">
{{ form.DANGER }}
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="管控措施" prop="MEASURES">
<el-input
v-model="form.MEASURES"
type="textarea"
:autosize="{
minRows: 3,
}"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="事故类型" prop="ACCIDENTS">
<el-select v-model="form.ACCIDENTS" multiple>
<el-option
v-for="item in accidentTypeList"
:key="item.BIANMA"
:label="item.NAME"
:value="item.BIANMA"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="应急处置措施" prop="EME_MEASURES">
<el-input
v-model="form.EME_MEASURES"
type="textarea"
:autosize="{
minRows: 3,
}"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="管控措施分类1" prop="MANAGEMENT_CONTROL_ONE">
<el-select
v-model="form.MANAGEMENT_CONTROL_ONE"
@change="form.MANAGEMENT_CONTROL_TWO = ''"
>
<el-option
v-for="item in controlList1"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="管控措施分类2" prop="MANAGEMENT_CONTROL_TWO">
<el-select v-model="form.MANAGEMENT_CONTROL_TWO">
<el-option
v-for="item in controlList2"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="管控措施分类3" prop="MANAGEMENT_CONTROL_THREE">
<el-input
v-model="form.MANAGEMENT_CONTROL_THREE"
type="textarea"
:autosize="{
minRows: 3,
}"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<el-button @click="fnClose"></el-button>
<el-button type="primary" @click="fnSubmit"> </el-button>
</template>
</el-dialog>
</template>
<script setup>
import { ref, watch, watchEffect } from "vue";
import { useVModels } from "@vueuse/core";
import { debounce } from "throttle-debounce";
import useFormValidate from "@/assets/js/useFormValidate.js";
import { ElMessage } from "element-plus";
import {
layoutFnGetAccidentType,
layoutFnGetControlMeasures1,
layoutFnGetControlMeasures2,
} from "@/assets/js/data_dictionary.js";
import {
getIdentifyingPartsListAll,
getRiskPointListAllById,
setRiskControlLedgerAdd,
setRiskControlLedgerEdit,
} from "@/request/risk_control.js";
import LayoutDepartment from "@/components/department/index.vue";
const props = defineProps({
visible: {
type: Boolean,
required: true,
default: false,
},
form: {
type: Object,
required: true,
default: () => ({}),
},
type: {
type: String,
required: true,
default: "",
},
});
const emits = defineEmits(["update:visible", "update:form", "get-data"]);
const { visible, form } = useVModels(props, emits);
const rules = {
DEPARTMENT_ID: [
{ required: true, message: "部门不能为空", trigger: "change" },
],
USER_ID: [{ required: true, message: "管控责任人不能为空", trigger: "blur" }],
RISK_UNIT_ID: [
{ required: true, message: "风险点(单元)不能为空", trigger: "change" },
],
IDENTIFICATION_ID: [
{ required: true, message: "辨识部位不能为空", trigger: "change" },
],
RISK_DESCR: [
{ required: true, message: "存在风险不能为空", trigger: "blur" },
],
LIKELIHOOD: [
{ required: true, message: "事故发生的可能性不能为空", trigger: "change" },
],
EXPOSURE: [
{
required: true,
message: "人员暴露于危险环境中的频繁程度不能为空",
trigger: "change",
},
],
CONSEQUENCE: [
{
required: true,
message: "一旦发生事故可能造成的后果不能为空",
trigger: "change",
},
],
LEVELID: [{ required: true, message: "风险分级不能为空", trigger: "blur" }],
MEASURES: [{ required: true, message: "管控措施不能为空", trigger: "blur" }],
EME_MEASURES: [
{ required: true, message: "应急处置措施不能为空", trigger: "blur" },
],
ACCIDENTS: [
{ required: true, message: "事故类型不能为空", trigger: "change" },
],
};
const formRef = ref(null);
const unitList = ref([]);
const partsList = ref([]);
const controlList2 = ref([]);
const controlList1 = await layoutFnGetControlMeasures1();
const controlList2All = await layoutFnGetControlMeasures2();
const fnGetUnitList = async () => {
const resData = await getRiskPointListAllById({
DEPARTMENT_ID: form.value.DEPARTMENT_ID,
});
unitList.value = resData.unitList;
};
const fnGetPartsList = async () => {
const resData = await getIdentifyingPartsListAll({
RISK_UNIT_ID: form.value.RISK_UNIT_ID,
});
partsList.value = resData.partsList;
};
const fnDepartmentChange = () => {
form.value.RISK_UNIT_ID = "";
form.value.IDENTIFICATION_ID = "";
unitList.value = [];
partsList.value = [];
};
const fnRiskUnitChange = () => {
form.value.IDENTIFICATION_ID = "";
partsList.value = [];
};
const accidentTypeList = await layoutFnGetAccidentType();
const fnGetLevelName = (LIKELIHOOD, EXPOSURE, CONSEQUENCE) => {
const DANGER = (LIKELIHOOD * EXPOSURE * CONSEQUENCE).toFixed(2);
if (DANGER > 320) {
form.value.LEVELID = "levelA";
form.value.LEVEL_NAME = "重大风险/A级";
} else if (DANGER > 160) {
form.value.LEVELID = "levelB";
form.value.LEVEL_NAME = "较大风险/B级";
} else if (DANGER > 70) {
form.value.LEVELID = "levelC";
form.value.LEVEL_NAME = "一般风险/C级";
} else {
form.value.LEVELID = "levelD";
form.value.LEVEL_NAME = "低风险/D级";
}
form.value.DANGER = DANGER;
};
watch(
[
() => props.form.LIKELIHOOD,
() => props.form.EXPOSURE,
() => props.form.CONSEQUENCE,
],
([LIKELIHOOD, EXPOSURE, CONSEQUENCE]) => {
if (!LIKELIHOOD || !EXPOSURE || !CONSEQUENCE) return;
fnGetLevelName(LIKELIHOOD, EXPOSURE, CONSEQUENCE);
}
);
watchEffect(() => {
if (form.value.DEPARTMENT_ID) fnGetUnitList();
if (form.value.RISK_UNIT_ID) fnGetPartsList();
if (form.value.MANAGEMENT_CONTROL_ONE) fnControlList1Change();
});
const fnControlList1Change = () => {
controlList2.value = [];
const id = form.value.MANAGEMENT_CONTROL_ONE;
let BZ = "";
for (let i = 0; i < controlList1.value.length; i++) {
if (controlList1.value[i].id === id) {
BZ = controlList1.value[i].BZ;
break;
}
}
for (let i = 0; i < controlList2All.value.length; i++) {
if (controlList2All.value[i].TBFIELD === BZ) {
controlList2.value.push(controlList2All.value[i]);
}
}
};
const fnClose = () => {
formRef.value.resetFields();
visible.value = false;
};
const fnSubmit = debounce(
1000,
async () => {
await useFormValidate(formRef);
const ACCIDENTS_NAME = accidentTypeList.value
.filter((item) => form.value.ACCIDENTS.includes(item.BIANMA))
.map((item) => item.NAME)
.join(",");
const params = {
...form.value,
CHECK_CONTENT: form.value.MEASURES,
ACCIDENTS: form.value.ACCIDENTS.join(","),
ACCIDENTS_NAME,
};
if (props.type === "add") await setRiskControlLedgerAdd(params);
else await setRiskControlLedgerEdit(params);
ElMessage.success("操作成功");
fnClose();
emits("get-data");
},
{ atBegin: true }
);
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,64 @@
<template>
<el-dialog v-model="visible" title="修改" :before-close="fnClose">
<el-form ref="formRef" :rules="rules" :model="form" label-width="100px">
<el-form-item label="检查内容" prop="CHECK_CONTENT">
<el-input
v-model="form.CHECK_CONTENT"
type="textarea"
:autosize="{ minRows: 3 }"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="fnClose"></el-button>
<el-button type="primary" @click="fnSubmit"> </el-button>
</template>
</el-dialog>
</template>
<script setup>
import { ref } from "vue";
import { useVModels } from "@vueuse/core";
import { debounce } from "throttle-debounce";
import useFormValidate from "@/assets/js/useFormValidate.js";
import { setRiskControlLedgerAllocationEdit } from "@/request/risk_control.js";
import { ElMessage } from "element-plus";
const props = defineProps({
visible: {
type: Boolean,
required: true,
default: false,
},
form: {
type: Object,
required: true,
default: () => ({}),
},
});
const emits = defineEmits(["update:visible", "update:form", "get-data"]);
const { visible, form } = useVModels(props, emits);
const rules = {
CHECK_CONTENT: [
{ required: true, message: "检查内容不能为空", trigger: "blur" },
],
};
const formRef = ref(null);
const fnClose = () => {
formRef.value.resetFields();
visible.value = false;
};
const fnSubmit = debounce(
1000,
async () => {
await useFormValidate(formRef);
await setRiskControlLedgerAllocationEdit({ ...form.value });
ElMessage.success("操作成功");
fnClose();
emits("get-data");
},
{ atBegin: true }
);
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,311 @@
<template>
<div>
<el-card>
<el-form
:model="searchForm"
label-width="90px"
@submit.prevent="fnResetPaginationTransfer"
>
<el-row>
<el-col :span="6">
<el-form-item label="关键字" prop="KEYWORDS">
<el-input
v-model="searchForm.KEYWORDS"
placeholder="请输入关键字"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="风险分级">
<el-select v-model="searchForm.LEVELID">
<el-option
v-for="item in riskClassificationList"
:key="item.BIANMA"
:label="item.NAME"
:value="item.BIANMA"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="管控部门" prop="DEPTIDS">
<layout-department
v-model="searchForm.DEPTIDS"
multiple
show-checkbox
collapse-tags
root-disabled="N"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="管控责任人" prop="gkzrName">
<el-input v-model="searchForm.gkzrName" placeholder="" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="事故类型">
<el-select v-model="searchForm.BIANMA">
<el-option
v-for="item in accidentTypeList"
:key="item.BIANMA"
:label="item.NAME"
:value="item.BIANMA"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label-width="10px">
<el-button type="primary" native-type="submit">搜索</el-button>
<el-button native-type="reset" @click="fnResetPaginationTransfer">
重置
</el-button>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label-width="10px" class="end">
<el-button @click="fnImportDialogChangeShow"> </el-button>
<el-button @click="fnExport"></el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<layout-card>
<layout-table
ref="tableRef"
:data="list"
v-model:pagination="pagination"
@get-data="fnGetDataTransfer"
row-key="RISKPOINT_ID"
>
<el-table-column reserve-selection type="selection" width="55" />
<el-table-column label="序号" width="70">
<template v-slot="{ $index }">
{{ serialNumber(pagination, $index) }}
</template>
</el-table-column>
<el-table-column prop="DEPT_NAME_ALL" label="管控部门" />
<el-table-column prop="RISKUNITNAME" label="风险点(单元)" />
<el-table-column prop="PARTSNAME" label="辨识部位" />
<el-table-column prop="LEVELID" label="风险分级">
<template v-slot="{ row }">
<span v-if="row.LEVELID === 'levelD'" class="text-blue">
低风险/D级
</span>
<span v-else-if="row.LEVELID === 'levelC'" class="text-yellow">
一般风险/C级
</span>
<span v-else-if="row.LEVELID === 'levelB'" class="text-orange">
较大风险/B级
</span>
<span v-else-if="row.LEVELID === 'levelA'" class="text-red">
重大风险/A级
</span>
</template>
</el-table-column>
<el-table-column label="事故类型">
<template v-slot="{ row }">
{{ row.ACCIDENTS_NAME.replace(/,/g, "、") }}
</template>
</el-table-column>
<el-table-column prop="USER_ID" label="管控责任人" />
<el-table-column label="操作" width="150">
<template v-slot="{ row }">
<el-button
v-if="buttonJurisdiction.edit"
type="primary"
text
link
@click="
router.push({
path: '/risk_control/ledger/allocation',
query: { RISKPOINT_ID: row.RISKPOINT_ID },
})
"
>
配置
</el-button>
<el-button
v-if="buttonJurisdiction.edit"
type="primary"
text
link
@click="fnAddOrEdit(row.RISKPOINT_ID, 'edit')"
>
编辑
</el-button>
<el-button
v-if="buttonJurisdiction.del"
type="primary"
text
link
@click="fnDelete(row.RISKPOINT_ID)"
>
删除
</el-button>
</template>
</el-table-column>
<template #button>
<el-button
v-if="buttonJurisdiction.add"
type="primary"
@click="fnAddOrEdit('', 'add')"
>
新增
</el-button>
<el-button
v-if="buttonJurisdiction.del"
type="danger"
@click="fnBatchDelete"
>
批量删除
</el-button>
</template>
</layout-table>
</layout-card>
<layout-import-file
v-model:visible="data.importDialogVisible"
template-url="template/riskpointExcelTemplate.xls"
@submit="fnSubmitImport"
/>
<add
v-model:visible="data.addOrEditDialog.visible"
v-model:form="data.addOrEditDialog.form"
:type="data.addOrEditDialog.type"
@get-data="fnResetPaginationTransfer"
/>
</div>
</template>
<script setup>
import { serialNumber } from "@/assets/js/utils.js";
import useListData from "@/assets/js/useListData.js";
import LayoutDepartment from "@/components/department/index.vue";
import {
getRiskControlLedgerList,
getRiskControlLedgerView,
setRiskControlLedgerBatchDelete,
setRiskControlLedgerDelete,
setRiskControlLedgerImport,
} from "@/request/risk_control.js";
import { debounce } from "throttle-debounce";
import { ElMessage, ElMessageBox } from "element-plus";
import { nextTick, reactive } from "vue";
import LayoutImportFile from "@/components/import_file/index.vue";
import {
layoutFnGetAccidentType,
layoutFnGetRiskClassification,
} from "@/assets/js/data_dictionary.js";
import useButtonJurisdiction from "@/assets/js/useButtonJurisdiction.js";
import Add from "./components/add.vue";
import { useRouter } from "vue-router";
const { list, pagination, searchForm, fnGetData, fnResetPagination, tableRef } =
useListData(getRiskControlLedgerList);
const router = useRouter();
const data = reactive({
importDialogVisible: false,
addOrEditDialog: {
visible: false,
type: "",
form: {
DEPARTMENT_ID: "",
USER_ID: "",
RISK_UNIT_ID: "",
IDENTIFICATION_ID: "",
RISK_DESCR: "",
LIKELIHOOD: "",
EXPOSURE: "",
CONSEQUENCE: "",
LEVEL_NAME: "",
DANGER: "",
MEASURES: "",
ACCIDENTS: [],
EME_MEASURES: "",
MANAGEMENT_CONTROL_ONE: "",
MANAGEMENT_CONTROL_TWO: "",
MANAGEMENT_CONTROL_THREE: "",
},
},
});
const buttonJurisdiction = await useButtonJurisdiction("riskunit");
const riskClassificationList = await layoutFnGetRiskClassification();
const accidentTypeList = await layoutFnGetAccidentType();
const fnGetDataTransfer = () => {
fnGetData({
DEPTIDS: searchForm.value.DEPTIDS?.join(","),
});
};
const fnResetPaginationTransfer = () => {
fnResetPagination({
DEPTIDS: searchForm.value.DEPTIDS?.join(","),
});
};
const fnDelete = debounce(
1000,
async (RISKPOINT_ID) => {
await ElMessageBox.confirm("确定要删除吗?", { type: "warning" });
await setRiskControlLedgerDelete({ RISKPOINT_ID });
ElMessage.success("删除成功");
fnResetPaginationTransfer();
},
{ atBegin: true }
);
const fnImportDialogChangeShow = () => {
data.importDialogVisible = !data.importDialogVisible;
};
const fnSubmitImport = async (formData) => {
const resData = await setRiskControlLedgerImport(formData);
if (resData.resultStr) {
ElMessage({
dangerouslyUseHTMLString: true,
message: resData.resultStr,
type: resData.resultType,
});
}
fnImportDialogChangeShow();
fnResetPaginationTransfer();
};
const fnExport = async () => {
const selectionData = tableRef.value.getSelectionRows();
if (selectionData.length === 0) {
ElMessage.warning("请选择需要导出至excel报表的记录信息");
return;
}
await ElMessageBox.confirm("确定要导出到excel吗", { type: "warning" });
const DATA_IDS = selectionData.map((item) => item.RISKPOINT_ID).join(",");
window.location.href =
import.meta.env[import.meta.env.DEV ? "VITE_PROXY" : "VITE_BASE_URL"] +
"riskpoint/excel?" +
"&KEYWORDS=" +
searchForm.value.KEYWORDS +
"&DATA_IDS=" +
DATA_IDS;
};
const fnBatchDelete = async () => {
const selectionData = tableRef.value.getSelectionRows();
if (selectionData.length === 0) {
ElMessage.warning("请选中要删除的项");
return;
}
await ElMessageBox.confirm("确定要删除选中的数据吗?", { type: "warning" });
const DATA_IDS = selectionData.map((item) => item.RISKPOINT_ID).join(",");
await setRiskControlLedgerBatchDelete({ DATA_IDS });
ElMessage.success("删除成功");
fnResetPaginationTransfer();
};
const fnAddOrEdit = async (RISKPOINT_ID, type) => {
data.addOrEditDialog.visible = true;
await nextTick();
data.addOrEditDialog.type = type;
if (type === "edit") {
const resData = await getRiskControlLedgerView({ RISKPOINT_ID });
data.addOrEditDialog.form = resData.pd;
data.addOrEditDialog.form.ACCIDENTS = resData.pd.ACCIDENTS.split(",");
}
};
</script>
<style scoped></style>

View File

@ -1,22 +1,24 @@
<template>
<el-dialog v-model="visible" title="查看二维码">
<el-dialog v-model="visible" title="打印">
<div id="printContent">
<el-divider content-position="left">风险点单元信息</el-divider>
<el-descriptions :column="2" border>
<el-descriptions-item label="风险点(单元)">
{{ info.RISKUNITNAME }}
</el-descriptions-item>
<el-descriptions-item label="管控部门">
{{ info.DEPT_NAME }}
</el-descriptions-item>
<el-descriptions-item label="所属公司">
{{ info.CORP_NAME }}
</el-descriptions-item>
<el-descriptions-item label="管控负责人">
{{ info.HEADMAN }}
</el-descriptions-item>
</el-descriptions>
<layout-qr-code :src="info.RISKUNIT_ID" />
<div v-for="item in list" :key="item.RISKUNIT_ID" class="page_break">
<el-divider content-position="left">风险点单元信息</el-divider>
<el-descriptions :column="2" border>
<el-descriptions-item label="风险点(单元)">
{{ item.RISKUNITNAME }}
</el-descriptions-item>
<el-descriptions-item label="管控部门">
{{ item.DEPT_NAME }}
</el-descriptions-item>
<el-descriptions-item label="所属公司">
{{ item.CORP_NAME }}
</el-descriptions-item>
<el-descriptions-item label="管控负责人">
{{ item.HEADMAN }}
</el-descriptions-item>
</el-descriptions>
<layout-qr-code :src="item.RISKUNIT_ID" />
</div>
</div>
<template #footer>
<el-button @click="visible = false">关闭</el-button>
@ -35,10 +37,10 @@ const props = defineProps({
required: true,
default: false,
},
info: {
type: Object,
list: {
type: Array,
required: true,
default: () => ({}),
default: () => [],
},
});
const emits = defineEmits(["update:visible"]);

View File

@ -40,7 +40,7 @@
</el-col>
<el-col :span="6">
<el-form-item label-width="10px" class="end">
<el-button>打印</el-button>
<el-button @click="fnBatchPrint"></el-button>
<el-button @click="fnImportDialogChangeShow"> </el-button>
<el-button @click="fnExport"></el-button>
</el-form-item>
@ -87,6 +87,7 @@
查看
</el-button>
<el-button
v-if="buttonJurisdiction.edit"
type="primary"
text
link
@ -95,6 +96,7 @@
编辑
</el-button>
<el-button
v-if="buttonJurisdiction.del"
type="primary"
text
link
@ -105,10 +107,20 @@
</template>
</el-table-column>
<template #button>
<el-button type="primary" @click="fnAddOrEdit('', 'add')">
<el-button
v-if="buttonJurisdiction.add"
type="primary"
@click="fnAddOrEdit('', 'add')"
>
新增
</el-button>
<el-button type="danger" @click="fnBatchDelete"> </el-button>
<el-button
v-if="buttonJurisdiction.del"
type="danger"
@click="fnBatchDelete"
>
批量删除
</el-button>
</template>
</layout-table>
</layout-card>
@ -125,7 +137,7 @@
/>
<print
v-model:visible="data.printDialog.visible"
:info="data.printDialog.info"
:list="data.printDialog.list"
/>
</div>
</template>
@ -148,6 +160,7 @@ import LayoutImportFile from "@/components/import_file/index.vue";
import Add from "./components/add.vue";
import { useRouter } from "vue-router";
import Print from "./components/print.vue";
import useButtonJurisdiction from "@/assets/js/useButtonJurisdiction.js";
const router = useRouter();
const { list, pagination, searchForm, fnGetData, fnResetPagination, tableRef } =
@ -164,9 +177,10 @@ const data = reactive({
},
printDialog: {
visible: false,
info: {},
list: [],
},
});
const buttonJurisdiction = await useButtonJurisdiction("riskunit");
const fnGetDataTransfer = () => {
fnGetData({
DEPTIDS: searchForm.value.DEPTIDS?.join(","),
@ -241,7 +255,15 @@ const fnAddOrEdit = async (RISKUNIT_ID, type) => {
};
const fnPrint = (row) => {
data.printDialog.visible = true;
data.printDialog.info = row;
data.printDialog.list = [row];
};
const fnBatchPrint = () => {
const selectionData = tableRef.value.getSelectionRows();
if (selectionData.length === 0) {
ElMessage.warning("请选择需要打印的数据");
}
data.printDialog.list = selectionData;
data.printDialog.visible = true;
};
</script>

View File

@ -1,6 +1,6 @@
<template>
<layout-card>
<el-divider content-position="left"> 风险点单元信息 </el-divider>
<el-divider content-position="left"> 风险点单元信息</el-divider>
<el-descriptions :column="2" border>
<el-descriptions-item label="风险点(单元)">
{{ RISKUNITNAME }}
@ -9,7 +9,7 @@
{{ DEPT_NAME }}
</el-descriptions-item>
</el-descriptions>
<el-divider content-position="left"> 检查内容 </el-divider>
<el-divider content-position="left"> 检查内容</el-divider>
<layout-table :data="list" :show-pagination="false">
<el-table-column type="index" label="序号" width="50" align="center" />
<el-table-column prop="PARTSNAME" label="辨识部位" />
@ -45,9 +45,7 @@ import useListData from "@/assets/js/useListData.js";
const route = useRoute();
const { RISKUNIT_ID, RISKUNITNAME, DEPT_NAME } = route.query;
const { list } = useListData(getRiskPointInspectList, {
otherParams: {
RISK_UNIT_ID: RISKUNIT_ID,
},
otherParams: { RISK_UNIT_ID: RISKUNIT_ID },
usePagination: false,
});
</script>