马宇豪
2025-05-09 cbb23429b8beed72b58cbb57f9b3c56a0fb2b5d2
src/views/analyse/plan/index.vue
@@ -30,18 +30,19 @@
                        <el-table-column prop="assessPlanName" label="评估计划名称"/>
                        <el-table-column prop="riskUnitName" label="风险单元名称" />
                        <el-table-column prop="planUserName" label="计划制定人" />
                        <el-table-column prop="identificationMethod" label="辨识方法" show-overflow-tooltip>
                            <template #default="scope">
                                <span>{{`${planState.identificationMethodList.find(item =>item.id === scope.row.identificationMethod)?.name}`}}</span>
                            </template>
                        <el-table-column prop="assessStartTime" label="评估开始时间">
                          <template #default="scope">
                            <span>{{scope.row.assessStartTime?scope.row.assessStartTime.substring(0,16):'--'}}</span>
                          </template>
                        </el-table-column>
                        <el-table-column prop="identificationUser" label="计划负责人" />
                        <el-table-column prop="evaluateMethod" label="推荐评价方法" show-overflow-tooltip>
                            <template #default="scope">
                                <span>{{`${planState.evaluateMethodList.find(item =>item.id === scope.row.evaluateMethod)?.name}`}}</span>
                            </template>
                        <el-table-column prop="assessEndTime" label="评估结束时间">
                          <template #default="scope">
                            <span>{{scope.row.assessEndTime?scope.row.assessEndTime.substring(0,16):'--'}}</span>
                          </template>
                        </el-table-column>
                        <el-table-column prop="identificationUser" label="辨识专家" />
                        <el-table-column prop="evaluateUser" label="评价专家" />
<!--                        <el-table-column prop="sceneUser" label="现场专家" />-->
                        <el-table-column prop="createTime" label="创建时间" show-overflow-tooltip></el-table-column>
                        <el-table-column prop="createByUserName" label="创建人" show-overflow-tooltip></el-table-column>
                        <el-table-column prop="updateTime" label="最后修改时间" show-overflow-tooltip></el-table-column>
@@ -64,9 +65,14 @@
                        </el-table-column>
                        <el-table-column label="操作" width="250">
                            <template #default="scope">
                                <el-button size="small" text type="primary" @click="accessPlan(scope.row)">派发</el-button>
                                <el-button size="small" text type="primary" v-if="scope.row.planSellStatus === 1" @click="accessPlan(scope.row)">派发</el-button>
                                <el-button size="small" text type="primary" :icon="View" @click="openPlanDialog('查看', scope.row)">查看</el-button>
                                <el-button v-if="scope.row.planSellStatus === 1" size="small" text type="primary" :icon="Edit" @click="openPlanDialog('修改', scope.row)">编辑</el-button>
                                <el-button v-if="scope.row.identityUsers?.find(i=>i.identificationUserId == planState.user)" size="small" text type="primary" :icon="Edit" @click="refuseIdentify(scope.row)">拒绝辨识</el-button>
                                <el-button v-if="scope.row.evaluateUsers?.find(i=>i.evaluateUserId== planState.user)" size="small" text type="primary" :icon="Edit" @click="refuseEvaluate(scope.row)">拒绝评价</el-button>
<!--                                <el-button v-if="scope.row.sceneUserId == planState.user" size="small" text type="primary" :icon="Edit" @click="refuseScene(scope.row)">拒绝现场</el-button>-->
                                <el-button v-if="!scope.row.identityUsers" size="small" text type="primary" :icon="Edit" @click="reSendJob(scope.row,1)">重新指派辨识</el-button>
                                <el-button v-if="!scope.row.evaluateUsers" size="small" text type="primary" :icon="Edit" @click="reSendJob(scope.row,2)">重新指派评价</el-button>
                                <el-button v-if="scope.row.planSellStatus === 1" size="small" text type="danger" :icon="Delete" @click="onDelPlan(scope.row)">删除</el-button>
                            </template>
                        </el-table-column>
@@ -78,25 +84,62 @@
            </div>
        </div>
        <plan-dialog ref="planDialogRef" @refresh="getPlanData"></plan-dialog>
        <el-dialog class="chooseExpert" :title="planState.reSendTitle" v-model="planState.reSendDialogVisible" width="50%">
          <el-form ref="ruleFormRef" :rules="planState.rules" :model="planState.reSendForm" label-width="120px">
            <el-form-item v-if="planState.reSendTitle == '指派辨识专家'" label="选择辨识专家" prop="identificationUserId" class="valueSelect">
              <el-select v-model="planState.reSendForm.userIds" multiple style="width:100%" :teleported="false" placeholder="辨识专家" clearable>
                <el-option v-for="item in planState.bsExperts" :key="item.id" :label="item.realName" :value="item.id">
                  <div class="valueTable">
                    <div><div>姓名:</div><span>{{item.realName}}</span></div>
                    <div><div>专业:</div><span>{{item.userIdentities?.map(i=>i.userIdentity).join(',')}}</span></div>
                  </div>
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item v-if="planState.reSendTitle == '指派评价专家'" label="选择评价专家" prop="evaluateUserId" class="valueSelect">
              <el-select v-model="planState.reSendForm.userIds" multiple style="width:100%" :teleported="false" placeholder="评价专家" clearable>
                <el-option v-for="item in planState.pjExperts" :key="item.id" :label="item.realName" :value="item.id">
                  <div class="valueTable">
                    <div><div>姓名:</div><span>{{item.realName}}</span></div>
                    <div><div>专业:</div><span>{{item.userIdentities?.map(i=>i.userIdentity).join(',')}}</span></div>
                  </div>
                </el-option>
              </el-select>
            </el-form-item>
          </el-form>
          <template #footer>
                <span class="dialog-footer" style="padding-top:10px;text-align: center !important;">
                  <el-button @click="planState.reSendDialogVisible = !planState.reSendDialogVisible" size="default">取 消</el-button>
                  <el-button type="primary" @click="onSubmitReSend(ruleFormRef)" size="default">确认指派</el-button>
                </span>
          </template>
        </el-dialog>
    </div>
