zhouwx
2025-01-06 2aac44c550cdb242225a2a18f7238fb41c618779
bug修改
已修改10个文件
已添加21个文件
7828 ■■■■■ 文件已修改
.env.development 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env.production 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Sidebar/Logo.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Sidebar/menu.js 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/request.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/projectManage/components/employNoticeRecord.vue 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/projectManage/index.vue 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/confirmEnd.vue 252 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/confirmEndDialog.vue 233 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/contractManage.vue 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/deviceDialog.vue 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/employNoticeRecord.vue 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/evaluatePlan.vue 521 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/evaluateTaskNotice.vue 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/expertsList.vue 344 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/innerReview.vue 276 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/mapLocation.vue 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/processCtrlReview.vue 364 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/projectArchive.vue 390 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/rateConclusion.vue 311 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/riskAnalysis.vue 474 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/signConfirm.vue 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/siteCheckRcd.vue 693 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/techLeaderReview.vue 267 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/uploadReviewRcd.vue 241 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/components/worksDialog.vue 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/index.vue 748 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/testManage/process.vue 1149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/userManage/expertUsers/components/projectDialog.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/userManage/institutionUsers/index.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env.development
@@ -1,5 +1,5 @@
# 页面标题
VITE_APP_TITLE = 智慧安评
VITE_APP_TITLE = 新疆智慧安评
# 开发环境配置
VITE_APP_ENV = 'development'
.env.production
@@ -1,5 +1,5 @@
# 页面标题
VITE_APP_TITLE = 智慧安评
VITE_APP_TITLE = 新疆智慧安评
# 生产环境配置
VITE_APP_ENV = 'production'
src/layout/components/Sidebar/Logo.vue
@@ -63,7 +63,7 @@
      width: 32px;
      height: 32px;
      vertical-align: middle;
      margin-right: 8px;
      margin-right: 0px;
    }
    & .sidebar-title {
src/layout/components/Sidebar/menu.js
@@ -1,10 +1,27 @@
import Layout from '@/layout'
const menu = {
    adminMenu: [
        // {
        //     path: '/project',
        //     name: 'Project',
        //     meta: { title: '项目管理',icon: 'form',affix: true }
        // },
        {
            path: '/project',
            name: 'Project',
            meta: { title: '项目管理',icon: 'form',affix: true }
            path: '/projectManage',
            redirect: '/projectManage/project',
            meta: { title: '项目管理',icon: 'clipboard'},
            children: [
                {
                    path: 'project',
                    name: 'project',
                    meta: { title: '安全评价',icon: 'monitor'}
                },
                {
                    path: 'test',
                    name: 'test',
                    meta: { title: '检验检测',icon: 'list'}
                },
            ]
        },
        {
            path: '/projectSupplement',
@@ -101,10 +118,27 @@
    ],
    agencyMenu: [
        // {
        //     path: '/project',
        //     name: 'Project',
        //     meta: { title: '项目管理',icon: 'form',affix: true }
        // },
        {
            path: '/project',
            name: 'Project',
            meta: { title: '项目管理',icon: 'form',affix: true }
            path: '/projectManage',
            redirect: '/projectManage/project',
            meta: { title: '项目管理',icon: 'clipboard'},
            children: [
                {
                    path: 'project',
                    name: 'project',
                    meta: { title: '安全评价',icon: 'monitor'}
                },
                {
                    path: 'test',
                    name: 'test',
                    meta: { title: '检验检测',icon: 'list'}
                },
            ]
        },
        {
            path: '/projectSupplement',
src/router/index.js
@@ -142,19 +142,40 @@
      }
    ]
  },
  // {
  //   path: '/project',
  //   component: Layout,
  //   redirect: '/project',
  //   children: [
  //     {
  //       path: '/project',
  //       component: () => import('@/views/safetyReview/projectManage/index.vue'),
  //       name: 'Project',
  //       meta: { title: '项目管理',icon: 'form', affix: true }
  //     }
  //   ]
  // },
  {
    path: '/project',
    path: '/projectManage',
    component: Layout,
    redirect: '/project',
    redirect: '/projectManage/project',
    meta: { title: '项目管理'},
    children: [
      {
        path: '/project',
        path: 'project',
        component: () => import('@/views/safetyReview/projectManage/index.vue'),
        name: 'Project',
        meta: { title: '项目管理',icon: 'form', affix: true }
      }
        meta: { title: '安全评价',icon: 'form', affix: true }
      },
      {
        path: 'test',
        component: () => import('@/views/safetyReview/testManage/index.vue'),
        name: 'Test',
        meta: { title: '检验检测',icon: 'form', affix: true }
      },
    ]
  },
  {
    path: '/projectSupplement',
    component: Layout,
@@ -177,7 +198,20 @@
        path: '/process',
        component: () => import('@/views/safetyReview/projectManage/process.vue'),
        name: 'Process',
        meta: { title: '项目信息管理'}
        meta: { title: '安全评价信息管理'}
      }
    ]
  },
  {
    path: '/processTest',
    component: Layout,
    redirect: '/processTest',
    children: [
      {
        path: '/processTest',
        component: () => import('@/views/safetyReview/testManage/process.vue'),
        name: 'ProcessTest',
        meta: { title: '检验检测信息管理'}
      }
    ]
  },
