From 19453ccbf5f0cd89450768fbcc29f7437ca8b282 Mon Sep 17 00:00:00 2001
From: 祖安之光 <11848914+light-of-zuan@user.noreply.gitee.com>
Date: 星期四, 07 八月 2025 09:16:39 +0800
Subject: [PATCH] 修改新增
---
public/maintainRecord.docx | 0
public/repairRecord.docx | 0
src/views/work/qualityInfo/infrastructureMng/maintainPlan/index.vue | 549 ++++++++
src/views/work/qualityInfo/infrastructureMng/repairRecord/index.vue | 235 +++
src/views/work/qualityInfo/infrastructureMng/repairRecord/components/editDialog.vue | 463 +++++++
public/reviewRecordStatistic.docx | 0
src/views/work/qualityInfo/infrastructureMng/ledger/index.vue | 214 +++
src/views/work/qualityInfo/infrastructureMng/maintainRecord/components/editDialog.vue | 553 ++++++++
src/api/infrastructureMng/ledger.js | 163 ++
src/views/work/qualityInfo/infrastructureMng/reviewRecordStatistics/index.vue | 207 +++
src/views/work/qualityInfo/infrastructureMng/ledger/components/editDialog.vue | 262 ++++
src/views/work/qualityInfo/infrastructureMng/maintainPlan/components/editDialog.vue | 541 ++++++++
src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityManual/index.vue | 1
package.json | 4
src/views/work/qualityInfo/infrastructureMng/reviewRecordStatistics/components/editDialog.vue | 426 ++++++
src/views/work/qualityInfo/infrastructureMng/maintainRecord/index.vue | 234 +++
16 files changed, 3,850 insertions(+), 2 deletions(-)
diff --git a/package.json b/package.json
index 2f30671..fcb5339 100644
--- a/package.json
+++ b/package.json
@@ -52,7 +52,9 @@
"vue-router": "4.1.4",
"vue3-json-excel": "^1.0.10-alpha",
"vue3-tree-org": "^4.2.2",
- "wangeditor5-for-vue3": "^0.1.0"
+ "wangeditor5-for-vue3": "^0.1.0",
+ "xlsx": "^0.18.5",
+ "xlsx-js-style": "^1.2.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "3.1.0",
diff --git a/public/maintainRecord.docx b/public/maintainRecord.docx
new file mode 100644
index 0000000..463f778
--- /dev/null
+++ b/public/maintainRecord.docx
Binary files differ
diff --git a/public/repairRecord.docx b/public/repairRecord.docx
new file mode 100644
index 0000000..7b806d8
--- /dev/null
+++ b/public/repairRecord.docx
Binary files differ
diff --git a/public/reviewRecordStatistic.docx b/public/reviewRecordStatistic.docx
new file mode 100644
index 0000000..213e5b4
--- /dev/null
+++ b/public/reviewRecordStatistic.docx
Binary files differ
diff --git a/src/api/infrastructureMng/ledger.js b/src/api/infrastructureMng/ledger.js
new file mode 100644
index 0000000..45a1b11
--- /dev/null
+++ b/src/api/infrastructureMng/ledger.js
@@ -0,0 +1,163 @@
+import request from '@/utils/request'
+
+export function getStandingBookList(query) {
+ return request({
+ url: '/system/standingBook/selectStandingBookList',
+ method: 'get',
+ params: query
+ })
+}
+
+export function delStandingBook(query) {
+ return request({
+ url: '/system/standingBook/delStandingBook',
+ method: 'get',
+ params: query
+ })
+}
+
+export function addStandingBook(data) {
+ return request({
+ url: '/system/standingBook/saveStandingBook',
+ method: 'post',
+ data: data
+ })
+}
+
+export function updateStandingBook(data) {
+ return request({
+ url: '/system/standingBook/updateStandingBook',
+ method: 'post',
+ data: data
+ })
+}
+
+export function getMaintenanceRecordList(query) {
+ return request({
+ url: '/system/annualMaintenanceRecord/selectAnnualMaintenanceRecordList',
+ method: 'get',
+ params: query
+ })
+}
+
+export function delMaintenanceRecord(query) {
+ return request({
+ url: '/system/annualMaintenanceRecord/deletedAnnualMaintenanceRecord',
+ method: 'get',
+ params: query
+ })
+}
+
+export function updateMaintenanceRecord(data) {
+ return request({
+ url: '/system/annualMaintenanceRecord/saveAnnualMaintenanceRecord',
+ method: 'post',
+ data: data
+ })
+}
+
+export function getMaintenanceRecordDetail(query) {
+ return request({
+ url: '/system/annualMaintenanceRecord/getAnnualMaintenanceRecord',
+ method: 'get',
+ params: query
+ })
+}
+
+export function getMaintenanceServiceList(query) {
+ return request({
+ url: '/system/annualMaintenanceService/selectAnnualMaintenanceServiceList',
+ method: 'get',
+ params: query
+ })
+}
+
+export function delMaintenanceService(query) {
+ return request({
+ url: '/system/annualMaintenanceService/deletedAnnualMaintenanceService',
+ method: 'get',
+ params: query
+ })
+}
+
+export function updateMaintenanceService(data) {
+ return request({
+ url: '/system/annualMaintenanceService/saveAnnualMaintenanceService',
+ method: 'post',
+ data: data
+ })
+}
+
+export function getMaintenanceServiceDetail(query) {
+ return request({
+ url: '/system/annualMaintenanceService/getAnnualMaintenanceService',
+ method: 'get',
+ params: query
+ })
+}
+
+export function getMaintenanceEvaluateList(query) {
+ return request({
+ url: '/system/annualMaintenanceEvaluate/selectAnnualMaintenanceEvaluateList',
+ method: 'get',
+ params: query
+ })
+}
+
+export function delMaintenanceEvaluate(query) {
+ return request({
+ url: '/system/annualMaintenanceEvaluate/deletedAnnualMaintenanceEvaluate',
+ method: 'get',
+ params: query
+ })
+}
+
+export function updateMaintenanceEvaluate(data) {
+ return request({
+ url: '/system/annualMaintenanceEvaluate/saveAnnualMaintenanceEvaluate',
+ method: 'post',
+ data: data
+ })
+}
+
+export function getMaintenanceEvaluateDetail(query) {
+ return request({
+ url: '/system/annualMaintenanceEvaluate/getAnnualMaintenanceEvaluate',
+ method: 'get',
+ params: query
+ })
+}
+
+
+
+export function getMaintenancePlanList(query) {
+ return request({
+ url: '/system/annualMaintenance/selectAnnualMaintenanceList',
+ method: 'get',
+ params: query
+ })
+}
+
+export function delMaintenancePlan(query) {
+ return request({
+ url: '/system/annualMaintenance/deletedAnnualMaintenance',
+ method: 'get',
+ params: query
+ })
+}
+
+export function updateMaintenancePlan(data) {
+ return request({
+ url: '/system/annualMaintenance/saveAnnualMaintenance',
+ method: 'post',
+ data: data
+ })
+}
+
+export function getMaintenancePlanDetail(query) {
+ return request({
+ url: '/system/annualMaintenance/getAnnualMaintenance',
+ method: 'get',
+ params: query
+ })
+}
diff --git a/src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityManual/index.vue b/src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityManual/index.vue
index 53f2ae7..ea3f499 100644
--- a/src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityManual/index.vue
+++ b/src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityManual/index.vue
@@ -236,7 +236,6 @@
data.companyInfo.policies = res.data.companyQualityPolicies ? res.data.companyQualityPolicies[0]?.policy : []
const duties = transToTableData(res.data.sysFunctionalDistributions,data.originDeptList)
data.companyInfo.allDepts = duties.allDepts
- console.log(data.companyInfo.allDepts,'all')
data.companyInfo.clauses = duties.clauses
data.companyInfo.temps = res.data.companyIndustryTemplates?.map((item,index)=>{
return {
diff --git a/src/views/work/qualityInfo/infrastructureMng/ledger/components/editDialog.vue b/src/views/work/qualityInfo/infrastructureMng/ledger/components/editDialog.vue
new file mode 100644
index 0000000..720804b
--- /dev/null
+++ b/src/views/work/qualityInfo/infrastructureMng/ledger/components/editDialog.vue
@@ -0,0 +1,262 @@
+<template>
+ <div class="notice">
+ <el-dialog
+ v-model="dialogVisible"
+ :title="state.title"
+ width="50%"
+ :before-close="handleClose"
+ :close-on-press-escape="false"
+ :close-on-click-modal="false"
+ >
+ <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px" >
+ <el-form-item v-if="state.isAdmin" label="企业:" prop="companyId">
+ <el-select v-model="state.form.companyId" placeholder="请选择" clearable @change="getDeptList" :disabled="state.title =='查看'">
+ <el-option
+ v-for="item in state.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="名称型号:" prop="model">
+ <el-input v-model.trim="state.form.model"></el-input>
+ </el-form-item>
+ <el-form-item label="部门:" prop="deptId">
+ <el-select
+ clearable
+ v-model="state.form.deptId"
+ :disabled="state.title =='查看'"
+ filterable
+ placeholder="选择部门"
+ style="width: 100%"
+ >
+ <el-option
+ v-for="item in state.deptList"
+ :key="item.deptId"
+ :label="item.deptName"
+ :value="item.deptId"
+ />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="责任人/使用人:" prop="personResponsible">
+ <el-select clearable v-model="state.form.personResponsible" :disabled="state.title =='查看'" filterable placeholder="责任人/使用人" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id"
+ />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="设备类型:" prop="deviceType">
+ <el-select v-model="state.form.deviceType" :disabled="state.title =='查看'" placeholder="请选择" clearable>
+ <el-option key="1" label="生产设备" :value="1"></el-option>
+ <el-option key="2" label="办公自动化设备" :value="2"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="编号:" prop="number">
+ <el-input v-model.trim="state.form.number" :readonly="state.title =='查看'"></el-input>
+ </el-form-item>
+ <el-form-item label="品牌:" prop="brand">
+ <el-input v-model.trim="state.form.brand" :readonly="state.title =='查看'"></el-input>
+ </el-form-item>
+ <el-form-item label="密级/类型:" prop="confidentiality">
+ <el-input v-model.trim="state.form.confidentiality" :readonly="state.title =='查看'"></el-input>
+ </el-form-item>
+ <el-form-item label="状态:" prop="status">
+ <el-select v-model="state.form.status" :disabled="state.title =='查看'" placeholder="请选择" clearable>
+ <el-option key="1" label="完好" :value="1"></el-option>
+ <el-option key="2" label="损坏" :value="2"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="用途:" prop="purpose">
+ <el-input v-model.trim="state.form.purpose" :readonly="state.title =='查看'"></el-input>
+ </el-form-item>
+ <el-form-item label="使用地点:" prop="location">
+ <el-input v-model.trim="state.form.location" :readonly="state.title =='查看'"></el-input>
+ </el-form-item>
+ <el-form-item label="使用情况:" prop="used">
+ <el-input v-model.trim="state.form.used" :readonly="state.title =='查看'"></el-input>
+ </el-form-item>
+ <el-form-item label="备注:" prop="remark">
+ <el-input v-model.trim="state.form.remark" :readonly="state.title =='查看'"></el-input>
+ </el-form-item>
+ </el-form>
+ <template #footer v-if="state.title !='查看'">
+ <span class="dialog-footer">
+ <el-button @click="handleClose" size="default">取 消</el-button>
+ <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+<script setup>
+import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue'
+import {ElMessage} from "element-plus";
+import {Base64} from "js-base64"
+import {getToken} from "@/utils/auth";
+import {
+ addInternalAuditCheck, getInternalAuditCheckInfo,
+ updateInternalAuditCheck
+} from "@/api/innerReview/meetingReview";
+import {getDepart} from "@/api/orgStructure/depart";
+import {listUser} from "@/api/system/user";
+import {addStandingBook, updateStandingBook} from "@/api/infrastructureMng/ledger";
+
+const emit = defineEmits(["getList"]);
+const dialogVisible = ref(false)
+const superRef = ref()
+
+const state = reactive({
+ title: '',
+ form: {
+ id: null,
+ model: '',
+ deptId: null,
+ personResponsible: null,
+ deviceType: null,
+ number: '',
+ brand: '',
+ confidentiality: '',
+ status: null,
+ purpose: '',
+ location: '',
+ used: '',
+ remark: '',
+ companyId: null
+ },
+ formRules:{
+ companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }],
+ deptId: [{ required: true, message: '请选择受部门', trigger: 'blur' }],
+ model: [{ required: true, message: '请填写名称型号', trigger: 'blur' }],
+ personResponsible: [{ required: true, message: '请选择责任人/使用人', trigger: 'blur' }],
+ deviceType: [{ required: true, message: '请选择设备类型', trigger: 'blur' }],
+ number: [{ required: true, message: '请填写编号', trigger: 'blur' }]
+ },
+ isAdmin: false,
+ companyList: [],
+ deptList: [],
+ userList: []
+})
+onMounted(() => {
+
+});
+
+const openDialog = async (type, value,companyId, isAdmin, companyList) => {
+ state.isAdmin = isAdmin
+ if(isAdmin){
+ state.companyList = companyList
+ }
+ await getUserList(companyId)
+ await getDepartList(companyId)
+ state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看'
+ state.form.companyId = companyId
+ if(state.title == '编辑'||state.title == '查看'){
+ Object.keys(state.form).forEach(key => {
+ if (key in value) {
+ state.form[key] = value[key]
+ }
+ })
+ }
+ dialogVisible.value = true
+}
+
+
+const onSubmit = async () => {
+ const valid = await superRef.value.validate();
+ if(valid){
+ if(state.title == '新增'){
+ const {id,...data} = state.form
+ const res = await addStandingBook(data)
+ if(res.code == 200){
+ ElMessage.success(res.message)
+ emit('getList')
+ handleClose()
+ dialogVisible.value = false;
+ }else{
+ ElMessage.warning(res.message)
+ }
+ }else{
+ const res = await updateStandingBook(state.form)
+ if(res.code == 200){
+ ElMessage.success(res.message)
+ emit('getList')
+ handleClose()
+ dialogVisible.value = false;
+ }else{
+ ElMessage.warning(res.message)
+ }
+ }
+ }
+}
+
+const getDeptList = async ()=>{
+ state.form.deptId = null
+ state.form.personResponsible = null
+ await getDepartList(state.form.companyId)
+ await getUserList(state.form.companyId)
+}
+
+const getDepartList = async (companyId)=> {
+ const params = {
+ companyId: companyId
+ }
+ const res = await getDepart(params)
+ if(res.code == 200){
+ state.deptList = res.data
+ }else{
+ ElMessage.warning(res.message)
+ }
+}
+
+const getUserList = async (companyId)=> {
+ const res = await listUser({pageIndex: 1,pageSize: 999, companyId: companyId})
+ if(res.code == 200){
+ state.userList = res.data.list?res.data.list:[]
+ }else{
+ ElMessage.warning(res.message)
+ }
+}
+
+const handleClose = () => {
+ state.form = {
+ id: null,
+ model: '',
+ deptId: null,
+ personResponsible: null,
+ deviceType: null,
+ number: '',
+ brand: '',
+ confidentiality: '',
+ status: null,
+ purpose: '',
+ location: '',
+ used: '',
+ remark: '',
+ companyId: null
+ }
+ superRef.value.clearValidate();
+ superRef.value.resetFields()
+ dialogVisible.value = false;
+}
+
+defineExpose({
+ openDialog
+});
+
+</script>
+
+<style scoped lang="scss">
+.notice{
+ :deep(.el-form .el-form-item__label) {
+ font-size: 15px;
+ }
+ .file {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ }
+}
+</style>
diff --git a/src/views/work/qualityInfo/infrastructureMng/ledger/index.vue b/src/views/work/qualityInfo/infrastructureMng/ledger/index.vue
new file mode 100644
index 0000000..8ed0b5c
--- /dev/null
+++ b/src/views/work/qualityInfo/infrastructureMng/ledger/index.vue
@@ -0,0 +1,214 @@
+<template>
+ <div class="app-container">
+ <div style="display: flex;justify-content: space-between">
+ <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" >
+ <el-form-item>
+ <el-button
+ type="primary"
+ plain
+ icon="Plus"
+ @click="openDialog('add',{})"
+ >新增</el-button>
+ </el-form-item>
+ <el-form-item v-if="isAdmin" label="企业:" >
+ <el-select v-model="data.queryParams.companyId" placeholder="请选择" clearable>
+ <el-option
+ v-for="item in companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item >
+ <el-button v-if="isAdmin" type="primary" @click="getList">查询</el-button>
+ <el-button v-if="isAdmin" type="primary" plain @click="reset">重置</el-button>
+ <vue3-json-excel
+ :json-data="expertData"
+ :fields="fields"
+ name="用户花名册.xls"
+ style="margin-left: 12px"
+ >
+ <el-button type="primary">导出</el-button>
+ </vue3-json-excel>
+ </el-form-item>
+ </el-form>
+ </div>
+ <!-- 表格数据 -->
+ <el-table v-loading="loading" :data="dataList" :border="true">
+ <el-table-column type="index" label="序号"></el-table-column>
+ <el-table-column prop="model" align="center" label="名称型号"></el-table-column>
+ <el-table-column prop="deptName" align="center" label="部门"></el-table-column>
+ <el-table-column prop="personResponsible" align="center" label="责任人/使用人"></el-table-column>
+ <el-table-column prop="number" align="center" label="编号"></el-table-column>
+ <el-table-column prop="location" align="center" label="使用地点"></el-table-column>
+ <el-table-column prop="used" align="center" label="使用情况"></el-table-column>
+<!-- <el-table-column label="检查表" align="center">-->
+<!-- <template #default="scope">-->
+<!-- {{scope.row.deptName }}内审检查表-->
+<!-- </template>-->
+<!-- </el-table-column>-->
+ <el-table-column label="操作" align="center">
+ <template #default="scope">
+ <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button>
+ <el-button link type="danger" @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"
+ />
+
+ <edit-dialog ref="dialogRef" @getList=getList></edit-dialog>
+ </div>
+</template>
+
+<script setup>
+import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
+import {ElMessage, ElMessageBox} from "element-plus";
+import {delCompany, getCompany} from "@/api/onlineEducation/company";
+import Cookies from "js-cookie";
+import editDialog from './components/editDialog.vue'
+import useUserStore from "@/store/modules/user";
+import {getStandardTemp,delStandardTemp} from "@/api/standardSys/standardSys";
+import { renderAsync } from "docx-preview";
+import {
+ delInternalAuditCheck,
+ delMeetingsList,
+ getInternalAuditCheck, getInternalAuditCheckInfo,
+ getMeetingsList
+} from "@/api/innerReview/meetingReview";
+import {generateWordDocument} from "@/utils/exportWord";
+import {delStandingBook, getStandingBookList} from "@/api/infrastructureMng/ledger";
+
+
+const userStore = useUserStore()
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const dialogRef = ref();
+const data = reactive({
+ queryParams: {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null
+ },
+ total: 0,
+ dataList: [],
+ companyList: [],
+ expertData: [],
+ isAdmin: false
+});
+const fields = ref({
+ '序号':'index',
+ '名称型号':'model',
+ '部门':'deptName',
+ '责任人/使用人':'personResponsible',
+ '编号':'number',
+ '使用地点':'location',
+ '使用情况':'used'
+});
+const { queryParams, total, dataList,companyList, isAdmin, expertData } = toRefs(data);
+const userInfo = ref()
+onMounted(async ()=>{
+ if(userStore.roles.includes('admin')){
+ data.isAdmin = true
+ await getCompanyList()
+ }else{
+ data.isAdmin = false
+ data.queryParams.companyId = userStore.companyId
+ }
+ await getList()
+})
+
+onUnmounted(()=>{
+
+})
+
+const getList = async () => {
+ loading.value = true
+ const res = await getStandingBookList(data.queryParams)
+ if(res.code == 200){
+ data.dataList = res.data.list || []
+ data.total = res.data.total
+ }else{
+ ElMessage.warning(res.message)
+ }
+ loading.value = false
+ await getAllList()
+}
+
+const getAllList = async () => {
+ let query = {
+ pageNum: data.queryParams.pageNum,
+ pageSize: 9999,
+ companyId: data.queryParams.companyId
+ }
+ const res = await getStandingBookList(query)
+ if(res.code == 200){
+ data.expertData = res.data.list?.map((item,index) => {
+ return {
+ ...item,
+ index: index + 1
+ }
+ })
+ }else{
+ ElMessage.warning(res.message)
+ }
+}
+
+
+const getCompanyList = async ()=>{
+ const queryParams = {
+ pageNum: 1,
+ pageSize: 999
+ }
+ const res = await getCompany(queryParams)
+ if (res.code == 200) {
+ data.companyList = res.data.list?res.data.list:[]
+ // data.queryParams.companyId = data.companyList[0].id
+ } else {
+ ElMessage.warning(res.message)
+ }
+}
+
+
+const openDialog = (type, value) => {
+ dialogRef.value.openDialog(type, value, data.queryParams.companyId, data.isAdmin, data.companyList);
+}
+
+/** 重置新增的表单以及其他数据 */
+const reset= async()=> {
+ data.queryParams = {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null
+ }
+ await getCompanyList()
+ await getList()
+}
+const handleDelete = (val) => {
+ ElMessageBox.confirm(
+ '确定删除此条数据?',
+ '提示',
+ {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning',
+ })
+ .then( async() => {
+ const res = await delStandingBook({id: val.id})
+ if(res.code == 200){
+ ElMessage.success('数据删除成功')
+ await getList()
+ }else{
+ ElMessage.warning(res.message)
+ }
+ })
+}
+
+</script>
diff --git a/src/views/work/qualityInfo/infrastructureMng/maintainPlan/components/editDialog.vue b/src/views/work/qualityInfo/infrastructureMng/maintainPlan/components/editDialog.vue
new file mode 100644
index 0000000..4f67770
--- /dev/null
+++ b/src/views/work/qualityInfo/infrastructureMng/maintainPlan/components/editDialog.vue
@@ -0,0 +1,541 @@
+<template>
+ <div class="notice">
+ <el-dialog
+ v-model="dialogVisible"
+ :title="state.title"
+ width="75%"
+ :before-close="handleClose"
+ :close-on-press-escape="false"
+ :close-on-click-modal="false"
+ >
+ <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="180px">
+ <el-form-item v-if="state.isAdmin" label="企业:" prop="companyId">
+ <el-select v-model="state.form.companyId" placeholder="请选择" :disabled="state.title =='查看'" clearable @change="getDeptList">
+ <el-option
+ v-for="item in state.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ <el-row>
+ <el-col :span="12">
+ <el-form-item label="年份:" prop="year">
+ <el-date-picker
+ v-model="state.form.year"
+ type="year"
+ value-format="YYYY"
+ placeholder="请选择年份"
+ :disabled="state.title =='查看'"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="编号:" prop="number">
+ <el-input v-model.trim="state.form.number" :readonly="state.title =='查看'"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-form-item label="年度基础设施维护计划:" prop="annualMaintenanceDeviceSaveDTOReqs">
+ <el-button
+ type="primary"
+ plain
+ icon="Plus"
+ @click="addLine"
+ style="margin-bottom: 10px"
+ v-if="state.title !=='查看'"
+ >新增</el-button>
+ </el-form-item>
+<!-- <el-table :data="state.form.annualMaintenanceDeviceSaveDTOReqs" class="customedTable" :border="true">-->
+<!-- <el-table-column label="序号" type="index" width="80" align="center">-->
+<!-- </el-table-column>-->
+<!-- <el-table-column label="设备名称" prop="deviceName" align="center">-->
+<!-- <template #default="scope">-->
+<!-- <el-input-->
+<!-- v-model.trim="scope.row.deviceName"-->
+<!-- size="large"-->
+<!-- type="textarea"-->
+<!-- style="width: 100%;"-->
+<!-- clearable-->
+<!-- >-->
+<!-- </el-input>-->
+<!-- </template>-->
+<!-- </el-table-column>-->
+<!-- <el-table-column label="型号" prop="model" align="center">-->
+<!-- <template #default="scope">-->
+<!-- <el-input-->
+<!-- v-model.trim="scope.row.model"-->
+<!-- size="large"-->
+<!-- type="textarea"-->
+<!-- style="width: 100%;"-->
+<!-- clearable-->
+<!-- >-->
+<!-- </el-input>-->
+<!-- </template>-->
+<!-- </el-table-column>-->
+<!-- <el-table-column label="厂内编号" prop="factoryNumber" align="center">-->
+<!-- <template #default="scope">-->
+<!-- <el-input-->
+<!-- v-model.trim="scope.row.factoryNumber"-->
+<!-- size="large"-->
+<!-- type="textarea"-->
+<!-- style="width: 100%;"-->
+<!-- clearable-->
+<!-- >-->
+<!-- </el-input>-->
+<!-- </template>-->
+<!-- </el-table-column>-->
+<!-- <el-table-column label="用途" prop="purpose" align="center">-->
+<!-- <template #default="scope">-->
+<!-- <el-input-->
+<!-- v-model.trim="scope.row.purpose"-->
+<!-- size="large"-->
+<!-- type="textarea"-->
+<!-- style="width: 100%;"-->
+<!-- clearable-->
+<!-- >-->
+<!-- </el-input>-->
+<!-- </template>-->
+<!-- </el-table-column>-->
+<!-- <el-table-column label="使用部门" prop="deptName" align="center">-->
+<!-- <template #default="scope">-->
+<!-- <el-input-->
+<!-- v-model.trim="scope.row.deptName"-->
+<!-- size="large"-->
+<!-- type="textarea"-->
+<!-- style="width: 100%;"-->
+<!-- clearable-->
+<!-- >-->
+<!-- </el-input>-->
+<!-- </template>-->
+<!-- </el-table-column>-->
+<!-- <el-table-column label="操作" align="center" width="70">-->
+<!-- <template #default="scope">-->
+<!-- <el-button link type="danger" @click="handleDelete(scope.$index)">删除</el-button>-->
+<!-- </template>-->
+<!-- </el-table-column>-->
+<!-- </el-table>-->
+ <div v-for="(device,deviceIndex) in state.form.annualMaintenanceDeviceSaveDTOReqs" :key="deviceIndex" class="device-table">
+ <table class="seven-col-table">
+ <thead>
+ <tr>
+ <th>序号</th>
+ <th>设备名称</th>
+ <th>型号</th>
+ <th>厂内编号</th>
+ <th>用途</th>
+ <th>使用部门</th>
+ <th v-if="state.title !=='查看'">操作</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>{{deviceIndex + 1}}</td>
+ <td>
+ <el-input v-model.trim="device.deviceName" type="textarea" style="width: 100%;" clearable :readonly="state.title =='查看'"></el-input>
+ </td>
+ <td>
+ <el-input v-model.trim="device.model" type="textarea" style="width: 100%;" clearable :readonly="state.title =='查看'"></el-input>
+ </td>
+ <td>
+ <el-input v-model.trim="device.factoryNumber" type="textarea" style="width: 100%;" clearable :readonly="state.title =='查看'"></el-input>
+ </td>
+ <td>
+ <el-input v-model.trim="device.purpose" type="textarea" style="width: 100%;" clearable :readonly="state.title =='查看'"></el-input>
+ </td>
+ <td>
+ <el-input v-model.trim="device.deptName" type="textarea" style="width: 100%;" clearable :readonly="state.title =='查看'"></el-input>
+ </td>
+ <td v-if="state.title !=='查看'">
+ <el-button link type="danger" @click="handleDelete(deviceIndex)">删除</el-button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <table class="maintain-table">
+ <thead>
+ <tr>
+ <th style="width: 120px;">项目</th>
+ <th style="width: 80px;">频度</th>
+ <th v-for="(month,monthIndex) in state.monthList" :key="monthIndex">{{month.label}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr v-for="(line,lineIndex) in state.form.annualMaintenanceDeviceSaveDTOReqs[deviceIndex].annualMaintenanceDeviceTypes" :key="lineIndex">
+ <td>{{line.projectType == 1?'日常例行点检':line.projectType == 2?'一级保养':'二级保养'}}</td>
+ <td>{{line.frequency == 1?'工作日':line.frequency == 2?'1次/3个月':'1次/6个月'}}</td>
+ <td v-for="(month,monthIndex2) in state.monthList" :key="monthIndex2">
+ <el-input v-model.trim="line[month.value]" style="width: 100%;" clearable :readonly="state.title =='查看'"></el-input>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <el-form-item label="核准:" prop="approvalId">
+ <el-select clearable v-model="state.form.approvalId" :disabled="state.title =='查看'" filterable placeholder="核准" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.userId"
+ :label="item.name"
+ :value="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="审核:" prop="processId">
+ <el-select clearable v-model="state.form.processId" :disabled="state.title =='查看'" filterable placeholder="审核" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.userId"
+ :label="item.name"
+ :value="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="做成:" prop="finishId">
+ <el-select clearable v-model="state.form.finishId" :disabled="state.title =='查看'" filterable placeholder="做成" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.userId"
+ :label="item.name"
+ :value="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ </el-form>
+ <template #footer v-if="state.title !='查看'">
+ <span class="dialog-footer">
+ <el-button @click="handleClose" size="default">取 消</el-button>
+ <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+<script setup>
+import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue'
+import {ElMessage} from "element-plus";
+import {Base64} from "js-base64"
+import {getToken} from "@/utils/auth";
+import {
+ addInternalAuditCheck, getInternalAuditCheckInfo,
+ updateInternalAuditCheck
+} from "@/api/innerReview/meetingReview";
+import {getDepart} from "@/api/orgStructure/depart";
+import {listUser} from "@/api/system/user";
+import {getMaintenancePlanDetail, updateMaintenancePlan} from "@/api/infrastructureMng/ledger";
+
+const emit = defineEmits(["getList"]);
+const dialogVisible = ref(false)
+const superRef = ref()
+const checkList = (rule, value, callback) => {
+ if (state.form.annualMaintenanceDeviceSaveDTOReqs.length == 0) {
+ callback(new Error('维护计划不可为空'))
+ } else {
+ callback()
+ }
+}
+const state = reactive({
+ title: '',
+ form: {
+ id: null,
+ companyId: null,
+ name: '',
+ year: '',
+ number: '',
+ annualMaintenanceDeviceSaveDTOReqs: [],
+ approvalId: null,
+ approvalName: '',
+ processId: null,
+ processName: '',
+ finishId: null,
+ finishName: '',
+ delDeviceIds: []
+ },
+ oldDeviceList: [],
+ formRules:{
+ companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }],
+ year: [{ required: true, message: '请选择年份', trigger: 'blur' }],
+ number: [{ required: true, message: '请填写编号', trigger: 'blur' }],
+ approvalId: [{ required: true, message: '请选择核准人', trigger: 'blur' }],
+ processId: [{ required: true, message: '请选择审核人', trigger: 'blur' }],
+ finishId: [{ required: true, message: '请选择做成人', trigger: 'blur' }],
+ annualMaintenanceDeviceSaveDTOReqs: [{ required: true, validator: checkList, trigger: 'blur' }],
+ },
+ isAdmin: false,
+ companyList: [],
+ userList: [],
+ monthList: [
+ {label: '一月',value: 'jan'},
+ {label: '二月',value: 'feb'},
+ {label: '三月',value: 'mar'},
+ {label: '四月',value: 'apr'},
+ {label: '五月',value: 'may'},
+ {label: '六月',value: 'jun'},
+ {label: '七月',value: 'jul'},
+ {label: '八月',value: 'aug'},
+ {label: '九月',value: 'sep'},
+ {label: '十月',value: 'oct'},
+ {label: '十一月',value: 'nov'},
+ {label: '十二月',value: 'decm'}
+ ]
+})
+onMounted(() => {
+
+});
+
+const openDialog = async (type, value,companyId, isAdmin, companyList) => {
+ state.isAdmin = isAdmin
+ if(isAdmin){
+ state.companyList = companyList
+ }
+ await getUserList(companyId)
+ state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看'
+ state.form.companyId = companyId
+ if(state.title == '编辑'||state.title == '查看'){
+ await getInfo(value.id)
+ }
+ dialogVisible.value = true
+}
+
+const addLine = () => {
+ const obj = {
+ id: null,
+ annualMaintenanceId: null,
+ annualMaintenanceDeviceTypes: [
+ {
+ id: null,
+ annualMaintenanceDeviceId: null,
+ projectType: 1,
+ frequency: 1,
+ jan: '',
+ feb: '',
+ mar: '',
+ apr: '',
+ may: '',
+ jun: '',
+ jul: '',
+ aug: '',
+ sep: '',
+ oct: '',
+ nov: '',
+ decm: ''
+ },
+ {
+ id: null,
+ annualMaintenanceDeviceId: null,
+ projectType: 2,
+ frequency: 2,
+ jan: '',
+ feb: '',
+ mar: '',
+ apr: '',
+ may: '',
+ jun: '',
+ jul: '',
+ aug: '',
+ sep: '',
+ oct: '',
+ nov: '',
+ decm: ''
+ },
+ {
+ id: null,
+ annualMaintenanceDeviceId: null,
+ projectType: 3,
+ frequency: 3,
+ jan: '',
+ feb: '',
+ mar: '',
+ apr: '',
+ may: '',
+ jun: '',
+ jul: '',
+ aug: '',
+ sep: '',
+ oct: '',
+ nov: '',
+ decm: ''
+ }
+ ],
+ delDeviceTypeIds: [],
+ deviceName: '',
+ model: '',
+ factoryNumber: '',
+ purpose: '',
+ deptName: ''
+ }
+ state.form.annualMaintenanceDeviceSaveDTOReqs.push(obj);
+}
+
+const handleDelete = (i) =>{
+ state.form.annualMaintenanceDeviceSaveDTOReqs = state.form.annualMaintenanceDeviceSaveDTOReqs.filter((item,index) => index != i)
+}
+
+const onSubmit = async () => {
+ const valid = await superRef.value.validate();
+ console.log(state.form,'form')
+ // return
+ if(valid){
+ const data = JSON.parse(JSON.stringify(state.form))
+ data.delDeviceIds = state.oldDeviceList.filter(i =>!data.annualMaintenanceDeviceSaveDTOReqs.some(item=>item.id == i.id)).map(i=>i.id)
+ data.approvalName = state.userList.find(i=>i.userId == data.approvalId)?.name
+ data.processName = state.userList.find(i=>i.userId == data.processId)?.name
+ data.finishName = state.userList.find(i=>i.userId == data.finishId)?.name
+ data.name = data.year + '年度基础设施维护计划'
+ if(state.title == '新增'){
+ delete data.id
+ const res = await updateMaintenancePlan(data)
+ if(res.code == 200){
+ ElMessage.success(res.message)
+ emit('getList')
+ handleClose()
+ dialogVisible.value = false;
+ }else{
+ ElMessage.warning(res.message)
+ }
+ }else{
+ const res = await updateMaintenancePlan(data)
+ if(res.code == 200){
+ ElMessage.success(res.message)
+ emit('getList')
+ handleClose()
+ dialogVisible.value = false;
+ }else{
+ ElMessage.warning(res.message)
+ }
+ }
+ }
+}
+
+const getInfo = async (id)=> {
+ const res = await getMaintenancePlanDetail({id: id})
+ if(res.code == 200){
+ Object.keys(state.form).forEach(key => {
+ if (key in res.data) {
+ state.form[key] = res.data[key]
+ }
+ })
+ state.form.annualMaintenanceDeviceSaveDTOReqs = res.data.annualMaintenanceDeviceList.map(item=>{
+ return {
+ ...item,
+ annualMaintenanceDeviceTypes: [...item.annualMaintenanceDeviceTypeList].sort((a, b) => a.projectType - b.projectType)
+ }
+ })
+ state.oldDeviceList = res.data.annualMaintenanceDeviceList
+ }else{
+ ElMessage.warning(res.message)
+ }
+}
+
+const getDeptList = async ()=>{
+ state.form.approvalId = null
+ state.form.processId = null
+ state.form.finishId = null
+ await getUserList(state.form.companyId)
+}
+
+const getUserList = async (companyId)=> {
+ const res = await listUser({pageIndex: 1,pageSize: 999,companyId: companyId})
+ if(res.code == 200){
+ state.userList = res.data.list?res.data.list.map(item=>{
+ const user = item.id
+ const {id, ...data} = item
+ return {
+ ...data,
+ userId: user
+ }
+ }):[]
+ if(state.form.deptId){
+ state.interUserList = state.userList.filter(i=>i.deptId !== state.form.deptId)
+ }else{
+ state.interUserList = state.userList
+ }
+ }else{
+ ElMessage.warning(res.message)
+ }
+}
+
+const handleClose = () => {
+ state.form = {
+ id: null,
+ companyId: null,
+ name: '',
+ year: '',
+ number: '',
+ annualMaintenanceDeviceSaveDTOReqs: [],
+ approvalId: null,
+ approvalName: '',
+ processId: null,
+ processName: '',
+ finishId: null,
+ finishName: '',
+ delDeviceIds: []
+ }
+ superRef.value.clearValidate();
+ superRef.value.resetFields()
+ dialogVisible.value = false;
+}
+
+defineExpose({
+ openDialog
+});
+
+</script>
+
+<style scoped lang="scss">
+.notice{
+ :deep(.el-form .el-form-item__label) {
+ font-size: 15px;
+ }
+ .file {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ }
+ .device-table {
+ width: calc(100% - 170px);
+ margin-left: 170px;
+ margin-bottom: 30px;
+ padding: 5px;
+ border: 1px solid #2563eb;
+ border-radius: 5px;
+ background: #fff;
+ box-shadow: 8px 8px 15px rgba(0, 21, 41, 0.08), -8px -8px 15px #fff;
+ }
+
+ table {
+ width: 100%;
+ border-collapse: collapse;
+ margin-bottom: 4px;
+ }
+
+ th, td {
+ border: 1px solid #ebeef5;
+ padding: 0;
+ text-align: center;
+ }
+
+ th {
+ padding: 4px 0;
+ background-color: #f8f8f9;
+ }
+ .maintain-table{
+ margin-bottom: 0;
+ }
+}
+</style>
+<style lang="scss">
+.device-table {
+ .el-textarea__inner{
+ border: none !important;
+ border-color: rgba(0,0,0,0);
+ border-radius: 0;
+ }
+ .el-input__wrapper{
+ border: none !important;
+ border-color: rgba(0,0,0,0);
+ border-radius: 0;
+ }
+}
+</style>
diff --git a/src/views/work/qualityInfo/infrastructureMng/maintainPlan/index.vue b/src/views/work/qualityInfo/infrastructureMng/maintainPlan/index.vue
new file mode 100644
index 0000000..674d657
--- /dev/null
+++ b/src/views/work/qualityInfo/infrastructureMng/maintainPlan/index.vue
@@ -0,0 +1,549 @@
+<template>
+ <div class="app-container">
+ <div style="display: flex;justify-content: space-between">
+ <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" >
+ <el-form-item>
+ <el-button
+ type="primary"
+ plain
+ icon="Plus"
+ @click="openDialog('add',{})"
+ >新增</el-button>
+ </el-form-item>
+ <el-form-item v-if="isAdmin" label="企业:" >
+ <el-select v-model="data.queryParams.companyId" placeholder="请选择" clearable>
+ <el-option
+ v-for="item in companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item v-if="isAdmin" label="年份:">
+ <el-date-picker
+ v-model="data.queryParams.year"
+ type="year"
+ value-format="YYYY"
+ placeholder="请选择年份"
+ />
+ </el-form-item>
+ <el-form-item >
+ <el-button v-if="isAdmin" type="primary" @click="getList">查询</el-button>
+ <el-button v-if="isAdmin" type="primary" plain @click="reset">重置</el-button>
+<!-- <el-button type="primary">导出</el-button>-->
+ </el-form-item>
+ </el-form>
+ </div>
+ <!-- 表格数据 -->
+ <el-table v-loading="loading" :data="dataList" :border="true">
+ <el-table-column type="index" label="序号"></el-table-column>
+ <el-table-column prop="name" align="center" label="名称"></el-table-column>
+ <el-table-column prop="year" align="center" label="年份"></el-table-column>
+ <el-table-column label="操作" align="center">
+ <template #default="scope">
+ <el-button link type="primary" @click="openDialog('view',scope.row)">查看</el-button>
+ <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button>
+ <el-button link type="primary" @click="downloadFile(scope.row)">导出</el-button>
+ <el-button link type="danger" @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"
+ />
+
+ <edit-dialog ref="dialogRef" @getList=getList></edit-dialog>
+ </div>
+</template>
+
+<script setup>
+import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
+import {ElMessage, ElMessageBox} from "element-plus";
+import {delCompany, getCompany} from "@/api/onlineEducation/company";
+import Cookies from "js-cookie";
+import editDialog from './components/editDialog.vue'
+import useUserStore from "@/store/modules/user";
+import { utils, writeFile } from 'xlsx-js-style';
+import {generateWordDocument} from "@/utils/exportWord";
+import {
+ delMaintenancePlan,
+ getMaintenanceEvaluateDetail,
+ getMaintenancePlanDetail,
+ getMaintenancePlanList
+} from "@/api/infrastructureMng/ledger";
+
+
+const userStore = useUserStore()
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const dialogRef = ref();
+const data = reactive({
+ queryParams: {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null
+ },
+ total: 0,
+ dataList: [],
+ companyList: [],
+ expertData: [],
+ isAdmin: false
+});
+const fields = ref({
+ '序号':'index',
+ '名称型号':'username',
+ '部门':'idCard',
+ '责任人/使用人':'entryTime',
+ '编号':'deptName',
+ '使用地点':'duty',
+ '使用情况':'phone'
+});
+const { queryParams, total, dataList,companyList, isAdmin, expertData } = toRefs(data);
+const userInfo = ref()
+onMounted(async ()=>{
+ if(userStore.roles.includes('admin')){
+ data.isAdmin = true
+ await getCompanyList()
+ }else{
+ data.isAdmin = false
+ data.queryParams.companyId = userStore.companyId
+ }
+ await getList()
+})
+
+onUnmounted(()=>{
+
+})
+
+const getList = async () => {
+ loading.value = true
+ const res = await getMaintenancePlanList(data.queryParams)
+ if(res.code == 200){
+ data.dataList = res.data.list || []
+ data.total = res.data.total
+ }else{
+ ElMessage.warning(res.message)
+ }
+ loading.value = false
+}
+
+const getCompanyList = async ()=>{
+ const queryParams = {
+ pageNum: 1,
+ pageSize: 999
+ }
+ const res = await getCompany(queryParams)
+ if (res.code == 200) {
+ data.companyList = res.data.list?res.data.list:[]
+ // data.queryParams.companyId = data.companyList[0].id
+ } else {
+ ElMessage.warning(res.message)
+ }
+}
+
+// const downloadFile = async (val)=>{
+// const res = await getMaintenancePlanDetail({id: val.id})
+// if(res.code == 200){
+// if(res.data){
+// let tableData = res.data
+// tableData.content = res.data.caluseNum.split('、').map((i,index)=>i + res.data.caluseContent.split(';\n')[index]).join('\n')
+// tableData.interPeople = res.data.internalAuditCheckPeople.map(i=>i.auditUserName)
+// try {
+// generateWordDocument('/interCheck.docx', tableData, tableData.deptName +'内审检查表.docx');
+// } catch (error){
+// ElMessage({
+// type: 'warning',
+// message: '导出失败'
+// });
+// }
+// }else{
+// ElMessage.warning('暂无数据')
+// }
+// }else{
+// ElMessage.warning(res.message)
+// }
+// }
+
+
+
+const downloadFile = async (val)=>{
+ const res = await getMaintenancePlanDetail({id: val.id})
+ if(res.code == 200){
+ if(res.data){
+ let tableData = res.data
+ if(data.isAdmin){
+ tableData.companyName = data.companyList.find(i=>i.id == val.companyId)?.name
+ }else{
+ tableData.companyName = userStore.companyName
+ }
+ const wb = utils.book_new();
+ const wsData = [];
+
+ // 第一行:企业名称(合并A1-T1)
+ wsData.push([{ v: tableData.companyName, t: 's', s: { font: { bold: true, sz: 16 }, alignment: { horizontal: 'center' } } }]);
+
+ // 第二行:标题(合并A2-T2)
+ wsData.push([{ v: tableData.name || '年度基础设施维护计划', t: 's', s: { font: { bold: true, sz: 14 }, alignment: { horizontal: 'center' } } }]);
+
+ // 第三行:表头上半部分
+ const row3 = [
+ // A-F列(将在下方与row4合并)
+ { v: '序号', t: 's', s: headerStyle },
+ { v: '设备名称', t: 's', s: headerStyle },
+ { v: '型号', t: 's', s: headerStyle },
+ { v: '厂内编号', t: 's', s: headerStyle },
+ { v: '用途', t: 's', s: headerStyle },
+ { v: '使用部门', t: 's', s: headerStyle },
+ // G-H列合并(维修保养)
+ { v: '维修保养', t: 's', s: mergedHeaderStyle },
+ null, // 合并单元格占位
+ // I-T列合并(年度)
+ { v: `${tableData.year}年度`, t: 's', s: mergedHeaderStyle },
+ ...Array(11).fill(null) // 合并单元格占位
+ ];
+
+ // 第四行:表头下半部分
+ const row4 = [
+ // A-F列留空(与row3合并)
+ ...Array(6).fill(null),
+ // G列:项目
+ { v: '项目', t: 's', s: subHeaderStyle },
+ // H列:频度
+ { v: '频度', t: 's', s: subHeaderStyle },
+ // I-T列:月份
+ { v: '一月', t: 's', s: subHeaderStyle },
+ { v: '二月', t: 's', s: subHeaderStyle },
+ { v: '三月', t: 's', s: subHeaderStyle },
+ { v: '四月', t: 's', s: subHeaderStyle },
+ { v: '五月', t: 's', s: subHeaderStyle },
+ { v: '六月', t: 's', s: subHeaderStyle },
+ { v: '七月', t: 's', s: subHeaderStyle },
+ { v: '八月', t: 's', s: subHeaderStyle },
+ { v: '九月', t: 's', s: subHeaderStyle },
+ { v: '十月', t: 's', s: subHeaderStyle },
+ { v: '十一月', t: 's', s: subHeaderStyle },
+ { v: '十二月', t: 's', s: subHeaderStyle }
+ ];
+
+ // 添加表头行
+ wsData.push(row3);
+ wsData.push(row4);
+
+ // 添加数据行
+ tableData.annualMaintenanceDeviceList.forEach((device, deviceIndex) => {
+ const rowBase = 4 + deviceIndex * 3; // 计算起始行号
+
+ // 获取三种类型的维护数据
+ const maintenanceTypes = device.annualMaintenanceDeviceTypeList || [];
+ const dailyData = maintenanceTypes.find(item => item.projectType === 1) || {};
+ const level1Data = maintenanceTypes.find(item => item.projectType === 2) || {};
+ const level2Data = maintenanceTypes.find(item => item.projectType === 3) || {};
+
+ // 主数据行(日常例行点检)
+ const mainRow = [
+ { v: deviceIndex + 1, t: 'n', s: dataStyle }, // A列:序号
+ { v: device.deviceName || '', t: 's', s: dataStyle }, // B列:设备名称
+ { v: device.model || '', t: 's', s: dataStyle }, // C列:型号
+ { v: device.factoryNumber || '', t: 's', s: dataStyle }, // D列:厂内编号
+ { v: device.purpose || '', t: 's', s: dataStyle }, // E列:用途
+ { v: device.deptName || '', t: 's', s: dataStyle }, // F列:使用部门
+ { v: '日常例行点检', t: 's', s: subDataStyle }, // G列
+ { v: getFrequencyText(dailyData.frequency), t: 's', s: subDataStyle }, // H列
+ // I-T列:月份数据(日常例行点检)
+ { v: dailyData.jan || '', t: 's', s: monthStyle },
+ { v: dailyData.feb || '', t: 's', s: monthStyle },
+ { v: dailyData.mar || '', t: 's', s: monthStyle },
+ { v: dailyData.apr || '', t: 's', s: monthStyle },
+ { v: dailyData.may || '', t: 's', s: monthStyle },
+ { v: dailyData.jun || '', t: 's', s: monthStyle },
+ { v: dailyData.jul || '', t: 's', s: monthStyle },
+ { v: dailyData.aug || '', t: 's', s: monthStyle },
+ { v: dailyData.sep || '', t: 's', s: monthStyle },
+ { v: dailyData.oct || '', t: 's', s: monthStyle },
+ { v: dailyData.nov || '', t: 's', s: monthStyle },
+ { v: dailyData.decm || '', t: 's', s: monthStyle }
+ ];
+
+ // 一级保养行
+ const subRow1 = [
+ ...Array(6).fill(null), // A-F列留空(与主行合并)
+ { v: '一级保养', t: 's', s: subDataStyle }, // G列
+ { v: getFrequencyText(level1Data.frequency), t: 's', s: subDataStyle }, // H列
+ // I-T列:月份数据(一级保养)
+ { v: level1Data.jan || '', t: 's', s: monthStyle },
+ { v: level1Data.feb || '', t: 's', s: monthStyle },
+ { v: level1Data.mar || '', t: 's', s: monthStyle },
+ { v: level1Data.apr || '', t: 's', s: monthStyle },
+ { v: level1Data.may || '', t: 's', s: monthStyle },
+ { v: level1Data.jun || '', t: 's', s: monthStyle },
+ { v: level1Data.jul || '', t: 's', s: monthStyle },
+ { v: level1Data.aug || '', t: 's', s: monthStyle },
+ { v: level1Data.sep || '', t: 's', s: monthStyle },
+ { v: level1Data.oct || '', t: 's', s: monthStyle },
+ { v: level1Data.nov || '', t: 's', s: monthStyle },
+ { v: level1Data.decm || '', t: 's', s: monthStyle }
+ ];
+ // 二级保养行
+ const subRow2 = [
+ ...Array(6).fill(null), // A-F列留空(与主行合并)
+ { v: '二级保养', t: 's', s: subDataStyle }, // G列
+ { v: getFrequencyText(level2Data.frequency), t: 's', s: subDataStyle }, // H列
+ // I-T列:月份数据(二级保养)
+ { v: level2Data.jan || '', t: 's', s: monthStyle },
+ { v: level2Data.feb || '', t: 's', s: monthStyle },
+ { v: level2Data.mar || '', t: 's', s: monthStyle },
+ { v: level2Data.apr || '', t: 's', s: monthStyle },
+ { v: level2Data.may || '', t: 's', s: monthStyle },
+ { v: level2Data.jun || '', t: 's', s: monthStyle },
+ { v: level2Data.jul || '', t: 's', s: monthStyle },
+ { v: level2Data.aug || '', t: 's', s: monthStyle },
+ { v: level2Data.sep || '', t: 's', s: monthStyle },
+ { v: level2Data.oct || '', t: 's', s: monthStyle },
+ { v: level2Data.nov || '', t: 's', s: monthStyle },
+ { v: level2Data.decm || '', t: 's', s: monthStyle }
+ ];
+ wsData.push(mainRow);
+ wsData.push(subRow1);
+ wsData.push(subRow2);
+ });
+ // 6. 说明行(合并A-T)
+ const noteRowIndex = wsData.length;
+ wsData.push([{
+ v: "说明:" + '\n' + "1、日常例行点检项目依设备日常点检表项目进行。" + '\n' + "2、一级保养:以操作工为主,维修工辅导,按计划对设备进行检查,清洗规定部位,疏通油管,更换和清洗油管、油毡、滤油器。调整设备各配合间隙,紧固设备各固定螺,对传动件进行润滑加油。频度为每季度/次。" + '\n' + "3、二级保养:以维修工为主,对设备进行部分解体检查修理。更换或修复磨损件、清洗、换油,检查修理电器部分。频度为半年/次。" + '\n' + "4、以上计划为设备在正常使用状态进行的计划,如设备处于暂停使用时不需做相关保养。",
+ t: 's',
+ s: noteStyle
+ }]);
+ // 7. 核准/审核/做成标题行
+ const approvalTitleRow = Array(20).fill({ v: '', t: 's', s: dataStyle });
+ approvalTitleRow[0] = { v: '核准', t: 's', s: footerHeaderStyle };
+ approvalTitleRow[7] = { v: '审核', t: 's', s: footerHeaderStyle };
+ approvalTitleRow[14] = { v: '做成', t: 's', s: footerHeaderStyle };
+ wsData.push(approvalTitleRow);
+ // 8. 人员信息行
+ const approvalDataRow = Array(20).fill({ v: '', t: 's', s: dataStyle });
+ approvalDataRow[0] = { v: tableData.approvalName || '', t: 's', s: footerDataStyle };
+ approvalDataRow[7] = { v: tableData.processName || '', t: 's', s: footerDataStyle };
+ approvalDataRow[14] = { v: tableData.finishName || '', t: 's', s: footerDataStyle };
+ wsData.push(approvalDataRow);
+ // 9. 表单编号行
+ const lastRow = wsData.length;
+ const noteText = "表单编号:" + tableData.number;
+ wsData.push([{
+ v: noteText,
+ t: 's',
+ s: {
+ font: { sz: 11 },
+ alignment: { horizontal: 'right', vertical: 'center', wrapText: true },
+
+ }
+ }]);
+
+ const ws = utils.aoa_to_sheet(wsData);
+
+ // 设置合并单元格
+
+ const merges = [
+ // 第一行合并(A1-T1)
+ { s: { r: 0, c: 0 }, e: { r: 0, c: 19 } },
+ // 第二行合并(A2-T2)
+ { s: { r: 1, c: 0 }, e: { r: 1, c: 19 } },
+
+ // A-F列在第三行和第四行合并
+ ...Array.from({ length: 6 }, (_, c) => ({
+ s: { r: 2, c }, e: { r: 3, c }
+ })),
+
+ // 第三行的维修保养合并(G3-H3)
+ { s: { r: 2, c: 6 }, e: { r: 2, c: 7 } },
+ // 第三行的年度合并(I3-T3)
+ { s: { r: 2, c: 8 }, e: { r: 2, c: 19 } },
+ // 说明行合并
+ { s: { r: noteRowIndex, c: 0 }, e: { r: noteRowIndex, c: 19 } },
+
+ // 核准/审核/做成标题合并
+ { s: { r: noteRowIndex + 1, c: 0 }, e: { r: noteRowIndex + 1, c: 6 } },
+ { s: { r: noteRowIndex + 1, c: 7 }, e: { r: noteRowIndex + 1, c: 13 } },
+ { s: { r: noteRowIndex + 1, c: 14 }, e: { r: noteRowIndex + 1, c: 19 } },
+
+ // 人员信息合并
+ { s: { r: noteRowIndex + 2, c: 0 }, e: { r: noteRowIndex + 2, c: 6 } },
+ { s: { r: noteRowIndex + 2, c: 7 }, e: { r: noteRowIndex + 2, c: 13 } },
+ { s: { r: noteRowIndex + 2, c: 14 }, e: { r: noteRowIndex + 2, c: 19 } },
+
+ { s: { r: lastRow, c: 0 }, e: { r: lastRow, c: 19 } }
+ ];
+
+ // 添加每个设备的三行合并
+ tableData.annualMaintenanceDeviceList.forEach((_, index) => {
+ const rowBase = 4 + index * 3;
+ // A-F列在三行中合并
+ for (let c = 0; c < 6; c++) {
+ merges.push({ s: { r: rowBase, c }, e: { r: rowBase + 2, c } });
+ }
+ });
+
+ ws['!merges'] = merges;
+
+ merges.forEach(merge => {
+ const { s, e } = merge; // 合并区域的起止位置
+ // 设置合并区域四个边的边框
+ for (let r = s.r; r <= e.r; r++) {
+ for (let c = s.c; c <= e.c; c++) {
+ const cellRef = utils.encode_cell({ r, c });
+ // 保留原有样式,只覆盖边框
+ ws[cellRef] = ws[cellRef] || { t: 's', v: '' };
+ ws[cellRef].s = {
+ ...(ws[cellRef].s || {}),
+ border: {
+ top: { style: 'thin', color: { rgb: '000000' } },
+ left: { style: 'thin', color: { rgb: '000000' } },
+ bottom: { style: 'thin', color: { rgb: '000000' } },
+ right: { style: 'thin', color: { rgb: '000000' } }
+ }
+ };
+ }
+ }
+ });
+
+ const totalRows = wsData.length;
+ if (!ws['!rows']) {
+ ws['!rows'] = Array(totalRows).fill(null);
+ }
+ ws['!rows'][noteRowIndex] = { hpx: 100 };
+ // 设置列宽
+ ws['!cols'] = [
+ { wch: 8 }, { wch: 15 }, { wch: 12 }, { wch: 12 },
+ { wch: 12 }, { wch: 12 }, { wch: 12 }, { wch: 10 },
+ ...Array(12).fill({ wch: 8 })
+ ];
+
+ // 添加工作表到工作簿
+ utils.book_append_sheet(wb, ws, '维护计划');
+
+ // 导出Excel文件
+ writeFile(wb, `${tableData.companyName}${tableData.year}年度基础设施维护计划.xlsx`);
+
+
+ }else{
+ ElMessage.warning('暂无数据')
+ }
+ }else{
+ ElMessage.warning(res.message)
+ }
+}
+
+// 频度文本转换
+function getFrequencyText(frequency) {
+ switch(frequency) {
+ case 1: return '工作日';
+ case 2: return '1次/3月';
+ case 3: return '1次/6月';
+ default: return '';
+ }
+}
+
+// 样式定义
+const headerStyle = {
+ font: { bold: true, color: { rgb: 'FFFFFF' } },
+ fill: { fgColor: { rgb: '4472C4' } },
+ alignment: { horizontal: 'center', vertical: 'center' },
+ border: {
+ top: { style: 'thin', color: { rgb: '000000' } },
+ bottom: { style: 'thin', color: { rgb: '000000' } },
+ left: { style: 'thin', color: { rgb: '000000' } },
+ right: { style: 'thin', color: { rgb: '000000' } }
+ }
+};
+
+const mergedHeaderStyle = {
+ ...headerStyle,
+ fill: { fgColor: { rgb: '70AD47' } }
+};
+
+const subHeaderStyle = {
+ font: { bold: true },
+ fill: { fgColor: { rgb: 'B4C6E7' } },
+ alignment: { horizontal: 'center', vertical: 'center' },
+ border: headerStyle.border
+};
+
+const dataStyle = {
+ alignment: { horizontal: 'center', vertical: 'center' },
+ border: headerStyle.border
+};
+
+const subDataStyle = {
+ font: { bold: true },
+ fill: { fgColor: { rgb: 'E2EFDA' } },
+ alignment: { horizontal: 'center', vertical: 'center' },
+ border: headerStyle.border
+};
+
+const monthStyle = {
+ alignment: { horizontal: 'center', vertical: 'center' },
+ border: headerStyle.border
+};
+
+const noteStyle = {
+ font: { italic: true, sz: 11 },
+ alignment: { horizontal: 'left', vertical: 'center', wrapText: true },
+ border: {
+ top: { style: 'thin', color: { rgb: '000000' } },
+ bottom: { style: 'thin', color: { rgb: '000000' } }
+ }
+};
+
+const footerHeaderStyle = {
+ ...headerStyle,
+ fill: { fgColor: { rgb: 'D9D9D9' } },
+ font: { bold: true, color: { rgb: '000000' } }
+};
+
+const footerDataStyle = {
+ ...dataStyle,
+ font: { bold: true },
+ alignment: { horizontal: 'center' }
+};
+
+
+const openDialog = (type, value) => {
+ dialogRef.value.openDialog(type, value, data.queryParams.companyId, data.isAdmin, data.companyList);
+}
+
+/** 重置新增的表单以及其他数据 */
+const reset= async()=> {
+ data.queryParams = {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null
+ }
+ await getCompanyList()
+ await getList()
+}
+const handleDelete = (val) => {
+ ElMessageBox.confirm(
+ '确定删除此条数据?',
+ '提示',
+ {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning',
+ })
+ .then( async() => {
+ const res = await delMaintenancePlan({id: val.id})
+ if(res.code == 200){
+ ElMessage.success('数据删除成功')
+ await getList()
+ }else{
+ ElMessage.warning(res.message)
+ }
+ })
+}
+
+</script>
diff --git a/src/views/work/qualityInfo/infrastructureMng/maintainRecord/components/editDialog.vue b/src/views/work/qualityInfo/infrastructureMng/maintainRecord/components/editDialog.vue
new file mode 100644
index 0000000..a5e1985
--- /dev/null
+++ b/src/views/work/qualityInfo/infrastructureMng/maintainRecord/components/editDialog.vue
@@ -0,0 +1,553 @@
+<template>
+ <div class="notice">
+ <el-dialog
+ v-model="dialogVisible"
+ :title="state.title"
+ width="75%"
+ :before-close="handleClose"
+ :close-on-press-escape="false"
+ :close-on-click-modal="false"
+ >
+ <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px">
+ <el-form-item v-if="state.isAdmin" label="企业:" prop="companyId">
+ <el-select v-model="state.form.companyId" placeholder="请选择" :disabled="state.title =='查看'" clearable @change="getDeptList">
+ <el-option
+ v-for="item in state.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ <el-row>
+ <el-col :span="8">
+ <el-form-item label="设备名称:" prop="deviceName">
+ <el-input v-model.trim="state.form.deviceName" :disabled="state.title =='查看'"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="设备编号:" prop="deviceNumber">
+ <el-input v-model.trim="state.form.deviceNumber" :disabled="state.title =='查看'"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="表单编号:" prop="number">
+ <el-input v-model.trim="state.form.number" :disabled="state.title =='查看'"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <el-table :data="state.maintainList" :border="true" class="customedTable" :span-method="objectSpanMethod" style="margin-bottom: 30px">
+ <el-table-column label="保养内容" align="center" width="100">
+ <template #default="scope">
+ 保养内容
+ </template>
+ </el-table-column>
+ <el-table-column label="标准" prop="standard" align="center">
+ <template #default="scope">
+ <p style="margin: 0;text-align: left">{{scope.row.standard}}</p>
+ </template>
+ </el-table-column>
+ <el-table-column label="保养等级" prop="level" align="center"/>
+ <el-table-column label="结论" prop="conclusion" align="center">
+ <template #default="scope">
+ <el-input
+ v-model.trim="scope.row.conclusion"
+ size="large"
+ type="textarea"
+ style="width: 100%"
+ :readonly="state.title =='查看'"
+ >
+ </el-input>
+ </template>
+ </el-table-column>
+ <el-table-column label="整改措施" prop="rectificationMeasures" align="center">
+ <template #default="scope">
+ <el-input
+ v-model.trim="scope.row.rectificationMeasures"
+ size="large"
+ type="textarea"
+ style="width: 100%"
+ :readonly="state.title =='查看'"
+ >
+ </el-input>
+ </template>
+ </el-table-column>
+ </el-table>
+ <el-form-item label="设备保养验收结论:" prop="conclusion">
+ <el-input v-model.trim="state.form.conclusion" type="textarea" :autosize="{ minRows: 2 }" :readonly="state.title =='查看'"></el-input>
+ </el-form-item>
+ 一级保养
+ <el-row>
+ <el-col :span="6">
+ <el-form-item label="操作工:" prop="operatorsOne">
+ <el-select clearable v-model="state.form.operatorsOne" :disabled="state.title =='查看'" value-key="userId" filterable multiple placeholder="操作工" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.userId"
+ :label="item.name"
+ :value="item"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="6">
+ <el-form-item label="日期:" prop="operateDateOne">
+ <el-date-picker
+ v-model="state.form.operateDateOne"
+ type="date"
+ value-format="YYYY-MM-DD"
+ placeholder="请选择日期"
+ :disabled="state.title =='查看'"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="6">
+ <el-form-item label="检查:" prop="checkersOne">
+ <el-select clearable v-model="state.form.checkersOne" :disabled="state.title =='查看'" value-key="userId" filterable multiple placeholder="检查" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.userId"
+ :label="item.name"
+ :value="item"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="6">
+ <el-form-item label="日期:" prop="checkDateOne">
+ <el-date-picker
+ v-model="state.form.checkDateOne"
+ type="date"
+ value-format="YYYY-MM-DD"
+ placeholder="请选择日期"
+ :disabled="state.title =='查看'"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ 二级保养
+ <el-row>
+ <el-col :span="6">
+ <el-form-item label="操作工:" prop="operatorsTwo">
+ <el-select clearable v-model="state.form.operatorsTwo" :disabled="state.title =='查看'" value-key="userId" filterable multiple placeholder="操作工" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.userId"
+ :label="item.name"
+ :value="item"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="6">
+ <el-form-item label="日期:" prop="operateDateTwo">
+ <el-date-picker
+ v-model="state.form.operateDateTwo"
+ type="date"
+ value-format="YYYY-MM-DD"
+ placeholder="请选择日期"
+ :disabled="state.title =='查看'"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="6">
+ <el-form-item label="检查:" prop="checkersTwo">
+ <el-select clearable v-model="state.form.checkersTwo" :disabled="state.title =='查看'" value-key="userId" filterable multiple placeholder="检查" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.userId"
+ :label="item.name"
+ :value="item"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="6">
+ <el-form-item label="日期:" prop="checkDateTwo">
+ <el-date-picker
+ v-model="state.form.checkDateTwo"
+ type="date"
+ value-format="YYYY-MM-DD"
+ placeholder="请选择日期"
+ :disabled="state.title =='查看'"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ </el-form>
+ <template #footer v-if="state.title !='查看'">
+ <span class="dialog-footer">
+ <el-button @click="handleClose" size="default">取 消</el-button>
+ <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+<script setup>
+import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue'
+import {ElMessage} from "element-plus";
+import {Base64} from "js-base64"
+import {getToken} from "@/utils/auth";
+import {
+ addInternalAuditCheck, getInternalAuditCheckInfo,
+ updateInternalAuditCheck
+} from "@/api/innerReview/meetingReview";
+import {getDepart} from "@/api/orgStructure/depart";
+import {listUser} from "@/api/system/user";
+import {getMaintenanceServiceDetail, updateMaintenanceService} from "@/api/infrastructureMng/ledger";
+
+const emit = defineEmits(["getList"]);
+const dialogVisible = ref(false)
+const superRef = ref()
+const checkFiles = (rule, value, callback) => {
+ if (state.fileList.length == 0) {
+ callback(new Error('请上传文件'))
+ } else {
+ callback()
+ }
+}
+const state = reactive({
+ title: '',
+ form: {
+ id: null,
+ companyId: null,
+ deviceName: '',
+ deviceNumber: '',
+ number: '',
+ annualMaintenanceServiceContentList: [],
+ annualMaintenanceServiceUserList: [],
+ conclusion: '',
+ operatorsOne: [],
+ operateDateOne: '',
+ checkersOne: [],
+ checkDateOne: '',
+ operatorsTwo: [],
+ operateDateTwo: '',
+ checkersTwo: [],
+ checkDateTwo: '',
+ delServiceUserIds: []
+ },
+ oldServiceUsers: [],
+ maintainList: [
+ {
+ id: null,
+ serviceType: 1,
+ standard: '1、设备内外清洁,无黄油、油垢、锈蚀,油质符合要求。',
+ level: '一、二级',
+ conclusion: '',
+ rectificationMeasures: ''
+ },{
+ id: null,
+ serviceType: 2,
+ standard: '2、根据设备情况、进行部分零件拆解、清洗、修复。对各紧固零件进行检查、修复,各部配合间隙进行适当调整。',
+ level: '一、二级',
+ conclusion: '',
+ rectificationMeasures: ''
+ },{
+ id: null,
+ serviceType: 3,
+ standard: '3、清洗毛毡、油线、滤油器;清理油路、管道、加足润滑油和润滑脂,补齐各种缺欠,保持无黄袍。',
+ level: '一、二级',
+ conclusion: '',
+ rectificationMeasures: ''
+ },{
+ id: null,
+ serviceType: 4,
+ standard: '4、对设备所有二操纵机构,各种挡铁、限位开关调修至灵敏可靠,将各种防尘、防屑、装置清洗修复至完整好用。',
+ level: '一、二级',
+ conclusion: '',
+ rectificationMeasures: ''
+ },{
+ id: null,
+ serviceType: 5,
+ standard: '5、各润滑部位进行全部清洗,结合换油周期进行换油,油质油量符合要求。',
+ level: '二级',
+ conclusion: '',
+ rectificationMeasures: ''
+ },{
+ id: null,
+ serviceType: 6,
+ standard: '6、检查设备的技术状况,调整安装水平,根据设备的使用情况进行全部或部分解体检查、清洗,调整各部分的配合精度。',
+ level: '二级',
+ conclusion: '',
+ rectificationMeasures: ''
+ },{
+ id: null,
+ serviceType: 7,
+ standard: '7、修复或更换磨损部件、零件,并为下一次二保或大修做好备件资料准备。',
+ level: '二级',
+ conclusion: '',
+ rectificationMeasures: ''
+ },{
+ id: null,
+ serviceType: 8,
+ standard: '8、零部件完整,随机附件基本齐全并保管好。',
+ level: '二级',
+ conclusion: '',
+ rectificationMeasures: ''
+ }
+ ],
+ formRules:{
+ companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }],
+ deviceName: [{ required: true, message: '请填写设备名称', trigger: 'blur' }],
+ deviceNumber: [{ required: true, message: '请填写设备编号', trigger: 'blur' }],
+ number: [{ required: true, message: '请填写表单编号', trigger: 'blur' }]
+ },
+ isAdmin: false,
+ companyList: [],
+ userList: []
+})
+onMounted(() => {
+
+});
+
+const openDialog = async (type, value,companyId, isAdmin, companyList) => {
+ state.isAdmin = isAdmin
+ if(isAdmin){
+ state.companyList = companyList
+ }
+ await getUserList(companyId)
+ state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看'
+ state.form.companyId = companyId
+ if(state.title == '编辑'||state.title == '查看'){
+ await getInfo(value.id)
+ }
+ dialogVisible.value = true
+}
+
+const objectSpanMethod = ({row, column, rowIndex, columnIndex,}) => {
+ if (columnIndex === 0) {
+ if (rowIndex === 0) {
+ return {
+ rowspan: state.maintainList.length,
+ colspan: 1
+ }
+ } else {
+ return {
+ rowspan: 0,
+ colspan: 0
+ }
+ }
+ }
+}
+
+const onSubmit = async () => {
+ const valid = await superRef.value.validate();
+ if(valid){
+ const data = JSON.parse(JSON.stringify(state.form))
+ data.operatorsOne = data.operatorsOne.map(i=>{
+ return {
+ id: i.id || null,
+ annualMaintenanceServiceId: i.annualMaintenanceServiceId || null,
+ userId: i.userId,
+ userName: i.name,
+ userType: 1,
+ checkDate: data.operateDateOne
+ }
+ })
+ data.checkersOne = data.checkersOne.map(i=>{
+ return {
+ id: i.id || null,
+ annualMaintenanceServiceId: i.annualMaintenanceServiceId || null,
+ userId: i.userId,
+ userName: i.name,
+ userType: 2,
+ checkDate: data.checkDateOne
+ }
+ })
+ data.operatorsTwo = data.operatorsTwo.map(i=>{
+ return {
+ id: i.id || null,
+ annualMaintenanceServiceId: i.annualMaintenanceServiceId || null,
+ userId: i.userId,
+ userName: i.name,
+ userType: 3,
+ checkDate: data.operateDateTwo
+ }
+ })
+ data.checkersTwo = data.checkersTwo.map(i=>{
+ return {
+ id: i.id || null,
+ annualMaintenanceServiceId: i.annualMaintenanceServiceId || null,
+ userId: i.userId,
+ userName: i.name,
+ userType: 4,
+ checkDate: data.checkDateTwo
+ }
+ })
+ data.annualMaintenanceServiceUserList = [...data.operatorsOne,...data.checkersOne,...data.operatorsTwo,...data.checkersTwo]
+ data.delServiceUserIds = state.oldServiceUsers.filter(i =>!data.annualMaintenanceServiceUserList.some(item=>item.id == i.id)).map(i=>i.id)
+ data.annualMaintenanceServiceContentList = state.maintainList.map(item=>{
+ return {
+ id: item.id,
+ serviceType: item.serviceType,
+ conclusion: item.conclusion,
+ rectificationMeasures: item.rectificationMeasures
+ }
+ })
+ delete data.operatorsOne
+ delete data.checkersOne
+ delete data.operatorsTwo
+ delete data.checkersTwo
+ delete data.operateDateOne
+ delete data.checkDateOne
+ delete data.operateDateTwo
+ delete data.checkDateTwo
+ if(state.title == '新增'){
+ delete data.id
+ const res = await updateMaintenanceService(data)
+ if(res.code == 200){
+ ElMessage.success(res.message)
+ emit('getList')
+ handleClose()
+ dialogVisible.value = false;
+ }else{
+ ElMessage.warning(res.message)
+ }
+ }else{
+ const res = await updateMaintenanceService(data)
+ if(res.code == 200){
+ ElMessage.success(res.message)
+ emit('getList')
+ handleClose()
+ dialogVisible.value = false;
+ }else{
+ ElMessage.warning(res.message)
+ }
+ }
+ }
+}
+
+const getInfo = async (id)=> {
+ const res = await getMaintenanceServiceDetail({id: id})
+ if(res.code == 200){
+ Object.keys(state.form).forEach(key => {
+ if (key in res.data) {
+ state.form[key] = res.data[key]
+ }
+ })
+ state.oldServiceUsers = state.form.annualMaintenanceServiceUserList?.map(item=>{
+ return {
+ id: item.id,
+ annualMaintenanceServiceId: item.annualMaintenanceServiceId,
+ userId: item.userId,
+ name: item.userName,
+ userType: item.userType,
+ checkDate: item.checkDate.substring(0,10)
+ }
+ })
+ state.form.operatorsOne = state.oldServiceUsers.filter(i=>i.userType == 1)
+ state.form.checkersOne = state.oldServiceUsers.filter(i=>i.userType == 2)
+ state.form.operatorsTwo = state.oldServiceUsers.filter(i=>i.userType == 3)
+ state.form.checkersTwo = state.oldServiceUsers.filter(i=>i.userType == 4)
+ state.form.operateDateOne = state.form.operatorsOne[0].checkDate || ''
+ state.form.checkDateOne = state.form.checkersOne[0].checkDate || ''
+ state.form.operateDateTwo = state.form.operatorsTwo[0].checkDate || ''
+ state.form.checkDateTwo = state.form.checkersTwo[0].checkDate || ''
+ state.maintainList = state.maintainList.map(item=>{
+ return {
+ id: state.form.annualMaintenanceServiceContentList.find(i=>i.serviceType == item.serviceType)?.id,
+ serviceType: item.serviceType,
+ standard: item.standard,
+ level: item.level,
+ conclusion: state.form.annualMaintenanceServiceContentList.find(i=>i.serviceType == item.serviceType)?.conclusion,
+ rectificationMeasures: state.form.annualMaintenanceServiceContentList.find(i=>i.serviceType == item.serviceType)?.rectificationMeasures,
+ }
+ })
+ }else{
+ ElMessage.warning(res.message)
+ }
+}
+
+const getDeptList = async ()=>{
+ state.form.operatorsOne = []
+ state.form.checkersOne = []
+ state.form.operatorsTwo = []
+ state.form.checkersTwo = []
+ await getUserList(state.form.companyId)
+}
+
+
+const getUserList = async (companyId)=> {
+ const res = await listUser({pageIndex: 1,pageSize: 999,companyId: companyId})
+ if(res.code == 200){
+ state.userList = res.data.list?res.data.list.map(item=>{
+ const user = item.id
+ const {id, ...data} = item
+ return {
+ ...data,
+ userId: user
+ }
+ }):[]
+ }else{
+ ElMessage.warning(res.message)
+ }
+}
+
+const handleClose = () => {
+ state.form = {
+ id: null,
+ companyId: null,
+ deviceName: '',
+ deviceNumber: '',
+ number: '',
+ annualMaintenanceServiceContentList: [],
+ annualMaintenanceServiceUserList: [],
+ conclusion: '',
+ operatorsOne: [],
+ operateDateOne: '',
+ checkersOne: [],
+ checkDateOne: '',
+ operatorsTwo: [],
+ operateDateTwo: '',
+ checkersTwo: [],
+ checkDateTwo: '',
+ delServiceUserIds: []
+ }
+ state.maintainList = state.maintainList.map(i=>{
+ return {
+ serviceType: i.serviceType,
+ standard: i.standard,
+ level: i.level,
+ conclusion: '',
+ rectificationMeasures: ''
+ }
+ })
+ superRef.value.clearValidate();
+ superRef.value.resetFields()
+ dialogVisible.value = false;
+}
+
+defineExpose({
+ openDialog
+});
+
+</script>
+
+<style scoped lang="scss">
+.notice{
+ :deep(.el-form .el-form-item__label) {
+ font-size: 15px;
+ }
+ .file {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ }
+}
+</style>
+<style lang="scss">
+.customedTable{
+ .el-table__cell{
+ padding: 2px 0 !important;
+ font-size: 14px !important;
+ }
+ .cell{
+ padding: 0 2px !important;
+ font-size: 14px !important;
+ }
+}
+</style>
diff --git a/src/views/work/qualityInfo/infrastructureMng/maintainRecord/index.vue b/src/views/work/qualityInfo/infrastructureMng/maintainRecord/index.vue
new file mode 100644
index 0000000..6d70635
--- /dev/null
+++ b/src/views/work/qualityInfo/infrastructureMng/maintainRecord/index.vue
@@ -0,0 +1,234 @@
+<template>
+ <div class="app-container">
+ <div style="display: flex;justify-content: space-between">
+ <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" >
+ <el-form-item>
+ <el-button
+ type="primary"
+ plain
+ icon="Plus"
+ @click="openDialog('add',{})"
+ >新增</el-button>
+ </el-form-item>
+ <el-form-item v-if="isAdmin" label="企业:" >
+ <el-select v-model="data.queryParams.companyId" placeholder="请选择" clearable>
+ <el-option
+ v-for="item in companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item >
+ <el-button v-if="isAdmin" type="primary" @click="getList">查询</el-button>
+ <el-button v-if="isAdmin" type="primary" plain @click="reset">重置</el-button>
+<!-- <el-button type="primary">导出</el-button>-->
+ </el-form-item>
+ </el-form>
+ </div>
+ <!-- 表格数据 -->
+ <el-table v-loading="loading" :data="dataList" :border="true">
+ <el-table-column type="index" label="序号"></el-table-column>
+ <el-table-column prop="deviceName" align="center" label="设备名称"></el-table-column>
+ <el-table-column prop="deviceNumber" align="center" label="设备编号"></el-table-column>
+ <el-table-column label="操作" align="center">
+ <template #default="scope">
+ <el-button link type="primary" @click="openDialog('view',scope.row)">查看</el-button>
+ <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button>
+ <el-button link type="primary" @click="downloadFile(scope.row)">导出</el-button>
+ <el-button link type="danger" @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"
+ />
+
+ <edit-dialog ref="dialogRef" @getList=getList></edit-dialog>
+ </div>
+</template>
+
+<script setup>
+import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
+import {ElMessage, ElMessageBox} from "element-plus";
+import {delCompany, getCompany} from "@/api/onlineEducation/company";
+import Cookies from "js-cookie";
+import editDialog from './components/editDialog.vue'
+import useUserStore from "@/store/modules/user";
+import {getStandardTemp,delStandardTemp} from "@/api/standardSys/standardSys";
+import { renderAsync } from "docx-preview";
+import {
+ delInternalAuditCheck,
+ delMeetingsList,
+ getInternalAuditCheck, getInternalAuditCheckInfo,
+ getMeetingsList
+} from "@/api/innerReview/meetingReview";
+import {generateWordDocument} from "@/utils/exportWord";
+import {
+ delMaintenanceService,
+ getMaintenanceRecordDetail, getMaintenanceServiceDetail,
+ getMaintenanceServiceList
+} from "@/api/infrastructureMng/ledger";
+
+
+const userStore = useUserStore()
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const dialogRef = ref();
+const data = reactive({
+ queryParams: {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null
+ },
+ total: 0,
+ dataList: [],
+ companyList: [],
+ isAdmin: false
+});
+
+const { queryParams, total, dataList,companyList, isAdmin } = toRefs(data);
+const userInfo = ref()
+onMounted(async ()=>{
+ if(userStore.roles.includes('admin')){
+ data.isAdmin = true
+ await getCompanyList()
+ }else{
+ data.isAdmin = false
+ data.queryParams.companyId = userStore.companyId
+ }
+ await getList()
+})
+
+onUnmounted(()=>{
+
+})
+
+const getList = async () => {
+ loading.value = true
+ const res = await getMaintenanceServiceList(data.queryParams)
+ if(res.code == 200){
+ data.dataList = res.data.list || []
+ data.total = res.data.total
+ }else{
+ ElMessage.warning(res.message)
+ }
+ loading.value = false
+}
+
+const getCompanyList = async ()=>{
+ const queryParams = {
+ pageNum: 1,
+ pageSize: 999
+ }
+ const res = await getCompany(queryParams)
+ if (res.code == 200) {
+ data.companyList = res.data.list?res.data.list:[]
+ // data.queryParams.companyId = data.companyList[0].id
+ } else {
+ ElMessage.warning(res.message)
+ }
+}
+
+const downloadFile = async (val)=>{
+ const res = await getMaintenanceServiceDetail({id: val.id})
+ if(res.code == 200){
+ if(res.data){
+ let tableData = res.data
+ if(Array.isArray(tableData.annualMaintenanceServiceUserList) && tableData.annualMaintenanceServiceUserList.length>0){
+ const serviceUsers = tableData.annualMaintenanceServiceUserList?.map(item=>{
+ return {
+ ...item,
+ checkDate: item.checkDate.substring(0,10)
+ }
+ })
+ tableData.operatorsOneNames = serviceUsers.filter(i=>i.userType == 1).map(i=>i.userName).join(',')
+ tableData.checkersOneNames = serviceUsers.filter(i=>i.userType == 2).map(i=>i.userName).join(',')
+ tableData.operatorsTwoNames = serviceUsers.filter(i=>i.userType == 3).map(i=>i.userName).join(',')
+ tableData.checkersTwoNames = serviceUsers.filter(i=>i.userType == 4).map(i=>i.userName).join(',')
+ tableData.operateDateOne = serviceUsers.find(i=>i.userType == 1).checkDate || ''
+ tableData.checkDateOne = serviceUsers.find(i=>i.userType == 2).checkDate || ''
+ tableData.operateDateTwo = serviceUsers.find(i=>i.userType == 3).checkDate || ''
+ tableData.checkDateTwo = serviceUsers.find(i=>i.userType == 4).checkDate || ''
+ }else{
+ tableData.operatorsOneNames = ''
+ tableData.checkersOneNames = ''
+ tableData.operatorsTwoNames = ''
+ tableData.checkersTwoNames = ''
+ tableData.operateDateOne = ''
+ tableData.checkDateOne = ''
+ tableData.operateDateTwo = ''
+ tableData.checkDateTwo = ''
+ }
+ if(data.isAdmin){
+ tableData.companyName = data.companyList.find(i=>i.id == val.companyId)?.name
+ }else{
+ tableData.companyName = userStore.companyName
+ }
+ for(let i = 0; i < 8; i++){
+ const num = Number(i) + 1
+ if(tableData.annualMaintenanceServiceContentList.find(i=>i.serviceType == num)){
+ tableData['col' + num] = tableData.annualMaintenanceServiceContentList.find(i=>i.serviceType == num).conclusion
+ tableData['act' + num] = tableData.annualMaintenanceServiceContentList.find(i=>i.serviceType == num).rectificationMeasures
+ }else{
+ tableData['col' + num] = ''
+ tableData['act' + num] = ''
+ }
+ }
+ try {
+ generateWordDocument('/maintainRecord.docx', tableData, tableData.companyName + '保养记录表.docx');
+ } catch (error){
+ ElMessage({
+ type: 'warning',
+ message: '导出失败'
+ });
+ }
+ }else{
+ ElMessage.warning('暂无数据')
+ }
+ }else{
+ ElMessage.warning(res.message)
+ }
+}
+
+const openDialog = (type, value) => {
+ dialogRef.value.openDialog(type, value, data.queryParams.companyId, data.isAdmin, data.companyList);
+}
+
+/** 重置新增的表单以及其他数据 */
+const reset= async()=> {
+ data.queryParams = {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null
+ }
+ await getCompanyList()
+ await getList()
+}
+const handleDelete = (val) => {
+ ElMessageBox.confirm(
+ '确定删除此条数据?',
+ '提示',
+ {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning',
+ })
+ .then( async() => {
+ const res = await delMaintenanceService({id: val.id})
+ if(res.code == 200){
+ ElMessage.success('数据删除成功')
+ await getList()
+ }else{
+ ElMessage.warning(res.message)
+ }
+ })
+}
+
+</script>
diff --git a/src/views/work/qualityInfo/infrastructureMng/repairRecord/components/editDialog.vue b/src/views/work/qualityInfo/infrastructureMng/repairRecord/components/editDialog.vue
new file mode 100644
index 0000000..b1ce2ca
--- /dev/null
+++ b/src/views/work/qualityInfo/infrastructureMng/repairRecord/components/editDialog.vue
@@ -0,0 +1,463 @@
+<template>
+ <div class="notice">
+ <el-dialog
+ v-model="dialogVisible"
+ :title="state.title"
+ width="50%"
+ :before-close="handleClose"
+ :close-on-press-escape="false"
+ :close-on-click-modal="false"
+ >
+ <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px" >
+ <el-form-item v-if="state.isAdmin" label="企业:" prop="companyId">
+ <el-select v-model="state.form.companyId" placeholder="请选择" :disabled="state.title =='查看'" clearable @change="getDeptList">
+ <el-option
+ v-for="item in state.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ <el-row>
+ <el-col :span="8">
+ <el-form-item label="设备名称:" prop="deviceName">
+ <el-input v-model.trim="state.form.deviceName" :disabled="state.title =='查看'"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="设备编号:" prop="number">
+ <el-input v-model.trim="state.form.number" :disabled="state.title =='查看'"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="表单编号:" prop="formNumber">
+ <el-input v-model.trim="state.form.formNumber" :disabled="state.title =='查看'"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row>
+ <el-col :span="12">
+ <el-form-item label="故障发生日期:" prop="faultDate">
+ <el-date-picker
+ v-model="state.form.faultDate"
+ type="date"
+ value-format="YYYY-MM-DD"
+ placeholder="请选择故障发生日期"
+ :disabled="state.title =='查看'"
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="要求维修日期:" prop="repairDate">
+ <el-date-picker
+ v-model="state.form.repairDate"
+ type="date"
+ value-format="YYYY-MM-DD"
+ placeholder="请选择要求维修日期"
+ :disabled="state.title =='查看'"
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-form-item label="故障现象:" prop="failurePhenomenon">
+ <el-input v-model.trim="state.form.failurePhenomenon" type="textarea" :autosize="{ minRows: 2 }" :readonly="state.title =='查看'"></el-input>
+ </el-form-item>
+ <el-row>
+ <el-col :span="12">
+ <el-form-item label="设施操作/管理员:" prop="maintainUsers">
+ <el-select clearable v-model="state.form.maintainUsers" :disabled="state.title =='查看'" value-key="userId" filterable multiple placeholder="设施操作/管理员" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.userId"
+ :label="item.name"
+ :value="item"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="主管:" prop="managerId">
+ <el-select clearable v-model="state.form.managerId" :disabled="state.title =='查看'" filterable placeholder="主管" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.userId"
+ :label="item.name"
+ :value="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-form-item label="故障原因及排除方法:" prop="faultCause">
+ <el-input v-model.trim="state.form.faultCause" type="textarea" :autosize="{ minRows: 2 }" :readonly="state.title =='查看'"></el-input>
+ </el-form-item>
+ <el-row>
+ <el-col :span="12">
+ <el-form-item label="维修方式:" prop="maintenanceMethod">
+ <el-radio-group v-model="state.form.maintenanceMethod" :disabled="state.title =='查看'">
+ <el-radio :label="1">内部维修</el-radio>
+ <el-radio :label="2">委外维修</el-radio>
+ </el-radio-group>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="委外地点:" prop="outsourcingLocation">
+ <el-input v-model.trim="state.form.outsourcingLocation" :disabled="state.title =='查看'"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row>
+ <el-col :span="12">
+ <el-form-item label="维修工时:" prop="repairTime">
+ <el-input v-model.trim="state.form.repairTime" :disabled="state.title =='查看'"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="停机时间:" prop="downTime">
+ <el-date-picker
+ v-model="state.form.downTime"
+ type="date"
+ value-format="YYYY-MM-DD"
+ placeholder="请选择停机时间"
+ :disabled="state.title =='查看'"
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row>
+ <el-col :span="12">
+ <el-form-item label="更换材料:" prop="replaceMaterials">
+ <el-input v-model.trim="state.form.replaceMaterials" :disabled="state.title =='查看'"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="金额(元):" prop="money">
+ <el-input v-model.trim="state.form.money" :disabled="state.title =='查看'"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row>
+ <el-col :span="12">
+ <el-form-item label="维修员:" prop="repairUsers">
+ <el-select clearable v-model="state.form.repairUsers" :disabled="state.title =='查看'" value-key="userId" filterable multiple placeholder="维修员" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.userId"
+ :label="item.name"
+ :value="item"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="设备科主管:" prop="deviceManagerId">
+ <el-select clearable v-model="state.form.deviceManagerId" :disabled="state.title =='查看'" filterableplaceholder="设备科主管" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.userId"
+ :label="item.name"
+ :value="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-form-item label="备注:" prop="remark">
+ <el-input v-model.trim="state.form.remark" type="textarea" :autosize="{ minRows: 2 }" :readonly="state.title =='查看'"></el-input>
+ </el-form-item>
+ <el-form-item label="设施管理部门验收确认:" prop="acceptanceConfirmation">
+ <el-input v-model.trim="state.form.acceptanceConfirmation" type="textarea" :autosize="{ minRows: 2 }" :readonly="state.title =='查看'"></el-input>
+ </el-form-item>
+ <el-form-item label="编制:" prop="establishmentId">
+ <el-select clearable v-model="state.form.establishmentId" :disabled="state.title =='查看'" filterable placeholder="编制人" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.userId"
+ :label="item.name"
+ :value="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="审核:" prop="processId">
+ <el-select clearable v-model="state.form.processId" :disabled="state.title =='查看'" filterable placeholder="审核人" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.userId"
+ :label="item.name"
+ :value="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="批准:" prop="approvalId">
+ <el-select clearable v-model="state.form.approvalId" :disabled="state.title =='查看'" filterable placeholder="批准人" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.userId"
+ :label="item.name"
+ :value="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ </el-form>
+ <template #footer v-if="state.title !='查看'">
+ <span class="dialog-footer">
+ <el-button @click="handleClose" size="default">取 消</el-button>
+ <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+<script setup>
+import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue'
+import {ElMessage} from "element-plus";
+import {Base64} from "js-base64"
+import {getToken} from "@/utils/auth";
+import {
+ addInternalAuditCheck, getInternalAuditCheckInfo,
+ updateInternalAuditCheck
+} from "@/api/innerReview/meetingReview";
+import {getDepart} from "@/api/orgStructure/depart";
+import {listUser} from "@/api/system/user";
+import {getMaintenanceRecordDetail, updateMaintenanceRecord} from "@/api/infrastructureMng/ledger";
+
+const emit = defineEmits(["getList"]);
+const dialogVisible = ref(false)
+const superRef = ref()
+
+const state = reactive({
+ title: '',
+ form: {
+ id: null,
+ deviceName: '',
+ number: '',
+ formNumber: '',
+ faultDate: '',
+ repairDate: '',
+ failurePhenomenon: '',
+ maintainUsers: [],
+ managerId: null,
+ managerName: '',
+ faultCause: '',
+ maintenanceMethod: null,
+ outsourcingLocation: '',
+ repairTime: '',
+ downTime: '',
+ replaceMaterials: '',
+ money: '',
+ repairUsers: [],
+ annualMaintenanceRecordUsers: [],
+ deviceManagerId: null,
+ deviceManagerName: '',
+ remark: '',
+ acceptanceConfirmation: '',
+ establishmentId: null,
+ processId: null,
+ approvalId: null,
+ companyId: null
+ },
+ formRules:{
+ companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }],
+ deviceName: [{ required: true, message: '请填写设备名称', trigger: 'blur' }],
+ number: [{ required: true, message: '请填写编号', trigger: 'blur' }],
+ formNumber: [{ required: true, message: '请填写表单编号', trigger: 'blur' }],
+ faultDate: [{ required: true, message: '请选择故障发生日期', trigger: 'blur' }],
+ repairDate: [{ required: true, message: '请选择要求维修日期', trigger: 'blur' }],
+ failurePhenomenon: [{ required: true, message: '请填写故障现象', trigger: 'blur' }],
+ maintainUsers: [{ required: true, message: '请选择设施操作/管理员', trigger: 'blur' }],
+ managerId: [{ required: true, message: '请选择主管', trigger: 'blur' }],
+ faultCause: [{ required: true, message: '请填写故障原因及排除方法', trigger: 'blur' }],
+ maintenanceMethod: [{ required: true, message: '请选择维修方式', trigger: 'blur' }],
+ establishmentId: [{ required: true, message: '请选择编制人', trigger: 'blur' }],
+ processId: [{ required: true, message: '请选择审核人', trigger: 'blur' }],
+ approvalId: [{ required: true, message: '请选择批准人', trigger: 'blur' }]
+ },
+ isAdmin: false,
+ companyList: [],
+ oldRecordUsers: [],
+ userList: []
+})
+onMounted(() => {
+
+});
+
+const openDialog = async (type, value,companyId, isAdmin, companyList) => {
+ state.isAdmin = isAdmin
+ if(isAdmin){
+ state.companyList = companyList
+ }
+ await getUserList(companyId)
+ state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看'
+ state.form.companyId = companyId
+ if(state.title == '编辑'||state.title == '查看'){
+ await getInfo(value.id)
+ }
+ dialogVisible.value = true
+}
+
+
+const onSubmit = async () => {
+ const valid = await superRef.value.validate()
+ if(valid){
+ const data = JSON.parse(JSON.stringify(state.form))
+ data.maintainUsers = data.maintainUsers.map(i=>{
+ return {
+ id: i.id || null,
+ annualMaintenanceRecordId: i.annualMaintenanceRecordId || null,
+ userId: i.userId,
+ userName: i.name,
+ userType: 1
+ }
+ })
+ data.repairUsers = data.repairUsers.map(i=>{
+ return {
+ id: i.id || null,
+ annualMaintenanceRecordId: i.annualMaintenanceRecordId || null,
+ userId: i.userId,
+ userName: i.name,
+ userType: 2
+ }
+ })
+ data.annualMaintenanceRecordUsers = data.maintainUsers.concat(data.repairUsers)
+ data.managerName = state.userList.find(i=>i.userId == data.managerId)?.name
+ data.deviceManagerName = state.userList.find(i=>i.userId == data.deviceManagerId)?.name
+ data.establishmentName = state.userList.find(i=>i.userId == data.establishmentId)?.name
+ data.processName = state.userList.find(i=>i.userId == data.processId)?.name
+ data.approvalName = state.userList.find(i=>i.userId == data.approvalId)?.name
+ data.delRecordUserIds = state.oldRecordUsers.filter(oldItem => !data.annualMaintenanceRecordUsers.some(newItem => newItem.id === oldItem.id)).map(item => item.id)
+ delete data.maintainUsers
+ delete data.repairUsers
+ if(state.title == '新增'){
+ delete data.id
+ const res = await updateMaintenanceRecord(data)
+ if(res.code == 200){
+ ElMessage.success(res.message)
+ emit('getList')
+ handleClose()
+ dialogVisible.value = false;
+ }else{
+ ElMessage.warning(res.message)
+ }
+ }else{
+ const res = await updateMaintenanceRecord(data)
+ if(res.code == 200){
+ ElMessage.success(res.message)
+ emit('getList')
+ handleClose()
+ dialogVisible.value = false;
+ }else{
+ ElMessage.warning(res.message)
+ }
+ }
+ }
+}
+
+const getInfo = async (id)=> {
+ const res = await getMaintenanceRecordDetail({id: id})
+ if(res.code == 200){
+ Object.keys(state.form).forEach(key => {
+ if (key in res.data) {
+ state.form[key] = res.data[key]
+ }
+ })
+ state.oldRecordUsers = state.form.annualMaintenanceRecordUsers?.map(item=>{
+ return {
+ id: item.id,
+ annualMaintenanceRecordId: item.annualMaintenanceRecordId,
+ userId: item.userId,
+ name: item.userName,
+ userType: item.userType
+ }
+ })
+ state.form.maintainUsers = state.oldRecordUsers.filter(i=>i.userType == 1)
+ state.form.repairUsers = state.oldRecordUsers.filter(i=>i.userType == 2)
+ }else{
+ ElMessage.warning(res.message)
+ }
+}
+
+const getDeptList = async ()=>{
+ state.form.maintainUsers = []
+ state.form.managerId = null
+ state.form.repairUsers = []
+ state.form.annualMaintenanceRecordUsers = []
+ state.form.deviceManagerId = null
+ state.form.establishmentId = null
+ state.form.processId = null
+ state.form.approvalId = null
+ await getUserList(state.form.companyId)
+}
+
+const getUserList = async (companyId)=> {
+ const res = await listUser({pageIndex: 1,pageSize: 999, companyId: companyId})
+ if(res.code == 200){
+ state.userList = res.data.list?res.data.list.map(item=>{
+ const user = item.id
+ const {id, ...data} = item
+ return {
+ ...data,
+ userId: user
+ }
+ }):[]
+ }else{
+ ElMessage.warning(res.message)
+ }
+}
+
+const handleClose = () => {
+ state.form = {
+ id: null,
+ deviceName: '',
+ number: '',
+ formNumber: '',
+ faultDate: '',
+ repairDate: '',
+ failurePhenomenon: '',
+ maintainUsers: [],
+ managerId: null,
+ faultCause: '',
+ maintenanceMethod: null,
+ outsourcingLocation: '',
+ repairTime: '',
+ downTime: '',
+ replaceMaterials: '',
+ money: '',
+ repairUsers: [],
+ annualMaintenanceRecordUsers: [],
+ deviceManagerId: null,
+ deviceManagerName: '',
+ remark: '',
+ acceptanceConfirmation: '',
+ establishmentId: null,
+ processId: null,
+ approvalId: null,
+ companyId: null
+ }
+ state.fileList = []
+ superRef.value.clearValidate();
+ superRef.value.resetFields()
+ dialogVisible.value = false;
+}
+
+defineExpose({
+ openDialog
+});
+
+</script>
+
+<style scoped lang="scss">
+.notice{
+ :deep(.el-form .el-form-item__label) {
+ font-size: 15px;
+ }
+ .file {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ }
+}
+</style>
diff --git a/src/views/work/qualityInfo/infrastructureMng/repairRecord/index.vue b/src/views/work/qualityInfo/infrastructureMng/repairRecord/index.vue
new file mode 100644
index 0000000..49740a3
--- /dev/null
+++ b/src/views/work/qualityInfo/infrastructureMng/repairRecord/index.vue
@@ -0,0 +1,235 @@
+<template>
+ <div class="app-container">
+ <div style="display: flex;justify-content: space-between">
+ <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" >
+ <el-form-item>
+ <el-button
+ type="primary"
+ plain
+ icon="Plus"
+ @click="openDialog('add',{})"
+ >新增</el-button>
+ </el-form-item>
+ <el-form-item v-if="isAdmin" label="企业:" >
+ <el-select v-model="data.queryParams.companyId" placeholder="请选择" clearable>
+ <el-option
+ v-for="item in companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item >
+ <el-button v-if="isAdmin" type="primary" @click="getList">查询</el-button>
+ <el-button v-if="isAdmin" type="primary" plain @click="reset">重置</el-button>
+<!-- <el-button type="primary">导出</el-button>-->
+ </el-form-item>
+ </el-form>
+ </div>
+ <!-- 表格数据 -->
+ <el-table v-loading="loading" :data="dataList" :border="true">
+ <el-table-column type="index" label="序号"></el-table-column>
+ <el-table-column prop="deviceName" align="center" label="设备名称"></el-table-column>
+ <el-table-column prop="failurePhenomenon" align="center" label="故障现象"></el-table-column>
+ <el-table-column prop="faultCause" align="center" label="故障原因及排除方法"></el-table-column>
+ <el-table-column prop="faultDate" align="center" label="故障发生日期">
+ <template #default="scope">
+ {{scope.row.faultDate.substring(0,10)}}
+ </template>
+ </el-table-column>
+ <el-table-column prop="repairDate" align="center" label="要求维修日期">
+ <template #default="scope">
+ {{scope.row.repairDate.substring(0,10)}}
+ </template>
+ </el-table-column>
+ <el-table-column prop="manageName" align="center" label="设施操作/管理员"></el-table-column>
+ <el-table-column prop="managerName" align="center" label="主管"></el-table-column>
+<!-- <el-table-column label="检查表" align="center">-->
+<!-- <template #default="scope">-->
+<!-- {{scope.row.deptName }}内审检查表-->
+<!-- </template>-->
+<!-- </el-table-column>-->
+ <el-table-column label="操作" align="center">
+ <template #default="scope">
+ <el-button link type="primary" @click="openDialog('view',scope.row)">查看</el-button>
+ <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button>
+ <el-button link type="primary" @click="downloadFile(scope.row)">导出</el-button>
+ <el-button link type="danger" @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"
+ />
+ <edit-dialog ref="dialogRef" @getList=getList></edit-dialog>
+ </div>
+</template>
+
+<script setup>
+import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
+import {ElMessage, ElMessageBox} from "element-plus";
+import {delCompany, getCompany} from "@/api/onlineEducation/company";
+import Cookies from "js-cookie";
+import editDialog from './components/editDialog.vue'
+import useUserStore from "@/store/modules/user";
+import {generateWordDocument} from "@/utils/exportWord";
+import {
+ delMaintenanceRecord,
+ getMaintenanceRecordDetail,
+ getMaintenanceRecordList
+} from "@/api/infrastructureMng/ledger";
+import {getInternalAuditCheckInfo} from "@/api/innerReview/meetingReview";
+
+
+const userStore = useUserStore()
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const dialogRef = ref();
+const data = reactive({
+ queryParams: {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null
+ },
+ total: 0,
+ dataList: [],
+ companyList: [],
+ expertData: [],
+ isAdmin: false
+});
+const fields = ref({
+ '序号':'index',
+ '名称型号':'username',
+ '部门':'idCard',
+ '责任人/使用人':'entryTime',
+ '编号':'deptName',
+ '使用地点':'duty',
+ '使用情况':'phone'
+});
+const { queryParams, total, dataList,companyList, isAdmin, expertData } = toRefs(data);
+const userInfo = ref()
+onMounted(async ()=>{
+ if(userStore.roles.includes('admin')){
+ data.isAdmin = true
+ await getCompanyList()
+ }else{
+ data.isAdmin = false
+ data.queryParams.companyId = userStore.companyId
+ }
+ await getList()
+})
+
+onUnmounted(()=>{
+
+})
+
+const getList = async () => {
+ loading.value = true
+ const res = await getMaintenanceRecordList(data.queryParams)
+ if(res.code == 200){
+ data.dataList = res.data.list || []
+ data.total = res.data.total
+ }else{
+ ElMessage.warning(res.message)
+ }
+ loading.value = false
+}
+
+const getCompanyList = async ()=>{
+ const queryParams = {
+ pageNum: 1,
+ pageSize: 999
+ }
+ const res = await getCompany(queryParams)
+ if (res.code == 200) {
+ data.companyList = res.data.list?res.data.list:[]
+ // data.queryParams.companyId = data.companyList[0].id
+ } else {
+ ElMessage.warning(res.message)
+ }
+}
+
+const openDialog = (type, value) => {
+ dialogRef.value.openDialog(type, value, data.queryParams.companyId, data.isAdmin, data.companyList);
+}
+
+const downloadFile = async (val)=>{
+ const res = await getMaintenanceRecordDetail({id: val.id})
+ if(res.code == 200){
+ if(res.data){
+ let tableData = res.data
+ tableData.maintainUsers = tableData.annualMaintenanceRecordUsers.filter(i=>i.userType == 1)?.map(i=>i.userName).join('、')
+ tableData.repairUsers = tableData.annualMaintenanceRecordUsers.filter(i=>i.userType == 2)?.map(i=>i.userName).join('、')
+ tableData.faultDate = tableData.faultDate.substring(0,10)
+ tableData.repairDate = tableData.repairDate.substring(0,10)
+ tableData.downTime = tableData.downTime.substring(0,10)
+ tableData.typeList = [
+ {
+ id: 1,
+ label: '内部维修',
+ checked: tableData.maintenanceMethod == 1 ? false : true
+ },
+ {
+ id: 2,
+ label: '委外维修',
+ checked: tableData.maintenanceMethod == 2 ? false : true
+ }
+ ]
+ if(data.isAdmin){
+ tableData.companyName = data.companyList.find(i=>i.id == val.companyId)?.name
+ }else{
+ tableData.companyName = userStore.companyName
+ }
+ try {
+ generateWordDocument('/repairRecord.docx', tableData, tableData.companyName + '基础设施维修记录.docx');
+ } catch (error){
+ ElMessage({
+ type: 'warning',
+ message: '导出失败'
+ });
+ }
+ }else{
+ ElMessage.warning('暂无数据')
+ }
+ }else{
+ ElMessage.warning(res.message)
+ }
+}
+
+/** 重置新增的表单以及其他数据 */
+const reset= async()=> {
+ data.queryParams = {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null
+ }
+ await getCompanyList()
+ await getList()
+}
+const handleDelete = (val) => {
+ ElMessageBox.confirm(
+ '确定删除此条数据?',
+ '提示',
+ {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning',
+ })
+ .then( async() => {
+ const res = await delMaintenanceRecord({id: val.id})
+ if(res.code == 200){
+ ElMessage.success('数据删除成功')
+ await getList()
+ }else{
+ ElMessage.warning(res.message)
+ }
+ })
+}
+
+</script>
diff --git a/src/views/work/qualityInfo/infrastructureMng/reviewRecordStatistics/components/editDialog.vue b/src/views/work/qualityInfo/infrastructureMng/reviewRecordStatistics/components/editDialog.vue
new file mode 100644
index 0000000..9c9a18e
--- /dev/null
+++ b/src/views/work/qualityInfo/infrastructureMng/reviewRecordStatistics/components/editDialog.vue
@@ -0,0 +1,426 @@
+<template>
+ <div class="notice">
+ <el-dialog
+ v-model="dialogVisible"
+ :title="state.title"
+ width="75%"
+ :before-close="handleClose"
+ :close-on-press-escape="false"
+ :close-on-click-modal="false"
+ >
+ <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px" >
+ <el-form-item v-if="state.isAdmin" label="企业:" prop="companyId">
+ <el-select v-model="state.form.companyId" placeholder="请选择" :disabled="state.title =='查看'" clearable @change="getDeptList">
+ <el-option
+ v-for="item in state.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ <el-row>
+ <el-col :span="8">
+ <el-form-item label="制定日期:" prop="enactmentDate">
+ <el-date-picker
+ v-model="state.form.enactmentDate"
+ type="date"
+ value-format="YYYY-MM-DD"
+ placeholder="请选择日期"
+ :disabled="state.title =='查看'"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="修订日期:" prop="revisionDate">
+ <el-date-picker
+ v-model="state.form.revisionDate"
+ type="date"
+ value-format="YYYY-MM-DD"
+ placeholder="请选择日期"
+ :disabled="state.title =='查看'"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="表单编号:" prop="number">
+ <el-input v-model.trim="state.form.number" :readonly="state.title =='查看'"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <el-form-item label="设备属性:" prop="annualMaintenanceEvaluateDeviceList">
+ <el-button
+ type="primary"
+ plain
+ icon="Plus"
+ @click="addLine"
+ style="margin-bottom: 10px"
+ >新增</el-button>
+ </el-form-item>
+ <el-table :data="state.form.annualMaintenanceEvaluateDeviceList" class="customedTable" :border="true">
+ <el-table-column label="序号" type="index" width="80" align="center">
+ </el-table-column>
+ <el-table-column label="设备编号" prop="deviceNumber" align="center">
+ <template #default="scope">
+ <el-input
+ v-model.trim="scope.row.deviceNumber"
+ size="large"
+ type="textarea"
+ style="width: 100%;"
+ clearable
+ :readonly="state.title =='查看'"
+ >
+ </el-input>
+ </template>
+ </el-table-column>
+ <el-table-column label="设备名称" prop="deviceName" align="center">
+ <template #default="scope">
+ <el-input
+ v-model.trim="scope.row.deviceName"
+ size="large"
+ type="textarea"
+ style="width: 100%;"
+ clearable
+ :readonly="state.title =='查看'"
+ >
+ </el-input>
+ </template>
+ </el-table-column>
+ <el-table-column label="型号" prop="model" align="center">
+ <template #default="scope">
+ <el-input
+ v-model.trim="scope.row.model"
+ size="large"
+ type="textarea"
+ style="width: 100%;"
+ clearable
+ :readonly="state.title =='查看'"
+ >
+ </el-input>
+ </template>
+ </el-table-column>
+ <el-table-column label="地点" prop="location" align="center">
+ <template #default="scope">
+ <el-input
+ v-model.trim="scope.row.location"
+ size="large"
+ type="textarea"
+ style="width: 100%;"
+ clearable
+ :readonly="state.title =='查看'"
+ >
+ </el-input>
+ </template>
+ </el-table-column>
+ <el-table-column label="使用人" prop="useUser" align="center">
+ <template #default="scope">
+ <el-input
+ v-model.trim="scope.row.useUser"
+ size="large"
+ type="textarea"
+ style="width: 100%;"
+ clearable
+ :readonly="state.title =='查看'"
+ >
+ </el-input>
+ </template>
+ </el-table-column>
+ <el-table-column label="设备使用部门" prop="deptName" align="center">
+ <template #default="scope">
+ <el-input
+ v-model.trim="scope.row.deptName"
+ size="large"
+ type="textarea"
+ style="width: 100%;"
+ clearable
+ :readonly="state.title =='查看'"
+ >
+ </el-input>
+ </template>
+ </el-table-column>
+ <el-table-column label="抽查结果" prop="resultType" align="center">
+ <template #default="scope">
+ <el-select v-model="scope.row.resultType" :disabled="state.title =='查看'" placeholder="请选择" clearable>
+ <el-option key="1" label="完好" :value="1"></el-option>
+ <el-option key="2" label="需整改" :value="2"></el-option>
+ <el-option key="3" label="报废" :value="3"></el-option>
+ </el-select>
+ </template>
+ </el-table-column>
+ <el-table-column label="操作" align="center" width="70">
+ <template #default="scope">
+ <el-button link type="danger" @click="handleDelete(scope.$index)">删除</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ <el-form-item label="编制:" prop="establishmentId">
+ <el-select clearable v-model="state.form.establishmentId" :disabled="state.title =='查看'" filterable placeholder="编制" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.userId"
+ :label="item.name"
+ :value="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="审核:" prop="processId">
+ <el-select clearable v-model="state.form.processId" :disabled="state.title =='查看'" filterable placeholder="审核" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.userId"
+ :label="item.name"
+ :value="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="批准:" prop="approvalId">
+ <el-select clearable v-model="state.form.approvalId" :disabled="state.title =='查看'" filterable placeholder="批准" style="width: 100%">
+ <el-option
+ v-for="item in state.userList"
+ :key="item.userId"
+ :label="item.name"
+ :value="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ </el-form>
+ <template #footer v-if="state.title !='查看'">
+ <span class="dialog-footer">
+ <el-button @click="handleClose" size="default">取 消</el-button>
+ <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+<script setup>
+import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue'
+import {ElMessage} from "element-plus";
+import {getToken} from "@/utils/auth";
+import {
+ updateMaintenanceEvaluate,
+ getMaintenanceEvaluateDetail
+} from "@/api/infrastructureMng/ledger";
+
+import {listUser} from "@/api/system/user";
+
+const emit = defineEmits(["getList"]);
+const dialogVisible = ref(false)
+const superRef = ref()
+const checkList = (rule, value, callback) => {
+ if (state.form.annualMaintenanceEvaluateDeviceList.length == 0) {
+ callback(new Error('设备属性不可为空'))
+ } else {
+ callback()
+ }
+}
+const state = reactive({
+ title: '',
+ form: {
+ id: null,
+ companyId: null,
+ enactmentDate: '',
+ revisionDate: '',
+ number: '',
+ annualMaintenanceEvaluateDeviceList: [],
+ establishmentId: null,
+ establishmentName: '',
+ processId: null,
+ processName: '',
+ approvalId: null,
+ approvalName: '',
+ evaluateDeviceIds: [],
+ name: ''
+ },
+ oldDeviceList: [],
+ formRules:{
+ companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }],
+ enactmentDate: [{ required: true, message: '请选择指定日期', trigger: 'blur' }],
+ revisionDate: [{ required: true, message: '请选择修订日期', trigger: 'blur' }],
+ number: [{ required: true, message: '请填写编号', trigger: 'blur' }],
+ annualMaintenanceEvaluateDeviceList: [{ required: true, validator: checkList, trigger: 'blur' }],
+ establishmentId: [{ required: true, message: '请选择编制人', trigger: 'blur' }],
+ processId: [{ required: true, message: '请选择审核人', trigger: 'blur' }],
+ approvalId: [{ required: true, message: '请选择批准人', trigger: 'blur' }]
+ },
+ isAdmin: false,
+ companyList: [],
+ userList: []
+})
+onMounted(() => {
+
+});
+
+const openDialog = async (type, value,companyId, isAdmin, companyList) => {
+ state.isAdmin = isAdmin
+ if(isAdmin){
+ state.companyList = companyList
+ }
+ await getUserList(companyId)
+ state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看'
+ state.form.companyId = companyId
+ if(state.title == '编辑'||state.title == '查看'){
+ await getInfo(value.id)
+ }
+ dialogVisible.value = true
+}
+
+const addLine = () => {
+ const obj = {
+ id: null,
+ annualMaintenanceEvaluateId: null,
+ deviceNumber: '',
+ deviceName: '',
+ model: '',
+ location: '',
+ useUser: '',
+ deptName: '',
+ resultType: null
+ }
+ state.form.annualMaintenanceEvaluateDeviceList.push(obj);
+}
+
+const handleDelete = (i) =>{
+ state.form.annualMaintenanceEvaluateDeviceList = state.form.annualMaintenanceEvaluateDeviceList.filter((item,index) => index != i)
+}
+
+const onSubmit = async () => {
+ const valid = await superRef.value.validate();
+ if(valid){
+ const data = JSON.parse(JSON.stringify(state.form))
+ data.evaluateDeviceIds = state.oldDeviceList.filter(i =>!data.annualMaintenanceEvaluateDeviceList.some(item=>item.id == i.id)).map(i=>i.id)
+ data.establishmentName = state.userList.find(i=>i.userId == data.establishmentId)?.name
+ data.processName = state.userList.find(i=>i.userId == data.processId)?.name
+ data.approvalName = state.userList.find(i=>i.userId == data.approvalId)?.name
+ data.name = data.enactmentDate + '设备完好性评价记录及完好率统计表'
+ if(state.title == '新增'){
+ delete data.id
+ const res = await updateMaintenanceEvaluate(data)
+ if(res.code == 200){
+ ElMessage.success(res.message)
+ emit('getList')
+ handleClose()
+ dialogVisible.value = false;
+ }else{
+ ElMessage.warning(res.message)
+ }
+ }else{
+ const res = await updateMaintenanceEvaluate(data)
+ if(res.code == 200){
+ ElMessage.success(res.message)
+ emit('getList')
+ handleClose()
+ dialogVisible.value = false;
+ }else{
+ ElMessage.warning(res.message)
+ }
+ }
+ }
+}
+
+const getInfo = async (id)=> {
+ const res = await getMaintenanceEvaluateDetail({id: id})
+ if(res.code == 200){
+ Object.keys(state.form).forEach(key => {
+ if (key in res.data) {
+ state.form[key] = res.data[key]
+ }
+ })
+ state.form.annualMaintenanceEvaluateDeviceList = res.data.annualMaintenanceEvaluateDeviceList?.map(item=>{
+ return {
+ id: item.id,
+ annualMaintenanceEvaluateId: item.annualMaintenanceEvaluateId,
+ deviceNumber: item.deviceNumber,
+ deviceName: item.deviceName,
+ model: item.model,
+ location: item.location,
+ useUser: item.useUser,
+ deptName: item.deptName,
+ resultType: item.resultType
+ }
+ })
+ state.oldDeviceList = state.form.annualMaintenanceEvaluateDeviceList
+ }else{
+ ElMessage.warning(res.message)
+ }
+}
+
+const getDeptList = async ()=>{
+ state.form.establishmentId = null
+ state.form.processId = null
+ state.form.approvalId = null
+ await getUserList(state.form.companyId)
+}
+
+const getUserList = async (companyId)=> {
+ const res = await listUser({pageIndex: 1,pageSize: 999,companyId: companyId})
+ if(res.code == 200){
+ state.userList = res.data.list?res.data.list.map(item=>{
+ const user = item.id
+ const {id, ...data} = item
+ return {
+ ...data,
+ userId: user
+ }
+ }):[]
+ }else{
+ ElMessage.warning(res.message)
+ }
+}
+
+const handleClose = () => {
+ state.form = {
+ id: null,
+ companyId: null,
+ enactmentDate: '',
+ revisionDate: '',
+ number: '',
+ annualMaintenanceEvaluateDeviceList: [],
+ establishmentId: null,
+ establishmentName: '',
+ processId: null,
+ processName: '',
+ approvalId: null,
+ approvalName: '',
+ evaluateDeviceIds: [],
+ name: ''
+ }
+ superRef.value.clearValidate();
+ superRef.value.resetFields()
+ dialogVisible.value = false;
+}
+
+defineExpose({
+ openDialog
+});
+
+</script>
+
+<style scoped lang="scss">
+.notice{
+ :deep(.el-form .el-form-item__label) {
+ font-size: 15px;
+ }
+ .file {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ }
+}
+</style>
+<style lang="scss">
+.customedTable{
+ width: calc(100% - 150px);
+ margin-left: 150px;
+ margin-bottom: 30px;
+ .el-table__cell{
+ padding: 2px 0 !important;
+ font-size: 14px !important;
+ }
+ .cell{
+ padding: 0 2px !important;
+ font-size: 14px !important;
+ }
+}
+</style>
diff --git a/src/views/work/qualityInfo/infrastructureMng/reviewRecordStatistics/index.vue b/src/views/work/qualityInfo/infrastructureMng/reviewRecordStatistics/index.vue
new file mode 100644
index 0000000..7b62bc1
--- /dev/null
+++ b/src/views/work/qualityInfo/infrastructureMng/reviewRecordStatistics/index.vue
@@ -0,0 +1,207 @@
+<template>
+ <div class="app-container">
+ <div style="display: flex;justify-content: space-between">
+ <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" >
+ <el-form-item>
+ <el-button
+ type="primary"
+ plain
+ icon="Plus"
+ @click="openDialog('add',{})"
+ >新增</el-button>
+ </el-form-item>
+ <el-form-item v-if="isAdmin" label="企业:" >
+ <el-select v-model="data.queryParams.companyId" placeholder="请选择" clearable>
+ <el-option
+ v-for="item in companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item >
+ <el-button v-if="isAdmin" type="primary" @click="getList">查询</el-button>
+ <el-button v-if="isAdmin" type="primary" plain @click="reset">重置</el-button>
+<!-- <el-button type="primary">导出</el-button>-->
+ </el-form-item>
+ </el-form>
+ </div>
+ <!-- 表格数据 -->
+ <el-table v-loading="loading" :data="dataList" :border="true">
+ <el-table-column type="index" label="序号"></el-table-column>
+ <el-table-column prop="companyName" align="center" label="公司名称" v-if="isAdmin"></el-table-column>
+ <el-table-column prop="enactmentDate" align="center" label="名称">
+ <template #default="scope">
+ {{scope.row.enactmentDate.substring(0,10) + '设备完好性评价记录及完好率统计表'}}
+ </template>
+ </el-table-column>
+ <el-table-column label="操作" align="center">
+ <template #default="scope">
+ <el-button link type="primary" @click="openDialog('view',scope.row)">查看</el-button>
+ <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button>
+ <el-button link type="primary" @click="downloadFile(scope.row)">导出</el-button>
+ <el-button link type="danger" @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"
+ />
+
+ <edit-dialog ref="dialogRef" @getList=getList></edit-dialog>
+ </div>
+</template>
+
+<script setup>
+import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
+import {ElMessage, ElMessageBox} from "element-plus";
+import {delCompany, getCompany} from "@/api/onlineEducation/company";
+import Cookies from "js-cookie";
+import editDialog from './components/editDialog.vue'
+import useUserStore from "@/store/modules/user";
+import {generateWordDocument} from "@/utils/exportWord";
+import {
+ delMaintenanceEvaluate,
+ getMaintenanceEvaluateDetail,
+ getMaintenanceEvaluateList
+} from "@/api/infrastructureMng/ledger";
+
+
+const userStore = useUserStore()
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const dialogRef = ref();
+const data = reactive({
+ queryParams: {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null
+ },
+ total: 0,
+ dataList: [],
+ companyList: [],
+ isAdmin: false
+});
+
+const { queryParams, total, dataList,companyList, isAdmin } = toRefs(data);
+const userInfo = ref()
+onMounted(async ()=>{
+ if(userStore.roles.includes('admin')){
+ data.isAdmin = true
+ await getCompanyList()
+ }else{
+ data.isAdmin = false
+ data.queryParams.companyId = userStore.companyId
+ }
+ await getList()
+})
+
+onUnmounted(()=>{
+
+})
+
+const getList = async () => {
+ loading.value = true
+ const res = await getMaintenanceEvaluateList(data.queryParams)
+ if(res.code == 200){
+ data.dataList = res.data.list || []
+ data.total = res.data.total
+ }else{
+ ElMessage.warning(res.message)
+ }
+ loading.value = false
+}
+
+const getCompanyList = async ()=>{
+ const queryParams = {
+ pageNum: 1,
+ pageSize: 999
+ }
+ const res = await getCompany(queryParams)
+ if (res.code == 200) {
+ data.companyList = res.data.list?res.data.list:[]
+ // data.queryParams.companyId = data.companyList[0].id
+ } else {
+ ElMessage.warning(res.message)
+ }
+}
+
+const downloadFile = async (val)=>{
+ const res = await getMaintenanceEvaluateDetail({id: val.id})
+ if(res.code == 200){
+ if(res.data){
+ let tableData = res.data
+ tableData.table = res.data.annualMaintenanceEvaluateDeviceList.map((item,index)=>{
+ return {
+ ...item,
+ index: index + 1,
+ isWell: item.resultType == 1 ? '√' : '',
+ isFix: item.resultType == 2 ? '√' : '',
+ isCrap: item.resultType == 3 ? '√' : ''
+ }
+ })
+ tableData.deviceCount = tableData.table.length
+ tableData.enactmentDate = tableData.enactmentDate.substring(0,10)
+ tableData.revisionDate = tableData.revisionDate.substring(0,10)
+ if(data.isAdmin){
+ tableData.companyName = data.companyList.find(i=>i.id == val.companyId)?.name
+ }else{
+ tableData.companyName = userStore.companyName
+ }
+ try {
+ generateWordDocument('/reviewRecordStatistic.docx', tableData, tableData.enactmentDate +'设备完好性评价记录及完好率统计表.docx');
+ } catch (error){
+ ElMessage({
+ type: 'warning',
+ message: '导出失败'
+ });
+ }
+ }else{
+ ElMessage.warning('暂无数据')
+ }
+ }else{
+ ElMessage.warning(res.message)
+ }
+}
+
+const openDialog = (type, value) => {
+ dialogRef.value.openDialog(type, value, data.queryParams.companyId, data.isAdmin, data.companyList);
+}
+
+/** 重置新增的表单以及其他数据 */
+const reset= async()=> {
+ data.queryParams = {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null
+ }
+ await getCompanyList()
+ await getList()
+}
+const handleDelete = (val) => {
+ ElMessageBox.confirm(
+ '确定删除此条数据?',
+ '提示',
+ {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning',
+ })
+ .then( async() => {
+ const res = await delMaintenanceEvaluate({id: val.id})
+ if(res.code == 200){
+ ElMessage.success('数据删除成功')
+ await getList()
+ }else{
+ ElMessage.warning(res.message)
+ }
+ })
+}
+
+</script>
--
Gitblit v1.9.2