</template>
<script setup lang="ts">
import {defineAsyncComponent, onMounted, reactive, ref} from "vue";
import {planApi} from "/@/api/analyse/plan";
import {ElMessage, ElMessageBox} from "element-plus";
import {ElMessage, ElMessageBox, FormInstance} from "element-plus";
import { Edit, View, Plus, Delete } from '@element-plus/icons-vue';
import {riskUnitApi} from "/@/api/analyse/riskUnit";
import {personApi} from "/@/api/basic/person";
import {useUserInfo} from "/@/stores/userInfo";
import { storeToRefs } from 'pinia';
import {userApi} from "/@/api/systemManage/user";
import {assessApplyApi} from "/@/api/analyse/assessApply";
const PlanDialog = defineAsyncComponent(() => import('./components/planDialog.vue'));
const planDialogRef = ref();
const userInfo = useUserInfo();
const { userInfos } = storeToRefs(userInfo);
const ruleFormRef = ref<FormInstance>()
const planState = reactive<PlanStateType>({
    planData: [],
    user: null,
    searchQuery: {
        pageIndex: 1,
        pageSize: 10,
@@ -107,19 +150,31 @@
    riskUnitList: [
    ],
    personList: [],
    bsExperts: [],
    pjExperts: [],
    identificationMethodList: [
    {id:1, name: 'PHA'},
    {id:2, name: 'JHA'},
    {id:3, name: 'SCL'},
    {id:4, name: 'HAZOP'},
    {id:5, name: '类比法'},
],
    evaluateMethodList: [
    {id:1, name: 'LEC'},
    {id:2, name: 'LS'},
    {id:3, name: 'MES'},
    {id:4, name: 'RS'},
]
        {id:1, name: 'PHA'},
        {id:2, name: 'JHA'},
        {id:3, name: 'SCL'},
        {id:4, name: 'HAZOP'},
        {id:5, name: '类比法'},
    ],
        evaluateMethodList: [
        {id:1, name: 'LEC'},
        {id:2, name: 'LS'},
        {id:3, name: 'MES'},
        {id:4, name: 'RS'},
    ],
    reSendTitle:'',
    reSendDialogVisible: false,
    reSendForm: {
      riskAssessPlanId: null,
      userIds: [],
      userType: null
    },
    rules: {
      userIds: [{ required: true, message: '请选择专家', trigger: 'blur' }]
    }
    // deviceUnitList: [
    //     {id:1, name: '台'},
    //     {id:2, name: '个'},
@@ -154,10 +209,13 @@
const getPersonList = async () => {
    let res = await userApi().getUserList({
        roleId: 1,
        usePage: false,
        pageIndex: 1,
        pageSize: 10
        pageSize: 99999,
        searchParams:{
          roleId: null,
          name: '',
          realName: ''
        }
    });
    if(res.data.code === 100){
        planState.personList = JSON.parse(JSON.stringify(res.data.data));
@@ -169,9 +227,148 @@
    }
};
const openPlanDialog = (title: string, value: PlanType) => {
    planDialogRef.value.showPlanDialog(title, value, planState.riskUnitList, planState.personList);
const getAllExperts = async () => {
  let res = await userApi().getExpertsList({
    pageIndex: 1,
    pageSize: 99999,
    searchParams:{
      userIndentityId: null
    }
  });
  if (res.data.code === 100) {
    const expertsList = res.data.data;
    for(let i of expertsList){
      if(i.roles?.find(obj=>obj.roleId == 2)){
        planState.bsExperts.push(i)
      }
      if(i.roles?.find(obj=>obj.roleId == 3)){
        planState.pjExperts.push(i)
      }
    }
  } else {
    ElMessage({
      type: 'warning',
      message: res.data.msg
    });
  }
};
const openPlanDialog = (title: string, value: PlanType) => {
    planDialogRef.value.showPlanDialog(title, value, planState.riskUnitList, planState.personList,planState.bsExperts,planState.pjExperts);
};
const refuseIdentify = async(val: PlanType)=>{
  ElMessageBox.confirm(`此操作将拒绝作为该计划:“${val.assessPlanName}”的辨识专家,是否继续?`, '提示', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning'
  })
      .then(async () => {
        let res = await planApi().refuseIdentify({ id: val.id });
        if (res.data.code === 100) {
          ElMessage({
            type: 'success',
            duration: 2000,
            message: '拒绝成功'
          });
          await getPlanData();
        } else {
          ElMessage({
            type: 'warning',
            message: res.data.msg
          });
        }
      })
      .catch((error) => {
      });
}
const reSendJob= async(val: PlanType,type:number | null)=>{
  planState.reSendForm = {
    riskAssessPlanId: val.id,
    userIds: [],
    userType: type
  }
  if(type==1){
    planState.reSendTitle = '指派辨识专家'
  }else{
    planState.reSendTitle = '指派评价专家'
  }
  planState.reSendDialogVisible = true
}
const onSubmitReSend = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate(async(valid, fields) => {
    if (valid) {
      let res = await planApi().reSendJob(planState.reSendForm);
      if(res.data.code === 100){
        ElMessage({
          type: 'success',
          message: '重新指派成功'
        });
      }else{
        ElMessage({
          type: 'warning',
          message: res.data.msg
        });
      }
      planState.reSendForm = {
        riskAssessPlanId: null,
        userIds: [],
        userType: null
      },
      planState.reSendDialogVisible = false
      getPlanData()
    } else {
      console.log('error submit!', fields)
    }
  })
}
const refuseEvaluate = async(val: PlanType)=>{
  ElMessageBox.confirm(`此操作将拒绝作为该计划:“${val.assessPlanName}”的评价专家,是否继续?`, '提示', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning'
  })
      .then(async () => {
        let res = await planApi().refuseEvaluate({ id: val.id });
        if (res.data.code === 100) {
          ElMessage({
            type: 'success',
            duration: 2000,
            message: '拒绝成功'
          });
          await getPlanData();
        } else {
          ElMessage({
            type: 'warning',
            message: res.data.msg
          });
        }
      })
      .catch((error) => {
      });
}
// const refuseScene = async(val: PlanType)=>{
//   let res = await planApi().refuseScene({ id: val.id });
//   if (res.data.code === 100) {
//     ElMessage({
//       type: 'success',
//       duration: 2000,
//       message: '拒绝成功'
//     });
//     await getPlanData();
//   } else {
//     ElMessage({
//       type: 'warning',
//       message: res.data.msg
//     });
//   }
// }
const onDelPlan = (val: PlanType) => {
    ElMessageBox.confirm(`此操作将永久删除该计划:“${val.assessPlanName}”,是否继续?`, '提示', {
@@ -247,13 +444,22 @@
onMounted(() => {
    getPlanData();
    getAllRiskUnitList();
    getAllExperts();
    getPersonList();
    planState.user = Number(userInfos.value.uid)
})
</script>
<style scoped lang="scss">
$homeNavLengh: 8;
::v-deep(.el-dialog){
  .el-dialog__body{
    overflow-y: visible !important;
    overflow-x: visible !important;
  }
}
.home-container {
    height: calc(100vh - 144px);
    box-sizing: border-box;
@@ -320,65 +526,42 @@
        }
    }
}
.stepItem {
    width: 100%;
    display: flex;
    align-items: flex-start;
    margin-bottom: 30px;
    margin-left: 30px;
    padding-bottom: 30px;
    border-left: 2px solid #ccc;
    &:first-of-type {
        margin-top: 30px;
    }
    &:last-of-type {
        margin-bottom: 0;
        border-left: none;
    }
    .stepNum {
        width: 30px;
        height: 30px;
        border-radius: 15px;
        box-sizing: border-box;
        color: #333;
        border: 1px solid #999;
        line-height: 28px;
        text-align: center;
        margin-right: 10px;
        margin-left: -16px;
        margin-top: -30px;
    }
    .stepCard {
        width: 100%;
        margin-top: -30px;
        .box-card {
            width: 100%;
            &:deep(.el-card__header) {
                padding: 10px 15px;
            }
            .card-header {
                width: 100%;
                display: flex;
                justify-content: space-between;
                align-items: center;
                & > div:first-of-type {
                    margin-right: 80px;
                    font-size: 18px;
                    font-weight: bold;
                }
            }
.valueSelect{
  ::v-deep(.el-popper){
    .el-select-dropdown__item{
      width: 100%;
      height: auto;
      white-space: normal;
      word-break: break-all;
      word-wrap: break-word;
      overflow: auto;
      padding: 10px 25px;
      border-bottom: 1px solid #ccc;
      .valueTable{
        &>div{
          line-height: 1.5;
          margin-bottom: 6px;
          display: flex;
          align-items: center;
          div{
            color: #999;
          }
          span{
            font-weight: bolder;
          }
          &:last-of-type{
            margin-bottom: 0;
          }
        }
      }
    }
    &:hover .card-header {
        color: #0098f5;
    }
    &:hover .stepNum {
        border: 2px solid #0098f5;
        color: #0098f5;
    }
  }
}
:deep(.el-date-editor) {
    width: 100%;
}