src/utils/request.js
@@ -132,6 +132,17 @@
  },
  error => {
    console.log('err' + error)
    if (error.response) {
      // 请求已发出,但服务器响应的状态码不在 2xx 范围内
      console.log('responseresponseresponseresponseresponseresponse')
    } else if (error.request) {
      // 请求已发出,但没有收到响应
      console.log('requestrequestrequestrequestrequestrequestrequest')
    } else {
      // 发生了一些问题导致请求不能发送到服务器
      console.log('error33333333')
    }
    let { message } = error;
    if (message == "Network Error") {
      message = "后端接口连接异常";
src/views/safetyReview/projectManage/components/employNoticeRecord.vue
@@ -64,12 +64,31 @@
        </el-table-column>
      </el-table>
    </el-form>
    <el-upload
        style="margin-top: 25px;width: 250px"
        :disabled="projectType === 'view' || isEnd"
        accept=".pdf"
        :action="state.uploadUrl"
        :data="{moduleType: 12,projectId: props.projectId}"
        :headers="state.header"
        method="post"
        :limit="state.imgLimit"
        :before-upload="beforeUpload"
        :on-success="handleAvatarSuccess"
        v-model:file-list="state.fileList"
        :on-preview="handlePreview"
        :on-remove="handleRemove">
      <el-button type="primary">上传从业告知书pdf</el-button>
      <template #tip>
        <div class="el-upload__tip">只能上传pdf类型,最多上传1份</div>
      </template>
    </el-upload>
  </div>
</template>
<script setup>
import {defineEmits, defineProps, onMounted, reactive, ref, watchEffect} from "vue"
import {ElMessage} from "element-plus"
import {ElMessage, ElMessageBox} from "element-plus"
import {Search} from '@element-plus/icons-vue'
import {addWorkRecord, editWorkRecord, getWorkDetail} from "@/api/projectManage/employNoticeRcd"
import {getWorks, editWorks} from "@/api/projectManage/evaPlan"
@@ -77,6 +96,10 @@
const props = defineProps(['projectId'])
const emit = defineEmits(["getNextStatus"])
import { useRoute } from 'vue-router'
import {getToken} from "@/utils/auth";
import {getFiles} from "@/api/projectManage/siteCheckRcd";
import {delAccessoryFile} from "@/api/projectManage/project";
import axios from "axios";
const route = useRoute()
const state = reactive({
  formData: {
@@ -92,9 +115,16 @@
  rules: {
    timeRange: [{required: true, message: '请选择技术服务期限', trigger: 'blur'}],
    investigationPlanDate: [{required: true, message: '请选择计划现场勘验时间', trigger: 'blur'}]
  }
  },
  imgLimit: 1,
  uploadUrl: import.meta.env.VITE_APP_BASE_API + '/manage/accessory-file/uploadFile',
  header: {
    Authorization: getToken()
  },
  fileList: []
})
const isEnd = ref('')
const isAmin = ref(false)
const formRef = ref()
onMounted(() => {
@@ -104,7 +134,9 @@
  }
  if(props.projectId){
    getWorksList(props.projectId)
    getProcessFiles(props.projectId);
  }
  isEnd.value = Cookies.get('end')
});
@@ -113,12 +145,19 @@
  state.formData.projectId = val
  state.projectId = val
  projectType.value = route.query.type;
  isEnd.value = Cookies.get('end')
  // await getWorksList(val)
  if(type === 'detail' || type === 'edit' ){
    const res = await getWorkDetail({projectId: val})
    if(res.code == 200){
      state.formData = JSON.parse(JSON.stringify(res.data))
      state.formData.timeRange = [state.formData.serviceStartDate,state.formData.serviceEndDate]
      // state.fileList = res.data.accessoryFiles.map(item => {
      //   return {
      //     ...item,
      //     name: item.originName,
      //   }
      // })
    }else {
      ElMessage.warning(res.message)
    }
@@ -189,7 +228,90 @@
  }
  await getWorksList(props.projectId)
}
const beforeUpload = (file) => {
  let fileType = file.name.substring(file.name.lastIndexOf(".") + 1);
  if (fileType === 'pdf') {
  } else {
    ElMessage.error("文件类型必须为pdf格式")
    return false
  }
}
const handleAvatarSuccess = (res) => {
  if(res.code === 200){
    getProcessFiles()
    ElMessage({
      type: 'success',
      message: '文件上传成功'
    })
  }else {
    state.fileList.splice(state.fileList.indexOf(uploadFile),1)
    ElMessage({
      type: 'warning',
      message: res.message
    })
  }
}
const handleRemove = async (file, uploadFiles) => {
  if (file && file.status === 'success') {
    ElMessageBox.confirm(
        '确定删除该附件?',
        '提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        })
        .then(async () => {
          let accessoryFileId = "";
          if (file.id) {
            accessoryFileId = file.id
          } else {
            accessoryFileId = file.response.data.id
          }
          const res = await delAccessoryFile(accessoryFileId)
          if (res.code == 200) {
            ElMessage({
              type: 'success',
              message: '文件已删除'
            })
            await getProcessFiles()
          } else {
            ElMessage({
              type: 'warning',
              message: res.message
            })
          }
        })
        .catch(() => {
          getProcessFiles()
        })
  }
}
const getProcessFiles = async (id)=>{
  const res = await getFiles({projectId: id ? id : props.projectId ,moduleType: 12})
  if(res.code == 200){
    if(res.data && res.data.length>0){
      state.fileList = res.data.map(i=>{
        return {
          name: i.originName,
          url: import.meta.env.VITE_APP_BASE_API + '/' + i.path,
          id: i.id,
          projectId: i.projectId,
          moduleType: i.moduleType
        }
      })
    }else{
      state.fileList = []
    }
  }else {
    ElMessage.warning(res.message)
  }
}
const handlePreview = (file) => {
  const url = file.url
  window.open(url)
}
defineExpose({
  riskOpen
});
src/views/safetyReview/projectManage/index.vue
@@ -65,6 +65,15 @@
        </div>
      </div>
    </div>
    <div style="margin-top: 10px;margin-bottom: 15px;margin-left: 20px;">
      <div style="font-size: 18px;font-weight: 800;color: #ed5565;display: flex">
        当前存在未完结:安全评价项目 <div style="cursor: pointer;border-radius: 8px;padding: 0 5px" :class="{active: isActive}" @click="chooseUn" >{{search.num.safetyTotal}}</div> 个,检验检测项目
        {{search.num.safetyCheckTotal}}
        个,共 {{search.num.unFinishTotal}} 个
      </div>
    </div>
    <!-- 表格数据 -->
    <el-table v-loading="loading" :data="dataList" :border="true" ref="tableRef" :height="tableHeight" style="width: 100%;">
      <el-table-column label="序号" width="80" align="center" type="index" ></el-table-column>
@@ -170,6 +179,28 @@
                size="large"
            />
          </el-form-item>
          <el-form-item  label="机构名称" >
            <el-select
                v-model="search.queryParams.agencyName"
                filterable
                remote
                @change="selectValue"
                reserve-keyword
                placeholder="所属机构"
                remote-show-suffix
                :remote-method="getCompanyList"
                :loading="loadingCompany"
                style="width:100%"
                clearable
            >
              <el-option
                  v-for="item in companyList"
                  :key="item.id"
                  :label="item.name"
                  :value="item.name"
              />
            </el-select>
          </el-form-item>
          <el-form-item  label="项目名称" >
            <el-input v-model.trim="search.queryParams.name" placeholder="请输入项目名称"></el-input>
          </el-form-item>
@@ -232,8 +263,10 @@
import {getDict} from "@/api/login";
import {getDictList} from "@/api/backManage/evaluate";
import Cookies from "js-cookie"
import {getAllAgency} from "@/api/backManage/insitution";
const router = useRouter();
const isActive = ref(false)
const loading = ref(false);
const direction = ref('rtl');
const showDrawer = ref(false);
@@ -248,6 +281,7 @@
    pageNum: 1,
    pageSize: 20,
    name: '',
    agencyName: '',
    client: '',
    province: '',
    city: '',
@@ -255,6 +289,8 @@
    business: '',
    estimateType: '',
    phase: '',
    safetyCheck: 0,
    unFinish: null,
    params:{
      lostMaterial: null
    }
@@ -265,9 +301,14 @@
    investigationTotal: 0,
    reviewTotal: 0,
    reportTotal: 0,
    archiveTotal: 0
    archiveTotal: 0,
    unFinishTotal: 0,
    safetyCheckTotal: 0,
    safetyTotal: 0
  }
});
const companyList = ref([])
const loadingCompany = ref(false)
const searchTime = ref([]);
const area = ref([]);
const businessList = ref([]);
@@ -311,6 +352,7 @@
  chooseType.value = val;
  search.queryParams.phase = val;
  getList();
  getStatistics()
}
const getList = async () => {
  loading.value = true;
@@ -350,10 +392,12 @@
  search.queryParams.pageNum = 1;
  search.queryParams.pageSize = val
  getList()
  getStatistics()
}
const handleCurrentChange = (val) => {
  search.queryParams.pageNum = val
  getList()
  getStatistics()
}
const toProcess = (type,value,toPath) => {
  value.type = type;
@@ -432,6 +476,7 @@
    pageNum: 1,
    pageSize: 20,
    name: '',
    agencyName: '',
    client: '',
    province: '',
    city: '',
@@ -439,6 +484,8 @@
    business: '',
    estimateType: '',
    phase: '',
    safetyCheck: 0,
    unFinish: null,
    params: {
      lostMaterial: null
    }
@@ -502,12 +549,53 @@
  console.log("val",val)
  toProcess('edit',val,toPath);
}
const selectValue = (val) => {
  console.log('val',val)
  if(val == ""){
    companyList.value = []
  }
  // data.companyList.forEach(item => {
  //   if(item.name === val){
  //     data.queryParams.companyId = item.id
  //   }
  // })
}
const getCompanyList = async (val)=>{
  if(val != ""){
    loadingCompany.value = true;
    const queryParams = {
      name: val
    }
    const res = await getAllAgency(queryParams)
    if (res.code == 200) {
      loadingCompany.value = false;
      companyList.value = res.data
    } else {
      ElMessage.warning(res.message)
    }
  }
}
const chooseUn = () => {
  isActive.value = !isActive.value
  if(isActive.value){
    search.queryParams.unFinish = 1
  }else {
    search.queryParams.unFinish = null
  }
  getList()
  getStatistics()
}
</script>
<style scoped lang="scss">
.project-container{
  .active {
    background-color: #fdb0b7;
    //border: 1px solid #dab4f6;
  }
  .header{
    margin: 15px 10px;
    display: flex;
src/views/safetyReview/testManage/components/confirmEnd.vue
对比新文件
@@ -0,0 +1,252 @@
<template>
  <div class="riskBox">
    <el-form ref="formRef" :model="state.formData" :rules="state.rules" class="register-form" label-position="top">
      <el-row :gutter="30">
        <el-col :span="6">
          <el-button type="primary" @click="addRectify('add',{})" :disabled="projectType ==='view' || isEnd ">新增整改</el-button>
        </el-col>
      </el-row>
      <el-table :data="state.recitificationList" :border="true" style="margin: 20px 0">
        <el-table-column label="序号" width="60" align="center" type="index"></el-table-column>
        <el-table-column label="整改时间" prop="rectifyTime" align="center"></el-table-column>
        <el-table-column label="提交时间" prop="updateTime" align="center"></el-table-column>
        <el-table-column label="整改说明" prop="reason" align="center"></el-table-column>
        <el-table-column label="整改人" prop="rectifyPerson" align="center"></el-table-column>
        <el-table-column label="附件" prop="" align="center">
          <template #default="scope">
            <span @click="handlePreview(scope.row.accessoryFile)" style="color: #3b82f6;cursor:pointer">{{scope.row.accessoryFile.originName}}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
          <template #default="scope">
            <el-button link type="primary" @click="addRectify('edit',scope.row)" :disabled="projectType ==='view' || isEnd ">编辑</el-button>
            <el-button link type="danger" @click="del(scope.row)" :disabled="projectType ==='view' || isEnd ">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
    <div class="pag-container">
      <el-pagination
          v-model:current-page="state.queryParams.pageNum"
          v-model:page-size="state.queryParams.pageSize"
          :page-sizes="[10,15,20,25]"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
      />
    </div>
    <confirm-end-dialog ref="confirmRef" @getList="getList(props.projectId)"></confirm-end-dialog>
  </div>
</template>
<script setup>
import {defineEmits, defineProps, onMounted, reactive, ref} from "vue";
import {ElMessage, ElMessageBox} from "element-plus";
import {addRecord, editRecord, getDetail} from "@/api/projectManage/contractMng";
import Cookies from "js-cookie";
import { getToken } from "@/utils/auth";
import confirmEndDialog from './confirmEndDialog.vue'
import {delProject, getAccessoryFile, getProjectStatus} from "@/api/projectManage/project";
import {delRecitification, doConfirm, getRecognitionList} from "@/api/projectManage/riskAnalysis";
import axios from "axios";
import { useRoute } from 'vue-router'
const route = useRoute()
const confirmRef = ref(null);
const emit = defineEmits(["getNextStatus"]);
const props = defineProps(['projectId'])
const state = reactive({
  formData: {},
  queryParams: {
    pageNum: 1,
    pageSize: 10,
  },
  recitificationList: [],
})
const isEnd = ref(false)
const total = ref(0);
const isAmin = ref(false)
const formRef = ref();
onMounted(() => {
  const userInfo = JSON.parse(Cookies.get('userInfo'))
  if(userInfo.identity === 0){
    isAmin.value = true;
  }
  if(props.projectId){
    state.formData.projectId = props.projectId;
    getList(state.formData.projectId);
    getStatus(state.formData.projectId);
  }
  isEnd.value = Cookies.get('end')
  projectType.value = route.query.type;
});
const getStatus = async (projectId) => {
  const res = await getProjectStatus(projectId);
  if(res.code == 200){
    if(res.data === 14){
      isEnd.value = true
    }
  }
}
const getList = async (val) => {
  const res = await getRecognitionList({projectId: val});
  if(res.code == 200){
    state.recitificationList = res.data.list;
    total.value = res.data.total;
  }else {
    ElMessage.warning(res.message)
  }
}
const projectType = ref('')
const riskOpen = async (type,val) => {
  // await  getList(val);
  projectType.value = route.query.type;
  state.formData.projectId = val;
  if(type === 'confirm') {
    const res = await doConfirm({projectId: val});
    if (res.code == 200) {
      ElMessage.success('保存成功')
      Cookies.set('end',true)
      isEnd.value = true;
      formRef.value.clearValidate();
      emit('getNextStatus', state.formData.projectId);
    } else {
      ElMessage.warning(res.message)
    }
  }
}
const addRectify = (type,val)=>{
  val.projectId =  state.formData.projectId;
  confirmRef.value.openDialog(type,val)
}
const delRectify = (index)=>{
  state.rectifyList.splice(index,1)
}
const handleSizeChange = (val) => {
  state.queryParams.pageNum = 1;
  state.queryParams.pageSize = val
  getList(props.projectId)
}
const handleCurrentChange = (val) => {
  state.queryParams.pageNum = val
  getList(props.projectId)
}
// 图片上传
const showTip =()=>{
  ElMessage({
    type: 'warning',
    message: '超出文件上传数量'
  });
}
const picSize = async (rawFile) => {
  if(rawFile.size / 1024 / 1024 > 5){
    ElMessage({
      type: 'warning',
      message: '文件大小不能超过5M'
    });
    return false
  }
};
const handleAvatarSuccess = (res, uploadFile) => {
  if(res.code == 200){
    // state.registerForm.agency.reportPath = res.data.path
  }else{
    ElMessage({
      type: 'warning',
      message: '文件上传失败'
    })
  }
}
const handleRemove = async (file, uploadFiles) => {
  const res = await delPic({path: state.registerForm.agency.reportPath})
  if(res.code == 200){
    ElMessage({
      type: 'success',
      message: '文件已删除'
    })
  }else{
    ElMessage({
      type: 'warning',
      message: res.message
    })
  }
}
const handlePreview = (file) => {
  const url = import.meta.env.VITE_APP_BASE_API + '/' + file.path
  axios.get( url,{
        headers:
            {
              'Content-Type': 'application/json',
              'Authorization':getToken(),
            },
        responseType: 'blob'
      }
  ).then(res=>{
    if (res) {
      const link = document.createElement('a')
      let blob = new Blob([res.data],{type: res.data.type})
      link.style.display = "none";
      link.href = URL.createObjectURL(blob); // 创建URL
      link.setAttribute("download", file.originName);
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    } else {
      this.$message.error('获取文件失败')
    }
  })
}
const del = (val) => {
  ElMessageBox.confirm(
      '确定删除此条数据?',
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
      .then( async() => {
        const res = await delRecitification(val)
        if(res.code == 200){
          ElMessage.success('数据删除成功')
          getList(props.projectId)
        }else{
          ElMessage.warning(res.message)
        }
      })
}
defineExpose({
  riskOpen
});
</script>
<style scoped lang="scss">
.riskBox{
  :deep(.el-form .el-form-item__label) {
    font-size: 15px;
  }
}
.pag-container{
  float: right;
  margin-top: 20px;
}
</style>
src/views/safetyReview/testManage/components/confirmEndDialog.vue
对比新文件
@@ -0,0 +1,233 @@
<template>
  <div class="notice">
    <el-dialog
        v-model="dialogVisible"
        :title="state.title"
        width="550px"
        :before-close="handleClose"
    >
      <el-form :model="state.form" size="default" ref="formRef" :rules="state.formRules" label-width="110px" >
        <el-form-item label="整改时间:" prop="rectifyTime" >
          <el-date-picker
              style="width: 100%"
              v-model="state.form.rectifyTime"
              type="date"
              value-format="YYYY-MM-DD 00:00:00"
              placeholder="请选择日期"
              size="large"
          />
        </el-form-item>
        <el-form-item label="整改人:"  prop="rectifyPerson">
          <el-input v-model.trim="state.form.rectifyPerson" show-word-limit type="text" size="large" placeholder="请输入整改人" />
        </el-form-item>
        <el-form-item label="整改说明:" prop="reason">
          <el-input v-model.trim="state.form.reason" show-word-limit type="text" size="large" placeholder="请输入整改说明"/>
        </el-form-item>
        <el-form-item prop="fileList">
          <el-upload accept=".pdf"
                     :action="state.uploadUrl"
                     :disabled="state.disabled"
                     :headers="state.header"
                     method="post"
                     :limit="state.imgLimit"
                     :before-upload="beforeUpload"
                     :on-success="handleAvatarSuccess"
                     v-model:file-list="state.form.fileList"
                     :on-remove="handleRemove"
                     :data="state.uploadData"
                     :on-preview="handlePreview"
          >
            <el-button type="primary">附件上传</el-button>
            <template #tip>
              <div class="el-upload__tip">
                只能上传pdf类型,且只能上传一个
              </div>
            </template>
          </el-upload>
        </el-form-item>
      </el-form>
      <template #footer >
        <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 {defineEmits, nextTick, reactive, ref} from "vue";
import {ElMessage} from "element-plus";
import axios from "axios";
import {getToken} from "@/utils/auth";
import {delAccessoryFile} from "@/api/projectManage/project";
import {addRate, addRecitification, editRecitification} from "@/api/projectManage/riskAnalysis";
const emit = defineEmits(["getList"]);
const formRef = ref(null)
const state = reactive({
  title: '',
  form: {
    id: null,
  },
  formRules:{
    rectifyTime: [{ required: true, message: '请选择整改时间', trigger: 'blur' }],
    rectifyPerson: [{ required: true, message: '请输入整改人', trigger: 'blur' }],
    fileList: [{ required: true, message: '请上传附件', trigger: 'blur' }],
    reason:[{ required: true, message: '请输入整改说明', trigger: 'blur' }],
  },
  imgLimit: 1,
  uploadUrl: import.meta.env.VITE_APP_BASE_API + '/manage/accessory-file/uploadFile',
  header: {
    Authorization: getToken()
  },
  uploadData: {
    moduleType: 11
  },
})
const dialogVisible = ref(false)
const openDialog = (type, value) => {
  state.uploadData.projectId = value.projectId;
  state.title = type === 'add' ? '新增' :  '编辑' ;
  if(state.title === '编辑'){
    state.form = value;
    state.form.fileList = [value.accessoryFile]
    state.form.fileList[0].name = value.accessoryFile.originName
  }
  dialogVisible.value = true
}
const beforeUpload = (file) => {
  let fileType = file.name.substring(file.name.lastIndexOf(".") + 1);
  if (fileType === 'pdf') {
  } else {
    ElMessage.error("文件类型必须为pdf格式")
    return false
  }
}
const handleAvatarSuccess = (res) => {
  if(res.code === 200){
    console.log("file",state.form.fileList)
    ElMessage({
      type: 'success',
      message: '文件上传成功'
    })
  }else {
    ElMessage({
      type: 'warning',
      message: '文件上传失败'
    })
  }
}
const handlePreview = (file) => {
  let path = "";
  if(file.path){
    path = file.path
  }else {
    path = file.response.data.path
  }
  const url = import.meta.env.VITE_APP_BASE_API + '/' + path
  axios.get( url,{
        headers:
            {
              'Content-Type': 'application/json',
              'Authorization':getToken(),
            },
        responseType: 'blob'
      }
  ).then(res=>{
    if (res) {
      const link = document.createElement('a')
      let blob = new Blob([res.data],{type: res.data.type})
      link.style.display = "none";
      link.href = URL.createObjectURL(blob); // 创建URL
      link.setAttribute("download", file.name);
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    } else {
      this.$message.error('获取文件失败')
    }
  })
}
const onSubmit = async () => {
  const valid = await formRef.value.validate();
  if(valid){
    state.form.fileId = state.form.fileList ? state.form.fileList[0].response ? state.form.fileList[0].response.data.id : state.form.fileList[0].id : '';
    if(state.title === '新增'){
      const {id,fileList, ...data} = JSON.parse(JSON.stringify(state.form))
      data.projectId = state.uploadData.projectId;
      console.log("Add",data)
      const res = await addRecitification(data);
      if (res.code == 200) {
        ElMessage.success('保存成功')
        handleClose();
        emit('getList');
      } else {
        ElMessage.warning(res.message)
      }
    }else if(state.title === '编辑'){
      const {ileList, ...data} = JSON.parse(JSON.stringify(state.form))
      data.projectId = state.uploadData.projectId;
      const res = await editRecitification(data);
      if (res.code == 200) {
        ElMessage.success('编辑成功')
       handleClose();
        emit('getList');
      } else {
        ElMessage.warning(res.message)
      }
    }
  }
}
const handleRemove = async (file, uploadFiles) => {
  if(file && file.status == 'success') {
    console.log("file", file)
    let accessoryFileId = "";
    if (file.id) {
      accessoryFileId = file.id
    } else {
      accessoryFileId = file.response.data.id
    }
    const res = await delAccessoryFile(accessoryFileId)
    if (res.code == 200) {
      ElMessage({
        type: 'success',
        message: '文件已删除'
      })
    } else {
      ElMessage({
        type: 'warning',
        message: res.message
      })
    }
  }
}
const handleClose = () => {
  state.form = {
    id: null,
    rectifyTime: '',
    rectifyPerson: '',
    reason: '',
    fileList: []
  }
  formRef.value.clearValidate();
  dialogVisible.value = false;
}
defineExpose({
  openDialog
});
</script>
<style scoped lang="scss">
</style>
src/views/safetyReview/testManage/components/contractManage.vue
对比新文件
@@ -0,0 +1,137 @@
<template>
  <div class="riskBox">
    <el-form ref="formRef" :model="state.formData" :rules="state.rules" class="register-form" label-position="top">
      <el-row :gutter="30">
        <el-col :span="6">
          <el-form-item prop="contractSignDate" label="合同签订日期">
            <el-date-picker
                style="width: 100%"
                v-model="state.formData.contractSignDate"
                type="date"
                value-format="YYYY-MM-DD 00:00:00"
                placeholder="选择日期"
                size="large"
            />
          </el-form-item>
        </el-col>
        <el-col :span="18">
          <el-form-item prop="contractMoney">
            <template #label>
              项目合同额<span style="font-size: 13px;color: red;font-weight: normal;display: inline-block;margin-left: 6px" @input="state.formData.contractMoney= state.formData.contractMoney.replace(/[^\d|\.]/g,'')"
            >预估合同金额,归档阶段可以进行修改。仅支持数字,单位万元,小数点后最多两位,数值范围(0.01-999.99)</span>
            </template>
            <el-input
                v-model.trim="state.formData.contractMoney"
                size="large"
                placeholder="请输入项目合同额"
                @input="state.formData.contractMoney= state.formData.contractMoney.replace(/[^0-9.\/\-]/g,'')"
            >
              <template #append>万元</template>
            </el-input>
          </el-form-item>
        </el-col>
      </el-row>
      <el-form-item label="项目合同额说明">
        <el-input
            v-model="state.formData.contractIntroduction"
            :autosize="{ minRows: 6 }"
            maxlength="100"
            show-word-limit
            type="textarea">
        </el-input>
      </el-form-item>
    </el-form>
  </div>
</template>
<script setup>
import {defineEmits, onMounted, reactive, ref} from "vue";
import {ElMessage} from "element-plus";
import {addRecord, editRecord, getDetail} from "@/api/projectManage/contractMng";
import Cookies from "js-cookie";
const emit = defineEmits(["getNextStatus"]);
const state = reactive({
  formData: {
    id: '',
    projectId: null,
    contractSignDate: '',
    contractMoney: '',
    contractIntroduction: ''
  },
  rules: {
    contractSignDate: [{required: true, message: '请选择合同签订日期', trigger: 'blur'}],
    contractMoney: [{required: true, message: '请输入项目合同额', trigger: 'blur'}]
  }
})
const isAmin = ref(false)
const formRef = ref();
onMounted(() => {
  const userInfo = JSON.parse(Cookies.get('userInfo'))
  if(userInfo.identity === 0){
    isAmin.value = true;
  }
});
const riskOpen = async (type,val) => {
  state.formData.projectId = val;
  if(type === 'detail' || type === 'edit' ){
    const res = await getDetail({projectId: val});
    if(res.code == 200){
      if(res.data){
        state.formData = res.data;
      }
    }else {
      ElMessage.warning(res.message)
    }
  }
  if(type === 'add' || type === 'clickEdit') {
    const valid = await formRef.value.validate();
    if(valid){
      if (isAmin.value) {
        ElMessage.warning("当前用户暂无权限");
        return;
      }
      if(type === 'add'){
        const {id, ...data} = JSON.parse(JSON.stringify(state.formData))
        const res = await addRecord(data);
        if (res.code == 200) {
          ElMessage.success('保存成功')
          formRef.value.clearValidate();
          emit('getNextStatus', state.formData.projectId);
        } else {
          ElMessage.warning(res.message)
        }
      }else if(type === 'clickEdit'){
        const { ...data} = JSON.parse(JSON.stringify(state.formData))
        const res = await editRecord(data);
        if (res.code == 200) {
          ElMessage.success('变更成功')
          formRef.value.clearValidate();
          // emit('getNextStatus', data.project.id);
        } else {
          ElMessage.warning(res.message)
        }
      }
    }
  }
}
defineExpose({
  riskOpen
});
</script>
<style scoped lang="scss">
.riskBox{
  :deep(.el-form .el-form-item__label) {
    font-size: 15px;
  }
}
</style>
src/views/safetyReview/testManage/components/deviceDialog.vue
对比新文件
@@ -0,0 +1,140 @@
<template>
    <div class="notice">
        <el-dialog
            v-model="dialogVisible"
            :title="title"
            width="500px"
            :before-close="handleClose"
        >
            <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-position="top">
                <el-form-item label="设备名称:" prop="deviceName">
                  <el-input v-model.trim="state.form.deviceName" maxlength="30" show-word-limit type="text" size="large"/>
                </el-form-item>
                <el-form-item label="开始时间:" prop="startDate">
                  <el-date-picker
                      style="width: 100%"
                      v-model="state.form.startDate"
                      type="date"
                      value-format="YYYY-MM-DD 00:00:00"
                      placeholder="选择日期"
                      size="large"
                  />
                </el-form-item>
                <el-form-item label="结束时间:" prop="endDate">
                  <el-date-picker
                      style="width: 100%"
                      v-model="state.form.endDate"
                      type="date"
                      value-format="YYYY-MM-DD 00:00:00"
                      placeholder="选择日期"
                      size="large"
                  />
                </el-form-item>
            </el-form>
            <template #footer>
                    <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 {defineProps, nextTick, reactive, ref, toRefs} from 'vue'
import {ElMessage} from "element-plus";
import {addDevice, editDevice} from "@/api/projectManage/evaPlan"
const dialogVisible = ref(false)
const title = ref("")
const busRef = ref()
const props = defineProps(['workList','typeList'])
const emit = defineEmits(["getList"])
const state = reactive({
    form: {
      id: null,
      projectId: null,
      deviceName: '',
      startDate: '',
      endDate: ''
    },
    formRules:{
      deviceName: [{ required: true, message: '请填写设备名称', trigger: 'blur' }],
      startDate: [{ required: true, message: '请选择开始日期', trigger: 'blur' }],
      endDate: [{ required: true, message: '请选择结束日期', trigger: 'blur' }]
    }
})
const openDialog = async (type, value,projectId) => {
    title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看'
    state.form.projectId = projectId
    if(type == 'add'){
      nextTick(()=>{
        busRef.value.resetFields()
      })
    }else if(type === 'edit') {
      state.form = JSON.parse(JSON.stringify(value))
    }
    dialogVisible.value = true;
}
const onSubmit = async () => {
    const valid = await busRef.value.validate();
    if(valid){
        if(title.value === '新增'){
            const {id,...data} = state.form
            const res = await addDevice(data)
            if(res.code === 200){
                ElMessage({
                    type: 'success',
                    message: '新增成功'
                });
            }else{
                ElMessage.warning(res.message)
            }
            emit("getList")
            busRef.value.clearValidate();
            busRef.value.resetFields()
            dialogVisible.value = false;
        }else if(title.value === '编辑'){
            const {...data} = state.form
            const res = await editDevice(data)
            if(res.code === 200){
                ElMessage({
                    type: 'success',
                    message: '修改成功'
                });
            }else{
                ElMessage.warning(res.message)
            }
            emit("getList")
            busRef.value.clearValidate();
            busRef.value.resetFields()
            dialogVisible.value = false;
        }
    }
}
const handleClose = () => {
    busRef.value.clearValidate();
    busRef.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>
src/views/safetyReview/testManage/components/employNoticeRecord.vue
对比新文件
@@ -0,0 +1,206 @@
<template>
  <div class="riskBox">
    <el-form ref="formRef" :model="state.formData" :rules="state.rules" class="register-form" label-position="top">
      <el-row :gutter="30">
        <el-col :span="12">
          <el-form-item prop="timeRange" label="技术服务期限">
            <el-date-picker
                v-model="state.formData.timeRange"
                style="width: 100%"
                type="daterange"
                range-separator="至"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                value-format="YYYY-MM-DD 00:00:00"
                size="large"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="investigationPlanDate" label="计划现场勘验时间">
            <el-date-picker
                style="width: 100%"
                v-model="state.formData.investigationPlanDate"
                type="date"
                value-format="YYYY-MM-DD 00:00:00"
                placeholder="选择日期"
                size="large"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="18">
          <div style="display: flex;align-items: center">项目组成员<el-icon style="margin-left: 10px;margin-right: 4px"><InfoFilled /></el-icon><span style="font-size: 13px">金属、非金属矿及其他矿采选业:安全、机械、电气、采矿、通风、地质、水工结构</span></div>
        </el-col>
      </el-row>
      <el-table  :data="state.planPersons" :border="true" style="margin: 20px 0">
        <el-table-column label="序号" width="60" align="center" type="index"></el-table-column>
        <el-table-column label="评价组成员" prop="person.name" align="center" :show-overflow-tooltip="true">
          <template #default="scope">
            <span v-if="scope.row.jobType === 2">{{ scope.row.person.name }} (组长)</span>
            <span v-else>{{scope.row.person.name}}</span>
          </template>
        </el-table-column>
        <el-table-column label="专业能力/资格证书" prop="person.certificateNo" align="center" :show-overflow-tooltip="true">
          <template #default="scope">
            {{ getCertNo(scope.row) }}
          </template>
        </el-table-column>
        <el-table-column label="承担工作" prop="work" align="center" class-name="small-padding fixed-width"></el-table-column>
        <el-table-column label="承诺后期前往现场勘验" prop="laterPromise" align="center" class-name="small-padding fixed-width">
          <template #default="scope">
            {{(scope.row.laterPromise==1 || scope.row.laterPromise==true)?'是':'否'}}
          </template>
        </el-table-column>
        <el-table-column label="未到现场勘验原因" prop="reason" align="center" class-name="small-padding fixed-width"></el-table-column>
        <el-table-column label="是否已告知" align="center" class-name="small-padding fixed-width">
          <template #default="scope">
            <el-radio-group v-model="scope.row.informed" size="large" @change="(value)=>changePerson(value,scope.row)" :disabled="projectType==='view'">
              <el-radio :label="1" size="large">是</el-radio>
              <el-radio :label="0" size="large">否</el-radio>
            </el-radio-group>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
  </div>
</template>
<script setup>
import {defineEmits, defineProps, onMounted, reactive, ref, watchEffect} from "vue"
import {ElMessage} from "element-plus"
import {Search} from '@element-plus/icons-vue'
import {addWorkRecord, editWorkRecord, getWorkDetail} from "@/api/projectManage/employNoticeRcd"
import {getWorks, editWorks} from "@/api/projectManage/evaPlan"
import Cookies from "js-cookie"
const props = defineProps(['projectId'])
const emit = defineEmits(["getNextStatus"])
import { useRoute } from 'vue-router'
const route = useRoute()
const state = reactive({
  formData: {
    id: null,
    projectId: null,
    timeRange: [],
    serviceStartDate: '',
    serviceEndDate: '',
    investigationPlanDate: ''
  },
  projectId: null,
  planPersons: [],
  rules: {
    timeRange: [{required: true, message: '请选择技术服务期限', trigger: 'blur'}],
    investigationPlanDate: [{required: true, message: '请选择计划现场勘验时间', trigger: 'blur'}]
  }
})
const isAmin = ref(false)
const formRef = ref()
onMounted(() => {
  const userInfo = JSON.parse(Cookies.get('userInfo'))
  if(userInfo.identity === 0){
    isAmin.value = true;
  }
  if(props.projectId){
    getWorksList(props.projectId)
  }
});
const projectType = ref('');
const riskOpen = async (type,val) => {
  state.formData.projectId = val
  state.projectId = val
  projectType.value = route.query.type;
  // await getWorksList(val)
  if(type === 'detail' || type === 'edit' ){
    const res = await getWorkDetail({projectId: val})
    if(res.code == 200){
      state.formData = JSON.parse(JSON.stringify(res.data))
      state.formData.timeRange = [state.formData.serviceStartDate,state.formData.serviceEndDate]
    }else {
      ElMessage.warning(res.message)
    }
  }
  if(type === 'add' || type === 'clickEdit') {
    const valid = await formRef.value.validate();
    if(valid){
      if (isAmin.value) {
        ElMessage.warning("当前用户暂无权限");
        return;
      }
      state.formData.serviceStartDate = state.formData.timeRange[0]
      state.formData.serviceEndDate = state.formData.timeRange[1]
      if(type === 'add'){
        const {timeRange,id,...data} = JSON.parse(JSON.stringify(state.formData))
        const res = await addWorkRecord(data)
        if (res.code == 200) {
          ElMessage.success('保存成功')
          formRef.value.clearValidate();
          emit('getNextStatus', state.projectId);
        } else {
          ElMessage.warning(res.message)
        }
      }else if(type === 'clickEdit'){
        const {timeRange, ...data} = JSON.parse(JSON.stringify(state.formData))
        const res = await editWorkRecord(data);
        if (res.code == 200) {
          ElMessage.success('变更成功')
          formRef.value.clearValidate();
          // emit('getNextStatus', data.project.id);
        } else {
          ElMessage.warning(res.message)
        }
      }
    }
  }
}
const getWorksList = async (id) =>{
  const works = await getWorks({projectId: id ? id : props.projectId})
  if(works.code == 200){
    state.planPersons = works.data
  }else {
    ElMessage.warning(works.message)
  }
}
const getCertNo = (row)=>{
  const obj = JSON.parse(row.person.certificateNo)
  const noArr = Object.values(obj)
  return row.person.majorNames.map((item,index)=>{
    return item + '(' + noArr[index] + ')'
  }).join(',')
}
const changePerson = async (value,row)=>{
  const params = {
    id: row.id,
    projectId: row.projectId,
    informed: value
  }
  const res = await editWorks(params)
  if(res.code === 200){
    console.log(res.message)
  }else{
    ElMessage.warning(res.message)
  }
  await getWorksList(props.projectId)
}
defineExpose({
  riskOpen
});
</script>
<style scoped lang="scss">
.riskBox{
  :deep(.el-form .el-form-item__label) {
    font-size: 15px;
  }
}
</style>
src/views/safetyReview/testManage/components/evaluatePlan.vue
对比新文件
@@ -0,0 +1,521 @@
<template>
  <div class="riskBox">
    <el-form ref="formRef" :model="state.formData" :rules="state.rules" class="register-form" label-position="top">
      <el-row :gutter="30">
        <el-col :span="6">
          <el-form-item prop="startDate" label="评价开始时间">
            <el-date-picker
                style="width: 100%"
                v-model="state.formData.startDate"
                type="date"
                value-format="YYYY-MM-DD 00:00:00"
                placeholder="选择日期"
                size="large"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="endDate" label="评价结束时间">
            <el-date-picker
                style="width: 100%"
                v-model="state.formData.endDate"
                type="date"
                value-format="YYYY-MM-DD 00:00:00"
                placeholder="选择日期"
                size="large"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="auser.name" label="机构评价负责人">
            <el-input
                v-model.trim="state.formData.auser.name"
                size="large"
                placeholder="请选择机构评价负责人"
                @focus="openExperts('机构评价负责人')"
            >
              <template #append>
                <el-button :icon="Search" @click="openExperts('机构评价负责人')"/>
              </template>
            </el-input>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="18">
          <div style="display: flex;align-items: center">评价日程安排<el-icon style="margin-left: 10px;margin-right: 4px"><InfoFilled /></el-icon><span style="font-size: 13px">不涉及的日程安排日期可不填</span></div>
        </el-col>
      </el-row>
      <el-table :data="state.formData.estimateSchedules" :border="true" style="margin: 20px 0">
        <el-table-column label="序号" width="60" align="center" type="index"></el-table-column>
        <el-table-column label="评价日程安排" prop="name" align="center" :show-overflow-tooltip="true"/>
        <el-table-column label="开始时间" align="center" class-name="small-padding fixed-width">
          <template #default="scope">
            <el-date-picker
                style="width: 100%"
                v-model="scope.row.startDate"
                type="date"
                value-format="YYYY-MM-DD 00:00:00"
                placeholder="选择日期"
                size="large"
            />
          </template>
        </el-table-column>
        <el-table-column label="结束时间" align="center" class-name="small-padding fixed-width">
          <template #default="scope">
            <el-date-picker
                style="width: 100%"
                v-model="scope.row.endDate"
                type="date"
                value-format="YYYY-MM-DD 00:00:00"
                placeholder="选择日期"
                size="large"
            />
          </template>
        </el-table-column>
      </el-table>
      <el-row>
        <el-col :span="18">
          <div style="display: flex;align-items: center">项目组成员<el-icon style="margin-left: 10px;margin-right: 4px"><InfoFilled /></el-icon><span style="font-size: 13px">金属、非金属矿及其他矿采选业:安全、机械、电气、采矿、通风、地质、水工结构</span></div>
        </el-col>
        <el-col :span="6">
          <div style="width: 100%;display: flex;justify-content: right">
            <el-button type="primary" icon="Plus" @click="openWorksDialog('add',{})" :disabled="projectType==='view' || isEnd">添加成员</el-button>
          </div>
        </el-col>
      </el-row>
      <el-table  :data="state.planPersons" :border="true" style="margin: 20px 0">
        <el-table-column label="序号" width="60" align="center" type="index"></el-table-column>
        <el-table-column label="评价组成员" prop="person.name" align="center" :show-overflow-tooltip="true">
          <template #default="scope">
            <span v-if="scope.row.jobType === 2">{{ scope.row.person.name }} (组长)</span>
            <span v-else>{{scope.row.person.name}}</span>
          </template>
        </el-table-column>
        <el-table-column label="专业能力/资格证书" prop="person.certificateNo" align="center" :show-overflow-tooltip="true">
          <template #default="scope">
            {{ getCertNo(scope.row) }}
          </template>
        </el-table-column>
<!--        <el-table-column label="专业能力" header-align="center" :show-overflow-tooltip="true"></el-table-column>-->
        <el-table-column label="承担工作" prop="work" align="center" class-name="small-padding fixed-width"></el-table-column>
        <el-table-column label="承诺后期前往现场勘验" prop="laterPromise" align="center" class-name="small-padding fixed-width">
          <template #default="scope">
            {{(scope.row.laterPromise==1 || scope.row.laterPromise==true)?'是':'否'}}
          </template>
        </el-table-column>
        <el-table-column label="未到现场勘验原因" prop="reason" align="center" class-name="small-padding fixed-width"></el-table-column>
        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
          <template #default="scope">
            <el-button link @click="openWorksDialog('edit',scope.row)" :disabled="projectType==='view' || isEnd">修改</el-button>
            <el-button link type="danger" @click="delMember(scope.row)" :disabled="projectType==='view' || isEnd">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-row>
        <el-col :span="18">
          <div style="display: flex;align-items: center">所需仪器设备</div>
        </el-col>
        <el-col :span="6">
          <div style="width: 100%;display: flex;justify-content: right">
            <el-button type="primary" icon="Plus" @click="openDeviceDialog('add',{})" :disabled="projectType==='view' || isEnd">添加设备</el-button>
          </div>
        </el-col>
      </el-row>
      <el-table  :data="state.devices" :border="true" style="margin: 20px 0">
        <el-table-column label="序号" width="60" align="center" type="index"></el-table-column>
        <el-table-column label="设备名称" prop="deviceName" align="center" class-name="small-padding fixed-width"/>
        <el-table-column label="开始时间" prop="startDate" align="center" class-name="small-padding fixed-width">
          <template #default="scope">
            {{scope.row.startDate.substring(0,10)}}
          </template>
        </el-table-column>
        <el-table-column label="结束时间" prop="endDate" align="center" class-name="small-padding fixed-width">
          <template #default="scope">
            {{scope.row.endDate.substring(0,10)}}
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
          <template #default="scope">
            <el-button link @click="openDeviceDialog('edit',scope.row)" :disabled="projectType==='view' || isEnd">修改</el-button>
            <el-button link type="danger" @click="delDeviceItem(scope.row)" :disabled="projectType==='view' || isEnd">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
    <experts-list ref="expertsListRef" @getName="getSelected"></experts-list>
    <works-dialog ref="worksRef" @getList="getWorksList" :workList="state.workList" :typeList="state.jobTypeList"></works-dialog>
    <device-dialog ref="deviceRef" @getList="getDeviceList"></device-dialog>
  </div>
</template>
<script setup>
import {defineEmits, defineProps, onMounted, reactive, ref} from "vue"
import {ElMessage, ElMessageBox} from "element-plus"
import {Search} from '@element-plus/icons-vue'
import {addRecord, editRecord, getDetail, getWorks, getDevice, delWorks, delDevice} from "@/api/projectManage/evaPlan"
import Cookies from "js-cookie"
import ExpertsList from "./expertsList"
import WorksDialog from './worksDialog'
import DeviceDialog from './deviceDialog'
const props = defineProps(['projectId'])
const emit = defineEmits(["getNextStatus"])
import { useRoute } from 'vue-router'
const route = useRoute()
const state = reactive({
  formData: {
    id: null,
    projectId: null,
    auser: {
      name: ''
    },
    auserId: null,
    estimateSchedules: [
      {
        id: null,
        sort: 1,
        name: '勘验准备',
        startDate: '',
        endDate: '',
        scheduleType: 1,
        projectId: null
      },
      {
        id: null,
        sort: 2,
        name: '现场勘验',
        startDate: '',
        endDate: '',
        scheduleType: 2,
        projectId: null
      },
      {
        id: null,
        sort: 3,
        name: '材料分析整理',
        startDate: '',
        endDate: '',
        scheduleType: 3,
        projectId: null
      },
      {
        id: null,
        sort: 4,
        name: '评价报告编写',
        startDate: '',
        endDate: '',
        scheduleType: 4,
        projectId: null
      },
      {
        id: null,
        sort: 5,
        name: '整改情况现场确认',
        startDate: '',
        endDate: '',
        scheduleType: 5,
        projectId: null
      },
      {
        id: null,
        sort: 6,
        name: '整理评价报告',
        startDate: '',
        endDate: '',
        scheduleType: 6,
        projectId: null
      },
      {
        id: null,
        sort: 7,
        name: '报告审核',
        startDate: '',
        endDate: '',
        scheduleType: 7,
        projectId: null
      },
      {
        id: null,
        sort: 8,
        name: '报告修改',
        startDate: '',
        endDate: '',
        scheduleType: 8,
        projectId: null
      },
    ],
    planPersons: [],
    devices: [],
    startDate: '',
    endDate: ''
  },
  projectId: null,
  planPersons: [],
  devices: [],
  rules: {
    "auser.name": [{required: true, message: '请填写机构评价负责人', trigger: 'change'}],
    startDate: [{required: true, message: '请选择评价开始时间', trigger: 'change'}],
    endDate: [{required: true, message: '请选择评价结束时间', trigger: 'change'}]
  },
  workList: [
    {value: '报告编制',label: '报告编制'},
    {value: '文字校对',label: '文字校对'},
    {value: '现场勘验',label: '现场勘验'},
    {value: '资料收集整理',label: '资料收集整理'}
  ],
  jobTypeList: [
    {value: 1,label: '普通人员'},
    {value: 2,label: '组长'},
  ]
})
const isAmin = ref(false)
const formRef = ref()
const expertsListRef = ref()
const worksRef = ref()
const deviceRef = ref()
onMounted(async () => {
  const userInfo = JSON.parse(Cookies.get('userInfo'))
  if(userInfo.identity === 0){
    isAmin.value = true
  }
  if(props.projectId){
    await getWorksList(props.projectId)
    await getDeviceList(props.projectId)
  }
  isEnd.value = Cookies.get('end')
  projectType.value = route.query.type;
})
const projectType = ref('');
const isEnd = ref('')
const riskOpen = async (type,val) => {
  state.formData.projectId = val
  isEnd.value = Cookies.get('end')
  state.projectId = val
  projectType.value = route.query.type;
  for(let i of state.formData.estimateSchedules){
    i.projectId = val
  }
  // await getWorksList(val)
  // await getDeviceList(val)
  if(type === 'detail' || type === 'edit' ){
    const res = await getDetail({projectId: val})
    if(res.code == 200){
      state.formData = JSON.parse(JSON.stringify(res.data))
    }else {
      ElMessage.warning(res.message)
    }
  }
  if(type === 'add' || type === 'clickEdit') {
    const valid = await formRef.value.validate();
    if(valid){
      if (isAmin.value) {
        ElMessage.warning("当前用户暂无权限");
        return;
      }
      if(type === 'add'){
        const {id, ...data} = JSON.parse(JSON.stringify(state.formData))
        const params = Object.assign({}, state.formData.estimateSchedules);
        let i = 0
        for (const key in params) {
          if ((params[key].startDate == '' || params[key].startDate == null ) && (params[key].endDate == '' || params[key].endDate == null)) {
            delete params[key].startDate;
            delete params[key].endDate;
            i++
          }
        }
        console.log('data',params)
        const finData =  Object.entries(params).map(([key, value]) => ({
          ...value,
        }));
        if(i == finData.length){
          ElMessage.warning("请选择至少一个的日程安排日期");
          return;
        }
        try {
          finData.forEach(item =>{
            // debugger
            console.log(item.endDate,'item.endDate')
            if(item.startDate && (item.startDate !='' || item.startDate !=null)){
              if(item.endDate =='' || item.endDate ==null){
                ElMessage.warning("请完善涉及的日程安排结束日期");
                throw new Error('Loop stopped')
              }
            }
            if(item.endDate && (item.endDate !='' || item.endDate !=null)){
              if(item.startDate =='' || item.startDate ==null){
                ElMessage.warning("请完善涉及的日程安排开始日期");
                throw new Error('Loop stopped')
              }
            }
          })
        }catch (e) {
          throw new Error(e)
        }
        data.estimateSchedules = finData
        const res = await addRecord(data);
        if (res.code == 200) {
          ElMessage.success('保存成功')
          formRef.value.clearValidate();
          emit('getNextStatus', state.formData.projectId);
        } else {
          ElMessage.warning(res.message)
        }
      }else if(type === 'clickEdit'){
        const { ...data} = JSON.parse(JSON.stringify(state.formData))
        const params = Object.assign({}, state.formData.estimateSchedules);
        let i = 0
        for (const key in params) {
          if (params[key].startDate == '' && params[key].endDate == '') {
            delete params[key].startDate;
            delete params[key].endDate;
            i++;
          }
        }
        const finData =  Object.entries(params).map(([key, value]) => ({
          ...value,
        }));
        if(i == finData.length){
          ElMessage.warning("请选择至少一个的日程安排日期");
          return;
        }
        try {
          finData.forEach(item =>{
            // debugger
            console.log(item.endDate,'item.endDate')
            if(item.startDate && (item.startDate !='' || item.startDate !=null)){
              if(item.endDate =='' || item.endDate ==null){
                ElMessage.warning("请完善涉及的日程安排结束日期");
                throw new Error('Loop stopped')
              }
            }
            if(item.endDate && (item.endDate !='' || item.endDate !=null)){
              if(item.startDate =='' || item.startDate ==null){
                ElMessage.warning("请完善涉及的日程安排开始日期");
                throw new Error('Loop stopped')
              }
            }
          })
        }catch (e) {
          throw new Error(e)
        }
        data.estimateSchedules = finData
        const res = await editRecord(data);
        if (res.code == 200) {
          ElMessage.success('变更成功')
          formRef.value.clearValidate();
          // emit('getNextStatus', data.project.id);
        } else {
          ElMessage.warning(res.message)
        }
      }
    }
  }
}
const getWorksList = async (id) =>{
  const works = await getWorks({projectId: id ? id : props.projectId})
  if(works.code == 200){
    state.planPersons = works.data
  }else {
    ElMessage.warning(works.message)
  }
}
const getDeviceList = async (id) =>{
  const device = await getDevice({projectId: id ? id : props.projectId})
  if(device.code == 200){
    state.devices = device.data
  }else {
    ElMessage.warning(device.message)
  }
}
const getCertNo = (row)=>{
  const obj = JSON.parse(row.person.certificateNo)
  const noArr = Object.values(obj)
  return row.person.majorNames.map((item,index)=>{
    return item + '(' + noArr[index] + ')'
  }).join(',')
}
const openExperts = (type) =>{
  expertsListRef.value.openDialog(type)
}
const getSelected = (type,obj)=>{
  state.formData.auser.name = obj.name
  state.formData.auserId = obj.id
}
const openWorksDialog = (type,data)=>{
  worksRef.value.openDialog(type,data,props.projectId)
}
const openDeviceDialog = (type,data)=>{
  deviceRef.value.openDialog(type,data,props.projectId)
}
const delMember = (row)=>{
  ElMessageBox.confirm(
      '确定删除此条数据?',
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
      .then( async() => {
        const res = await delWorks(row.id)
        if(res.code == 200){
          ElMessage.success('数据删除成功')
          await getWorksList()
        }else{
          ElMessage.warning(res.message)
        }
      })
}
const delDeviceItem = (row)=>{
  console.log(row,'row')
  ElMessageBox.confirm(
      '确定删除此条数据?',
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
      .then( async() => {
        const res = await delDevice(row.id)
        if(res.code == 200){
          ElMessage.success('数据删除成功')
          await getDeviceList()
        }else{
          ElMessage.warning(res.message)
        }
      })
}
defineExpose({
  riskOpen
});
</script>
<style scoped lang="scss">
.riskBox{
  :deep(.el-form .el-form-item__label) {
    font-size: 15px;
  }
}
</style>
src/views/safetyReview/testManage/components/evaluateTaskNotice.vue
对比新文件
@@ -0,0 +1,197 @@
<template>
  <div class="riskBox">
    <el-form ref="formRef" :model="state.formData" :rules="state.rules" class="register-form" label-position="top">
      <el-row :gutter="30">
        <el-col :span="6">
          <el-form-item prop="leader.name" label="项目负责人">
            <el-input
                v-model.trim="state.formData.leader.name"
                size="large"
                placeholder="请选择项目负责人"
                @focus="openExperts('项目负责人')"
            >
              <template #append>
                <el-button :icon="Search" @click="openExperts('项目负责人')"/>
              </template>
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="linkMan" label="联系人">
            <el-input
                v-model.trim="state.formData.linkMan"
                size="large"
                placeholder="请选择联系人"
            >
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="linkPhone" label="联系电话">
            <el-input
                v-model.trim="state.formData.linkPhone"
                size="large"
                placeholder="请选择联系电话"
            >
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="传真">
            <el-input
                v-model.trim="state.formData.fax"
                size="large"
                placeholder="请选择传真"
            >
            </el-input>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="30">
        <el-col :span="6">
          <el-form-item label="任务下达人">
            <el-input
                v-model.trim="state.formData.transmitPerson"
                size="large"
                placeholder="请选择任务下达人"
                @focus="openExperts('任务下达人')"
            >
              <template #append>
                <el-button :icon="Search" @click="openExperts('任务下达人')"/>
              </template>
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="transmitDate" label="任务下达时间">
            <el-date-picker
                style="width: 100%"
                v-model="state.formData.transmitDate"
                type="date"
                value-format="YYYY-MM-DD 00:00:00"
                placeholder="选择日期"
                size="large"
            />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <experts-list ref="expertsListRef" @getName="getSelected"></experts-list>
  </div>
</template>
<script setup>
import {defineEmits, onMounted, reactive, ref} from "vue";
import {ElMessage} from "element-plus";
import {Search} from '@element-plus/icons-vue'
import {addRecord, editRecord, getDetail} from "@/api/projectManage/evaTaskNotice";
import Cookies from "js-cookie"
import ExpertsList from "./expertsList";
const emit = defineEmits(["getNextStatus"]);
const state = reactive({
  formData: {
    id: '',
    projectId: null,
    leader: {
      name: ''
    },
    fax: '',
    leaderId: null,
    linkMan: '',
    transmitPerson: '',
    transmitDate: ''
  },
  rules: {
    "leader.name": [{required: true, message: '请选择项目负责人', trigger: 'change'}],
    linkMan: [{required: true, message: '请输入联系人', trigger: 'blur'}],
    linkPhone: [{required: true, message: '请输入联系电话', trigger: 'blur'}],
    transmitDate: [{required: true, message: '请选择任务下达时间', trigger: 'change'}]
  }
})
const props = {
  expandTrigger: 'hover',
  value: 'name',
  label: 'name'
}
const isAmin = ref(false)
const formRef = ref()
const expertsListRef = ref()
onMounted(() => {
  const userInfo = JSON.parse(Cookies.get('userInfo'))
  if(userInfo.identity === 0){
    isAmin.value = true;
  }
})
const riskOpen = async (type,val) => {
  state.formData.projectId = val
  if(type === 'detail' || type === 'edit' ){
    const res = await getDetail({projectId: val});
    if(res.code == 200){
      state.formData = res.data;
    }else {
      ElMessage.warning(res.message)
    }
  }
  if(type === 'add' || type === 'clickEdit') {
    const valid = await formRef.value.validate();
    if(valid){
      if (isAmin.value) {
        ElMessage.warning("当前用户暂无权限");
        return;
      }
      if(type === 'add'){
        const {id, ...data} = JSON.parse(JSON.stringify(state.formData))
        const res = await addRecord(data);
        if (res.code == 200) {
          ElMessage.success('保存成功')
          formRef.value.clearValidate();
          emit('getNextStatus', state.formData.projectId);
        } else {
          ElMessage.warning(res.message)
        }
      }else{
        const { ...data} = JSON.parse(JSON.stringify(state.formData))
        const res = await editRecord(data);
        if (res.code == 200) {
          ElMessage.success('变更成功')
          formRef.value.clearValidate();
          // emit('getNextStatus', data.project.id);
        } else {
          ElMessage.warning(res.message)
        }
      }
    }
  }
}
const openExperts = (type) =>{
  expertsListRef.value.openDialog(type)
}
const getSelected = (type,obj)=>{
  if(type == '项目负责人'){
    state.formData.leader.name = obj.name
    state.formData.leaderId = obj.id
  }
  if(type == '任务下达人'){
    state.formData.transmitPerson = obj.name
  }
}
defineExpose({
  riskOpen
});
</script>
<style scoped lang="scss">
.riskBox{
  :deep(.el-form .el-form-item__label) {
    font-size: 15px;
  }
}
</style>
src/views/safetyReview/testManage/components/expertsList.vue
对比新文件
@@ -0,0 +1,344 @@
<template>
    <div class="notice">
        <el-dialog
            v-model="dialogVisible"
            :title="title"
            width="60%"
        >
          <el-form :model="queryParams" :inline="true" label-width="90px">
            <el-form-item label="专业类别">
              <el-radio-group v-model="queryParams.expertType">
                <el-radio-button label="">全部</el-radio-button>
                <el-radio-button label="1">安全评价</el-radio-button>
                <el-radio-button label="2">检验检测</el-radio-button>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="姓名">
              <el-input
                  v-model.trim="queryParams.name"
                  placeholder="姓名"
                  style="width: 250px"
              />
            </el-form-item>
            <el-form-item label="手机号">
              <el-input
                  v-model.trim="queryParams.phone"
                  placeholder="手机号"
                  style="width: 250px"
              />
            </el-form-item>
            <el-form-item label="评价师等级">
              <el-select v-model="queryParams.level" style="width: 250px" placeholder="评价师等级" >
                <el-option
                    v-for="item in levelList"
                    :key="item.id"
                    :label="item.name"
                    :value="item.name"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="专业方向">
              <el-select v-model="queryParams.major" clearable value-key="id" style="width: 250px" placeholder="专业方向">
                <el-option
                    v-for="item in majorList"
                    :key="item.id"
                    :label="item.label"
                    :value="item.id"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="职务">
              <el-select v-model="queryParams.post" clearable style="width: 250px" placeholder="请选择职务">
                <el-option
                    v-for="item in postList"
                    :key="item.id"
                    :label="item.name"
                    :value="item.name"
                />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="Search" @click="search">搜索</el-button>
              <el-button icon="Refresh" @click="research">重置</el-button>
            </el-form-item>
          </el-form>
          <el-table v-loading="loading" ref="tableRef" :data="dataList" :border="true" @select="select" @selection-change="handleSelectionChange">
            <el-table-column type="selection" width="55" />
            <el-table-column label="用户ID" prop="id" align="center"  />
            <el-table-column label="姓名" prop="name" align="center" width="110" />
            <el-table-column label="手机号" prop="phone" align="center" width="125" />
            <el-table-column label="用户名" prop="username" align="center" width="110" />
            <el-table-column label="性别" prop="sex" align="center" >
              <template #default="scope">
                <span v-if="scope.row.sex === 0">男</span>
                <span v-if="scope.row.sex === 1">女</span>
              </template>
            </el-table-column>
            <el-table-column label="所属机构" prop="agency.name" align="center" width="110"  />
            <el-table-column label="社保" prop="socialSecurity" align="center" width="120">
              <template #default="scope">
                <div class="demo-image__preview" v-if="scope.row.socialAttach && scope.row.socialAttach.length>0">
                  <el-image
                      style="width: 100px; height: 100px"
                      :src= "scope.row.socialAttach[0]"
                      :zoom-rate="1.2"
                      :max-scale="7"
                      :min-scale="0.2"
                      :preview-src-list="scope.row.socialAttach"
                      :initial-index="0"
                      fit="cover"
                      :preview-teleported= true
                  />
                </div>
              </template>
            </el-table-column>
            <el-table-column label="医保" prop="medicalInsurance" align="center" width="120">
              <template #default="scope">
                <div class="demo-image__preview" v-if="scope.row.medicalAttach && scope.row.medicalAttach.length>0">
                  <el-image
                      style="width: 100px; height: 100px"
                      :src="scope.row.medicalAttach[0]"
                      :zoom-rate="1.2"
                      :max-scale="7"
                      :min-scale="0.2"
                      :preview-src-list="scope.row.medicalAttach"
                      :initial-index="0"
                      fit="cover"
                      :preview-teleported= true
                  />
                </div>
              </template>
            </el-table-column>
            <el-table-column label="工资清单" prop="salaryList" align="center" width="120">
              <template #default="scope">
                <div class="demo-image__preview" v-if="scope.row.salaryAttach && scope.row.salaryAttach.length>0">
                  <el-image
                      style="width: 100px; height: 100px"
                      :src= "scope.row.salaryAttach[0]"
                      :zoom-rate="1.2"
                      :max-scale="7"
                      :min-scale="0.2"
                      :preview-src-list="scope.row.salaryAttach"
                      :initial-index="0"
                      fit="cover"
                      :preview-teleported= true
                  />
                </div>
              </template>
            </el-table-column>
            <el-table-column label="职务" prop="post" align="center" width="120" />
            <el-table-column label="职称" prop="jobTitle" align="center"  />
            <el-table-column label="专业方向" prop="majorNames" align="center" width="100" />
            <el-table-column label="评价师等级" prop="level" align="center" width="100" />
            <el-table-column label="业绩汇总" prop="summary" align="center">
              <template #default="scope">
                <div style="cursor:pointer;color: #3b82f6;" @click="openList(scope.row)">
                  <span>{{scope.row.projectCount}}</span>
                </div>
              </template>
            </el-table-column>
            <el-table-column label="最近评价时间" prop="lastEstimateTime" align="center" width="120" />
          </el-table>
          <pagination
              v-show="total > 0"
              :total="total"
              v-model:page="queryParams.pageNum"
              v-model:limit="queryParams.pageSize"
              @pagination="getList"
          />
<!--            <template #footer>-->
<!--                    <span class="dialog-footer">-->
<!--                        <el-button @click="dialogVisible = false" size="default">取 消</el-button>-->
<!--                        <el-button type="primary"  @click="onSubmit" size="default" v-preReClick>确认</el-button>-->
<!--                    </span>-->
<!--            </template>-->
        </el-dialog>
      <project-dialog ref="projectRef" @getList="getList"></project-dialog>
    </div>
</template>
<script setup>
import {getCurrentInstance, onMounted, reactive, ref, toRefs,defineEmits} from "vue";
import {getDictList} from "@/api/backManage/evaluate";
import {ElMessage, ElMessageBox} from "element-plus";
import projectDialog from "@/views/safetyReview/userManage/expertUsers/components/projectDialog.vue"
import Cookies from "js-cookie";
import {delMonitor, getExpertList, getMonitorList} from "@/api/sysUsers";
const { proxy } = getCurrentInstance();
const loading = ref(false);
const emit = defineEmits(['getName'])
const data = reactive({
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    expertType: "",
    name: '',
    phone: '',
    level: '',
    major: null,
    post: ''
  },
  total: 0,
  dataList: [],
  majorList: [],
  levelList: [
    {
      id: '1',
      name: '一级'
    },
    {
      id: '2',
      name: '二级'
    },
    {
      id: '3',
      name: '三级'
    },
    {
      id: '4',
      name: '其他'
    },
  ],
  postList: [
    {
      id: '1',
      name: '法人'
    },
    {
      id: '2',
      name: '过程控制负责人'
    },
    {
      id: '3',
      name: '机构负责人'
    },
    {
      id: '4',
      name: '技术负责人'
    },
    {
      id: '5',
      name: '员工'
    },
  ],
  dialogVisible: false,
  title: '',
  selected: []
})
const tableRef = ref()
const { queryParams, total, dataList, majorList, levelList, postList, dialogVisible,title,selected } = toRefs(data);
const openDialog = (type) => {
  getMajor()
  research()
  data.selected = []
  data.title = type
  data.dialogVisible = true
}
const onSubmit = async () => {
  if(data.selected.length>0)
  emit('getName',data.title,data.selected[data.selected.length - 1])
  data.dialogVisible = false
}
const getList = async () => {
  loading.value = true
  const res = await getExpertList(data.queryParams)
  if(res.code == 200){
    data.dataList = res.data.list.map(item => {
      return{
        ...item,
        socialAttach: item.socialAttach.map(s => { return import.meta.env.VITE_APP_BASE_API + '/' + s.path}),
        medicalAttach: item.medicalAttach.map(s => { return import.meta.env.VITE_APP_BASE_API + '/' + s.path}),
        salaryAttach: item.salaryAttach.map(s => { return import.meta.env.VITE_APP_BASE_API + '/' + s.path}),
        lastEstimateTime: item.personProjectVO ? item.personProjectVO.lastEstimateTime.slice(0,10) : '',
        projectCount: item.personProjectVO ? item.personProjectVO.projectCount : ''
      }
    })
    console.log('RES',data.dataList)
    data.total = res.data.total
  }else{
    ElMessage.warning(res.message)
  }
  loading.value = false
}
const projectRef = ref();
const openList = (val) => {
  projectRef.value.openDialog(val);
}
const getMajor = async () => {
  const queryParams = {
    pageNum: 1,
    pageSize: 50,
    dictType: 'sys_major_orientation'
  }
  const res = await getDictList(queryParams);
  if(res.code === 200){
    data.majorList = res.data.list
  }else{
    ElMessage.warning(res.message)
  }
}
const select = ((selection, row) => {
  tableRef.value.clearSelection()
  if(selection.length == 0)  {
    return
  }
  tableRef.value.toggleRowSelection(row, true);
})
const handleSelectionChange = (val) => {
  data.selected = val
  if(data.selected.length>0){
    emit('getName',data.title,data.selected[data.selected.length - 1])
    data.dialogVisible = false
  }
}
const search = ()=>{
  data.queryParams.pageNum = 1
  getList()
}
const research = ()=>{
  data.queryParams = {
    pageNum: 1,
    pageSize: 10,
    expertType: "",
    name: '',
    phone: '',
    level: '',
    major: null,
    post: ''
  }
  getList()
}
defineExpose({
    openDialog
});
</script>
<style scoped lang="scss">
.notice{
    :deep(.el-form .el-form-item__label) {
        font-size: 15px;
    }
    ::v-deep(.el-table th.el-table__cell:nth-child(1) .cell) {
      visibility: hidden;
    }
    .file {
        display: flex;
        flex-direction: column;
        align-items: flex-start;
    }
}
</style>
src/views/safetyReview/testManage/components/innerReview.vue
对比新文件
@@ -0,0 +1,276 @@
<template>
  <div class="riskBox">
    <el-form ref="formRef" :model="state.formData" :rules="state.rules" class="register-form" label-position="top">
      <el-row :gutter="30">
        <el-col :span="6">
          <el-form-item prop="auditDate" label="审核日期">
            <el-date-picker
                style="width: 100%"
                v-model="state.formData.auditDate"
                type="date"
                value-format="YYYY-MM-DD 00:00:00"
                placeholder="选择日期"
                size="large"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="assessor.name" label="内部审核员">
            <el-input
                v-model.trim="state.formData.assessor.name"
                size="large"
                placeholder="请选择内部审核员"
                @focus="openExperts('内部审核员')"
            >
              <template #append>
                <el-button :icon="Search" @click="openExperts('内部审核员')"/>
              </template>
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="内部审核确认日期" prop="affirmDate">
            <el-date-picker
                style="width: 100%"
                v-model="state.formData.affirmDate"
                type="date"
                value-format="YYYY-MM-DD 00:00:00"
                placeholder="选择日期"
                size="large"
            />
          </el-form-item>
        </el-col>
      </el-row>
<!--      <el-row :gutter="30">-->
<!--        <el-col :span="6">-->
<!--          <el-form-item label="附件上传">-->
<!--            <el-upload accept="image/*" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="handleAvatarSuccess" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='state.imgLimit' v-model:file-list="state.fileList" list-type="picture-card" :before-upload="picSize" :on-remove="handleRemove" :before-remove="beforeRemove">-->
<!--              <el-icon><Plus /></el-icon>-->
<!--              <template #tip>-->
<!--                <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传1张</div>-->
<!--              </template>-->
<!--            </el-upload>-->
<!--          </el-form-item>-->
<!--        </el-col>-->
<!--      </el-row>-->
      <el-table  :data="state.tableData" :border="true" style="margin: 20px 0">
        <el-table-column label="序号" width="60" align="center" type="index"></el-table-column>
        <el-table-column label="内容" prop="content" header-align="center" :show-overflow-tooltip="true"/>
        <el-table-column label="选择" header-align="center" class-name="small-padding fixed-width" width="175">
          <template #default="scope">
            <el-radio-group v-model="scope.row.status" >
              <el-radio :label="1">是</el-radio>
              <el-radio :label="0">否</el-radio>
            </el-radio-group>
          </template>
        </el-table-column>
      </el-table>
      <el-form-item prop="suggestions" label="存在问题及建议">
        <el-input
            v-model.trim="state.formData.suggestions"
            :autosize="{ minRows: 6 }"
            maxlength="500"
            show-word-limit
            type="textarea">
        </el-input>
      </el-form-item>
    </el-form>
<!--    <el-dialog v-model="state.dialogImg">-->
<!--      <el-image style="width: 100%; height: 100%" :src="state.dialogImageUrl"/>-->
<!--    </el-dialog>-->
    <experts-list ref="expertsListRef" @getName="getSelected"></experts-list>
  </div>
</template>
<script setup>
import {defineEmits, onMounted, reactive, ref} from "vue";
import {ElMessage} from "element-plus";
import {Search} from '@element-plus/icons-vue'
import {addInnerReview, editInnerReview, getInnerReviewDetail} from "@/api/projectManage/innerReview"
import {delPic} from "@/api/login"
import { getToken } from "@/utils/auth";
import Cookies from "js-cookie"
import ExpertsList from "./expertsList";
const emit = defineEmits(["getNextStatus"]);
const state = reactive({
  formData: {
    id: '',
    projectId: '',
    auditDate:'',
    auditType: 1,
    assessor: {
      name: ''
    },
    assessorId: null,
    affirmDate: '',
    suggestions: ''
  },
  rules: {
    "assessor.name": [{required: true, message: '请选择内部审核员', trigger: 'change'}],
    auditDate: [{required: true, message: '请选择审核日期', trigger: 'change'}],
    affirmDate: [{required: true, message: '请选择内部审核确认日期', trigger: 'change'}]
  },
  tableData: [
    {id: 1, content: '评价依据是否充分、准确、有效',key: 'isBasis', status: 1},
    {id: 2, content: '评价范围是否与合同一致', key: 'isScope', status: 1},
    {id: 3, content: '危险有害因素识别是否全面', key: 'isDangerOverall', status: 1},
    {id: 4, content: '评价单元划分是否合理', key: 'isUnitDivision', status: 1},
    {id: 5, content: '评价方法选择是否适当', key: 'isMethodSelection', status: 1},
    {id: 6, content: '对策措施与建议是否可行', key: 'isMeasure', status: 1},
    {id: 7, content: '结论是否正确', key: 'isConclusion', status: 1},
    {id: 8, content: '格式是否符合要求', key: 'isFormat', status: 1},
    {id: 9, content: '附件与附图是否有效及规范', key: 'isFile', status: 1},
    {id: 10, content: '文字、数据是否准确', key: 'isText', status: 1},
    {id: 11, content: '已按要求修改完成', key: 'isAmendFinish', status: 1},
    {id: 12, content: '可报技术负责人审核', key: 'isReportAudit', status: 1}
  ],
  imgLimit: 1,
  fileList: [],
  uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile',
  header: {
    Authorization: getToken()
  },
  dialogImageUrl: '',
  dialogImg: false
})
const isAmin = ref(false)
const formRef = ref()
const expertsListRef = ref()
onMounted(() => {
  const userInfo = JSON.parse(Cookies.get('userInfo'))
  if(userInfo.identity === 0){
    isAmin.value = true;
  }
})
const riskOpen = async (type,val) => {
  state.formData.projectId = val
  if(type === 'detail' || type === 'edit' ){
    const res = await getInnerReviewDetail({projectId: val,auditType: 1});
    if(res.code == 200){
      state.formData = res.data
      for(let key in res.data){
        for(let item of state.tableData){
          if(item.key == key){
            item.status = res.data[key]==true?1:0
          }
        }
      }
    }else {
      ElMessage.warning(res.message)
    }
  }
  if(type === 'add' || type === 'clickEdit') {
    const valid = await formRef.value.validate();
    if(valid){
      if (isAmin.value) {
        ElMessage.warning("当前用户暂无权限");
        return;
      }
      if(type === 'add'){
        const {id, ...data} = JSON.parse(JSON.stringify(state.formData))
        for(let i of state.tableData){
          data[i.key] = i.status
        }
        const res = await addInnerReview(data);
        if (res.code == 200) {
          ElMessage.success('保存成功')
          formRef.value.clearValidate();
          emit('getNextStatus', val);
        } else {
          ElMessage.warning(res.message)
        }
      }else if(type === 'clickEdit'){
        const { ...data} = JSON.parse(JSON.stringify(state.formData))
        for(let i of state.tableData){
          data[i.key] = i.status
        }
        const res = await editInnerReview(data);
        if (res.code == 200) {
          ElMessage.success('变更成功')
          formRef.value.clearValidate();
          // emit('getNextStatus', data.project.id);
        } else {
          ElMessage.warning(res.message)
        }
      }
    }
  }
}
const openExperts = (type) =>{
  expertsListRef.value.openDialog(type)
}
const getSelected = (type,obj)=>{
  state.formData.assessor.name = obj.name
  state.formData.assessorId = obj.id
}
// 图片上传
const showTip =()=>{
  ElMessage({
    type: 'warning',
    message: '超出文件上传数量'
  });
}
const picSize = async (rawFile) => {
  if(rawFile.size / 1024 / 1024 > 5){
    ElMessage({
      type: 'warning',
      message: '文件大小不能超过5M'
    });
    return false
  }
};
const handlePictureCardPreview = (uploadFile) => {
  state.dialogImageUrl = uploadFile.url
  state.dialogImg = true
};
const handleAvatarSuccess = (res, uploadFile) => {
  if(res.code == 200){
    // state.registerForm.agency.reportPath = res.data.path
  }else{
    ElMessage({
      type: 'warning',
      message: '文件上传失败'
    })
  }
}
const handleRemove = async (file, uploadFiles) => {
  const res = await delPic({path: state.registerForm.agency.reportPath})
  if(res.code == 200){
    ElMessage({
      type: 'success',
      message: '文件已删除'
    })
  }else{
    ElMessage({
      type: 'warning',
      message: res.message
    })
  }
}
defineExpose({
  riskOpen
});
</script>
<style scoped lang="scss">
.riskBox{
  :deep(.el-form .el-form-item__label) {
    font-size: 15px;
  }
}
</style>
src/views/safetyReview/testManage/components/mapLocation.vue
对比新文件
@@ -0,0 +1,162 @@
<template>
  <el-dialog
      v-model="state.mapLocationVisible"
      append-to-body
      :close-on-click-modal="false"
      width="75%"
      :title="state.title"
  >
    <div class="mapLocation_head">
      <div>
        <el-alert
            title="点击地点获取经纬度信息"
            type="info"
            :closable="false"
        >
        </el-alert>
      </div>
      <div class="mapLocation_latlng">
        <span>经度:</span>
        <el-input class="mapLocation_latlng_input" id="lng" v-model.trim="state.longitude" @change="getAdress"></el-input>
      </div>
      <div class="mapLocation_latlng">
        <span>纬度:</span>
        <el-input class="mapLocation_latlng_input" id="lat" v-model.trim="state.latitude" @change="getAdress"></el-input>
      </div>
      <div class="mapLocation_latlng">
        <span>地址:</span>
        <el-input class="mapLocation_latlng_input" id="lat" v-model.trim="state.BAddress"></el-input>
      </div>
    </div>
    <div class="mapLocation_body">
      <baidu-map class="map"  @ready="getAdress" ak="BkZdiHBj9aGrMdVFM48r2njNiMzsekga" v="3.0" type="API" :center="state.center" :zoom="state.zoom" scroll-wheel-zoom  @click="getPosition">
        <div style="position: absolute;z-index: 999;margin-top: -495px">
          <label>搜索:<input v-model="state.keyword"></label>
          <bm-local-search
              :keyword="state.keyword"
              :auto-viewport="true"
              location="新疆"
              :pageCapacity="3"
          ></bm-local-search>
        </div>
        <bm-marker :position="{lng: state.longitude, lat: state.latitude}" :dragging="true" animation="BMAP_ANIMATION_BOUNCE">
          <bm-label content="选择地点" :labelStyle="{color: 'red', fontSize : '24px'}" :offset="{width: -35, height: 30}"/>
        </bm-marker>
      </baidu-map>
    </div>
    <div  align="right" style="margin-top: 10px">
      <el-button @click="state.mapLocationVisible = false">取消</el-button>
      <el-button type="primary" @click="submitLatLng()">确认</el-button>
    </div>
  </el-dialog>
</template>
<script setup>
import {ref, onMounted, reactive, toRefs, defineComponent, defineExpose, defineEmits, watch} from 'vue';
import { BaiduMap,BmMarker,BmLocalSearch } from 'vue-baidu-map-3x'
const state = reactive({
  title: '',
  longitude: '',
  latitude: '',
  mapLocationVisible: false,
  zoom: 7,
  center: {
    lng: '116.42585576793277',
    lat: '39.88973394962104'
  },
  keyword:'',
  location: '',
  BAddress: ''
})
const emit = defineEmits(['giveLatLng'])
onMounted(() => {
  // ...(mounted钩子中的代码不变)
});
const map = reactive({})
const getPosition = ({type, target, point, pixel, overlay})=>{
  state.longitude = point.lng
  state.latitude = point.lat
  getAdress()
}
const openMapLocation=(longitude,latitude)=>{
  if(longitude != ""){
    state.longitude = longitude
    state.latitude = latitude
    state.zoom = 13
    state.center = {
      lng: longitude,
      lat: latitude
    }
  }else {
    state.zoom = 7
    state.center = {
      lng: '87.61552721758208',
      lat: '43.839018284106565'
    }
  }
  state.mapLocationVisible = true
}
const submitLatLng=()=>{
  state.mapLocationVisible = false
  emit('giveLatLng',state.longitude,state.latitude);
}
const initMap=()=>{
}
const myGeo = ref(null)
const getAdress = () => {
  myGeo.value = new BMap.Geocoder();
  const pt = new BMap.Point(state.longitude, state.latitude);
  myGeo.value.getLocation(pt,function(result){
      state.BAddress = result.address; //获取到当前定位的详细地址信息
    },
      { enableHighAccuracy: true }
  );
}
defineExpose({
  openMapLocation
})
</script>
<style lang="scss" scoped>
.map {
  width: 100%;
  height: 500px;
  :deep(.BMap_cpyCtrl){
    display: none!important;
    visibility: hidden!important;
  }
  :deep(.anchorBL) {
    display: none!important;
    visibility: hidden!important;
  }
}
.mapLocation_head{
  width:100%;
  height:100px;
}
.mapLocation_body{
  width:100%;
  height:500px
}
.mapLocation_latlng{
  padding-top:10px;
  display:inline-block;
  margin-right: 20px;
}
.mapLocation_latlng_input{
  width:250px;
}
</style>
src/views/safetyReview/testManage/components/processCtrlReview.vue
对比新文件
@@ -0,0 +1,364 @@
<template>
  <div class="riskBox">
    <el-form ref="formRef" :model="state.formData" :rules="state.rules" class="register-form" label-position="top">
      <el-row :gutter="30">
        <el-col :span="6">
          <el-form-item prop="auditDate" label="审核日期">
            <el-date-picker
                style="width: 100%"
                v-model="state.formData.auditDate"
                type="date"
                value-format="YYYY-MM-DD 00:00:00"
                placeholder="选择日期"
                size="large"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="processLeader.name" label="过程控制负责人">
            <el-input
                v-model.trim="state.formData.processLeader.name"
                size="large"
                placeholder="请选择过程控制负责人"
                @focus="openExperts('过程控制负责人')"
            >
              <template #append>
                <el-button :icon="Search" @click="openExperts('过程控制负责人')"/>
              </template>
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="isFullProcess" label="审核结论:是否满足过程控制要求">
            <el-radio-group v-model="state.formData.isFullProcess" >
              <el-radio :label="1">是</el-radio>
              <el-radio :label="0">否</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
      </el-row>
      <el-table  :data="state.tableData" :border="true" style="margin: 20px 0">
        <el-table-column label="序号" width="60" align="center" type="index"></el-table-column>
        <el-table-column label="过程控制关键点" prop="content" header-align="center" :show-overflow-tooltip="true"/>
        <el-table-column label="审核结果" header-align="center" class-name="small-padding fixed-width" width="175">
          <template #default="scope">
            <el-radio-group v-model="scope.row.status" @change="changeStatus(scope.row)">
              <el-radio :label="1">符合</el-radio>
              <el-radio :label="0">不符合</el-radio>
            </el-radio-group>
          </template>
        </el-table-column>
        <el-table-column label="不符合描述" header-align="center" class-name="small-padding fixed-width" width="700">
          <template #default="scope">
            <el-input
                v-model.trim="scope.row.reason"
                size="large"
                :disabled="scope.row.status == 1"
                placeholder="如不符合,请填写不符合描述"
            />
          </template>
        </el-table-column>
      </el-table>
      <el-form-item prop="suggestions" label="存在问题及建议">
        <el-input
            v-model.trim="state.formData.suggestions"
            :autosize="{ minRows: 6 }"
            maxlength="500"
            show-word-limit
            type="textarea">
        </el-input>
      </el-form-item>
      <el-row :gutter="30">
        <el-col :span="18">
          <el-form-item label="附件上传" prop="assAccessoryFiles">
            <el-upload accept="image/*,.pdf,.doc,.docx,.xlsx,.xls" :action="state.uploadUrl" :data="{moduleType: 8,projectId: props.projectId}" :headers="state.header" method="post" :on-success="handleAvatarSuccess" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='1' v-model:file-list="state.fileList" :before-upload="picSize" :disabled="projectType === 'view' || isEnd" :on-remove="handleRemove" >
              <el-button type="primary">附件上传</el-button>
              <template #tip>
                <div class="el-upload__tip">上传文件尺寸小于5M,最多可上传1份</div>
              </template>
            </el-upload>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <el-dialog v-model="state.dialogImg">
      <el-image style="width: 100%; height: 100%" :src="state.dialogImageUrl"/>
    </el-dialog>
    <experts-list ref="expertsListRef" @getName="getSelected"></experts-list>
  </div>
</template>
<script setup>
import {defineEmits, onMounted, reactive, ref} from "vue";
import {ElMessage, ElMessageBox} from "element-plus";
import {Search} from '@element-plus/icons-vue'
import {delFile, getFiles} from "@/api/projectManage/siteCheckRcd"
import {addProcessCtrl, editProcessCtrl,getProcessCtrlDetail} from "@/api/projectManage/processCtrl"
import {delPic} from "@/api/login"
import { getToken } from "@/utils/auth";
import Cookies from "js-cookie"
import ExpertsList from "./expertsList";
import axios from "axios";
import { useRoute } from 'vue-router'
const route = useRoute()
const props = defineProps(['projectId'])
const emit = defineEmits(["getNextStatus"]);
const state = reactive({
  formData: {
    id: null,
    projectId: null,
    auditDate: '',
    processLeader: {name: ''},
    processLeaderId: null,
    isFullProcess: null,
    suggestions: ''
  },
  rules: {
    auditDate: [{required: true, message: '请选择审核日期', trigger: 'blur'}],
    'processLeader.name': [{required: true, message: '请选择过程控制负责人', trigger: 'change'}],
    isFullProcess: [{required: true, message: '请选择审核结论', trigger: 'blur'}]
  },
  tableData: [
    {id: 1, content: '风险分析', status: 1, key:'isRiskAnalyse', reasonKey: 'riskAnalyseDes', reason: ''},
    {id: 2, content: '签订合同', status: 1, key:'isSignContract', reasonKey: 'signContractDes', reason: ''},
    {id: 3, content: '评价任务通知书', status: 1, key:'isEstimateTask', reasonKey: 'estimateTaskDes', reason: ''},
    {id: 4, content: '编制安全评价项目计划书', status: 1, key:'isEstimatePlan', reasonKey: 'estimatePlanDes', reason: ''},
    {id: 5, content: '被评价单位提供材料清单', status: 1, key:'isProvideMaterials', reasonKey: 'provideMaterialsDes', reason: ''},
    {id: 6, content: '从业告知', status: 1, key:'isWorkNotification', reasonKey: 'workNotificationDes', reason: ''},
    {id: 7, content: '现场勘验记录及影像资料', status: 1, key:'isInvestigationSite', reasonKey: 'investigationSiteDes', reason: ''},
    {id: 8, content: '评价报告内部审核', status: 1, key:'isInteriorAudit', reasonKey: 'interiorAuditDes', reason: ''},
    {id: 9, content: '技术负责人审核', status: 1, key:'isTechnolgyAudit', reasonKey: 'technolgyAuditDes', reason: ''},
    {id: 6, content: '评价报告外审意见', status: 1, key:'isExteriorAudit', reasonKey: 'exteriorAuditDes', reason: ''},
    {id: 7, content: '评价项目网上信息公开', status: 1, key:'isOpenInformation', reasonKey: 'openInformationDes', reason: ''},
    // {id: 8, content: '二维码的使用', status: 1, key:'isUseQrcode', reasonKey: 'useQrcodeDes', reason: ''},
    {id: 9, content: '报告归档材料完整性', status: 1, key:'isFullMaterials', reasonKey: 'fullMaterialsDes', reason: ''}
  ],
  uploadUrl: import.meta.env.VITE_APP_BASE_API + '/manage/accessory-file/uploadFile',
  header: {
    Authorization: getToken()
  },
  disabled:false
})
const isAmin = ref(false)
const formRef = ref()
const expertsListRef = ref()
onMounted(() => {
  const userInfo = JSON.parse(Cookies.get('userInfo'))
  if(userInfo.identity === 0){
    isAmin.value = true;
  }
  getProcessFiles(props.projectId)
  isEnd.value = Cookies.get('end')
  projectType.value = route.query.type;
})
const projectType = ref('');
const isEnd = ref('')
const riskOpen = async (type,val) => {
  state.formData.projectId = val
  isEnd.value = Cookies.get('end')
  projectType.value = route.query.type;
  if(type === 'detail' || type === 'edit' ){
    if(type === 'detail'){
      state.disabled = true
    }
    const res = await getProcessCtrlDetail({projectId: val});
    if(res.code == 200){
      state.formData = res.data
      state.formData.isFullProcess = res.data.isFullProcess==true?1:0
      for(let key in res.data){
        for(let item of state.tableData){
          if(item.key == key){
            item.status = res.data[key]==true?1:0
          }
          if(item.reasonKey == key){
            item.reason = res.data[key]
          }
        }
      }
    }else {
      ElMessage.warning(res.message)
    }
  }
  if(type === 'add' || type === 'clickEdit') {
    const valid = await formRef.value.validate();
    if(valid){
      if (isAmin.value) {
        ElMessage.warning("当前用户暂无权限");
        return;
      }
      if(type === 'add'){
        const {id,processLeader, ...data} = JSON.parse(JSON.stringify(state.formData))
        for(let i of state.tableData){
          if(i.status == 1){
            i.reason = ''
          }else{
            if(i.reason == ''){
              ElMessage.warning("请完善不符合项描述");
              return
            }
          }
          data[i.key] = i.status
          data[i.reasonKey] = i.reason
        }
        const res = await addProcessCtrl(data);
        if (res.code == 200) {
          ElMessage.success('保存成功')
          formRef.value.clearValidate();
          emit('getNextStatus', val);
        } else {
          ElMessage.warning(res.message)
        }
      }else if(type === 'clickEdit'){
        const {processLeader, ...data} = JSON.parse(JSON.stringify(state.formData))
        for(let i of state.tableData){
          data[i.key] = i.status
          data[i.reasonKey] = i.reason
          if(i.status == 1){
            i.reason = ''
          }
        }
        const res = await editProcessCtrl(data);
        if (res.code == 200) {
          ElMessage.success('变更成功')
          formRef.value.clearValidate();
          // emit('getNextStatus', data.project.id);
        } else {
          ElMessage.warning(res.message)
        }
      }
    }
  }
}
const changeStatus = (val) => {
  if(val.status == 1 && val.reason != "") {
    const index = state.tableData.findIndex(item => item.id == val.id)
    state.tableData[index].reason = ""
  }
}
const openExperts = (type) =>{
  expertsListRef.value.openDialog(type)
}
const getSelected = (type,obj)=>{
  state.formData.processLeader.name = obj.name
  state.formData.processLeaderId = obj.id
}
const getProcessFiles = async (id)=>{
  const res = await getFiles({projectId: id ? id : props.projectId,moduleType: 8})
  if(res.code == 200){
    if(res.data && res.data.length>0){
      state.fileList = res.data.map(i=>{
        return {
          name: i.originName,
          url: import.meta.env.VITE_APP_BASE_API + '/' + i.path,
          id: i.id,
          projectId: i.projectId,
          moduleType: i.moduleType
        }
      })
    }else{
      state.fileList = []
    }
  }else {
    ElMessage.warning(res.message)
  }
}
// 图片上传
const showTip =()=>{
  ElMessage({
    type: 'warning',
    message: '超出文件上传数量'
  });
}
const picSize = async (rawFile) => {
  if(rawFile.size / 1024 / 1024 > 5){
    ElMessage({
      type: 'warning',
      message: '文件大小不能超过5M'
    });
    return false
  }
};
const handlePictureCardPreview = (uploadFile) => {
  axios.get(uploadFile.url,{headers:{'Content-Type': 'application/json','Authorization': `${getToken()}`,'uid':`${Cookies.get('uid')}`},responseType: 'blob'}).then(res=>{
    if (res) {
      const link = document.createElement('a')
      let blob = new Blob([res.data],{type: res.data.type})
      link.style.display = "none";
      link.href = URL.createObjectURL(blob); // 创建URL
      window.open(link.href)
    } else {
      ElMessage({
        type: 'warning',
        message: '文件读取失败'
      });
    }
  })
};
const handleAvatarSuccess = (res, uploadFile) => {
  if(res.code == 200){
    getProcessFiles()
  }else{
    ElMessage({
      type: 'warning',
      message: '文件上传失败'
    })
  }
}
const handleRemove = async (file, uploadFile) => {
  if(file && file.status == 'success') {
    ElMessageBox.confirm(
        '确定删除该附件?',
        '提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        })
        .then(async () => {
          const res = await delFile(file.id)
          if (res.code == 200) {
            ElMessage({
              type: 'success',
              message: '文件已删除'
            })
            await getProcessFiles()
          } else {
            ElMessage({
              type: 'warning',
              message: res.message
            })
          }
        })
        .catch(() => {
          getProcessFiles()
        })
  }
}
defineExpose({
  riskOpen
});
</script>
<style scoped lang="scss">
.riskBox{
  :deep(.el-form .el-form-item__label) {
    font-size: 15px;
  }
}
</style>
src/views/safetyReview/testManage/components/projectArchive.vue
对比新文件
@@ -0,0 +1,390 @@
<template>
  <div class="riskBox">
    <el-form ref="formRef" :model="state.formData" :rules="state.rules" class="register-form" label-position="top">
      <el-row :gutter="30">
        <el-col :span="10">
<!--          <el-button type="primary" :disabled="projectType === 'edit'" @click="addUpload">新增附件列表</el-button>-->
          <span style="font-size: 20px;font-weight: 600">附件列表</span>
          <span style="font-size: 13px;color: rgb(232, 78, 79);font-weight: 400;margin-left: 10px">项目列表仅支持pdf、jpg、jpeg 等格式上传</span>
        </el-col>
      </el-row>
      <el-table  :data="state.uploadList" :border="true" style="margin: 20px 0">
        <el-table-column label="序号" width="60" align="center" type="index"></el-table-column>
        <el-table-column label="名称" align="center" class-name="small-padding fixed-width">
          <template #default="scope">
            <span   type="text" size="large">{{scope.row.name}}</span>
          </template>
        </el-table-column>
        <el-table-column label="是否必须文件" align="center" class-name="small-padding fixed-width">
          <template #default="scope">
            <el-radio-group v-model="scope.row.type" >
              <el-radio :label="1">是</el-radio>
              <el-radio :label="0">否</el-radio>
            </el-radio-group>
          </template>
        </el-table-column>
        <el-table-column label="原因说明" align="center" class-name="small-padding fixed-width">
          <template #default="scope">
            <el-input v-model="scope.row.remark"  show-word-limit type="text" size="large"  />
          </template>
        </el-table-column>
        <el-table-column label="附件上传" align="center" class-name="small-padding fixed-width">
          <template #default="scope">
            <el-upload accept=".pdf,.doc,.docx"
                       :action="state.uploadUrl"
                       :disabled="projectType === 'view' || isEnd"
                       :headers="state.header"
                       method="post"
                       :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,scope.row)"
                       v-model:file-list="scope.row.fileList"
                       :on-remove="handleRemove"
                       :data="state.uploadData"
                       :on-preview="handlePreview"
            >
              <el-button type="primary">附件上传</el-button>
            </el-upload>
          </template>
        </el-table-column>
<!--        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">-->
<!--          <template #default="scope">-->
<!--            <el-button link type="danger" @click="delUpload(scope.$index)">删除</el-button>-->
<!--          </template>-->
<!--        </el-table-column>-->
      </el-table>
      <el-row :gutter="30">
        <el-col :span="6">
          <el-form-item  label="合同签订日期">
            <el-date-picker
                style="width: 100%"
                v-model="state.formData.contractSignDate"
                type="date"
                value-format="YYYY-MM-DD 00:00:00"
                placeholder="选择日期"
                size="large"
            />
          </el-form-item>
        </el-col>
        <el-col :span="18">
          <el-form-item prop="actualContractMoney">
            <template #label>
              项目合同额<span style="font-size: 13px;color: red;font-weight: normal;display: inline-block;margin-left: 6px">预估合同金额,归档阶段可以进行修改。仅支持数字,单位万元,小数点后最多两位,数值范围(0.01-999.99)</span>
            </template>
            <el-input
                v-model.trim="state.actualContract.actualContractMoney"
                @input="state.actualContract.actualContractMoney= state.actualContract.actualContractMoney.replace(/[^0-9.\/\-]/g,'')"
                size="large"
                placeholder="请输入项目合同额"
            >
              <template #append>万元</template>
            </el-input>
          </el-form-item>
        </el-col>
      </el-row>
      <el-form-item label="实际合同额说明">
        <el-input
            v-model.trim="state.actualContract.actualContractIntroduction"
            :autosize="{ minRows: 6 }"
            maxlength="100"
            show-word-limit
            type="textarea">
        </el-input>
      </el-form-item>
    </el-form>
  </div>
</template>
<script setup>
import {defineEmits, defineProps, onMounted, reactive, ref} from "vue";
import {ElMessage} from "element-plus";
import {addRecord, editRecord, getDetail} from "@/api/projectManage/contractMng";
import Cookies from "js-cookie";
import { getToken } from "@/utils/auth";
import axios from "axios";
import {delAccessoryFile, getAccessoryFile} from "@/api/projectManage/project";
import {addProcessMaterial, getProcessMaterialDetail, editProcessMaterial} from "@/api/projectManage/riskAnalysis";
import { useRoute } from 'vue-router'
const route = useRoute()
const props = defineProps(['projectId'])
const emit = defineEmits(["getNextStatus"]);
const state = reactive({
  formData: {
    id: '',
    contractSignDate: '',
  },
  actualContract: {
    actualContractMoney: '',
    actualContractIntroduction: ''
  },
  uploadList: [
    {
      name: '安全评价过程控制记录文档',
      type: 1,
      remark: '',
    },
    {
      name: '项目发票电子版',
      type: 1,
      remark: '',
    },
    {
      name: '项目转账记录/入账证明',
      type: 1,
      remark: '',
    }
  ],
  rules: {
    contractSignDate: [{required: true, message: '请选择合同签订日期', trigger: 'blur'}],
  },
  fileList: [],
  uploadUrl: import.meta.env.VITE_APP_BASE_API + '/manage/accessory-file/uploadFile',
  header: {
    Authorization: getToken()
  },
  uploadData: {
    moduleType: 9
  },
})
const isAmin = ref(false)
const formRef = ref();
onMounted(async () => {
  const userInfo = JSON.parse(Cookies.get('userInfo'))
  if(userInfo.identity === 0){
    isAmin.value = true;
  }
  if(props.projectId){
    state.uploadData.projectId = props.projectId;
    await getRecord(state.uploadData.projectId);
    // const res = await  getAccessoryFile({projectId: val,moduleType: 9});
    // console.log('res',res)
  }
  isEnd.value = Cookies.get('end')
  projectType.value = route.query.type;
});
const getRecord = async (val) =>{
  const res = await getDetail({projectId: val});
  if(res.code == 200){
    state.formData = res.data;
    state.actualContract.actualContractMoney = res.data.actualContractMoney;
    state.actualContract.actualContractIntroduction = res.data.actualContractIntroduction;
  }else {
    ElMessage.warning(res.message)
  }
}
const projectType = ref('')
const isEnd = ref('')
const riskOpen = async (type,val) => {
  projectType.value = route.query.type;
  isEnd.value = Cookies.get('end')
  state.uploadData.projectId = val;
  if(type === 'detail' || type === 'edit' ){
    const res = await getProcessMaterialDetail({projectId: val});
    if(res.code == 200){
      state.uploadList = res.data;
      state.uploadList.forEach((item,index) => {
        if(item.accessoryFile){
          item.accessoryFile.name = item.accessoryFile.originName
          state.uploadList[index].fileList = [item.accessoryFile];
        }
      })
      console.log("res",state.uploadList)
    }else {
      ElMessage.warning(res.message)
    }
  }
  if(type === 'add' || type === 'clickEdit') {
    const valid = await formRef.value.validate();
    if(valid){
      if (isAmin.value) {
        ElMessage.warning("当前用户暂无权限");
        return;
      }
      if(state.actualContract.actualContractMoney == '' || !state.actualContract.actualContractMoney) {
        ElMessage.warning("请输入项目合同额");
        return;
      }
      console.log(state.uploadList,'state.uploadList')
      const file = state.uploadList.map(item => {
        return{
          id: item.id ? item.id : null,
          fileId: item.fileList && item.fileList.length>0 ? item.fileList[0].response ? item.fileList[0].response.data.id : item.fileList[0].id : '',
          name: item.name,
          type: item.type,
          remark: item.remark,
          projectId: val
        }
      })
      let isOk = false;
      try{
        state.uploadList.forEach(item => {
          if(item.type == 1 && (!item.fileList || item.fileList .length == 0) && item.remark == ""){
            isOk = true;
            throw Error();
          }
        })
      }catch (e) {}
      if(isOk){
        ElMessage.warning("请上传附件或完善原因说明!");
        return;
      }
      const { ...data} = JSON.parse(JSON.stringify(state.formData))
      data.actualContractMoney = state.actualContract.actualContractMoney;
      data.actualContractIntroduction = state.actualContract.actualContractIntroduction;
      const params = {
        projectId: val,
        projectMaterials: file,
        contract: data
      }
      console.log("params",params)
      if(type === 'add'){
        const res = await addProcessMaterial(params);
        if (res.code == 200) {
          ElMessage.success('保存成功')
          formRef.value.clearValidate();
          emit('getNextStatus', val);
        } else {
          ElMessage.warning(res.message)
        }
      }else if(type === 'clickEdit'){
        const res = await editProcessMaterial(params);
        if (res.code == 200) {
          ElMessage.success('变更成功')
          projectType.value='edit';
          formRef.value.clearValidate();
          // emit('getNextStatus', data.project.id);
        } else {
          ElMessage.warning(res.message)
        }
      }
    }
  }
}
const addUpload = ()=>{
  let file = {
    name: '',
    type: 1,
    remark: '',
  }
  state.uploadList.push(file)
}
const delUpload = (index)=>{
  state.uploadList.splice(index,1)
}
// 图片上传
const showTip =()=>{
  ElMessage({
    type: 'warning',
    message: '超出文件上传数量'
  });
}
const picSize = async (rawFile) => {
  if(rawFile.size / 1024 / 1024 > 5){
    ElMessage({
      type: 'warning',
      message: '文件大小不能超过5M'
    });
    return false
  }
};
const handleAvatarSuccess = (res, uploadFile,val) => {
  if(res.code === 200){
    ElMessage({
      type: 'success',
      message: '文件上传成功'
    })
  }else {
    const delVal = state.uploadList.findIndex(i => i.id === val.id);
    state.uploadList[delVal].fileList.splice(state.uploadList[delVal].fileList.indexOf(uploadFile),1)
    ElMessage({
      type: 'warning',
      message: res.message
    })
  }
}
const handlePreview = (file) => {
  let path = "";
  if(file.path){
    path = file.path
  }else {
    path = file.response.data.path
  }
  const url = import.meta.env.VITE_APP_BASE_API + '/' + path
  axios.get( url,{
        headers:
            {
              'Content-Type': 'application/json',
              'Authorization':getToken(),
            },
        responseType: 'blob'
      }
  ).then(res=>{
    if (res) {
      const link = document.createElement('a')
      let blob = new Blob([res.data],{type: res.data.type})
      link.style.display = "none";
      link.href = URL.createObjectURL(blob); // 创建URL
      link.setAttribute("download", file.name);
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    } else {
      this.$message.error('获取文件失败')
    }
  })
}
const handleRemove = async (file, uploadFiles) => {
  if (file && file.status == 'success') {
  console.log("file", file)
  let accessoryFileId = "";
  if (file.id) {
    accessoryFileId = file.id
  } else {
    accessoryFileId = file.response.data.id
  }
  const res = await delAccessoryFile(accessoryFileId)
  if (res.code == 200) {
    // ElMessage({
    //   type: 'success',
    //   message: '文件已删除'
    // })
  } else {
    ElMessage({
      type: 'warning',
      message: res.message
    })
  }
}
}
defineExpose({
  riskOpen
});
</script>
<style scoped lang="scss">
.riskBox{
  :deep(.el-form .el-form-item__label) {
    font-size: 15px;
  }
}
</style>
src/views/safetyReview/testManage/components/rateConclusion.vue
对比新文件
@@ -0,0 +1,311 @@
<template>
  <div class="riskBox">
    <el-form ref="formRef" :model="state.formData" :rules="state.rules" class="register-form" label-position="top">
      <el-form-item prop="conclusion" label="评价结论">
        <el-input
            v-model.trim="state.formData.conclusion"
            :autosize="{ minRows: 6 }"
            maxlength="500"
            show-word-limit
            type="textarea">
        </el-input>
      </el-form-item>
      <el-row :gutter="30">
        <el-col :span="9">
          <el-form-item prop="isReviseManual" label="评价报告修改说明">
<!--            <el-radio-group v-model="state.formData.isReviseManual" >-->
<!--              <el-radio :label="1">是</el-radio>-->
<!--              <el-radio :label="0">否</el-radio>-->
<!--            </el-radio-group>-->
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="30">
        <el-col :span="18">
          <el-form-item>
            <el-upload
                accept="image/*,.pdf,.doc,.docx,.xlsx,.xls"
                 :action="state.uploadUrl"
                :disabled="projectType === 'view' || isEnd"
                 :headers="state.header"
                 method="post"
                :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)"
                 :on-exceed="showTip"
                 v-model:file-list="state.fileList"
                 :on-remove="handleRemove"
                 :data="state.uploadData"
                 :on-preview="handlePreview"
                 :limit='15'
                 :before-upload="picSize"
            >
              <el-button type="primary">评价报告上传</el-button>
              <template #tip>
                <div class="el-upload__tip">上传文件尺寸小于15M,最多可上传15份,多张图片建议合并为PDF文件规范上传。</div>
              </template>
            </el-upload>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
  </div>
</template>
<script setup>
import {defineEmits, defineProps, onMounted, reactive, ref} from "vue";
import {ElMessage, ElMessageBox} from "element-plus";
import {Search} from '@element-plus/icons-vue'
import {addRate, addRisk, editRate, editRisk, getRateDetail, getRiskDetail} from "@/api/projectManage/riskAnalysis"
import {delPic} from "@/api/login"
import { getToken } from "@/utils/auth";
import Cookies from "js-cookie"
import {delAccessoryFile, getAccessoryFile} from "@/api/projectManage/project";
import axios from "axios";
import {delFile, getFiles} from "@/api/projectManage/siteCheckRcd";
import { useRoute } from 'vue-router'
const route = useRoute()
const emit = defineEmits(["getNextStatus"]);
const prop = defineProps(['projectId'])
const state = reactive({
  formData: {
    isReviseManual: 1,
  },
  rules: {
    conclusion: [{required: true, message: '请输入评价结论', trigger: 'blur'}],
  },
  imgLimit: 3,
  uploadUrl: import.meta.env.VITE_APP_BASE_API + '/manage/accessory-file/uploadFile',
  header: {
    Authorization: getToken()
  },
  fileList: [],
  uploadData: {
    moduleType: 7
  },
  disabled: false
})
const props = {
  expandTrigger: 'hover',
  value: 'name',
  label: 'name'
}
const isAmin = ref(false)
const formRef = ref()
onMounted(() => {
  const userInfo = JSON.parse(Cookies.get('userInfo'))
  if(userInfo.identity === 0){
    isAmin.value = true;
  }
  if(prop.projectId){
    const val = prop.projectId;
    state.uploadData.projectId = val;
    getProcessFiles(val);
  }
  isEnd.value = Cookies.get('end')
  projectType.value = route.query.type;
})
const projectType = ref('');
const isEnd = ref('')
const riskOpen = async (type,val) => {
  state.uploadData.projectId = val;
  projectType.value = route.query.type;
  isEnd.value = Cookies.get('end')
  if(type === 'detail' || type === 'edit' ){
    if(type === 'detail'){
      state.disabled = true
    }
    const res = await getRateDetail({projectId: val});
    if(res.code == 200){
      if(res.data){
        state.formData = res.data;
        state.formData.isReviseManual = res.data.isReviseManual ? 1 : 0
        state.fileList = res.data.accessoryFiles.map(item => {
          return {
            ...item,
            name: item.originName,
          }
        })
      }
    }else {
      ElMessage.warning(res.message)
    }
  }
  if(type === 'add' || type === 'clickEdit') {
    const valid = await formRef.value.validate();
    if(state.fileList && state.fileList.length<=0 ){
      ElMessage.warning('请上传评价报告')
      return
    }
    if(valid){
      if (isAmin.value) {
        ElMessage.warning("当前用户暂无权限");
        return;
      }
      if(type === 'add'){
        const {id,attachments, ...data} = JSON.parse(JSON.stringify(state.formData))
        data.projectId = val;
        data.accessoryFiles = state.fileList
        const res = await addRate(data);
        if (res.code == 200) {
          ElMessage.success('保存成功')
          formRef.value.clearValidate();
          emit('getNextStatus', val);
        } else {
          ElMessage.warning(res.message)
        }
      }else if(type === 'clickEdit'){
        const { attachments, ...data} = JSON.parse(JSON.stringify(state.formData))
        data.accessoryFiles = state.fileList
        const res = await editRate(data);
        if (res.code == 200) {
          ElMessage.success('变更成功')
          formRef.value.clearValidate();
          // emit('getNextStatus', data.project.id);
        } else {
          ElMessage.warning(res.message)
        }
      }
    }
  }
}
// 上传
const showTip =()=>{
  ElMessage({
    type: 'warning',
    message: '超出文件上传数量'
  });
}
const picSize = async (rawFile) => {
  if(rawFile.size / 1024 / 1024 > 15){
    ElMessage({
      type: 'warning',
      message: '文件大小不能超过15M'
    });
    return false
  }
};
const handleAvatarSuccess = (res,uploadFile) => {
  if(res.code === 200){
    getProcessFiles()
    ElMessage({
      type: 'success',
      message: '文件上传成功'
    })
  }else {
    state.fileList.splice(state.fileList.indexOf(uploadFile),1)
    ElMessage({
      type: 'warning',
      message: res.message
    })
  }
}
const handlePreview = (file) => {
  let path = "";
  if(file.path){
    path = file.path
  }else {
    path = file.response.data.path
  }
  const url = import.meta.env.VITE_APP_BASE_API + '/' + path
  axios.get( url,{
        headers:
            {
              'Content-Type': 'application/json',
              'Authorization':getToken(),
            },
        responseType: 'blob'
      }
  ).then(res=>{
    if (res) {
      const link = document.createElement('a')
      let blob = new Blob([res.data],{type: res.data.type})
      link.style.display = "none";
      link.href = URL.createObjectURL(blob); // 创建URL
      link.setAttribute("download", file.name);
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    } else {
      this.$message.error('获取文件失败')
    }
  })
}
const getProcessFiles = async (id)=>{
  const res = await getFiles({projectId: id ? id : prop.projectId ,moduleType: 7})
  if(res.code == 200){
    if(res.data && res.data.length>0){
      state.fileList = res.data.map(i=>{
        return {
          name: i.originName,
          url: import.meta.env.VITE_APP_BASE_API + '/' + i.path,
          id: i.id,
          projectId: i.projectId,
          moduleType: i.moduleType
        }
      })
    }else{
      state.fileList = []
    }
  }else {
    ElMessage.warning(res.message)
  }
}
const handleRemove = async (file, uploadFiles) => {
  if (file && file.status === 'success') {
  ElMessageBox.confirm(
      '确定删除该附件?',
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
      .then(async () => {
        let accessoryFileId = "";
        if (file.id) {
          accessoryFileId = file.id
        } else {
          accessoryFileId = file.response.data.id
        }
        const res = await delAccessoryFile(accessoryFileId)
        if (res.code == 200) {
          ElMessage({
            type: 'success',
            message: '文件已删除'
          })
          await getProcessFiles()
        } else {
          ElMessage({
            type: 'warning',
            message: res.message
          })
        }
      })
      .catch(() => {
        getProcessFiles()
      })
  }
}
defineExpose({
  riskOpen
});
</script>
<style scoped lang="scss">
.riskBox{
  :deep(.el-form .el-form-item__label) {
    font-size: 15px;
  }
}
</style>
src/views/safetyReview/testManage/components/riskAnalysis.vue
对比新文件
@@ -0,0 +1,474 @@
<template>
  <div class="riskBox">
    <el-form ref="formRef" :model="state.formData" :rules="state.rules" class="register-form" label-position="top">
      <el-row :gutter="30">
        <el-col :span="6">
          <el-form-item prop="project.name" label="项目名称">
            <el-input
                maxlength="100"
                show-word-limit
                v-model.trim="state.formData.project.name"
                size="large"
                placeholder="请输入项目名称"
            >
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="project.client" label="委托单位">
            <el-input
                v-model.trim="state.formData.project.client"
                size="large"
                placeholder="请输入委托单位"
            >
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="project.creditCode" label="委托单位统一社会信用代码">
            <el-input
                v-model.trim="state.formData.project.creditCode"
                size="large"
                placeholder="请输入委托单位统一社会信用代码"
            >
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="project.address" label="详细地址">
            <el-input
                maxlength="100"
                show-word-limit
                v-model.trim="state.formData.project.address"
                size="large"
                placeholder="请输入详细地址"
            >
            </el-input>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="30">
        <el-col :span="6">
          <el-form-item prop="project.estimateType" label="类型">
            <el-input v-model="state.formData.project.estimateType" disabled></el-input>
<!--            <el-select v-model="state.formData.project.estimateType" class="m-2" size="large" placeholder="请选择" style="width: 100%" >-->
<!--              <el-option-->
<!--                  v-for="item in state.estimateTypeList"-->
<!--                  :key="item.id"-->
<!--                  :label="item.label"-->
<!--                  :value="item.id"-->
<!--              />-->
<!--            </el-select>-->
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="project.code" label="项目编号">
            <el-input
                v-model.trim="state.formData.project.code"
                size="large"
                placeholder="请输入项目编号"
            >
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="project.invest" label="项目投资金额">
            <el-input
                @input="state.formData.project.invest= state.formData.project.invest.replace(/[^0-9.\/\-]/g,'')"
                v-model.trim="state.formData.project.invest"
                size="large"
                placeholder="请输入项目投资金额"
            >
              <template #append>万元</template>
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="project.area" label="所属区域">
            <el-cascader
                v-model="state.formData.project.area"
                :options="state.addressList"
                :props="props"
                @change="handleChange"
                style="width: 100%"
                size="large"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row el-row :gutter="30">
        <el-col :span="6">
          <el-form-item prop="project.business" label="业务范围">
            <el-select v-model="state.formData.project.business" class="m-2" size="large" placeholder="请选择" style="width: 100%" >
              <el-option
                  v-for="item in state.businessList"
                  :key="item.id"
                  :label="item.label"
                  :value="item.id"
              />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-form-item prop="project.introduction" label="基本概括">
        <el-input
            v-model.trim="state.formData.project.introduction"
            :autosize="{ minRows: 6 }"
            maxlength="500"
            show-word-limit
            type="textarea">
        </el-input>
      </el-form-item>
      <el-form-item prop="riskCharacter" label="行业风险特性">
        <el-input
            v-model.trim="state.formData.riskCharacter"
            :autosize="{ minRows: 6 }"
            maxlength="500"
            show-word-limit
            type="textarea">
        </el-input>
      </el-form-item>
      <el-form-item prop="surroundings" label="周边环境">
        <el-input
            v-model.trim="state.formData.surroundings"
            :autosize="{ minRows: 6 }"
            maxlength="500"
            show-word-limit
            type="textarea">
        </el-input>
      </el-form-item>
      <el-form-item prop="equipment" label="主要生产装置">
        <el-input
            v-model.trim="state.formData.equipment"
            :autosize="{ minRows: 6 }"
            maxlength="500"
            show-word-limit
            type="textarea">
        </el-input>
      </el-form-item>
      <el-form-item prop="technology" label="生产工艺概况">
        <el-input
            v-model="state.formData.technology"
            :autosize="{ minRows: 6 }"
            maxlength="500"
            show-word-limit
            type="textarea">
        </el-input>
      </el-form-item>
      <el-table  :data="state.tableData" :border="true" style="margin: 20px 0">
        <el-table-column label="序号" width="60" align="center" type="index"></el-table-column>
        <el-table-column label="内容" prop="content" header-align="center" :show-overflow-tooltip="true"/>
        <el-table-column label="选择" header-align="center" class-name="small-padding fixed-width" width="175">
          <template #default="scope">
            <el-radio-group v-model="scope.row.status" >
              <el-radio :label="1">{{scope.row.id ==='6' ? '可行': '是'}}</el-radio>
              <el-radio :label="0">{{scope.row.id ==='6' ? '不可行': '否'}}</el-radio>
            </el-radio-group>
          </template>
        </el-table-column>
      </el-table>
      <el-row :gutter="30">
        <el-col :span="6">
          <el-form-item prop="estimateDate" label="评估日期">
            <el-date-picker
                style="width: 100%"
                v-model="state.formData.estimateDate"
                type="date"
                value-format="YYYY-MM-DD 00:00:00"
                placeholder="选择日期"
                size="large"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="techOpinion" label="技术负责人意见">
            <el-input
                v-model="state.formData.techOpinion"
                size="large"
                maxlength="30"
                show-word-limit
                placeholder="技术负责人意见"
            >
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="riskOpinion" label="风险评估人意见">
            <el-input
                v-model="state.formData.riskOpinion"
                size="large"
                maxlength="30"
                show-word-limit
                placeholder="风险评估人意见"
            >
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="agencyOpinon" label="机构评价负责人意见">
            <el-input
                maxlength="30"
                show-word-limit
                v-model="state.formData.agencyOpinon"
                size="large"
                placeholder="机构评价负责人意见"
            >
            </el-input>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
  </div>
</template>
<script setup>
import {defineEmits, onMounted, reactive, ref} from "vue";
import {getDictList} from "@/api/backManage/evaluate";
import {ElMessage} from "element-plus";
import {getDict} from "@/api/login";
import {getRegionTree} from "@/api/area";
import {addRisk, editRisk, getRiskDetail} from "@/api/projectManage/riskAnalysis";
import Cookies from "js-cookie";
const emit = defineEmits(["getNextStatus"]);
const isAmin = ref(false)
const formRef = ref();
onMounted(() => {
  const userInfo = JSON.parse(Cookies.get('userInfo'))
  if(userInfo.identity === 0){
    isAmin.value = true;
  }
  // getRiskList();
  getBusinessList();
  getArea();
});
const state = reactive({
  formData: {
    project: {
      id: '',
      name: '',
      client: '',
      creditCode: '',
      address:'',
      estimateType: '检验检测',
      code: '',
      invest: '',
      area: [],
      district: '',
      city: '',
      province: '',
      business: '',
      introduction: '',
    },
    id: '',
    riskCharacter: '',
    surroundings: '',
    equipment: '',
    technology: '',
    isInBusiness: true,
    isSatisfyNeed: true,
    isNeedExpert: true,
    isFinishReport: true,
    isAcceptChargess: true,
    isFeasibility: true,
    estimateDate: '',
    techOpinion: '',
    riskOpinion: '',
    agencyOpinon: ''
  },
  rules: {
    "project.name": [{required: true, message: '请填写项目名称', trigger: 'blur'}],
    "project.client": [{required: true, message: '请填写委托单位', trigger: 'blur'}],
    "project.creditCode": [{required: true, message: '请填写委托单位统一社会信用代码', trigger: 'blur'}],
    // "project.estimateType": [{required: true, message: '请选择类型', trigger: 'blur'}],
    "project.address": [{required: true, message: '请填写详细地址', trigger: 'blur'}],
    "project.invest": [{required: true, message: '请填写投资金额', trigger: 'blur'}],
    "project.area": [{required: true, message: '请选择所属区域', trigger: 'blur'}],
    "project.business": [{required: true, message: '请选择业务范围', trigger: 'blur'}],
    "project.introduction": [{required: true, message: '请填写基本概况', trigger: 'blur'}],
    riskCharacter: [{required: true, message: '请填写行业风险特性', trigger: 'blur'}],
    surroundings: [{required: true, message: '请填写周边环境', trigger: 'blur'}],
    estimateDate: [{required: true, message: '请选择评估日期', trigger: 'blur'}],
    techOpinion: [{required: true, message: '请填写技术负责人意见', trigger: 'blur'}],
    riskOpinion: [{required: true, message: '请填写风险评估人意见', trigger: 'blur'}],
    agencyOpinon: [{required: true, message: '请填写机构评价负责人意见', trigger: 'blur'}],
  },
  estimateTypeList: [],
  addressList: [],
  businessList: [],
  tableData: [
    {
      id: '1',
      content: '评价项目是否在本机构资质业务范围内',
      status: 1
    },
    {
      id: '2',
      content: '评价人员专业构成是否满足评价项目需要',
      status: 1
    },
    {
      id: '3',
      content: '是否需要聘请相关专业的技术专家',
      status: 1
    },
    {
      id: '4',
      content: '是否能在约定的时间内完成评价报告',
      status: 1
    },
    {
      id: '5',
      content: '评价费用是否在本机构所接受的范围内',
      status: 1
    },
    {
      id: '6',
      content: '项目的可行性(风险分析结论)',
      status: 1
    },
  ]
})
const props = {
  expandTrigger: 'hover',
  value: 'name',
  label: 'name'
}
// const getRiskList = async () => {
//   const res = await getDictList({dictType: "sys_assess_type"});
//   if(res.code === 200){
//     state.estimateTypeList = res.data.list
//   }else{
//     ElMessage.warning(res.message)
//   }
// }
const getBusinessList = async () => {
  const res = await getDict({dictType: 'sys_business_scope'})
  if(res.code === 200){
    state.businessList = res.data
  }else{
    ElMessage.warning(res.message)
  }
}
const getArea = async ()=>{
  const type = 1
  const res = await getRegionTree({name: '',parentId: null,regionType: type})
  if(res.code == 200){
    state.addressList = res.data
  }else{
    ElMessage.warning(res.message)
  }
}
const riskOpen = async (type,val) => {
  console.log("type",type,val)
  if(type === 'detail' || type === 'edit' ){
    const res = await getRiskDetail({projectId: val});
    if(res.code == 200){
      state.formData = res.data;
      state.formData.project.estimateType = '检验检测'
      state.formData.project.business = parseInt(res.data.project.business);
      if(res.data.project.province == '北京市' || res.data.project.province == '天津市' || res.data.project.province == '上海市' || res.data.project.province == '重庆市' || res.data.project.province == '香港特别行政区' || res.data.project.province == '澳门特别行政区'){
        state.formData.project.area = [res.data.project.province]
      }else{
        state.formData.project.area = [res.data.project.province,res.data.project.city];
      }
      state.tableData[0].status = res.data.isInBusiness ? 1 : 0;
      state.tableData[1].status = res.data.isSatisfyNeed ? 1 : 0;
      state.tableData[2].status = res.data.isNeedExpert ? 1 : 0;
      state.tableData[3].status = res.data.isFinishReport ? 1 : 0;
      state.tableData[4].status = res.data.isAcceptChargess ? 1 : 0;
      state.tableData[5].status = res.data.isFeasibility ? 1 : 0;
    }else {
      ElMessage.warning(res.message)
    }
  }
  if(type === 'add' || type === 'clickEdit') {
    const valid = await formRef.value.validate();
    if(valid){
      if (isAmin.value) {
        ElMessage.warning("当前用户暂无权限");
        return;
      }
      state.formData.project.estimateType = 33
      if(type === 'add'){
        const {id, ...data} = JSON.parse(JSON.stringify(state.formData))
        delete data.project.area;
        delete data.project.id;
        if(data.project.province == '北京市' || data.project.province == '天津市' || data.project.province == '上海市' || data.project.province == '重庆市' || data.project.province == '香港特别行政区' || data.project.province == '澳门特别行政区'){
          data.project.city = data.project.province
        }
        data.isInBusiness = state.tableData[0].status === 1;
        data.isSatisfyNeed = state.tableData[1].status === 1;
        data.isNeedExpert = state.tableData[2].status === 1;
        data.isFinishReport = state.tableData[3].status === 1;
        data.isAcceptChargess = state.tableData[4].status === 1;
        data.isFeasibility = state.tableData[5].status === 1;
        const res = await addRisk(data);
        if (res.code == 200) {
          ElMessage.success('保存成功')
          formRef.value.clearValidate();
          emit('getNextStatus', res.data);
        } else {
          ElMessage.warning(res.message)
        }
      }else if(type === 'clickEdit'){
        const { ...data} = JSON.parse(JSON.stringify(state.formData))
        data.id = val;
        data.project.id = val;
        if(data.project.province == '北京市' || data.project.province == '天津市' || data.project.province == '上海市' || data.project.province == '重庆市' || data.project.province == '香港特别行政区' || data.project.province == '澳门特别行政区'){
          data.project.city = data.project.province
        }
        delete data.project.area;
        data.isInBusiness = state.tableData[0].status === 1
        data.isSatisfyNeed = state.tableData[1].status === 1
        data.isNeedExpert = state.tableData[2].status === 1
        data.isFinishReport = state.tableData[3].status === 1
        data.isAcceptChargess = state.tableData[4].status === 1
        data.isFeasibility = state.tableData[5].status === 1
        const res = await editRisk(data);
        if (res.code == 200) {
          ElMessage.success('变更成功')
          formRef.value.clearValidate();
          // emit('getNextStatus', data.project.id);
        } else {
          ElMessage.warning(res.message)
        }
      }
    }
  }
}
const handleChange = (value) => {
  // if(state.registerForm.agency.attribute == 0){
  //   state.registerForm.agency.province = '新疆维吾尔自治区'
  //   state.registerForm.agency.city = value[0]?value[0]:''
  //   state.registerForm.agency.district  = value[1]?value[1]:''
  // }else{
    state.formData.project.province = value[0]?value[0]:''
    state.formData.project.city = value[1]?value[1]:''
    state.formData.project.district  = value[2]?value[2]:''
  // }
}
defineExpose({
  riskOpen
});
</script>
<style scoped lang="scss">
.riskBox{
  :deep(.el-form .el-form-item__label) {
    font-size: 15px;
  }
}
</style>
src/views/safetyReview/testManage/components/signConfirm.vue
对比新文件
@@ -0,0 +1,184 @@
<template>
  <div class="riskBox">
    <el-table v-loading="loading" ref="tableRef" :data="tableData" :border="true" style="margin-top: 20px">
      <el-table-column label="序号" type="index" width="55" />
      <el-table-column label="人员姓名" prop="planPerson.person.name" align="center"/>
      <el-table-column label="联系电话" prop="planPerson.person.phone" align="center"/>
      <el-table-column label="职位" prop="planPerson.person.post" align="center"/>
      <el-table-column label="项目担任角色" prop="username" align="center" width="180">
        <template #default="scope">
          <div v-for="(item,index) in scope.row.playRolesName" :key="index">
            <span>{{item.roleName}}</span><span v-if="index!==scope.row.playRolesName.length-1">,</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="评价师等级" prop="planPerson.person.level" align="center"/>
      <el-table-column label="专业能力" prop="planPerson.person.majorNames" align="center"/>
      <el-table-column label="工作类型"  align="center">
        <template #default="scope">
          <span>{{scope.row.planPerson.jobType === 1 ? '普通人员' : scope.row.planPerson.jobType === 2?'组长': ''}}</span>
        </template>
      </el-table-column>
      <el-table-column label="扫脸时间" prop="faceRecord.updateTime" align="center" width="120"/>
      <el-table-column label="是否扫脸" prop="username" align="center">
        <template #default="scope">
          <span v-if="scope.row.facePic.length>0">是</span>
          <span v-else>否</span>
        </template>
      </el-table-column>
<!--      <el-table-column label="是否变更" prop="username" align="center"/>-->
      <el-table-column label="人脸照片" prop="socialSecurity" align="center" width="120">
        <template #default="scope">
          <div class="demo-image__preview" v-if="scope.row.facePic && scope.row.facePic.length>0">
            <el-image
                style="width: 100px; height: 100px"
                :src= "scope.row.facePic[0]"
                :zoom-rate="1.2"
                :max-scale="7"
                :min-scale="0.2"
                :preview-src-list="scope.row.facePic"
                :initial-index="0"
                fit="cover"
                :preview-teleported=true
            />
          </div>
        </template>
      </el-table-column>
      <el-table-column label="签字图片" prop="socialSecurity" align="center" width="120">
        <template #default="scope">
          <div class="demo-image__preview" v-if="scope.row.signPic && scope.row.signPic.length>0">
            <el-image
                style="width: 100px; height: 100px"
                :src= "scope.row.signPic[0]"
                :zoom-rate="1.2"
                :max-scale="7"
                :min-scale="0.2"
                :preview-src-list="scope.row.signPic"
                :initial-index="0"
                fit="cover"
                :preview-teleported=true
            />
          </div>
        </template>
      </el-table-column>
      <el-table-column label="承诺书" prop="socialSecurity" align="center" width="120">
        <template #default="scope">
          <div class="demo-image__preview" v-if="scope.row.commitPic && scope.row.commitPic.length>0">
            <el-image
                style="width: 100px; height: 100px"
                :src= "scope.row.commitPic[0]"
                :zoom-rate="1.2"
                :max-scale="7"
                :min-scale="0.2"
                :preview-src-list="scope.row.commitPic"
                :initial-index="0"
                fit="cover"
                :preview-teleported=true
            />
          </div>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>
<script setup>
import {defineEmits, defineProps, onMounted, reactive, ref, toRefs} from "vue";
import {ElMessage} from "element-plus";
import {Search} from '@element-plus/icons-vue'
import {
  addFaceRecognition,
  addRisk, checkAll,
  editRisk,
  getRecognitionDetail,
  getRiskDetail
} from "@/api/projectManage/riskAnalysis"
import {delPic} from "@/api/login"
import { getToken } from "@/utils/auth";
import Cookies from "js-cookie"
import {getDetail} from "@/api/projectManage/contractMng";
const emit = defineEmits(["getNextStatus"]);
const props = defineProps(['projectId'])
const state = reactive({
  loading: false,
  queryParams: {
    pageNum: 1,
    pageSize: 10,
  },
  total: 0,
  tableData: []
})
const {loading,queryParams,total,tableData} = toRefs(state)
const isAmin = ref(false)
const formRef = ref()
onMounted(() => {
  const userInfo = JSON.parse(Cookies.get('userInfo'))
  if(userInfo.identity === 0){
    isAmin.value = true;
  }
  if(props.projectId){
    getRecognition(props.projectId);
  }
})
const getRecognition = async (val) =>{
  const res = await getRecognitionDetail({projectId: val});
  if(res.code == 200){
    state.tableData = res.data.map(item => {
      return {
        ...item,
        facePic: item.faceRecord.facePath ? [import.meta.env.VITE_APP_BASE_API + '/' + item.faceRecord.facePath ] : [],
        signPic: item.signPath ? [import.meta.env.VITE_APP_BASE_API + '/' + item.signPath] : [],
        commitPic: item.insurancePath ? [import.meta.env.VITE_APP_BASE_API + '/' + item.insurancePath] : [],
        playRolesName: item.planPerson.playRoles.map(role => {
          const roleName =  role === 1?'项目负责人':role === 2? '项目组成员':role === 3? '过程控制负责人':role === 4? '机构评价负责人':role === 5? '技术负责人':role === 6?'内部审核员':''
          return{
            roleName
          }
        })
      }
    })
   console.log("res", state.tableData)
  }else {
    ElMessage.warning(res.message)
  }
}
const riskOpen = async (type,val) => {
  // if((type === 'detail' || type === 'edit') && !props.projectId){
  //   getRecognition(val);
  // }
  if(type === 'add' || type === 'clickEdit') {
    if (isAmin.value) {
      ElMessage.warning("当前用户暂无权限");
      return;
    }
    if(type === 'add'){
      const res = await addFaceRecognition({projectId: val});
      if (res.code == 200) {
        ElMessage.success('保存成功')
        emit('getNextStatus', val);
      } else {
        ElMessage.warning(res.message)
      }
    }
  }
}
defineExpose({
  riskOpen
});
</script>
<style scoped lang="scss">
.riskBox{
  :deep(.el-form .el-form-item__label) {
    font-size: 15px;
  }
}
</style>
src/views/safetyReview/testManage/components/siteCheckRcd.vue
对比新文件
@@ -0,0 +1,693 @@
<template>
  <div class="riskBox">
    <el-form ref="formRef" :model="state.formData" :rules="state.rules" class="register-form" label-position="top">
      <el-row :gutter="30" style="margin-bottom: 20px">
        <el-col :span="28">
          <el-alert title="说明:现场勘验记录由项目组成员通过APP端进行信息填报,组长完成现场勘验并在APP端提交后,电脑可对资料信息完善并进行下一步操作。" type="warning" />
        </el-col>
<!--        <el-col :span="6" style="display:flex;justify-content: right">-->
<!--          <el-button type="primary">全部查看</el-button>-->
<!--          <el-button type="primary">全部下载</el-button>-->
<!--        </el-col>-->
      </el-row>
      <el-row :gutter="30" style="margin-bottom: 30px" v-if="state.data.length>0">
        <el-col :span="28">
          <div style="display: flex;align-items: center">
            <span style="font-size: 22px;font-weight: 600;margin-top: 10px;">记录编号:{{ chooseItem.index }}(提交时间:{{chooseItem.createTime}})</span>
            <div style="display: flex;align-items: center;flex-wrap: wrap">
              <div v-for="(item,index) in state.data">
                <el-check-tag style="margin-left: 20px;margin-top:10px;cursor: pointer;padding: 15px 25px" :checked="chooseItem.id === item.id" size="large" @click="chooseRecord(item,index)">记录编号{{ index+1 }}</el-check-tag>
              </div>
            </div>
          </div>
        </el-col>
      </el-row>
      <el-row :gutter="30">
        <el-col :span="6">
          <el-form-item prop="investigationDate" label="现场勘验时间">
            <el-date-picker
                style="width: 100%"
                v-model="state.formData.investigationDate"
                type="date"
                value-format="YYYY-MM-DD 00:00:00"
                placeholder="选择日期"
                size="large"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item prop="location" label="现场勘验位置">
            <el-input
                v-model.trim="state.formData.location"
                size="large"
                placeholder="请填写现场勘验位置"
                @focus="openLocation"
            >
              <template #append>
                <el-button :icon="Search" @click="openLocation"/>
              </template>
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="isSafetyCheck" label="编制现场安全检查表">
            <el-radio-group v-model="state.formData.isSafetyCheck" size="large" @change="changeRadio" :disabled="projectType==='view' || isEnd">
              <el-radio :label="1" size="large">是</el-radio>
              <el-radio :label="0" size="large">否</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="30">
        <el-col :span="24" v-if="state.formData.isSafetyCheck == 1">
          <el-form-item label="安全检查表上传" prop="assAccessoryFiles">
            <el-upload  :disabled="projectType==='view' || isEnd" accept="image/*,.pdf,.doc,.docx,.xlsx,.xls" :action="state.uploadUrl" :data="{moduleType: 5,projectId: props.projectId}" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,5)" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='1' v-model:file-list="state.safetyList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,5)">
              <el-button type="primary">附件上传</el-button>
              <template #tip>
                <div class="el-upload__tip">上传文件尺寸小于5M,最多可上传1份</div>
              </template>
            </el-upload>
          </el-form-item>
        </el-col>
        <el-col :span="24" v-if="state.formData.isSafetyCheck == 0">
          <el-form-item prop="recordData" label="现场勘验记录">
            <el-input
                v-model.trim="state.formData.recordData"
                :autosize="{ minRows: 6 }"
                maxlength="200"
                show-word-limit
                type="textarea">
            </el-input>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row style="border: 1px dashed #999;border-radius: 4px;padding: 10px;margin-top: 20px">
        <el-col :span="24">
          <el-form-item label="主要装置前合影照片" prop="deviceImages">
            <el-upload accept="image/*" :disabled="projectType === 'view' || isEnd" :action="state.uploadUrl" :data="{moduleType: 1,projectId: props.projectId}" list-type="picture-card" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,1)" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='10' v-model:file-list="state.beforeDeviceList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,1)" >
              <el-icon><Plus /></el-icon>
              <template #tip>
                <div class="el-upload__tip">上传照片尺寸小于5M,最多可上传10张</div>
              </template>
            </el-upload>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row style="border: 1px dashed #999;border-radius: 4px;padding: 10px;margin-top: 20px">
        <el-col :span="24">
          <el-form-item label="现场勘验照片" prop="investingationImages">
            <el-upload accept="image/*" :disabled="projectType === 'view' || isEnd" :action="state.uploadUrl" :data="{moduleType: 2,projectId: props.projectId}" list-type="picture-card" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,2)" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='10' v-model:file-list="state.siteCheckList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,2)" >
              <el-icon><Plus /></el-icon>
              <template #tip>
                <div class="el-upload__tip">上传照片尺寸小于5M,最多可上传10张</div>
              </template>
            </el-upload>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row style="border: 1px dashed #999;border-radius: 4px;padding: 10px;margin-top: 20px;margin-bottom: 20px">
        <el-col :span="24">
          <el-form-item label="企业陪同人员照片" prop="companyImages">
            <el-upload :disabled="projectType === 'view' || isEnd" accept="image/*" :action="state.uploadUrl" :data="{moduleType: 3,projectId: props.projectId}" list-type="picture-card" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,3)" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='10' v-model:file-list="state.companyList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,3)" >
              <el-icon><Plus /></el-icon>
              <template #tip>
                <div class="el-upload__tip">上传照片尺寸小于5M,最多可上传10张</div>
              </template>
            </el-upload>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <el-dialog v-model="state.imgDialog">
      <img style="width: 100%" :src="state.imgUrl" alt="Preview Image" />
    </el-dialog>
    <map-location ref="mapLocationRef" @giveLatLng="achieveLatLng"></map-location>
  </div>
</template>
<script setup>
import {defineEmits, onMounted, reactive, ref} from "vue"
import {ElMessage, ElMessageBox} from "element-plus"
import {Search} from '@element-plus/icons-vue'
import {
  addSiteCheck,
  editSiteCheck,
  getSiteCheckDetail,
  delFile,
  getFiles,
  getDetailById, doSiteCheck
} from "@/api/projectManage/siteCheckRcd";
import { getToken } from "@/utils/auth";
import Cookies from "js-cookie"
import { useRoute } from 'vue-router'
const route = useRoute()
const props = defineProps(['projectId'])
const emit = defineEmits(["getNextStatus"])
import MapLocation from "./mapLocation.vue"
const direction = ref('rtl');
const size = ref('400px')
const showDrawer = ref(false);
let checkSafetyFiles = (rule, value, callback)=>{
  if(state.safetyList.length === 0){
    callback(new Error('请上传现场安全检查表'))
  }else{
    callback()
  }
}
let checkInvestFiles = (rule, value, callback)=>{
  if(state.siteCheckList.length === 0){
    callback(new Error('请上传现场勘验照片'))
  }else{
    callback()
  }
}
let checkCompanyFiles = (rule, value, callback)=>{
  if(state.companyList.length === 0){
    callback(new Error('请上传企业陪同人员照片'))
  }else{
    callback()
  }
}
const state = reactive({
  data: [],
  formData: {
    id: null,
    projectId: null,
    investigationDate: '',
    location: '',
    isSafetyCheck: null,
    recordData: '',
    assAccessoryFiles: [],
    deviceImages: [],
    investingationImages: [],
    companyImages:[]
  },
  projectId: null,
  planPersons: [],
  rules: {
    investigationDate: [{required: true, message: '请选择现场勘验时间', trigger: 'blur'}],
    location: [{required: true, message: '请选择现场勘验位置', trigger: 'change'}],
    isSafetyCheck: [{required: true, message: '请选择是否编制现场安全检查表', trigger: 'blur'}],
    recordData: [{required: true, message: '请填写现场勘验记录', trigger: 'blur'}],
    assAccessoryFiles: [{required: true, validator: checkSafetyFiles, trigger: 'blur'}],
    // investingationImages: [{required: true, validator: checkInvestFiles, trigger: 'blur'}],
    // ccompanyImages: [{required: true, validator: checkCompanyFiles, trigger: 'blur'}]
  },
  beforeDeviceList: [],
  siteCheckList: [],
  companyList: [],
  safetyList: [],
  imgLimit: 1,
  uploadUrl: import.meta.env.VITE_APP_BASE_API + '/manage/accessory-file/uploadFile',
  header: {
    Authorization: getToken()
  },
  imgDialog: false,
  imgUrl: ''
})
const isAmin = ref(false)
const formRef = ref()
const mapLocationRef = ref()
onMounted(() => {
  const userInfo = JSON.parse(Cookies.get('userInfo'))
  if(userInfo.identity === 0){
    isAmin.value = true;
  }
  if(props.projectId){
    getDetail(props.projectId)
  }
  isEnd.value = Cookies.get('end')
  projectType.value = route.query.type;
});
const chooseRecord = async (item, index) => {
  state.formData = item;
  state.data.forEach((i,index) => {
    if(i.id === item.id){
      chooseItem.value = i;
      chooseItem.value.index = index+1;
    }
  })
  await getPicDetail(item.id);
  showDrawer.value = false;
}
const chooseItem = ref();
const getDetail = async (val) => {
  const res = await getSiteCheckDetail({projectId: val});
  if(res.code == 200){
    if(res.data && res.data.length > 0){
      Cookies.set('btn','变更')
      state.data = res.data;
      state.formData = res.data[0];
      chooseItem.value = state.formData;
      chooseItem.value.index = 1;
      await getPicDetail(state.formData.id)
    }else {
      Cookies.set('btn','保存')
    }
  }else {
    ElMessage.warning(res.message)
  }
}
const getPicDetail = async (val) => {
  const res = await getDetailById(val);
  if(res.code == 200){
    if(res.data){
      state.formData = res.data;
      doPic(res.data)
    }
  }else {
    ElMessage.warning(res.message)
  }
}
const doPic = (val) => {
  state.beforeDeviceList = val.deviceImages?.map(i=>{
    return {
      name: i.fileName,
      url: import.meta.env.VITE_APP_BASE_API + '/' + i.path,
      id: i.id,
      projectId: i.projectId,
      moduleType: i.moduleType
    }
  })
  state.siteCheckList = val.investingationImages?.map(i=>{
    return {
      name: i.fileName,
      url: import.meta.env.VITE_APP_BASE_API + '/' + i.path,
      id: i.id,
      projectId: i.projectId,
      moduleType: i.moduleType
    }
  })
  state.companyList = val.companyImages?.map(i=>{
    return {
      name: i.fileName,
      url: import.meta.env.VITE_APP_BASE_API + '/' + i.path,
      id: i.id,
      projectId: i.projectId,
      moduleType: i.moduleType
    }
  })
  state.safetyList = val.assAccessoryFiles?.map(i=>{
    return {
      name: i.originName,
      url: import.meta.env.VITE_APP_BASE_API + '/' + i.path,
      id: i.id,
      projectId: i.projectId,
      moduleType: i.moduleType
    }
  })
}
const changeRadio = () => {
  if(state.formData.isSafetyCheck == 1){
    getSafetyFiles()
  }
}
const projectType = ref('');
const isEnd = ref('')
const riskOpen = async (type,val) => {
  state.formData.projectId = val
  isEnd.value = Cookies.get('end')
  state.projectId = val
  projectType.value = route.query.type;
  if(type === 'sixEnd') {
    const res = await doSiteCheck({projectId: val});
    if(res.code == 200) {
      emit('getNextStatus', val);
      }else {
        ElMessage.warning(res.message)
      }
  }
  if(type === 'detail' || type === 'edit' ){
    // await getDetail(val)
  }
  if(type === 'add' || type === 'clickEdit') {
    const valid = await formRef.value.validate();
    if(valid){
      if (isAmin.value) {
        ElMessage.warning("当前用户暂无权限");
        return;
      }
      if(type === 'add'){
        if(!state.data.length >0){
         await saveData(val);
        }else {
          await editData();
        }
      }else if(type === 'clickEdit'){
          await editData();
      }
    }
  }
}
const saveData = async (val) => {
  if(state.formData.isSafetyCheck == 1){
    state.formData.recordData = ''
  }
  const {id, ...data} = JSON.parse(JSON.stringify(state.formData))
  const res = await addSiteCheck(data);
  if (res.code == 200) {
    ElMessage.success('保存成功')
    // const res = await doSiteCheck({projectId: val});
    // if(res.code == 200) {
    if(state.formData.isSafetyCheck == 0){
      if(state.safetyList && state.safetyList.length >0){
        console.log('删除原有附件',state.safetyList[0])
        let id = state.safetyList[0].response.data.id
        const res = await delFile(id)
        if(res.code == 200){
          console.log('删除原有附件')
          await getSafetyFiles()
        }else{
          ElMessage({
            type: 'warning',
            message: res.message
          })
        }
      }
    }
    await getDetail(val)
    formRef.value.clearValidate();
    // emit('getNextStatus', val);
    // }else {
    //   ElMessage.warning(res.message)
    // }
  } else {
    ElMessage.warning(res.message)
  }
}
const editData = async () => {
  if(state.formData.isSafetyCheck == 1){
    state.formData.recordData = ''
  }
  const { ...data} = JSON.parse(JSON.stringify(state.formData))
  const res = await editSiteCheck(data);
  if (res.code == 200) {
    ElMessage.success('变更成功')
    if(state.formData.isSafetyCheck == 0 && state.safetyList.length>0){
      const res = await delFile(state.safetyList[0].id)
      if(res.code == 200){
        await getSafetyFiles()
      }else{
        ElMessage({
          type: 'warning',
          message: res.message
        })
      }
    }
    await getPicDetail(chooseItem.value.id)
    formRef.value.clearValidate();
    // emit('getNextStatus', data.project.id);
  } else {
    ElMessage.warning(res.message)
  }
}
const getBeforeFiles = async (id)=>{
  const res = await getFiles({projectId: id ? id : props.projectId,moduleType: 1,processId:chooseItem.value.id })
  if(res.code == 200){
    if(res.data && res.data.length>0){
      state.beforeDeviceList = res.data.map(i=>{
        return {
          name: i.fileName,
          url: import.meta.env.VITE_APP_BASE_API + '/' + i.path,
          id: i.id,
          processId: state.formData.id,
          projectId: i.projectId,
          moduleType: i.moduleType
        }
      })
     state.formData.deviceImages = state.beforeDeviceList;
    }else{
      state.beforeDeviceList=[]
    }
  }else {
    ElMessage.warning(res.message)
  }
}
const getSiteCheckFiles = async (id)=>{
  const res = await getFiles({projectId: id ? id : props.projectId,moduleType: 2,processId:chooseItem.value.id})
  if(res.code == 200){
    if(res.data && res.data.length>0){
      state.siteCheckList = res.data.map(i=>{
        return {
          name: i.fileName,
          url: import.meta.env.VITE_APP_BASE_API + '/' + i.path,
          id: i.id,
          processId: state.formData.id,
          projectId: i.projectId,
          moduleType: i.moduleType
        }
      })
      state.formData.investingationImages = state.siteCheckList;
    }else{
      state.siteCheckList = []
    }
  }else {
    ElMessage.warning(res.message)
  }
}
const getCompanyFiles = async (id)=>{
  const res = await getFiles({projectId: id ? id : props.projectId,moduleType: 3,processId:chooseItem.value.id})
  if(res.code == 200){
    if(res.data && res.data.length>0){
      state.companyList = res.data.map(i=>{
        return {
          name: i.fileName,
          url: import.meta.env.VITE_APP_BASE_API + '/' + i.path,
          id: i.id,
          processId: state.formData.id,
          projectId: i.projectId,
          moduleType: i.moduleType
        }
      })
      state.formData.companyImages = state.companyList;
    }else{
      state.companyList=[]
    }
  }else {
    ElMessage.warning(res.message)
  }
}
const getSafetyFiles = async (id)=>{
  const res = await getFiles({projectId: id ? id : props.projectId,moduleType: 5,processId: chooseItem.value? chooseItem.value.id:''})
  if(res.code == 200){
    if(res.data && res.data.length>0){
      state.safetyList = res.data.map(i=>{
        return {
          name: i.originName,
          url: import.meta.env.VITE_APP_BASE_API + '/' + i.path,
          id: i.id,
          processId: state.formData.id,
          projectId: i.projectId,
          moduleType: i.moduleType
        }
      })
      state.formData.assAccessoryFiles = state.safetyList
    }else{
      state.safetyList = []
    }
  }else {
    ElMessage.warning(res.message)
  }
}
const openLocation = ()=>{
  mapLocationRef.value.openMapLocation(state.formData.location.split(',')[0],state.formData.location.split(',')[1])
}
const achieveLatLng=(lng,lat)=>{
  if(lng && lat){
    state.formData.location = lng + ',' + lat
  }else {
    ElMessage.warning('请选择勘验位置')
  }
}
// 图片上传
const showTip =()=>{
  ElMessage({
    type: 'warning',
    message: '超出文件上传数量'
  });
}
const picSize = async (rawFile) => {
  if(rawFile.size / 1024 / 1024 > 5){
    ElMessage({
      type: 'warning',
      message: '文件大小不能超过5M'
    });
    return false
  }
};
const handlePictureCardPreview = (uploadFile) => {
  console.log(uploadFile,'file')
  state.imgUrl = uploadFile.url
  state.imgDialog = true
};
const handleAvatarSuccess = (res, uploadFile, type) => {
  if(res.code == 200){
    if(type == 1){
      let obj = {
        name: res.data.fileName,
        url: import.meta.env.VITE_APP_BASE_API + '/' + res.data.path,
        id: res.data.id,
        processId: state.formData.id,
        projectId: res.data.projectId,
        moduleType: res.data.moduleType
      }
      state.formData.deviceImages.push(obj);
      // getBeforeFiles()
    }
    if(type == 2){
      let obj = {
        name: res.data.fileName,
        url: import.meta.env.VITE_APP_BASE_API + '/' + res.data.path,
        id: res.data.id,
        processId: state.formData.id,
        projectId: res.data.projectId,
        moduleType: res.data.moduleType
      }
      state.formData.investingationImages.push(obj);
      // getSiteCheckFiles()
    }
    if(type == 3){
      let obj = {
        name: res.data.fileName,
        url: import.meta.env.VITE_APP_BASE_API + '/' + res.data.path,
        id: res.data.id,
        processId: state.formData.id,
        projectId: res.data.projectId,
        moduleType: res.data.moduleType
      }
      state.formData.companyImages.push(obj);
      // getCompanyFiles()
    }
    if(type == 5){
      let obj = {
        name: res.data.fileName,
        url: import.meta.env.VITE_APP_BASE_API + '/' + res.data.path,
        id: res.data.id,
        processId: state.formData.id,
        projectId: res.data.projectId,
        moduleType: res.data.moduleType
      }
      state.formData.assAccessoryFiles.push(obj);
      console.log(res,'res')
      // getSafetyFiles()
    }
  }else{
    ElMessage({
      type: 'warning',
      message: res.message
    })
  }
}
const handleRemove = async (file, uploadFiles,type) => {
  if(file && file.status == 'success') {
    ElMessageBox.confirm(
        '确定删除该附件?',
        '提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        })
        .then(async () => {
          const res = await delFile(file.id)
          if (res.code == 200) {
            ElMessage({
              type: 'success',
              message: '文件已删除'
            })
            if (type == 1) {
              const index = state.formData.deviceImages.findIndex(v => v.id === file.id)
              state.formData.deviceImages.splice(index, 1);
            }
            if (type == 2) {
              const index = state.formData.investingationImages.findIndex(v => v.id === file.id)
              state.formData.investingationImages.splice(index, 1);
            }
            if (type == 3) {
              const index = state.formData.companyImages.findIndex(v => v.id === file.id)
              state.formData.companyImages.splice(index, 1);
            }
            if (type == 5) {
              const index = state.formData.assAccessoryFiles.findIndex(v => v.id === file.id)
              state.formData.assAccessoryFiles.splice(index, 1);
            }
          } else {
            ElMessage({
              type: 'warning',
              message: res.message
            })
          }
        })
        .catch(() => {
          // if(type == 1){
          //   getBeforeFiles()
          // }
          // if(type == 2){
          //   getSiteCheckFiles()
          // }
          // if(type == 3){
          //   getCompanyFiles()
          // }
          // if(type == 5){
          //   getSafetyFiles()
          // }
        })
  }
}
defineExpose({
  riskOpen
});
</script>
<style scoped lang="scss">
.riskBox{
  :deep(.el-form .el-form-item__label) {
    font-size: 15px;
  }
}
.textColor{
  color: #3b82f6;
}
</style>
src/views/safetyReview/testManage/components/techLeaderReview.vue
对比新文件
@@ -0,0 +1,267 @@
<template>
  <div class="riskBox">
    <el-form ref="formRef" :model="state.formData" :rules="state.rules" class="register-form" label-position="top">
      <el-row :gutter="30">
        <el-col :span="6">
          <el-form-item prop="auditDate" label="审核日期">
            <el-date-picker
                style="width: 100%"
                v-model="state.formData.auditDate"
                type="date"
                value-format="YYYY-MM-DD 00:00:00"
                placeholder="选择日期"
                size="large"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item prop="assessor.name" label="技术负责人">
            <el-input
                v-model.trim="state.formData.assessor.name"
                size="large"
                placeholder="请选择技术负责人"
                @focus="openExperts('技术负责人')"
            >
              <template #append>
                <el-button :icon="Search" @click="openExperts('技术负责人')"/>
              </template>
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="确认日期" prop="affirmDate">
            <el-date-picker
                style="width: 100%"
                v-model="state.formData.affirmDate"
                type="date"
                value-format="YYYY-MM-DD 00:00:00"
                placeholder="选择日期"
                size="large"
            />
          </el-form-item>
        </el-col>
      </el-row>
<!--      <el-row :gutter="30">-->
<!--        <el-col :span="6">-->
<!--          <el-form-item label="附件上传">-->
<!--            <el-upload accept="image/*" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="handleAvatarSuccess" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='state.imgLimit' v-model:file-list="state.fileList" list-type="picture-card" :before-upload="picSize" :on-remove="handleRemove" :before-remove="beforeRemove">-->
<!--              <el-icon><Plus /></el-icon>-->
<!--              <template #tip>-->
<!--                <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传1张</div>-->
<!--              </template>-->
<!--            </el-upload>-->
<!--          </el-form-item>-->
<!--        </el-col>-->
<!--      </el-row>-->
      <el-table  :data="state.tableData" :border="true" style="margin: 20px 0">
        <el-table-column label="序号" width="60" align="center" type="index"></el-table-column>
        <el-table-column label="内容" prop="content" header-align="center" :show-overflow-tooltip="true"/>
        <el-table-column label="选择" header-align="center" class-name="small-padding fixed-width" width="175">
          <template #default="scope">
            <el-radio-group v-model="scope.row.status" >
              <el-radio :label="1">是</el-radio>
              <el-radio :label="0">否</el-radio>
            </el-radio-group>
          </template>
        </el-table-column>
      </el-table>
      <el-form-item label="存在问题及建议">
        <el-input
            v-model.trim="state.formData.suggestions"
            :autosize="{ minRows: 6 }"
            maxlength="500"
            show-word-limit
            type="textarea">
        </el-input>
      </el-form-item>
    </el-form>
    <el-dialog v-model="state.dialogImg">
      <el-image style="width: 100%; height: 100%" :src="state.dialogImageUrl"/>
    </el-dialog>
    <experts-list ref="expertsListRef" @getName="getSelected"></experts-list>
  </div>
</template>
<script setup>
import {defineEmits, onMounted, reactive, ref} from "vue";
import {ElMessage} from "element-plus";
import {Search} from '@element-plus/icons-vue'
import {addInnerReview, editInnerReview, getInnerReviewDetail} from "@/api/projectManage/innerReview"
import {delPic} from "@/api/login"
import { getToken } from "@/utils/auth";
import Cookies from "js-cookie"
import ExpertsList from "./expertsList";
const emit = defineEmits(["getNextStatus"])
const state = reactive({
  formData: {
    id: '',
    projectId: '',
    auditDate:'',
    auditType: 2,
    assessor: {
      name: ''
    },
    assessorId: null,
    affirmDate: '',
    suggestions: ''
  },
  rules: {
    "assessor.name": [{required: true, message: '请选择技术负责人', trigger: 'change'}],
    auditDate: [{required: true, message: '请选择审核日期', trigger: 'change'}],
    affirmDate: [{required: true, message: '请选择确认日期', trigger: 'change'}]
  },
  tableData: [
    {id: 1, content: '报告中所列评价依据是否得到引用和验证',key: 'isBasisQuote', status: 1},
    {id: 2, content: '现场收集的有关资料是否齐全、有效',key: 'isData', status: 1},
    {id: 3, content: '危险有害因素识别是否充分', key: 'isDangerFull',status: 1},
    {id: 4, content: '报告是否有重大遗漏', key: 'isOmission',status: 1},
    {id: 5, content: '评价方法选用是否合理', key: 'isMethodRational',status: 1},
    {id: 6, content: '对策措施及建议是否具有针对性、合理性', key: 'isMeasureEquitable',status: 1},
    {id: 7, content: '评价结论及格式是否正确', key: 'isConclusionRight',status: 1},
    {id: 8, content: '已按要求修改完成', key: 'isAmendFinish',status: 1},
    {id: 9, content: '可报过程控制负责人审核', key: 'isReportAudit',status: 1}
  ],
  imgLimit: 1,
  uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile',
  header: {
    Authorization: getToken()
  },
  dialogImageUrl: '',
  dialogImg: false
})
const isAmin = ref(false)
const formRef = ref()
const expertsListRef = ref()
onMounted(() => {
  const userInfo = JSON.parse(Cookies.get('userInfo'))
  if(userInfo.identity === 0){
    isAmin.value = true;
  }
})
const riskOpen = async (type,val) => {
  state.formData.projectId = val
  if(type === 'detail' || type === 'edit' ){
    const res = await getInnerReviewDetail({projectId: val,auditType: 2});
    if(res.code == 200){
      state.formData = res.data
      for(let key in res.data){
        for(let item of state.tableData){
          if(item.key == key){
            item.status = res.data[key]==true?1:0
          }
        }
      }
    }else {
      ElMessage.warning(res.message)
    }
  }
  if(type === 'add' || type === 'clickEdit') {
    const valid = await formRef.value.validate();
    if(valid){
      if (isAmin.value) {
        ElMessage.warning("当前用户暂无权限");
        return;
      }
      if(type === 'add'){
        const {id, ...data} = JSON.parse(JSON.stringify(state.formData))
        for(let i of state.tableData){
          data[i.key] = i.status
        }
        const res = await addInnerReview(data);
        if (res.code == 200) {
          ElMessage.success('保存成功')
          formRef.value.clearValidate();
          emit('getNextStatus', val);
        } else {
          ElMessage.warning(res.message)
        }
      }else if(type === 'clickEdit'){
        const { ...data} = JSON.parse(JSON.stringify(state.formData))
        for(let i of state.tableData){
          data[i.key] = i.status
        }
        const res = await editInnerReview(data);
        if (res.code == 200) {
          ElMessage.success('变更成功')
          formRef.value.clearValidate();
          // emit('getNextStatus', data.project.id);
        } else {
          ElMessage.warning(res.message)
        }
      }
    }
  }
}
const openExperts = (type) =>{
  expertsListRef.value.openDialog(type)
}
const getSelected = (type,obj)=>{
  state.formData.assessor.name = obj.name
  state.formData.assessorId = obj.id
}
// 图片上传
const showTip =()=>{
  ElMessage({
    type: 'warning',
    message: '超出文件上传数量'
  });
}
const picSize = async (rawFile) => {
  if(rawFile.size / 1024 / 1024 > 5){
    ElMessage({
      type: 'warning',
      message: '文件大小不能超过5M'
    });
    return false
  }
};
const handleAvatarSuccess = (res, uploadFile) => {
  if(res.code == 200){
    // state.registerForm.agency.reportPath = res.data.path
  }else{
    ElMessage({
      type: 'warning',
      message: '文件上传失败'
    })
  }
}
const handleRemove = async (file, uploadFiles) => {
  const res = await delPic({path: state.registerForm.agency.reportPath})
  if(res.code == 200){
    ElMessage({
      type: 'success',
      message: '文件已删除'
    })
  }else{
    ElMessage({
      type: 'warning',
      message: res.message
    })
  }
}
defineExpose({
  riskOpen
});
</script>
<style scoped lang="scss">
.riskBox{
  :deep(.el-form .el-form-item__label) {
    font-size: 15px;
  }
}
</style>
src/views/safetyReview/testManage/components/uploadReviewRcd.vue
对比新文件
@@ -0,0 +1,241 @@
<template>
  <div class="riskBox">
    <el-form ref="formRef" :model="state.formData" :rules="state.rules" class="register-form" label-position="top">
      <el-row :gutter="30">
        <el-col :span="18">
          <el-form-item label="附件上传">
            <el-upload :disabled="projectType === 'view' || isEnd" accept="image/*,.pdf,.doc,.docx" :action="state.uploadUrl" :data="{moduleType: 6,projectId: props.projectId}" :headers="state.header" method="post" :on-success="handleAvatarSuccess" :on-exceed="showTip" v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="handleRemove">
              <el-button type="primary">上传评审记录</el-button>
              <template #tip>
                <div class="el-upload__tip">上传文件尺寸尺寸小于5M</div>
              </template>
            </el-upload>
          </el-form-item>
        </el-col>
      </el-row>
      <el-table  :data="state.tableData" :border="true" style="margin: 20px 0">
        <el-table-column label="序号" width="60" align="center" type="index"></el-table-column>
        <el-table-column label="原名称" prop="originName" align="center" :show-overflow-tooltip="true"/>
        <el-table-column label="操作" header-align="center" class-name="small-padding fixed-width" width="120">
          <template #default="scope">
            <el-button link type="primary" @click="checkFile(scope.row)">查看</el-button>
            <el-button link type="danger" @click="handleRemove(scope.row,[])" :disabled="projectType === 'view'">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
  </div>
</template>
<script setup>
import {defineEmits, onMounted, reactive, ref} from "vue";
import {ElMessage, ElMessageBox} from "element-plus";
import {Search} from '@element-plus/icons-vue'
import {delFile, getFiles, getReviewDone} from "@/api/projectManage/siteCheckRcd";
import { getToken } from "@/utils/auth";
import Cookies from "js-cookie"
import axios from 'axios'
import { useRoute } from 'vue-router'
const route = useRoute()
const emit = defineEmits(["getNextStatus"]);
const props = defineProps(['projectId'])
const state = reactive({
  formData: {},
  rules: {},
  tableData: [],
  uploadUrl: import.meta.env.VITE_APP_BASE_API + '/manage/accessory-file/uploadFile',
  header: {
    Authorization: getToken()
  },
  fileList: []
})
const isAmin = ref(false)
const formRef = ref()
onMounted(() => {
  const userInfo = JSON.parse(Cookies.get('userInfo'))
  if(userInfo.identity === 0){
    isAmin.value = true;
  }
  getReviewFiles(props.projectId)
  isEnd.value = Cookies.get('end')
  projectType.value = route.query.type;
})
const projectType = ref('');
const isEnd = ref('')
const riskOpen = async (type,val) => {
  projectType.value = route.query.type;
  isEnd.value = Cookies.get('end')
  if(type === 'detail' || type === 'edit' ){
    await getReviewFiles
  }
  if(type === 'add' || type === 'clickEdit') {
    const valid = await formRef.value.validate();
    if(valid){
      if (isAmin.value) {
        ElMessage.warning("当前用户暂无权限");
        return;
      }
      if(type === 'add'){
        const res = await getFiles({projectId: val,moduleType: 6})
        if(res.code == 200){
          if(res.data && res.data.length>0){
            state.tableData = res.data
            ElMessage.success('保存成功')
            getReviewDone({projectId: val}).then((res)=>{
              if(res.code == 200){
                emit('getNextStatus', val);
              }else{
                ElMessage.warning(res.message)
              }
            })
          }else{
            state.tableData=[]
            ElMessage.warning('请上传评审记录附件')
          }
        }else {
          ElMessage.warning(res.message)
        }
      }else if(type === 'clickEdit'){
        const res = await getFiles({projectId: val,moduleType: 6})
        if(res.code == 200){
          if(res.data && res.data.length>0){
            state.tableData = res.data
            ElMessage.success('变更成功')
          }else{
            state.tableData=[]
            ElMessage.warning('请上传评审记录附件')
          }
        }else {
          ElMessage.warning(res.message)
        }
      }
    }
  }
}
const getReviewFiles = async (id)=>{
  const res = await getFiles({projectId: id ? id : props.projectId,moduleType: 6})
  if(res.code == 200){
    if(res.data && res.data.length>0){
      state.tableData = res.data
      state.fileList = res.data.map(i => {
        return {
          name: i.originName,
          url: import.meta.env.VITE_APP_BASE_API + '/' + i.path,
          id: i.id,
          projectId: i.projectId,
          moduleType: i.moduleType
        }
      })
    }else{
      state.tableData=[]
    }
  }else {
    ElMessage.warning(res.message)
  }
}
// 图片上传
const showTip =()=>{
  ElMessage({
    type: 'warning',
    message: '超出文件上传数量'
  });
}
const picSize = async (rawFile) => {
  if(rawFile.size / 1024 / 1024 > 5){
    ElMessage({
      type: 'warning',
      message: '文件大小不能超过5M'
    });
    return false
  }
};
const handlePictureCardPreview = (uploadFile) => {
  console.log(uploadFile,'file')
  state.imgUrl = uploadFile.url
  state.imgDialog = true
};
const handleAvatarSuccess = (res, uploadFile, type) => {
  if(res.code == 200){
    getReviewFiles()
  }else{
    state.fileList.splice(state.fileList.indexOf(uploadFile),1)
    ElMessage({
      type: 'warning',
      message: res.message
    })
  }
}
const handleRemove = async (file, uploadFiles) => {
  if(file && file.status == 'success'){
    ElMessageBox.confirm(
        '确定删除该附件?',
        '提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        })
        .then( async() => {
          const res = await delFile(file.id)
          if(res.code == 200){
            ElMessage({
              type: 'success',
              message: '文件已删除'
            })
            await getReviewFiles()
          }else{
            ElMessage({
              type: 'warning',
              message: res.message
            })
          }
        })
        .catch(()=>{
          getReviewFiles()
        })
  }
}
const checkFile = async (file)=>{
  axios.get(import.meta.env.VITE_APP_BASE_API +'/' + file.path,{headers:{'Content-Type': 'application/json','Authorization': `${getToken()}`,'uid':`${Cookies.get('uid')}`},responseType: 'blob'}).then(res=>{
    if (res) {
      const link = document.createElement('a')
      let blob = new Blob([res.data],{type: res.data.type})
      link.style.display = "none";
      link.href = URL.createObjectURL(blob); // 创建URL
      window.open(link.href)
    } else {
      ElMessage({
        type: 'warning',
        message: '文件读取失败'
      });
    }
  })
}
defineExpose({
  riskOpen
});
</script>
<style scoped lang="scss">
.riskBox{
  :deep(.el-form .el-form-item__label) {
    font-size: 15px;
  }
}
</style>
src/views/safetyReview/testManage/components/worksDialog.vue
对比新文件
@@ -0,0 +1,205 @@
<template>
    <div class="notice">
        <el-dialog
            v-model="dialogVisible"
            :title="title"
            width="500px"
            :before-close="handleClose"
        >
            <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-position="top">
                <el-form-item label="评价组成员:" prop="person.name">
                  <el-input
                      v-model.trim="state.form.person.name"
                      size="large"
                      placeholder="请选择评价组成员"
                      @focus="openExperts('评价组成员')"
                  >
                    <template #append>
                      <el-button :icon="Search" @click="openExperts('评价组成员')"/>
                    </template>
                  </el-input>
                </el-form-item>
                <el-form-item label="工作类型:" prop="jobType">
                  <el-select v-model="state.form.jobType" placeholder="工作类型" style="width: 100%" size="large">
                    <el-option v-for="(item,index) in props.typeList" :key="index" :label="item.label" :value="item.value"/>
                  </el-select>
                </el-form-item>
<!--                <el-form-item label="专业能力:" prop="person.major">-->
<!--                  <el-select v-model="state.form.person.majorName" placeholder="专业能力" style="width: 100%" size="large" @change="getCerNo">-->
<!--                    <el-option v-for="(item,index) in state.form.person.majorNames" :key="index" :label="item" :value="item"/>-->
<!--                  </el-select>-->
<!--                </el-form-item>-->
<!--                <el-form-item label="资格证书:" prop="person.certificateNo">-->
<!--                  <el-input-->
<!--                      v-model="state.form.person.certificateNo"-->
<!--                      size="large"-->
<!--                      readonly-->
<!--                  />-->
<!--                </el-form-item>-->
              <el-form-item label="承担工作:" prop="work">
                <el-select v-model="state.form.work" multiple placeholder="承担工作" style="width: 100%" size="large">
                  <el-option v-for="item in props.workList" :key="item.value" :label="item.label" :value="item.value"/>
                </el-select>
              </el-form-item>
              <el-form-item label="承诺后期前往现场勘验:" prop="laterPromise">
                <el-radio-group v-model="state.form.laterPromise" size="large">
                  <el-radio :label="1" size="large">是</el-radio>
                  <el-radio :label="0" size="large">否</el-radio>
                </el-radio-group>
              </el-form-item>
              <el-form-item label="未到现场勘验原因:">
                <el-input v-model.trim="state.form.reason" maxlength="30" show-word-limit type="text" size="large"/>
              </el-form-item>
            </el-form>
            <template #footer>
                    <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>
          <experts-list ref="expertsListRef" @getName="getSelected"></experts-list>
        </el-dialog>
    </div>
</template>
<script setup>
import {defineProps, nextTick, reactive, ref, toRefs} from 'vue'
import {ElMessage} from "element-plus";
import {Search} from '@element-plus/icons-vue'
import {addWorks, editWorks} from "@/api/projectManage/evaPlan"
import ExpertsList from "./expertsList"
const dialogVisible = ref(false);
const title = ref("");
const busRef = ref();
const expertsListRef = ref()
const props = defineProps(['workList','typeList'])
const emit = defineEmits(["getList"]);
const state = reactive({
    form: {
      id: null,
      person: {
        name: '',
        // major: {},
        // certificateNo: '',
        // certs: '',
        // majorName: '',
        // majorNames: [],
        // ids: []
      },
      personId: null,
      jobType: null,
      projectId: null,
      informed: 0,
      work: [],
      laterPromise: 0,
      reason: ''
    },
    formRules:{
        'person.name': [{ required: true, message: '请选择评价组成员', trigger: 'change' }],
        'person.major': [{ required: true, message: '请选择专业能力', trigger: 'blur' }],
        work: [{ required: true, message: '请选择承担工作', trigger: 'blur' }],
        jobType: [{ required: true, message: '请选择工作类型', trigger: 'blur' }]
    },
})
const openDialog = async (type, value,projectId) => {
    title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看'
    state.form.projectId = projectId
    if(type == 'add'){
      nextTick(()=>{
        busRef.value.resetFields()
      })
    }else if(type === 'edit') {
      state.form = JSON.parse(JSON.stringify(value))
      state.form.work = value.work.split(',')
      state.form.laterPromise = value.laterPromise?1:0
    }
    dialogVisible.value = true;
}
const openExperts = (type) =>{
  expertsListRef.value.openDialog(type)
}
const getSelected = (type,obj)=>{
    state.form.person.name = obj.name
    state.form.personId = obj.id
    // state.form.person.certs = obj.certificateNo
    // state.form.person.majorNames = obj.majorNames
    // state.form.person.ids = obj.major.split(',')
}
// const getCerNo = () =>{
//   const i = state.form.person.majorNames.indexOf(state.form.person.majorName)
//   const obj = JSON.parse(state.form.person.certs)
//   state.form.person.certificateNo = Object.values(obj)[i]
//   state.form.person.major[state.form.person.ids[i]] = state.form.person.certificateNo
// }
const onSubmit = async () => {
    const valid = await busRef.value.validate();
    if(valid){
        if(title.value === '新增'){
            const {id,work,...data} = state.form
            data['work'] =  state.form.work.join(',')
            // const {name,major,...rest} = state.form.person
            // data.person = { name,major }
            // data.person.major =  JSON.stringify(state.form.person.major)
            const res = await addWorks(data)
            if(res.code === 200){
                ElMessage({
                    type: 'success',
                    message: '新增成功'
                });
            }else{
                ElMessage.warning(res.message)
            }
            emit("getList")
            busRef.value.clearValidate();
            busRef.value.resetFields()
            dialogVisible.value = false;
        }else if(title.value === '编辑'){
            const {...data} = state.form
            data['work'] =  state.form.work.join(',')
            const res = await editWorks(data)
            if(res.code === 200){
                ElMessage({
                    type: 'success',
                    message: '修改成功'
                });
            }else{
                ElMessage.warning(res.message)
            }
            emit("getList")
            busRef.value.clearValidate();
            busRef.value.resetFields()
            dialogVisible.value = false;
        }
    }
}
const handleClose = () => {
    busRef.value.clearValidate();
    busRef.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>
src/views/safetyReview/testManage/index.vue
对比新文件
@@ -0,0 +1,748 @@
<template>
  <div class="project-container">
    <div class="header">
      <el-button type="success" icon="Plus" @click="toProcess('add',{})">新增</el-button>
      <vue3-json-excel
          :json-data="dataList"
          :fields="fields"
          name="项目信息表.xlsx"
          style="margin-right: 5px;margin-left: 5px"
      >
        <el-button type="warning">导出</el-button>
      </vue3-json-excel>
      <el-button type="primary"  icon="Filter" @click="showDrawer = true">筛选</el-button>
    </div>
    <div class="middle">
      <div class="card-box">
        <div class="box-left" @click="choose('')">
          <div class="font-left">
            <div>项目</div>
            <div>总数</div>
          </div>
          <div class="font-right">{{search.num.projectTotal}}</div>
        </div>
        <div class="box-right">
          <div class="inbox" @click="choose(1)" style="box-shadow: rgba(132, 122, 253, 0.2) 0 3px 5px 0;" :class="{btn1: chooseType === 1}">
            <div class="top" style="background: linear-gradient(90deg, rgb(127, 118, 253), rgb(218, 180, 246));">
              <span class="top-right-font">风险分析及计划评价</span>
            </div>
            <div class="bottom">
              <span class="top-right-font-bottom">{{search.num.riskTotal}}</span>
            </div>
          </div>
          <div class="inbox" @click="choose(2)" style="box-shadow: rgba(255, 142, 139, 0.15) 0 3px 5px 0;" :class="{btn2: chooseType === 2}">
            <div class="top" style="background: linear-gradient(90deg, rgb(255, 140, 138), rgb(239, 186, 141));">
              <span class="top-right-font">现场勘验</span>
            </div>
            <div class="bottom">
              <span class="top-right-font-bottom">{{search.num.investigationTotal}}</span>
            </div>
          </div>
          <div class="inbox"  @click="choose(3)" style="box-shadow: rgba(222, 106, 169, 0.15) 0 3px 5px 0;" :class="{btn3: chooseType === 3}">
            <div class="top" style="background: linear-gradient(90deg, rgb(229, 119, 180), rgb(249, 159, 192));">
              <span class="top-right-font">项目审核</span>
            </div>
            <div class="bottom">
              <span class="top-right-font-bottom">{{search.num.reviewTotal}}</span>
            </div>
          </div>
          <div class="inbox" @click="choose(4)" style="box-shadow: rgba(109, 177, 254, 0.2) 0 3px 5px 0;" :class="{btn4: chooseType === 4}">
            <div class="top" style="background: linear-gradient(90deg, rgb(54, 115, 255), rgb(124, 196, 242));">
              <span class="top-right-font">出具报告</span>
            </div>
            <div class="bottom">
              <span class="top-right-font-bottom">{{search.num.reportTotal}}</span>
            </div>
          </div>
          <div class="inbox" @click="choose(5)" style="box-shadow: rgba(88, 211, 137, 0.2) 0 3px 5px 0;" :class="{btn5: chooseType === 5}">
            <div class="top" style="background: linear-gradient(90deg, rgb(0, 195, 151), rgb(114, 232, 200));">
              <span class="top-right-font">项目归档</span>
            </div>
            <div class="bottom">
              <span class="top-right-font-bottom">{{search.num.archiveTotal}}</span>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div style="margin-top: 10px;margin-bottom: 15px;margin-left: 20px;">
      <div style="font-size: 18px;font-weight: 800;color: #ed5565;display: flex">
        当前存在未完结:安全评价项目 {{search.num.safetyTotal}} 个,检验检测项目
        <div style="cursor: pointer;border-radius: 8px;padding: 0 5px" :class="{active: isActive}" @click="chooseUn" >{{search.num.safetyCheckTotal}}</div>
        个,共 {{search.num.unFinishTotal}} 个
      </div>
    </div>
    <!-- 表格数据 -->
    <el-table v-loading="loading" :data="dataList" :border="true" ref="tableRef" :height="tableHeight" style="width: 100%;">
      <el-table-column label="序号" width="80" align="center" type="index" ></el-table-column>
      <el-table-column label="项目名称" prop="name" align="center" :show-overflow-tooltip="true" width="180" />
      <el-table-column label="填报机构" prop="agencyName" align="center" :show-overflow-tooltip="true" width="180" />
      <el-table-column label="委托单位" prop="client" align="center"  :show-overflow-tooltip="true" width="180"/>
      <el-table-column label="所属地市" align="center"  width="250">
        <template #default="scope">
         {{scope.row.area}}
        </template>
      </el-table-column>
      <el-table-column label="类型" prop="estimateTypeName" align="center"  width="150"/>
      <el-table-column label="业务范围" prop="businessName" align="center" :show-overflow-tooltip="true" width="150"/>
      <el-table-column label="项目负责人" prop="leaderName" align="center"  width="120" :show-overflow-tooltip="true"/>
      <el-table-column label="项目阶段" align="center"  width="200">
        <template #default="scope">
          <div v-if="scope.row.process === 1" class="process1">
            <span>风险分析及计划评价</span>
          </div>
          <div v-else-if="scope.row.process === 2" class="process1 process2">
            <span>现场勘验</span>
          </div>
          <div v-else-if="scope.row.process === 3" class="process1 process3">
            <span>项目审核</span>
          </div>
          <div v-else-if="scope.row.process === 4" class="process1 process4">
            <span>出具报告</span>
          </div>
          <div v-else class="process1 process5">
            <span>项目归档</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="项目实施天数" prop="filingDate" align="center"  width="150"/>
<!--      <el-table-column label="项目变更" prop="" align="center"  width="120">-->
<!--        <template #default="scope">-->
<!--          <div style="cursor:pointer;color: #3b82f6;" >-->
<!--            <span v-if="scope.row.process !== 1" @click="goMenu('toFive',scope.row)">{{}}</span>-->
<!--            <span v-else></span>-->
<!--          </div>-->
<!--        </template>-->
<!--      </el-table-column>-->
      <el-table-column label="预估金额(万元)" prop="contractMoney" align="center"  width="130"/>
      <el-table-column label="归档金额(万元)" prop="actualContractMoney" align="center"  width="130"/>
      <el-table-column label="缺失要件"  align="center"  width="150">
        <template #default="scope">
          <div style="cursor:pointer;color: #3b82f6;" >
            <span v-if="scope.row.process === 5" @click="goMenu('toTwelve',scope.row)">{{scope.row.missingMaterialCnt}}</span>
            <span v-else></span>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="归档确认" prop="" align="center"  width="150">
        <template #default="scope">
          <div style="cursor:pointer;color: #3b82f6;" >
            <span  v-if="scope.row.process === 5" @click="goMenu('toThirteen',scope.row)">{{scope.row.activeConfirm}}</span>
<!--            <span v-else></span>-->
          </div>
        </template>
      </el-table-column>
      <el-table-column fixed="right" label="操作" align="center" class-name="small-padding fixed-width" width="180">
        <template #default="scope">
          <el-button link type="primary" @click="toProcess('view',scope.row)">查看</el-button>
          <el-button link type="primary" v-if="scope.row.reportProgress !== 14" @click="toProcess('edit',scope.row)">编辑</el-button>
          <el-button link type="danger" v-if="(isAgency && scope.row.reportProgress !== 14) || (!isAgency && scope.row.reportProgress !== 14)" @click="del(scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <div class="pag-container">
      <el-pagination
          v-model:current-page="search.queryParams.pageNum"
          v-model:page-size="search.queryParams.pageSize"
          :page-sizes="[10,15,20,25]"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
      />
    </div>
    <el-drawer v-model="showDrawer" :direction="direction" :with-header="false"  :size="size" >
      <template #default>
      <div class="drawer">
        <el-form ref="drawerRef"  class="register-form" label-position="top">
            <el-form-item label="时间选择">
              <el-date-picker
                  v-model="searchTime"
                  type="daterange"
                  @change="changeTime"
                  range-separator="至"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期"
                  value-format="YYYY-MM-DD"
              />
            </el-form-item>
          <el-form-item  label="所属区域">
            <el-cascader
                v-model="area"
                :options="addressList"
                :props="props"
                @change="handleChange"
                style="width: 100%"
                size="large"
            />
          </el-form-item>
          <el-form-item  label="机构名称" >
            <el-select
                v-model="search.queryParams.agencyName"
                filterable
                remote
                @change="selectValue"
                reserve-keyword
                placeholder="所属机构"
                remote-show-suffix
                :remote-method="getCompanyList"
                :loading="loadingCompany"
                style="width:100%"
                clearable
            >
              <el-option
                  v-for="item in companyList"
                  :key="item.id"
                  :label="item.name"
                  :value="item.name"
              />
            </el-select>
          </el-form-item>
          <el-form-item  label="项目名称" >
            <el-input v-model.trim="search.queryParams.name" placeholder="请输入项目名称"></el-input>
          </el-form-item>
          <el-form-item  label="委托单位">
            <el-input v-model.trim="search.queryParams.client" placeholder="委托单位"></el-input>
          </el-form-item>
          <el-form-item  label="业务范围">
            <el-select v-model="search.queryParams.business" class="m-2" size="large" placeholder="请选择" style="width: 100%" >
              <el-option
                  v-for="item in businessList"
                  :key="item.id"
                  :label="item.label"
                  :value="item.id"
              />
            </el-select>
          </el-form-item>
<!--          <el-form-item  label="类型">-->
<!--            <el-select v-model="search.queryParams.estimateType" class="m-2" size="large" placeholder="请选择" style="width: 100%" >-->
<!--              <el-option-->
<!--                  v-for="item in estimateTypeList"-->
<!--                  :key="item.id"-->
<!--                  :label="item.label"-->
<!--                  :value="item.id"-->
<!--              />-->
<!--            </el-select>-->
<!--          </el-form-item>-->
          <el-form-item  label="缺失要件">
            <el-select v-model="search.queryParams.params.lostMaterial" class="m-2" size="large" placeholder="请选择" style="width: 100%" >
              <el-option
                  v-for="item in missingList"
                  :key="item.id"
                  :label="item.label"
                  :value="item.id"
              />
            </el-select>
          </el-form-item>
        </el-form>
      </div>
      </template>
      <template #footer>
        <div style="flex: auto">
          <el-button type="primary" @click="searchClick">查询</el-button>
          <el-button type="warning" @click="reset">重置</el-button>
          <el-button @click="confirmClick">取消</el-button>
        </div>
      </template>
    </el-drawer>
  </div>
</template>
<script setup>
import {onMounted, reactive, ref} from "vue";
import {delProject, getProjectList, getProjectStatistics} from "@/api/projectManage/project";
import {ElMessage, ElMessageBox} from "element-plus";
import {getRegionTree} from "@/api/area";
import {getDict} from "@/api/login";
import {getDictList} from "@/api/backManage/evaluate";
import Cookies from "js-cookie"
import {getAllAgency} from "@/api/backManage/insitution";
const router = useRouter();
const loading = ref(false);
const direction = ref('rtl');
const showDrawer = ref(false);
const size = ref('400px')
const props = {
  expandTrigger: 'hover',
  value: 'name',
  label: 'name'
}
const search = reactive({
  queryParams: {
    pageNum: 1,
    pageSize: 20,
    name: '',
    agencyName: '',
    client: '',
    province: '',
    city: '',
    district: '',
    business: '',
    estimateType: '',
    phase: '',
    safetyCheck: 1,
    params:{
      lostMaterial: null
    }
  },
  num: {
    projectTotal: 0,
    riskTotal: 0,
    investigationTotal: 0,
    reviewTotal: 0,
    reportTotal: 0,
    archiveTotal: 0,
    unFinishTotal: 0,
    safetyCheckTotal: 0,
    safetyTotal: 0
  }
});
const companyList = ref([])
const loadingCompany = ref(false)
const searchTime = ref([]);
const area = ref([]);
const businessList = ref([]);
const addressList = ref([]);
const estimateTypeList = ref([]);
const missingList = ref([
  {
    id: 1,
    label: '是'
  },
  {
    id: 0,
    label: '否'
  }
])
const tableRef  = ref(null);
const tableHeight = ref(0);
const dataList = ref([]);
const total = ref(0);
const isAgency = ref(false);
onMounted(() => {
  Cookies.remove('projectId')
  Cookies.remove('end')
  Cookies.remove('btn')
  getList();
  getStatistics();
  getArea();
  getBusinessList();
  getRiskList();
  tableHeight.value = window.innerHeight - tableRef.value.$el.offsetTop - 170;
  // 监听浏览器高度变化
  window.onresize = () => {
    tableHeight.value = window.innerHeight - tableRef.value.$el.offsetTop - 170;
  };
  const userInfo = JSON.parse(Cookies.get('userInfo'))
  isAgency.value = userInfo.identity === 1;
});
const chooseType = ref('');
const choose = (val) => {
  chooseType.value = val;
  search.queryParams.phase = val;
  getList();
  getStatistics()
}
const getList = async () => {
  loading.value = true;
  const res = await getProjectList(search.queryParams);
  if(res.code == 200){
    dataList.value = res.data.list.map(item => {
      return {
        ...item,
        process: item.reportProgress <= 4 ? 1 : item.reportProgress > 4 && item.reportProgress <= 6 ? 2 : item.reportProgress > 6 && item.reportProgress <= 9 ? 3 : item.reportProgress > 9 && item.reportProgress <= 11 ? 4 : 5,
        leaderName: item.leader ? item.leader.name : '',
        area: item.district ? item.province + '/' + item.city + '/' + item.district : item.city != item.province ? item.province + '/' + item.city: item.province ,
        filingDate: item.filingDate ? conversionDays(item.filingDate,item.createTime) : conversionDays('',item.createTime),
        contractMoney: item.contract ? item.contract.contractMoney : '',
        actualContractMoney: item.contract ? item.contract.actualContractMoney : '',
        activeConfirm: item.personRecognition ?  item.personRecognition.recognitionCnt +  '/' +  item.personRecognition.personCnt: '',
        missingMaterialCnt:  3-item.materialCnt,
        activeConfirmOut: item.personRecognition ? "\'" + item.personRecognition.recognitionCnt +  '/' +  item.personRecognition.personCnt: '',
      }
    })
    total.value = res.data.total
    loading.value = false;
    console.log('11',dataList.value)
  }else{
    ElMessage.warning(res.message)
  }
}
const getStatistics = async () => {
  const {pageNum,pageSize, ...data} = JSON.parse(JSON.stringify(search.queryParams))
  const res = await getProjectStatistics(data);
  if(res.code == 200){
    search.num = res.data
  }else{
    ElMessage.warning(res.message)
  }
}
const handleSizeChange = (val) => {
  search.queryParams.pageNum = 1;
  search.queryParams.pageSize = val
  getList()
  getStatistics()
}
const handleCurrentChange = (val) => {
  search.queryParams.pageNum = val
  getList()
  getStatistics()
}
const toProcess = (type,value,toPath) => {
  value.type = type;
  router.push({ path: '/processTest', query: {id: value.id, type: type, toPath: toPath, process: value.reportProgress}});
}
const getArea = async ()=>{
  const type = 1
  const res = await getRegionTree({name: '',parentId: null,regionType: type})
  if(res.code == 200){
   addressList.value = res.data
  }else{
    ElMessage.warning(res.message)
  }
}
const getBusinessList = async () => {
  const res = await getDict({dictType: 'sys_business_scope'})
  if(res.code === 200){
    businessList.value = res.data
  }else{
    ElMessage.warning(res.message)
  }
}
const getRiskList = async () => {
  const res = await getDictList({dictType: "sys_assess_type"});
  if(res.code === 200){
    estimateTypeList.value = res.data.list
  }else{
    ElMessage.warning(res.message)
  }
}
const del = (val) => {
  ElMessageBox.confirm(
      '确定删除此条数据?',
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
      .then( async() => {
        const res = await delProject(val)
        if(res.code == 200){
          ElMessage.success('数据删除成功')
          getList()
          getStatistics()
        }else{
          ElMessage.warning(res.message)
        }
      })
}
const confirmClick = () => {
  showDrawer.value = false;
}
const changeTime=(value)=>{
  if(!value){
    search.queryParams.params.endTime = ""
    search.queryParams.params.startTime = ""
  }
}
const searchClick = () => {
  if(searchTime.value && searchTime.value.length>0){
    search.queryParams.params.startTime = searchTime.value[0]
    search.queryParams.params.endTime = searchTime.value[1]
  }
  getList();
  getStatistics();
  showDrawer.value = false;
}
const reset = () => {
  searchTime.value = [];
  area.value = [];
  search.queryParams = {
    pageNum: 1,
    pageSize: 20,
    name: '',
    agencyName: '',
    client: '',
    province: '',
    city: '',
    district: '',
    business: '',
    estimateType: '',
    phase: '',
    safetyCheck: 1,
    params: {
      lostMaterial: null
    }
  }
  chooseType.value = '';
  getList();
  getStatistics();
  showDrawer.value = false;
}
const conversionDays = (time,createTime) => {
  let day = "";
  if(time) {
    day = new Date(time).getTime() - new Date(createTime).getTime();//日期转时间戳
  }else {
    day = Date.now() - new Date(createTime).getTime();//日期转时间戳
  }
  return Math.floor(day / 86400000) ;//时间戳获取天数
}
const handleChange = (value) => {
  // if(state.registerForm.agency.attribute == 0){
  //   state.registerForm.agency.province = '新疆维吾尔自治区'
  //   state.registerForm.agency.city = value[0]?value[0]:''
  //   state.registerForm.agency.district  = value[1]?value[1]:''
  // }else{
  search.queryParams.province = value[0]?value[0]:''
  search.queryParams.city = value[1]?value[1]:''
  search.queryParams.district  = value[2]?value[2]:''
  // }
}
// 导出表格
const fields = ref({
  '项目名称':'name',
  '委托单位':'client',
  '所属地市': 'area',
  '类型': 'estimateTypeName',
  '业务范围': 'businessName',
  '项目负责人': 'leaderName',
  '项目阶段': {
    field: 'process',
    callback: (value) => {
      if (value === 1) {
        return '风险分析及计划评价'
      } else if(value === 2){
        return '现场勘验'
      }else if(value === 3){
        return '项目审核'
      }else if(value === 4){
        return '出具报告'
      }else if(value === 5){
        return '项目归档'
      }
    }
  },
  '项目实施天数': 'filingDate',
  '预估金额(万元)': 'contractMoney',
  '归档金额(万元)': 'actualContractMoney',
  '缺失要件': 'missingMaterialCnt',
  '归档确认': 'activeConfirmOut'
});
const goMenu = (toPath,val) => {
  console.log("val",val)
  toProcess('edit',val,toPath);
}
const selectValue = (val) => {
  console.log('val',val)
  if(val == ""){
    companyList.value = []
  }
  // data.companyList.forEach(item => {
  //   if(item.name === val){
  //     data.queryParams.companyId = item.id
  //   }
  // })
}
const getCompanyList = async (val)=>{
  if(val != ""){
    loadingCompany.value = true;
    const queryParams = {
      name: val
    }
    const res = await getAllAgency(queryParams)
    if (res.code == 200) {
      loadingCompany.value = false;
      companyList.value = res.data
    } else {
      ElMessage.warning(res.message)
    }
  }
}
const isActive = ref(false)
const chooseUn = () => {
  isActive.value = !isActive.value
  if(isActive.value){
    search.queryParams.unFinish = 1
  }else {
    search.queryParams.unFinish = null
  }
  getList()
  getStatistics()
}
</script>
<style scoped lang="scss">
.project-container{
  .active {
    background-color: #fdb0b7;
    //border: 1px solid #dab4f6;
  }
  .header{
    margin: 15px 10px;
    display: flex;
    align-items: center;
    justify-content: flex-end;
  }
  .middle{
    height: 99px;
    margin-bottom: 20px;
  }
  .card-box{
    margin: 20px;
    height: 99px;
    background: #fff;
    box-shadow: 0 3px 10px 0 rgba(62,62,62,.25);
    border-radius: 10px;
    display: flex;
    .box-left{
      width: 20%;
      min-width: 200px;
      height: 99px;
      background: #fff;
      box-shadow: 0 0 5px 0 rgba(62,62,62,.2);
      border-radius: 10px;
      display: flex;
      margin-left: -15px;
      align-items: center;
      cursor: pointer;
      padding-left: 2%;
      .font-left{
        width: 40px;
        height: 40px;
        font-size: 20px;
        font-weight: 400;
        color: #9198ad;
        line-height: 18px;
        font-family: fantasy;
      }
      .font-right{
        position: relative;
        left: 7%;
        top: -3px;
        height: 40px;
        font-size: 36px;
        font-family: fantasy;
        font-weight: 400;
        color: #222733;
      }
    }
    .box-left:hover{
      border: 1px solid #4378f1
    }
    .box-right{
      width: 80%;
      height: 99px;
      border-radius: 10px;
      margin-left: 15px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      .inbox{
        width: 19%;
        height: 76px;
        background: #fff;
        border-radius: 5px;
        cursor: pointer;
        .top{
          width: 100%;
          height: 39px;
          border-top-left-radius: 5px;
          border-top-right-radius: 5px;
          .top-right-font{
            font-size: 16px;
            color: #fff;
            line-height: 39px;
            margin-left: 10px;
          }
        }
        .bottom{
          height: 37px;
          .top-right-font-bottom{
            font-size: 20px;
            color: #333;
            line-height: 37px;
            margin-left: 20px;
            font-family: fantasy;
          }
        }
      }
      .inbox:nth-child(1):hover{
        border: 1px solid #dab4f6;
      }
      .inbox:nth-child(2):hover{
        border: 1px solid #efba8d;
      }
      .inbox:nth-child(3):hover{
        border: 1px solid #f99fc0;
      }
      .inbox:nth-child(4):hover{
        border: 1px solid #7cc4f2;
      }
      .inbox:nth-child(5):hover{
        border: 1px solid #72e8c8;
      }
    }
  }
  .btn1{
    border: 1px solid #dab4f6;
  }
  .btn2{
    border: 1px solid #efba8d;
  }
  .btn3{
    border: 1px solid #f99fc0;
  }
  .btn4{
    border: 1px solid #7cc4f2;
  }
  .btn5{
    border: 1px solid #72e8c8;
  }
  .pag-container{
    float: right;
    margin-top: 20px;
  }
  .process1{
    border-radius: 5px;
    color: rgb(255, 255, 255);
    padding: 5px 10px;
    background: linear-gradient(90deg, rgb(127, 118, 253), rgb(218, 180, 246));
  }
  .process2{
    background: linear-gradient(90deg, rgb(255, 140, 138), rgb(239, 186, 141));
  }
  .process3 {
    background: linear-gradient(90deg, rgb(229, 119, 180), rgb(249, 159, 192));;
  }
  .process4 {
    background: linear-gradient(90deg, rgb(54, 115, 255), rgb(124, 196, 242));;
  }
  .process5 {
    background: linear-gradient(90deg, rgb(0, 195, 151), rgb(114, 232, 200));;
  }
  .drawer{
    :deep(.el-form .el-form-item__label) {
      font-size: 15px;
    }
  }
}
</style>
src/views/safetyReview/testManage/process.vue
对比新文件
@@ -0,0 +1,1149 @@
<template>
  <div class="process-container">
    <div class="flow">
      <div class="content"  :class="{show: isShowMenu}" >
        <div class="content-middle" @click="clickMenu(true)">
          <div class="project-title">
<!--            <img :src="projectPng">-->
            <span>项目</span>
            <span>阶段</span>
          </div>
          <div v-for="item in menuList" :key="item.id" style="flex: 1" :class="{choose: item.status === 1 || item.status === 2}">
            <div class="header-item">
              <div class="item-content">
                <img v-if="item.status === 0" :src="status0Png">
                <img v-else-if="item.status === 1" :src="status1Png">
                <img v-else :src="status2Png">
                <span class="text-eclipse" style="margin-left: 5px">{{item.name}}</span>
              </div>
            </div>
            <div v-for="child in item.subMenus" :key="child.id" @click="chooseSubMenu(child,true)">
              <div class="down-item" :class="{itemActive: child.status === 1 || child.status === 3, itemPrev: child.status === 2}">
                <div class="item-icon-status0" v-if="child.status === 0">{{child.id}}</div>
                <div class="item-icon-status0 item-icon-status1" v-else-if="child.status === 1 || (selectedObj.status === 3 && child.id === selectedObj.id)">{{child.id}}</div>
                <div  class="item-icon-status0 item-icon-status2" v-else-if="child.status === 2 "><img :src="itemStatus2Png"></div>
                <div class="item-icon-status0 item-icon-status4 "  v-else-if="nextObj.status === 4 && child.id === nextObj.id">{{child.id}}</div>
                <div class="text-eclipse" style="margin-right: 15%">{{child.name}}</div>
                <div v-if="child.status === 1 || (selectedObj.status === 1 && child.id ===selectedObj.id)" class="item-icon-status0 item-icon-status2"><img :src="status1Png"></div>
                <div v-if="nextObj.status === 4 && child.id === nextObj.id" class="item-icon-status0 item-icon-status4" ><img :src="status1Png"></div>
              </div>
              <div></div>
            </div>
          </div>
        </div>
        <div class="content-bottom" @click="clickMenu(false)"></div>
      </div>
    </div>
    <div class="middle" :style="'height:' + middleHeight + 'px'">
      <el-card>
        <div class="card-header">{{selectedObj.id}}- {{selectedObj.name}}</div>
        <div class="card-content">
          <div :style="'height:' + middleContentHeight + 'px'" style="overflow-y: scroll;">
            <rickAnalysis ref="riskRef" v-if="selectedObj.id === 1" @getNextStatus="getNextStatus"></rickAnalysis>
            <contract-manage ref="contractMngRef" v-if="selectedObj.id === 2" @getNextStatus="getNextStatus"></contract-manage>
            <evaluate-task-notice ref="evaluteRef" v-if="selectedObj.id === 3" @getNextStatus="getNextStatus"></evaluate-task-notice>
            <evaluate-plan ref="evalPlanRef" v-if="selectedObj.id === 4" @getNextStatus="getNextStatus" :projectId="projectId"></evaluate-plan>
            <employ-notice-record ref="employNoticeRcdRef" v-if="selectedObj.id === 5" @getNextStatus="getNextStatus" :projectId="projectId"></employ-notice-record>
            <site-check-rcd ref="siteCheckRcdRef" v-if="selectedObj.id === 6" @getNextStatus="getNextStatus" :projectId="projectId"></site-check-rcd>
            <inner-review ref="innerReviewRef" v-if="selectedObj.id === 7" @getNextStatus="getNextStatus"></inner-review>
            <tech-leader-review ref="techReviewRef" v-if="selectedObj.id === 8" @getNextStatus="getNextStatus"></tech-leader-review>
            <upload-review-rcd ref="uploadReviewRef" v-if="selectedObj.id === 9" @getNextStatus="getNextStatus" :projectId="projectId"></upload-review-rcd>
            <rate-conclusion ref="rateConRef" v-if="selectedObj.id === 10" @getNextStatus="getNextStatus" :projectId="projectId"></rate-conclusion>
            <process-ctrl-review ref="proCtrlRef" v-if="selectedObj.id === 11" @getNextStatus="getNextStatus" :projectId="projectId"></process-ctrl-review>
            <project-archive ref="proArchRef" v-if="selectedObj.id === 12" @getNextStatus="getNextStatus" :projectId="projectId"></project-archive>
            <sign-confirm ref="signConfirmRef" v-if="selectedObj.id === 13" @getNextStatus="getNextStatus" :projectId="projectId"></sign-confirm>
            <confirm-end ref="confirmEndRef" v-if="selectedObj.id === 14" @getNextStatus="getNextStatus" :projectId="projectId"></confirm-end>
          </div>
          <div style="display: flex;align-items: center;justify-content: center;margin-bottom: -30px;margin-top: 10px">
            <el-button type="primary" v-if="selectedObj.id !== 1" style="width: 80px" @click="back">上一步</el-button>
            <el-button type="warning" style="width: 80px"  v-if="(projectStatus === 'add'   && selectedObj.status === 1 && selectedObj.id !== 14)||(projectStatus === 'edit' && selectedObj.status === 1 && selectedObj.id !== 14)  " @click="save">保存</el-button>
            <el-button type="warning" style="width: 80px"  v-if="(projectStatus === 'edit' && selectedObj.status !== 1 && selectedObj.id !== 13 && selectedObj.id !== 14 && reportProcess != 14) || (projectStatus === 'add'   && selectedObj.status !== 1 && selectedObj.id !== 14 && reportProcess != 14) " @click="clickEdit">变更</el-button>
            <el-button type="warning" style="width: 80px" v-if="selectedObj.id === 14 && selectedObj.status === 1 && reportProcess != 14" @click="confirm">确认完结</el-button>
            <el-button type="primary" style="width: 80px" v-if="selectedObj.id !== 14" @click="next">下一步</el-button>
          </div>
        </div>
      </el-card>
    </div>
    <div class="bottom">
      <el-button type="primary" v-if="selectedObj.id === 3" plain @click="downloadFile">
        评价任务通知书<el-icon class="el-icon--right"><Download /></el-icon>
      </el-button>
      <el-button type="primary" v-if="selectedObj.id === 13" plain @click="downloadCommitFile">
        承诺书<el-icon class="el-icon--right"><Download /></el-icon>
      </el-button>
    </div>
  </div>
</template>
<script setup>
import {onMounted, ref} from "vue";
import {ElMessage, ElMessageBox} from "element-plus";
import rickAnalysis from "./components/riskAnalysis.vue"
import contractManage from "./components/contractManage.vue"
import evaluateTaskNotice from "./components/evaluateTaskNotice.vue"
import {Download} from '@element-plus/icons-vue'
import projectPng from "@/assets/images/project.png"
import status0Png from "@/assets/images/status0.png"
import status1Png from "@/assets/images/status1.png"
import status2Png from "@/assets/images/status2.png"
import itemStatus2Png from "@/assets/images/itemStatus2-1.png"
import { useRoute } from 'vue-router'
import {getProjectStatus} from "@/api/projectManage/project"
import ContractManage from "./components/contractManage";
import EvaluateTaskNotice from "./components/evaluateTaskNotice"
import EvaluatePlan from "./components/evaluatePlan";
import EmployNoticeRecord from "./components/employNoticeRecord"
import SiteCheckRcd from "./components/siteCheckRcd"
import InnerReview from "./components/innerReview"
import TechLeaderReview from "./components/techLeaderReview"
import UploadReviewRcd from "./components/uploadReviewRcd"
import RateConclusion from "./components/rateConclusion"
import ProcessCtrlReview from "./components/processCtrlReview"
import ProjectArchive from "./components/projectArchive"
import SignConfirm from "./components/signConfirm"
import ConfirmEnd from "./components/confirmEnd"
import Cookies from "js-cookie"
import {delMonitor} from "@/api/sysUsers";
const route = useRoute()
const menuList = ref([
  {
    id: 'a',
    name: '风险分析及计划评价',
    status: 1 ,
    subMenus: [
      {
        id: 1,
        name: '项目风险分析',
        status: 1 // 0:未完成,1:选中待完成,2:已完成 ,3:选中已完成,4:未选中待完成
      },
      {
        id: 2,
        name: '合同管理',
        status: 0
      },
      {
        id: 3,
        name: '评价任务通知',
        status: 0
      },
      {
        id: 4,
        name: '评价项目计划',
        status: 0
      },
    ]
  },
  {
    id: 'b',
    name: '现场勘验',
    status: 0,
    subMenus: [
      {
        id: 5,
        name: '从业告知',
        status: 0
      },
      {
        id: 6,
        name: '现场勘验',
        status: 0
      },
    ]
  },
  {
    id: 'c',
    name: '项目审核',
    status: 0,
    subMenus: [
      {
        id: 7,
        name: '内部审核',
        status: 0
      },
      {
        id: 8,
        name: '技术负责人审核',
        status: 0
      },
      {
        id: 9,
        name: '审核记录',
        status: 0
      },
    ]
  },
  {
    id: 'd',
    name: '出具报告',
    status: 0,
    subMenus: [
      {
        id: 10,
        name: '评价结论',
        status: 0
      },
      {
        id: 11,
        name: '过程控制负责人审核',
        status: 0
      }
    ]
  },
  {
    id: 'e',
    name: '项目归档',
    status: 0,
    subMenus: [
      {
        id: 12,
        name: '项目归档',
        status: 0
      },
      {
        id: 13,
        name: '签字确认',
        status: 0
      },
      {
        id: 14,
        name: '确认完结',
        status: 0
      },
    ]
  },
])
const riskRef = ref();
const contractMngRef = ref()
const evaluteRef = ref()
const evalPlanRef = ref()
const employNoticeRcdRef = ref()
const siteCheckRcdRef = ref()
const innerReviewRef = ref()
const techReviewRef = ref()
const uploadReviewRef = ref()
const rateConRef = ref()
const proCtrlRef = ref()
const proArchRef = ref()
const signConfirmRef = ref()
const confirmEndRef = ref()
const isShowMenu = ref(false)
const selectedObj = ref({})
const middleHeight = ref(0)
const middleContentHeight = ref(0)
const projectId = ref()
const projectStatus = ref()
const toPath = ref();
const reportProcess = ref();
onMounted(() => {
  middleHeight.value = window.innerHeight - 250;
  middleContentHeight.value = window.innerHeight - 385;
  // 监听浏览器高度变化
  window.onresize = () => {
    middleHeight.value = window.innerHeight - 250;
    middleContentHeight.value = window.innerHeight - 385;
  };
  if(route.query.type !== 'add'){
    projectStatus.value = route.query.type;
    projectId.value = route.query.id;
    toPath.value = route.query.toPath;
    reportProcess.value = route.query.process;
    getStatus(projectId.value);
  }else {
    projectStatus.value = route.query.type;
    selectedObj.value =  {
      id: 1,
      name: '项目风险分析',
      status: 1
    }
  }
});
const nextObj = ref({})
const setMenuList = (id) => {
  menuList.value[id].subMenus.forEach(item => {
    item.status = 2;
  })
}
const getStatus = async (projectId) => {
  const res = await getProjectStatus(projectId);
  if(res.code == 200){
    reportProcess.value = res.data
    let fiveObj = {}
    if(toPath.value && toPath.value === 'toFive' ){
      fiveObj = menuList.value[1].subMenus[0]
    }
    if(res.data <= 4 ){
      menuList.value[0].subMenus.forEach(item => {
        if(item.id <= res.data){
          item.status = 2
        }
        if(projectStatus.value !== 'view'){
          if(item.id  === res.data + 1){
            item.status = 4;
            nextObj.value = item;
          }
        }
        if(item.id === res.data){
          item.status = 3;
          selectedObj.value =item;
            setTimeout(() => {
              goRouter(selectedObj.value.id)
            }, 10)
        }
      })
      menuList.value[0].status = 1;
      console.log("menu11",menuList.value)
    }
    if(res.data >=4 && res.data <=6){
      setMenuList(0)
      if(res.data === 4){
        menuList.value[0].subMenus[3].status = 3;
      }
      menuList.value[1].subMenus.forEach(item => {
        if(item.id <= res.data) {
          item.status = 2
        }
        if(projectStatus.value !== 'view'){
          if(item.id  === res.data + 1){
            item.status = 4;
            nextObj.value = item;
          }
        }
        if(item.id === res.data){
          item.status = 3;
          selectedObj.value =item;
          setTimeout(() => {
            goRouter(selectedObj.value.id)
          }, 10)
        }
      })
      menuList.value[0].status = 2;
      menuList.value[1].status = 1;
      console.log("menu22",menuList.value)
    }
    if(res.data >= 6 && res.data <= 9){
      setMenuList(0);
      setMenuList(1);
      if(res.data === 6){
        menuList.value[1].subMenus[1].status = 3;
      }
      menuList.value[2].subMenus.forEach(item => {
        if(item.id <= res.data) {
          item.status = 2
        }
        if(projectStatus.value !== 'view'){
          if(item.id  === res.data + 1){
            item.status = 4;
            nextObj.value = item;
          }
        }
        if(item.id === res.data){
          item.status = 3;
          selectedObj.value =item;
          setTimeout(() => {
            goRouter(selectedObj.value.id)
          }, 10)
        }
      })
      menuList.value[0].status = 2;
      menuList.value[1].status = 2;
      menuList.value[2].status = 1;
    }
    if(res.data >= 9 && res.data <=11){
      setMenuList(0);
      setMenuList(1);
      setMenuList(2);
      if(res.data === 9){
        menuList.value[2].subMenus[2].status = 3;
      }
      menuList.value[3].subMenus.forEach(item => {
        if(item.id <= res.data) {
          item.status = 2
        }
        if(projectStatus.value !== 'view'){
          if(item.id  === res.data + 1){
            item.status = 4;
            nextObj.value = item;
          }
        }
        if(item.id === res.data){
          item.status = 3;
          selectedObj.value =item;
          setTimeout(() => {
            goRouter(selectedObj.value.id)
          }, 10)
        }
      })
      menuList.value[0].status = 2;
      menuList.value[1].status = 2;
      menuList.value[2].status = 2;
      menuList.value[3].status = 1;
    }
    if(res.data >= 11){
      setMenuList(0);
      setMenuList(1);
      setMenuList(2);
      setMenuList(3);
      if(res.data === 11){
        menuList.value[3].subMenus[1].status = 3;
      }
      let twelveObj = {};
      let thirteenObj = {};
      menuList.value[4].subMenus.forEach(item => {
        if(item.id <= res.data) {
          item.status = 2
        }
        if(projectStatus.value !== 'view'){
          if(item.id  === res.data + 1){
            item.status = 4;
            nextObj.value = item;
          }
        }
        if(item.id === res.data){
          item.status = 3;
          selectedObj.value =item;
          setTimeout(() => {
            goRouter(selectedObj.value.id)
          }, 10)
        }
        menuList.value[0].status = 2;
        menuList.value[1].status = 2;
        menuList.value[2].status = 2;
        menuList.value[3].status = 2;
        menuList.value[4].status = 1;
        if(res.data === 14 && res.data === item.id){
          item.status = 3;
          menuList.value[4].status = 2;
          selectedObj.value =item;
        }
        if(toPath.value && toPath.value === 'toTwelve' && item.id === 12){
          twelveObj = item;
        }else if(toPath.value && toPath.value === 'toThirteen' && item.id === 13){
          thirteenObj = item;
        }
      })
      if(toPath.value && toPath.value === 'toTwelve' && twelveObj){
        chooseSubMenu(twelveObj,true)
      }else if(toPath.value && toPath.value === 'toThirteen' && thirteenObj){
        chooseSubMenu(thirteenObj,true)
      }
    }
    if(toPath.value && toPath.value === 'toFive' && fiveObj){
      chooseSubMenu(fiveObj,true)
    }
  }else{
    ElMessage.warning(res.message)
  }
}
const clickMenu = (val) => {
  isShowMenu.value = !isShowMenu.value
}
const downloadFile = () => {
  const link = document.createElement('a')
  link.href = 'files/evaluateNotice.doc'
  link.target = '_blank'
  link.download = '评价任务通知书.doc'
  link.click()
}
const downloadCommitFile = () => {
  const link = document.createElement('a')
  link.href = 'files/commitLetter.doc'
  link.target = '_blank'
  link.download = '承诺书.doc'
  link.click()
}
const sixBtn = ref("");
const chooseSubMenu = (val,flag) => {
  if(val.status === 0) {
    setTimeout(() => {
      isShowMenu.value = false;
      ElMessage({
        type: 'warning',
        message: '请按顺序操作,未完成步骤无法查看!'
      });
    }, 10)
  }else if(val.status === 1){
    setTimeout(() => {
      isShowMenu.value = false;
      selectedObj.value = val;
    }, 10)
  }else if(val.status === 2){
    setTimeout(() => {
      isShowMenu.value = false;
      if((val !== selectedObj.value && nextObj.value === selectedObj.value) || nextObj.value === selectedObj.value){
        nextObj.value = selectedObj.value;
      }
      if(nextObj.value !== val) {
        selectedObj.value.status = 2
      }
      selectedObj.value = val;
      selectedObj.value.status = 3;
      nextObj.value.status = 4;
      //跳转
    }, 10)
    if(flag){
      setTimeout(() => {
        goRouter(selectedObj.value.id)
      }, 10)
    }
  }else if (val.status === 3) {
    setTimeout(() => {
      isShowMenu.value = false;
      selectedObj.value = val;
      //跳转
    }, 10)
  }else if (val.status === 4) {
    setTimeout(() => {
      if(val.id === 6){
        sixBtn.value = Cookies.get('btn')
      }
      console.log('sixBtn.value',sixBtn.value)
      isShowMenu.value = false;
      nextObj.value = selectedObj.value;
      selectedObj.value = val;
      selectedObj.value.status = 1;
      nextObj.value.status = 2;
      nextObj.value = val;
      //跳转
    }, 10)
  }
}
const next = () => {
  if(selectedObj.value.status === 3){
    if(selectedObj.value.id + 1 <= 4){
      nextMenu(0)
    }else if (selectedObj.value.id+ 1 >4 && selectedObj.value.id+ 1 <= 6){
      nextMenu(1)
    }else if (selectedObj.value.id+ 1 >6 && selectedObj.value.id+ 1 <= 9){
      nextMenu(2)
    }else if (selectedObj.value.id+ 1 >9 && selectedObj.value.id+ 1 <= 11){
      nextMenu(3)
    }else if (selectedObj.value.id+ 1 >11){
      nextMenu(4)
    }
  }else if(selectedObj.value.id === 6){
    if(selectedObj.value.id === 6) {
      ElMessageBox.confirm(
          '确定结束现场勘验?',
          '提示',
          {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
          })
          .then( async() => {
            goRouter(selectedObj.value.id,'sixEnd')
          })
    }
  } else {
    setTimeout(() => {
      isShowMenu.value = false;
      ElMessage({
        type: 'warning',
        message: '请按顺序操作,未完成步骤无法查看!'
      });
    }, 10)
  }
  //
  // setTimeout( () => {
  //   goRouter(selectedObj.value.id)
  // }, 100)
}
const nextMenu = (id) => {
  menuList.value[id].subMenus.forEach( item => {
    if(item.id === selectedObj.value.id + 1){
      chooseSubMenu(item,true);
    }
  })
}
const backMenu = (id) => {
  menuList.value[id].subMenus.forEach(async item => {
    if(item.id === selectedObj.value.id - 1){
     await chooseSubMenu(item,true);
    }
  })
}
//上一步——回退(查看详情)
const back = () => {
    if(selectedObj.value.id-1 <= 4){
      backMenu(0)
    }else if (selectedObj.value.id-1 >4 && selectedObj.value.id-1 <= 6){
      backMenu(1)
    }else if (selectedObj.value.id-1 >6 && selectedObj.value.id-1 <= 9){
      backMenu(2)
    }else if (selectedObj.value.id-1 >9 && selectedObj.value.id-1 <= 11){
      backMenu(3)
    }else if (selectedObj.value.id-1 >11){
      backMenu(4)
    }
  // setTimeout( () => {
  //   goRouter(selectedObj.value.id)
  // }, 100)
}
const clickEdit = () => {
  goRouter(selectedObj.value.id,'clickEdit')
}
const getNextStatus = async (val) => {
  projectId.value = val
  const res = await getProjectStatus(val);
  if(res.code == 200){
    reportProcess.value = res.data
    if(res.data <=4){
      menuList.value[0].subMenus.forEach(item => {
        if(item.id <= res.data){
          item.status = 2
        }
        if(item.id === res.data + 1){
          item.status = 1;
          selectedObj.value =item;
          nextObj.value = item;
        }
        // else if(item.id  === res.data ){
        //   item.status = 3;
        //   selectedObj.value =item;
        // }else if(item.id === res.data + 1){
        //   item.status = 4;
        //   nextObj.value = item;
        // }
      })
      menuList.value[0].status = 1;
      console.log("menu11",menuList.value)
    }
    if(res.data >=4 && res.data<=6){
      setMenuList(0)
      menuList.value[1].subMenus.forEach(item => {
        if(item.id <= res.data) {
          item.status = 2
        }
        if(item.id  === res.data + 1){
          item.status = 1;
          selectedObj.value =item;
          nextObj.value = item;
        }
        // if(item.id === res.data){
        //   item.status = 3;
        //   selectedObj.value =item;
        // }
      })
      menuList.value[0].status = 2;
      menuList.value[1].status = 1;
      console.log("menu22",menuList.value)
    }
    if(res.data >= 6 && res.data <= 9){
      setMenuList(0);
      setMenuList(1);
      menuList.value[2].subMenus.forEach(item => {
        if(item.id <= res.data) {
          item.status = 2
        }
        if(item.id  === res.data + 1){
          item.status = 1;
          selectedObj.value =item;
          nextObj.value = item;
        }
        // if(item.id === res.data){
        //   item.status = 3;
        //   selectedObj.value =item;
        // }
      })
      menuList.value[0].status = 2;
      menuList.value[1].status = 2;
      menuList.value[2].status = 1;
    }
    if(res.data >= 9 && res.data <=11){
      setMenuList(0);
      setMenuList(1);
      setMenuList(2);
      menuList.value[3].subMenus.forEach(item => {
        if(item.id <= res.data) {
          item.status = 2
        }
        if(item.id  === res.data + 1){
          item.status = 1;
          selectedObj.value =item;
          nextObj.value = item;
        }
        // if(item.id === res.data){
        //   item.status = 3;
        //   selectedObj.value =item;
        // }
      })
      menuList.value[0].status = 2;
      menuList.value[1].status = 2;
      menuList.value[2].status = 2;
      menuList.value[3].status = 1;
    }
    if(res.data >= 11){
      setMenuList(0);
      setMenuList(1);
      setMenuList(2);
      setMenuList(3);
      // if(res.data === 11){
      //   menuList.value[3].subMenus[1].status = 3;
      // }
      menuList.value[4].subMenus.forEach(item => {
        if(item.id <= res.data) {
          item.status = 2
        }
        if(item.id  === res.data + 1){
          item.status = 1;
          selectedObj.value =item;
          nextObj.value = item;
        }
        // if(item.id === res.data){
        //   item.status = 3;
        //   selectedObj.value =item;
        // }
        menuList.value[0].status = 2;
        menuList.value[1].status = 2;
        menuList.value[2].status = 2;
        menuList.value[3].status = 2;
        menuList.value[4].status = 1;
        if(res.data === 14 && res.data === item.id){
          item.status = 3;
          menuList.value[4].status = 2;
          selectedObj.value =item;
        }
      })
    }
  }
}
const save = () => {
  // if(selectedObj.value.id === 6) {
  //   ElMessageBox.confirm(
  //       '确定结束现场勘验?',
  //       '提示',
  //       {
  //         confirmButtonText: '确定',
  //         cancelButtonText: '取消',
  //         type: 'warning',
  //       })
  //       .then( async() => {
  //         goRouter(selectedObj.value.id,'add')
  //       })
  // }else {
    goRouter(selectedObj.value.id,'add')
  // }
}
const confirm = () => {
  goRouter(selectedObj.value.id,'confirm')
}
const goRouter = (val,type) => {
  switch (val){
    case 1:
      if(type === 'add'){
        riskRef.value.riskOpen('add','');
      }else if (type === 'clickEdit'){
        riskRef.value.riskOpen('clickEdit',projectId.value);
      }else {
        if(projectStatus.value === 'view' || projectStatus.value === 'add'){
          riskRef.value.riskOpen('detail',projectId.value);
        }else if(projectStatus.value === 'edit'){
          riskRef.value.riskOpen('edit',projectId.value);
        }
      }
      console.log("1")
      break;
    case 2:
      if(type === 'add'){
        contractMngRef.value.riskOpen('add',projectId.value);
      }else if (type === 'clickEdit'){
        contractMngRef.value.riskOpen('clickEdit',projectId.value);
      }else {
        if(projectStatus.value === 'view' || projectStatus.value === 'add'){
          contractMngRef.value.riskOpen('detail',projectId.value);
        }else if(projectStatus.value === 'edit'){
          contractMngRef.value.riskOpen('edit',projectId.value);
        }
      }
      console.log("2")
      break;
    case 3:
      if(type === 'add'){
        evaluteRef.value.riskOpen('add',projectId.value);
      }else if (type === 'clickEdit'){
        evaluteRef.value.riskOpen('clickEdit',projectId.value);
      }else {
        if(projectStatus.value === 'view' || projectStatus.value === 'add'){
          evaluteRef.value.riskOpen('detail',projectId.value);
        }else if(projectStatus.value === 'edit'){
          evaluteRef.value.riskOpen('edit',projectId.value);
        }
      }
      console.log("3")
      break;
    case 4:
      if(type === 'add'){
        evalPlanRef.value.riskOpen('add',projectId.value);
      }else if (type === 'clickEdit'){
        evalPlanRef.value.riskOpen('clickEdit',projectId.value);
      }else {
        if(projectStatus.value === 'view' || projectStatus.value === 'add'){
          evalPlanRef.value.riskOpen('detail',projectId.value);
        }else if(projectStatus.value === 'edit'){
          evalPlanRef.value.riskOpen('edit',projectId.value);
        }
      }
      console.log("4")
      break;
    case 5:
      if(type === 'add'){
        employNoticeRcdRef.value.riskOpen('add',projectId.value);
      }else if (type === 'clickEdit'){
        employNoticeRcdRef.value.riskOpen('clickEdit',projectId.value);
      }else {
        if(projectStatus.value === 'view' || projectStatus.value === 'add'){
          employNoticeRcdRef.value.riskOpen('detail',projectId.value);
        }else if(projectStatus.value === 'edit'){
          employNoticeRcdRef.value.riskOpen('edit',projectId.value);
        }
      }
      console.log("5")
      break;
    case 6:
      if(type === 'add'){
        siteCheckRcdRef.value.riskOpen('add',projectId.value);
      }else if (type === 'clickEdit'){
        siteCheckRcdRef.value.riskOpen('clickEdit',projectId.value);
      }else if (type === 'sixEnd'){
        siteCheckRcdRef.value.riskOpen('sixEnd',projectId.value);
      } else {
        if(projectStatus.value === 'view' || projectStatus.value === 'add'){
          siteCheckRcdRef.value.riskOpen('detail',projectId.value);
        }else if(projectStatus.value === 'edit'){
          siteCheckRcdRef.value.riskOpen('edit',projectId.value);
        }
      }
      console.log("6")
      break;
    case 7:
      if(type === 'add'){
        innerReviewRef.value.riskOpen('add',projectId.value);
      }else if (type === 'clickEdit'){
        innerReviewRef.value.riskOpen('clickEdit',projectId.value);
      }else {
        if(projectStatus.value === 'view' || projectStatus.value === 'add'){
          innerReviewRef.value.riskOpen('detail',projectId.value);
        }else if(projectStatus.value === 'edit'){
          innerReviewRef.value.riskOpen('edit',projectId.value);
        }
      }
      console.log("7")
      break;
    case 8:
      if(type === 'add'){
        techReviewRef.value.riskOpen('add',projectId.value);
      }else if (type === 'clickEdit'){
        techReviewRef.value.riskOpen('clickEdit',projectId.value);
      }else {
        if(projectStatus.value === 'view' || projectStatus.value === 'add'){
          techReviewRef.value.riskOpen('detail',projectId.value);
        }else if(projectStatus.value === 'edit'){
          techReviewRef.value.riskOpen('edit',projectId.value);
        }
      }
      console.log("8")
      break;
    case 9:
      if(type === 'add'){
        uploadReviewRef.value.riskOpen('add',projectId.value);
      }else if (type === 'clickEdit'){
        uploadReviewRef.value.riskOpen('clickEdit',projectId.value);
      }else {
        if(projectStatus.value === 'view' || projectStatus.value === 'add'){
          uploadReviewRef.value.riskOpen('detail',projectId.value);
        }else if(projectStatus.value === 'edit'){
          uploadReviewRef.value.riskOpen('edit',projectId.value);
        }
      }
      console.log("9")
      break;
    case 10:
      if(type === 'add'){
        rateConRef.value.riskOpen('add',projectId.value);
      }else if (type === 'clickEdit'){
        rateConRef.value.riskOpen('clickEdit',projectId.value);
      }else {
        if(projectStatus.value === 'view' || projectStatus.value === 'add'){
          rateConRef.value.riskOpen('detail',projectId.value);
        }else if(projectStatus.value === 'edit'){
          rateConRef.value.riskOpen('edit',projectId.value);
        }
      }
      console.log("10")
      break;
    case 11:
      if(type === 'add'){
        proCtrlRef.value.riskOpen('add',projectId.value);
      }else if (type === 'clickEdit'){
        proCtrlRef.value.riskOpen('clickEdit',projectId.value);
      }else {
        if(projectStatus.value === 'view' || projectStatus.value === 'add'){
          proCtrlRef.value.riskOpen('detail',projectId.value);
        }else if(projectStatus.value === 'edit'){
          proCtrlRef.value.riskOpen('edit',projectId.value);
        }
      }
      console.log("11")
      break;
    case 12:
      if(type === 'add'){
        proArchRef.value.riskOpen('add',projectId.value);
      }else if (type === 'clickEdit'){
        proArchRef.value.riskOpen('clickEdit',projectId.value);
      }else {
        if(projectStatus.value === 'view' || projectStatus.value === 'add'){
          proArchRef.value.riskOpen('detail',projectId.value);
        }else if(projectStatus.value === 'edit'){
          proArchRef.value.riskOpen('edit',projectId.value);
        }
      }
      console.log("12")
      break;
    case 13:
      if(type === 'add'){
        signConfirmRef.value.riskOpen('add',projectId.value);
      }else if (type === 'clickEdit'){
        signConfirmRef.value.riskOpen('clickEdit',projectId.value);
      }else {
        if(projectStatus.value === 'view' || projectStatus.value === 'add'){
          signConfirmRef.value.riskOpen('detail',projectId.value);
        }else if(projectStatus.value === 'edit'){
          signConfirmRef.value.riskOpen('edit',projectId.value);
        }
      }
      console.log("13")
      break;
    case 14:
      if(type === 'add'){
        confirmEndRef.value.riskOpen('add',projectId.value);
      }else if (type === 'clickEdit'){
        confirmEndRef.value.riskOpen('clickEdit',projectId.value);
      }
      else if (type === 'confirm'){
        confirmEndRef.value.riskOpen('confirm',projectId.value);
      }else {
          if(projectStatus.value === 'view' || projectStatus.value === 'add'){
          confirmEndRef.value.riskOpen('detail',projectId.value);
        }else if(projectStatus.value === 'edit'){
          confirmEndRef.value.riskOpen('edit',projectId.value);
        }
      }
      console.log("14")
      break;
  }
}
</script>
<style scoped lang="scss">
.process-container{
  height: 100%;
  .flow{
    position: relative;
    height: 85px;
    background: transparent;
    .content{
      z-index: 10;
      top: 0;
      left: 0;
      right: 0;
      min-height: 85px;
      max-height: 85px;
      cursor: pointer;
      background-color: hsla(0,0%,100%,.97);
      //background-image: url(../../../assets/images/bg2.png);
      background-repeat: no-repeat;
      background-size: 100% 84px;
      overflow: hidden;
      transition: max-height .3s linear;
      position: absolute;
      .content-bottom{
        position: relative;
        height: 18px;
        text-align: center;
        background-color: transparent;
        pointer-events: none;
      }
      .content-bottom:after {
        content: " ";
        cursor: pointer;
        position: absolute;
        top: 0;
        bottom: 0;
        left: 50%;
        pointer-events: auto;
        transform: translateX(-50%);
        width: 118px;
        background-image: url(../../../assets/images/back1.png);
      }
      .choose .header-item{
        color: #fff;
        background-image: url(../../../assets/images/choosed.png);
      }
    }
    .show{
      cursor: default;
      max-height: 600px;
    }
    .content-middle{
      padding-left: 37px;
      padding-right: 27px;
      display: flex;
      flex-direction: row;
      box-shadow: 0 0 18px 3px rgba(145,146,171,.2);
      .project-title{
        margin-right: 20px;
        height: 85px;
        display: flex;
        align-items: center;
        flex-shrink: 1;
        flex-direction: column;
        justify-content: center;
        font-size: 20px;
        font-weight: 700;
        color: rgb(255, 140, 138);
      }
    }
    .header-item{
      position: relative;
      height: 83px;
      color: #5d6c8e;
      flex: 1;
      margin-left: -2%;
      display: flex;
      align-items: center;
      justify-content: center;
      background-repeat: no-repeat;
      background-size: 100% 100%;
      background-image: url(../../../assets/images/header.png);
      cursor: pointer;
      .item-content{
        width: 80%;
        padding: 0 20px;
        display: flex;
        align-items: center;
        margin-left: 8%;
        margin-bottom: 2px;
        font-size: 20px;
        font-weight: 400;
      }
    }
    .down-item{
      height: 47px;
      margin: 30px auto 10px auto;
      font-size: 19px;
      color: #626c8b;
      border: 1px solid #fff;
      background: rgba(233 223 211 / 20%);
      border-radius: 8px;
      display: flex;
      align-items: center;
      width: 80%;
      padding-left: 20px;
      padding-right: 15px;
      cursor: pointer;
      .item-icon-status0{
        width: 21px;
        height: 21px;
        color: #fff;
        font-size: 16px;
        line-height: 20px;
        text-align: center;
        border-radius: 50%;
        background: #f3ccb0;
        margin-right: 10px;
        min-width: 21px;
        min-height: 21px;
      }
      .item-icon-status1{
        color: #f17235;
        background: #fff;
      }
      .item-icon-status2{
        background: transparent;
      }
      .item-icon-status4{
        background: #0cca8f;
      }
    }
    .itemActive{
      cursor: pointer;
      color: #fff;
      border: 1px solid #c6e6ff;
      background: linear-gradient(90deg,rgb(239, 186, 141),rgb(255, 140, 138));
    }
    .itemPrev{
      cursor: pointer;
      color: #f38323;
      border: 1px solid #f5e4cf;
      background: rgb(249 210 170 / 40%);
    }
    .itemPrev:hover{
      transform: scale(1.1);
      -webkit-transform: scale(1.1);
      -moz-transform: scale(1.1);
      -o-transform: scale(1.1);
      -ms-transform: scale(1.1);
    }
  }
  .middle{
    padding: 10px;
    .card-header{
      height: 50px;
      line-height: 26px;
      font-weight: 700;
      padding: 12px 56px;
      font-size: 18px;
      color: #fff;
      background-image: url(../../../assets/images/cardHeader2.png);
      background-size: 100% 100%;
      background-repeat: no-repeat;
      margin: -20px;
    }
    .card-content{
      padding: 20px 60px;
      margin-top: 20px;
    }
    ::-webkit-scrollbar {
      display: none;
    }
  }
  .bottom{
    height: 60px;
    background: rgb(255, 255, 255);
    padding: 9px 10px;
  }
  .text-eclipse{
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-size: 16px;
  }
}
</style>
src/views/safetyReview/userManage/expertUsers/components/projectDialog.vue
@@ -154,7 +154,13 @@
const toProcess = (type,value,toPath) => {
  dialogVisible.value = false;
  value.type = type;
  router.push({ path: '/process', query: {id: value.id, type: type, toPath: toPath}});
  if(value.estimateType == 33){
    router.push({ path: '/processTest', query: {id: value.id, type: type, toPath: toPath}});
  }else{
    router.push({ path: '/process', query: {id: value.id, type: type, toPath: toPath}});
  }
}
const goMenu = (toPath,val) => {
  console.log("val",val)
src/views/safetyReview/userManage/institutionUsers/index.vue
@@ -46,6 +46,7 @@
        </div>
        <!-- 表格数据 -->
        <el-table v-loading="loading" :data="dataList" :border="true">
          <el-table-column label="序号" type="index" align="center" width="60" />
          <el-table-column label="用户ID" prop="id" align="center"/>
          <el-table-column label="机构名称" prop="agency.name" align="center"/>
          <el-table-column label="信用代码" prop="agency.creditCode" align="center"/>