马宇豪
2024-12-03 1da948c1c8808077f10e3aa32fafd30939ee5c12
新增
已修改12个文件
已添加1个文件
700 ■■■■ 文件已修改
public/evaluateFile.docx 补丁 | 查看 | 原始文档 | blame | 历史
src/api/backManage/evaluate.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/form.js 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/expertManage/applyRecords/components/expertForm.vue 97 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/expertManage/applyRecords/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/expertManage/evaluateRecord/components/evaluateDetail.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/expertManage/experts/index.vue 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/expertManage/fillForm/index.vue 87 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/expertManage/postEvaluation/components/evaluate.vue 319 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/expertManage/postEvaluation/components/expertList.vue 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/expertManage/postEvaluation/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/projectManage/components/exportWord.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safetyReview/projectManage/components/projectApproval.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/evaluateFile.docx
Binary files differ
src/api/backManage/evaluate.js
@@ -119,7 +119,7 @@
export function getExpertEvaDetail(params) {
    return request({
        url: '/system/management/selectProjectExpertDetailList',
        url: '/system/management/selectProjectExpertDetail',
        method: 'get',
        params: params
    })
src/api/form.js
@@ -9,7 +9,16 @@
  })
}
// 获取专家列表
// 获取专家列表(限制处室)
export function getExpertsPerList(params) {
  return request({
    url: '/system/expert_info/perList',
    method: 'get',
    params: params
  })
}
// 删除专家
export function delExpert(id) {
  return request({
    url: '/system/expert_info/del/'+id,
@@ -102,4 +111,13 @@
    method: 'post',
    data: data
  })
}
// 统一修改有效期
export function changeEmploymentDate(data) {
  return request({
    url: '/system/expert_info/batchChangeEmploymentDate',
    method: 'post',
    data: data
  })
}
src/views/safetyReview/expertManage/applyRecords/components/expertForm.vue
@@ -6,8 +6,6 @@
            width="80%"
            :before-close="handleClose"
        >
          <div class="main-title">专家信息录入</div>
          <!--    <el-divider>专家信息录入</el-divider>-->
          <div class="main_form">
            <el-form :model="state.form" :rules="state.rules" ref="ruleFormRef" label-width="200px">
              <el-row>
@@ -89,7 +87,19 @@
              </el-row>
              <el-row>
                <el-col :span="20">
                  <el-form-item label="证件照" prop="electronicPhoto">
                  <el-form-item label="职称或资质证明材料" prop="evidence">
                    <el-upload accept="image/*" multiple :action="state.uploadUrl" :headers="state.header" method="post" :disabled="state.disable" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,'著作')" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='8' v-model:file-list="state.evidenceList" list-type="picture-card" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,'证明')" :before-remove="beforeRemove">
                      <el-icon><Plus /></el-icon>
                      <template #tip>
                        <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传5张</div>
                      </template>
                    </el-upload>
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row>
                <el-col :span="20">
                  <el-form-item label="2寸免冠证件照">
                    <el-upload accept="image/*" :action="state.uploadUrl" :headers="state.header" :disabled="state.disable" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,'证件照')" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='1' v-model:file-list="state.fileList" list-type="picture-card" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,'证件照')" :before-remove="beforeRemove">
                      <el-icon><Plus /></el-icon>
                      <template #tip>
@@ -195,7 +205,7 @@
              </el-row>
              <el-row>
                <el-col :span="20">
                  <el-form-item label="支撑方向_安全生产" prop="supportDirectionSafety">
                  <el-form-item label="支撑方向_安全生产" prop="supportDirectionEmergency">
                    <!--              <el-radio-group v-model="form.supportDirectionSafety">-->
                    <!--                <el-radio v-for="item in directionList" :label="item.value" :key="item.value">{{ item.label }}</el-radio>-->
                    <!--              </el-radio-group>-->
@@ -207,7 +217,7 @@
              </el-row>
              <el-row>
                <el-col :span="20">
                  <el-form-item label="支撑方向_防灾减灾救灾" prop="supportDirectionPrevention">
                  <el-form-item label="支撑方向_防灾减灾救灾" prop="supportDirectionEmergency">
                    <!--              <el-radio-group v-model="form.supportDirectionPrevention">-->
                    <!--                <el-radio v-for="item in directionList" :label="item.value" :key="item.value">{{ item.label }}</el-radio>-->
                    <!--              </el-radio-group>-->
@@ -231,11 +241,11 @@
              </el-row>
              <el-row>
                <el-col :span="20">
                  <el-form-item label="工作简历">
                    <el-upload accept="image/*" multiple :action="state.uploadUrl" :headers="state.header" method="post" :disabled="state.disable" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,'简历')" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='8' v-model:file-list="state.resumeList" list-type="picture-card" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,'简历')" :before-remove="beforeRemove">
                      <el-icon><Plus /></el-icon>
                  <el-form-item label="工作简历" prop="resumeKey">
                    <el-upload accept=".pdf" multiple :action="state.uploadUrl" :headers="state.header" method="post" :disabled="state.disable" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,'简历')" :on-exceed="showTip" :limit='8' v-model:file-list="state.resumeList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,'简历')" :before-remove="beforeRemove">
                      <el-button type="primary">点击上传</el-button>
                      <template #tip>
                        <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传5张</div>
                        <div class="el-upload__tip">上传pdf格式文件尺寸小于5M,最多可上传5份</div>
                      </template>
                    </el-upload>
                  </el-form-item>
@@ -279,7 +289,7 @@
              </el-row>
              <el-row>
                <el-col :span="20">
                  <el-form-item label="专家本人意见">
                  <el-form-item label="专家本人意见" prop="recommendUnitOpinionKey">
                    <el-upload accept="image/*" multiple :action="state.uploadUrl" :headers="state.header" method="post" :disabled="state.disable" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,'本人')" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='8' v-model:file-list="state.proAdviceList" list-type="picture-card" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,'本人')" :before-remove="beforeRemove">
                      <el-icon><Plus /></el-icon>
                      <template #tip>
@@ -291,7 +301,7 @@
              </el-row>
              <el-row>
                <el-col :span="20">
                  <el-form-item label="推荐单位意见">
                  <el-form-item label="推荐单位意见" prop="recommendUnitOpinionKey">
                    <el-upload accept="image/*" multiple :action="state.uploadUrl" :headers="state.header" method="post" :disabled="state.disable" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,'单位')" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='8' v-model:file-list="state.adviceList" list-type="picture-card" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,'单位')" :before-remove="beforeRemove">
                      <el-icon><Plus /></el-icon>
                      <template #tip>
@@ -400,13 +410,38 @@
const ruleFormRef = ref()
const assessFormRef = ref()
const { proxy } = getCurrentInstance()
var validatePass = (rule, value, callback) => {
  if (state.fileList.length == 0) {
    callback(new Error('请上传证件照'));
let validatePass = (rule, value, callback) => {
  if (state.resumeList.length == 0) {
    callback(new Error('请上传工作简历'));
  } else {
    callback();
  }
}
let validateEvidence = (rule, value, callback) => {
  if (state.evidenceList.length == 0) {
    callback(new Error('请上传证明材料'));
  } else {
    callback();
  }
}
let validateOneOfTwo = (rule, value, callback) => {
  if (state.proAdviceList.length == 0 && state.adviceList.length == 0) {
    callback(new Error('专家本人意见和推荐单位意见须至少上传一项'));
  } else {
    callback();
  }
}
let validateOneOfThree = (rule, value, callback) => {
  if (state.form.supportDirectionSafety.length==0&&state.form.supportDirectionSafety.length==0&&state.form.supportDirectionSafety.length==0) {
    callback(new Error('请至少从三种支撑方向中勾选一种'));
  } else {
    callback();
  }
}
let validatePhone = (rule, value, callback)=>{
  if(value === ''){
    callback(new Error('请输入手机号'))
@@ -458,6 +493,7 @@
    supportDirectionSafety: [],
    supportDirectionPrevention: [],
    supportDirectionEmergency: [],
    evidence: '',
    resumeKey: '',
    paperSituationKey: '',
    rewardKey: '',
@@ -502,6 +538,7 @@
    Authorization: 'Bearer ' + getToken()
  },
  fileList: [],
  evidenceList: [],
  resumeList: [],
  inventionList: [],
  rewardList: [],
@@ -517,8 +554,11 @@
    birthday: [{ required: true, message: '请选择出生日期', trigger: 'blur' }],
    phone:[{ required: true, validator: validatePhone, trigger: 'blur' }],
    title: [{ required: true, message: '请填写职称', trigger: 'blur' }],
    electronicPhoto: [{ required: true,validator: validatePass, trigger: 'blur' }],
    evidence: [{ required: true,validator: validateEvidence, trigger: 'blur' }],
    resumeKey: [{ required: true,validator: validatePass, trigger: 'blur' }],
    recommendUnitOpinionKey: [{ required: true,validator: validateOneOfTwo, trigger: 'blur' }],
    idCard: [{ required: true, validator: verifyId, trigger: 'blur' }],
    supportDirectionEmergency: [{ required: true,validator: validateOneOfThree, trigger: 'blur' }],
    dutyStatus: [{ required: true, message: '请选择在岗情况', trigger: 'blur' }],
    companyName: [{ required: true, message: '请填写单位全称', trigger: 'blur' }],
    degree: [{ required: true, message: '请填写最高学历', trigger: 'blur' }]
@@ -562,12 +602,22 @@
            }else{
              state.form.supportDirectionEmergency = []
            }
            state.fileList.push({
              name: state.form.electronicPhoto,
              url: state.form.electronicPhoto,
            })
            if(state.form.electronicPhoto!== ''){
              state.fileList.push({
                name: state.form.electronicPhoto,
                url: state.form.electronicPhoto,
              })
            }
            if(state.form.resumeKey !== ''){
              state.resumeList = state.form.resumeKey.split(',').map(i=>{
                return {
                  name: i,
                  url: i,
                }
              })
            }
            if(state.form.evidence !== ''){
              state.evidenceList = state.form.evidence.split(',').map(i=>{
                return {
                  name: i,
                  url: i,
@@ -797,14 +847,11 @@
  if (!formEl) return
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      if(state.form.supportDirectionSafety.length==0&&state.form.supportDirectionSafety.length==0&&state.form.supportDirectionSafety.length==0){
        ElMessage.warning('请至少选择一种支撑方向')
        return
      }
      let data = JSON.parse(JSON.stringify(state.form))
      data.supportDirectionSafety = Array.isArray(data.supportDirectionSafety)?data.supportDirectionSafety.join(','):''
      data.supportDirectionPrevention = Array.isArray(data.supportDirectionPrevention)?data.supportDirectionPrevention.join(','):''
      data.supportDirectionEmergency = Array.isArray(data.supportDirectionEmergency)?data.supportDirectionEmergency.join(','):''
      data.evidence = state.evidenceList.map(i=>i.name).join(',')
      data.resumeKey = state.resumeList.map(i=>i.name).join(',')
      data.paperSituationKey = state.inventionList.map(i=>i.name).join(',')
      data.rewardKey = state.rewardList.map(i=>i.name).join(',')
@@ -817,6 +864,7 @@
        if(res.code == 200){
          ElMessage.success(res.msg)
          state.fileList = []
          state.evidenceList = []
          state.resumeList = []
          state.inventionList = []
          state.rewardList = []
@@ -834,6 +882,7 @@
        if(res.code == 200){
          ElMessage.success(res.msg)
          state.fileList = []
          state.evidenceList = []
          state.resumeList = []
          state.inventionList = []
          state.rewardList = []
@@ -902,6 +951,7 @@
        supportDirectionSafety: [],
        supportDirectionPrevention: [],
        supportDirectionEmergency: [],
        evidence: '',
        resumeKey: '',
        paperSituationKey: '',
        rewardKey: '',
@@ -912,6 +962,7 @@
        source: 2
      }
      state.fileList = []
      state.evidenceList = []
      state.resumeList = []
      state.inventionList = []
      state.rewardList = []
src/views/safetyReview/expertManage/applyRecords/index.vue
@@ -100,7 +100,7 @@
import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
import {ElMessage, ElMessageBox} from "element-plus";
import ExpertForm from "./components/expertForm";
import {delExpert, getExpertsList, getExpertTypes} from "../../../../api/form";
import {delExpert, getExpertsList, getExpertsPerList, getExpertTypes} from "../../../../api/form";
import { Plus } from '@element-plus/icons-vue'
const loading = ref(false);
@@ -184,7 +184,7 @@
const getList = async () => {
  loading.value = true;
  const res = await getExpertsList(data.queryParams)
  const res = await getExpertsPerList(data.queryParams)
  if(res.code == 200){
    data.expertList = res.rows
    data.total = res.total
src/views/safetyReview/expertManage/evaluateRecord/components/evaluateDetail.vue
@@ -75,7 +75,7 @@
        }
        const res = await getExpertEvaDetail(param);
        if(res.code === 200){
            state.form.tableData = res.data
            state.form.tableData = res.data.expertDetails
        }else{
            ElMessage.warning(res.msg)
        }
src/views/safetyReview/expertManage/experts/index.vue
@@ -42,10 +42,12 @@
        <el-form-item>
          <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
          <el-button icon="Edit" @click="openSetDate">一键设置有效期</el-button>
        </el-form-item>
      </el-form>
      <el-table v-loading="loading" :data="expertList" :border="true">
        <el-table-column type="index" width="55" align="center" />
      <el-table v-loading="loading" ref="multipleTableRef" :data="expertList" :border="true" @selection-change="handleSelectionChange" :row-key="(row) => { return row.id }">
        <el-table-column type="selection" width="55" :reserve-selection="true"/>
        <el-table-column type="index" width="55" align="center" label="序号"/>
        <el-table-column label="姓名" align="center" prop="name" />
        <el-table-column label="身份证号" align="center" prop="idCard" />
        <el-table-column label="出生日期" align="center" prop="birthday">
@@ -94,6 +96,7 @@
        </el-table-column>
        <el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
          <template #default="scope">
            <el-button type="primary" link @click="openDialog('edit',scope.row)">编辑</el-button>
            <el-button type="primary" link @click="openDialog('view',scope.row)">查看</el-button>
          </template>
        </el-table-column>
@@ -105,6 +108,31 @@
          v-model:limit="queryParams.pageSize"
          @pagination="getList"
      />
      <el-dialog
          v-model="assessDialog"
          title="修改有效期"
          width="50%"
          :before-close="closeAssess"
      >
        <el-form :model="assessForm" :rules="assessRules" ref="assessFormRef" label-width="200px">
          <el-form-item label="专家聘用期限" prop="employTime">
            <el-date-picker
                v-model="assessForm.employTime"
                type="daterange"
                range-separator="至"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                value-format="YYYY-MM-DD"
            />
          </el-form-item>
        </el-form>
        <template #footer>
                <span class="dialog-footer">
                  <el-button @click="closeAssess" size="default">取 消</el-button>
                  <el-button type="primary" @click="assessSubmit(assessFormRef)" size="default" v-preReClick>确认</el-button>
                </span>
        </template>
      </el-dialog>
      <expert-form ref="expertFormRef" @getList="getList"></expert-form>
    </div>
</template>
@@ -113,10 +141,11 @@
import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
import {ElMessage, ElMessageBox} from "element-plus";
import ExpertForm from "../applyRecords/components/expertForm";
import {delExpert, getExpertsList, getExpertTypes} from "../../../../api/form";
import {changeApprove, changeEmploymentDate, delExpert, getExpertsList, getExpertTypes} from "../../../../api/form";
import {useRouter} from "vue-router";
const router = useRouter();
const loading = ref(false);
const loading = ref(false)
const data = reactive({
  showSearch: true,
  total: 0,
@@ -159,10 +188,20 @@
      label: '其他'
    }
  ],
  multipleSelection: [],
  assessDialog: false,
  assessForm: {
    employTime: []
  },
  assessRules: {
    employTime:[{ required: true, message: '请选择有效期', trigger: 'blur' }],
  }
});
const { showSearch,total, expertTypes,expertList,queryParams,classiFy,searchTime} = toRefs(data);
const { showSearch,total, expertTypes,expertList,queryParams,searchTime,assessForm,assessDialog,assessRules,multipleSelection} = toRefs(data);
const expertFormRef = ref()
const assessFormRef = ref()
const multipleTableRef = ref()
onMounted(()=>{
  getList()
  getTypes()
@@ -171,6 +210,10 @@
onUnmounted(()=>{
})
const handleSelectionChange = (val) => {
  data.multipleSelection = val
}
const getTypes = async()=> {
  const res = await getExpertTypes()
@@ -269,6 +312,52 @@
  expertFormRef.value.openDialog(type, value);
}
const openSetDate = ()=>{
  if(data.multipleSelection.length>0){
    data.assessDialog = true
  }else{
    ElMessage.warning('请选择要设置的人员')
  }
}
const assessSubmit = async (formEl)=> {
  if (!formEl) return
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      let params = {
        id: data.multipleSelection.map(i=>i.id),
        employmentDateStart: data.assessForm.employTime[0],
        employmentDateEnd: data.assessForm.employTime[1]
      }
      const res = await changeEmploymentDate(params)
      if(res.code == 200){
        ElMessage({
          type: 'success',
          message: '修改成功'
        })
        data.multipleSelection = []
        multipleTableRef.value.clearSelection()
        await getList()
        data.assessDialog = false
      }else{
        ElMessage({
          type: 'warning',
          message: res.msg
        });
      }
    }else {
      ElMessage.warning('请完善必填信息')
    }
  })
}
const closeAssess = ()=>{
  assessFormRef.value.clearValidate()
  data.assessForm = {
    employTime: []
  }
  data.assessDialog = false;
}
const resetQuery=()=> {
  data.queryParams = {
    name: '',
src/views/safetyReview/expertManage/fillForm/index.vue
@@ -82,7 +82,19 @@
              </el-row>
              <el-row>
                <el-col :span="20">
                  <el-form-item label="证件照" prop="electronicPhoto">
                  <el-form-item label="职称或资质证明材料" prop="evidence">
                    <el-upload accept="image/*" multiple :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,'著作')" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='8' v-model:file-list="state.evidenceList" list-type="picture-card" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,'证明')" :before-remove="beforeRemove">
                      <el-icon><Plus /></el-icon>
                      <template #tip>
                        <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传5张</div>
                      </template>
                    </el-upload>
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row>
                <el-col :span="20">
                  <el-form-item label="2寸免冠证件照">
                    <el-upload accept="image/*" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,'证件照')" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='1' v-model:file-list="state.fileList" list-type="picture-card" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,'证件照')" :before-remove="beforeRemove">
                      <el-icon><Plus /></el-icon>
                      <template #tip>
@@ -188,7 +200,7 @@
              </el-row>
              <el-row>
                <el-col :span="20">
                  <el-form-item label="支撑方向_安全生产" prop="supportDirectionSafety">
                  <el-form-item label="支撑方向_安全生产" prop="supportDirectionEmergency">
                    <!--              <el-radio-group v-model="form.supportDirectionSafety">-->
                    <!--                <el-radio v-for="item in directionList" :label="item.value" :key="item.value">{{ item.label }}</el-radio>-->
                    <!--              </el-radio-group>-->
@@ -200,7 +212,7 @@
              </el-row>
              <el-row>
                <el-col :span="20">
                  <el-form-item label="支撑方向_防灾减灾救灾" prop="supportDirectionPrevention">
                  <el-form-item label="支撑方向_防灾减灾救灾" prop="supportDirectionEmergency">
                    <!--              <el-radio-group v-model="form.supportDirectionPrevention">-->
                    <!--                <el-radio v-for="item in directionList" :label="item.value" :key="item.value">{{ item.label }}</el-radio>-->
                    <!--              </el-radio-group>-->
@@ -224,11 +236,11 @@
              </el-row>
              <el-row>
                <el-col :span="20">
                  <el-form-item label="工作简历">
                    <el-upload accept="image/*" multiple :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,'简历')" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='8' v-model:file-list="state.resumeList" list-type="picture-card" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,'简历')" :before-remove="beforeRemove">
                      <el-icon><Plus /></el-icon>
                  <el-form-item label="工作简历" prop="resumeKey">
                    <el-upload accept=".pdf" multiple :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,'简历')" :on-exceed="showTip" :limit='8' v-model:file-list="state.resumeList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,'简历')" :before-remove="beforeRemove">
                      <el-button type="primary">点击上传</el-button>
                      <template #tip>
                        <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传5张</div>
                        <div class="el-upload__tip">上传pdf格式文件尺寸小于5M,最多可上传5份</div>
                      </template>
                    </el-upload>
                  </el-form-item>
@@ -272,8 +284,8 @@
              </el-row>
              <el-row>
                <el-col :span="20">
                  <el-form-item label="专家本人意见">
                    <el-upload accept="image/*" multiple :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,'本人')" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='8' v-model:file-list="state.proAdviceList" list-type="picture-card" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,'本人')" :before-remove="beforeRemove">
                  <el-form-item label="专家本人意见" prop="recommendUnitOpinionKey">
                    <el-upload accept="image/*" multiple :action="state.uploadUrl" :headers="state.header" method="post" :disabled="state.disable" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,'本人')" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='8' v-model:file-list="state.proAdviceList" list-type="picture-card" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,'本人')" :before-remove="beforeRemove">
                      <el-icon><Plus /></el-icon>
                      <template #tip>
                        <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传5张</div>
@@ -284,8 +296,8 @@
              </el-row>
              <el-row>
                <el-col :span="20">
                  <el-form-item label="推荐单位意见">
                    <el-upload accept="image/*" multiple :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,'单位')" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='8' v-model:file-list="state.adviceList" list-type="picture-card" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,'单位')" :before-remove="beforeRemove">
                  <el-form-item label="推荐单位意见" prop="recommendUnitOpinionKey">
                    <el-upload accept="image/*" multiple :action="state.uploadUrl" :headers="state.header" method="post" :disabled="state.disable" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile,'单位')" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='8' v-model:file-list="state.adviceList" list-type="picture-card" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,'单位')" :before-remove="beforeRemove">
                      <el-icon><Plus /></el-icon>
                      <template #tip>
                        <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传5张</div>
@@ -324,13 +336,38 @@
const { proxy } = getCurrentInstance();
const imgDialog = ref(false)
const ruleFormRef = ref()
var validatePass = (rule, value, callback) => {
  if (state.fileList.length == 0) {
    callback(new Error('请上传证件照'));
let validatePass = (rule, value, callback) => {
  if (state.resumeList.length == 0) {
    callback(new Error('请上传工作简历'));
  } else {
    callback();
  }
}
let validateEvidence = (rule, value, callback) => {
  if (state.evidenceList.length == 0) {
    callback(new Error('请上传证明材料'));
  } else {
    callback();
  }
}
let validateOneOfTwo = (rule, value, callback) => {
  if (state.proAdviceList.length == 0 && state.adviceList.length == 0) {
    callback(new Error('专家本人意见和推荐单位意见须至少上传一项'));
  } else {
    callback();
  }
}
let validateOneOfThree = (rule, value, callback) => {
  if (state.form.supportDirectionSafety.length==0&&state.form.supportDirectionSafety.length==0&&state.form.supportDirectionSafety.length==0) {
    callback(new Error('请至少从三种支撑方向中勾选一种'));
  } else {
    callback();
  }
}
let validatePhone = (rule, value, callback)=>{
  if(value === ''){
    callback(new Error('请输入手机号'))
@@ -380,6 +417,7 @@
    supportDirectionSafety: [],
    supportDirectionPrevention: [],
    supportDirectionEmergency: [],
    evidence: '',
    resumeKey: '',
    paperSituationKey: '',
    rewardKey: '',
@@ -418,6 +456,7 @@
    Authorization: 'Bearer ' + getToken()
  },
  fileList: [],
  evidenceList: [],
  resumeList: [],
  inventionList: [],
  rewardList: [],
@@ -433,8 +472,11 @@
    birthday: [{ required: true, message: '请选择出生日期', trigger: 'blur' }],
    phone:[{ required: true, validator: validatePhone, trigger: 'blur' }],
    title: [{ required: true, message: '请填写职称', trigger: 'blur' }],
    electronicPhoto: [{ required: true,validator: validatePass, trigger: 'blur' }],
    evidence: [{ required: true,validator: validateEvidence, trigger: 'blur' }],
    resumeKey: [{ required: true,validator: validatePass, trigger: 'blur' }],
    recommendUnitOpinionKey: [{ required: true,validator: validateOneOfTwo, trigger: 'blur' }],
    idCard: [{ required: true, validator: verifyId, trigger: 'blur' }],
    supportDirectionEmergency: [{ required: true,validator: validateOneOfThree, trigger: 'blur' }],
    dutyStatus: [{ required: true, message: '请选择在岗情况', trigger: 'blur' }],
    companyName: [{ required: true, message: '请填写单位全称', trigger: 'blur' }],
    degree: [{ required: true, message: '请填写最高学历', trigger: 'blur' }]
@@ -534,7 +576,7 @@
            } else {
              ElMessage({
                type: 'warning',
                message: res.message
                message: res.msg
              })
            }
          })
@@ -545,14 +587,11 @@
  if (!formEl) return
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      if(state.form.supportDirectionSafety.length==0&&state.form.supportDirectionSafety.length==0&&state.form.supportDirectionSafety.length==0){
        ElMessage.warning('请至少选择一种支撑方向')
        return
      }
      let data = JSON.parse(JSON.stringify(state.form))
      data.supportDirectionSafety = data.supportDirectionSafety.join(',')
      data.supportDirectionPrevention = data.supportDirectionPrevention.join(',')
      data.supportDirectionEmergency = data.supportDirectionEmergency.join(',')
      data.supportDirectionSafety = Array.isArray(data.supportDirectionSafety)?data.supportDirectionSafety.join(','):''
      data.supportDirectionPrevention = Array.isArray(data.supportDirectionPrevention)?data.supportDirectionPrevention.join(','):''
      data.supportDirectionEmergency = Array.isArray(data.supportDirectionEmergency)?data.supportDirectionEmergency.join(','):''
      data.evidence = state.evidenceList.map(i=>i.name).join(',')
      data.resumeKey = state.resumeList.map(i=>i.name).join(',')
      data.paperSituationKey = state.inventionList.map(i=>i.name).join(',')
      data.rewardKey = state.rewardList.map(i=>i.name).join(',')
@@ -587,6 +626,7 @@
          supportDirectionSafety: [],
          supportDirectionPrevention: [],
          supportDirectionEmergency: [],
          evidence: '',
          resumeKey: '',
          paperSituationKey: '',
          rewardKey: '',
@@ -597,6 +637,7 @@
          source: 1
        }
        state.fileList = []
        state.evidenceList = []
        state.resumeList = []
        state.inventionList = []
        state.rewardList = []
src/views/safetyReview/expertManage/postEvaluation/components/evaluate.vue
@@ -6,81 +6,179 @@
        width="50%"
        :before-close="handleClose"
    >
      <el-form :model="state.info" inline size="default" ref="busRef" label-width="140px">
        <el-form-item label="姓名:">
          <el-input v-model.trim="state.info.name" readonly></el-input>
        </el-form-item>
        <el-form-item label="身份证号:">
          <el-input v-model.trim="state.info.idCard" readonly></el-input>
        </el-form-item>
        <el-form-item label="项目名称:">
          <el-input v-model.trim="state.info.projectName" readonly></el-input>
        </el-form-item>
        <el-form-item label="是否为专家组组长:">
          <el-input v-model.trim="state.info.teamLeader" readonly></el-input>
        </el-form-item>
        <el-form-item label="考评记录时间:">
          <el-input v-model.trim="state.info.evaluateTime" readonly></el-input>
        </el-form-item>
        <el-form-item label="总计:">
          <el-input v-model.trim="state.info.score" readonly></el-input>
        </el-form-item>
      <el-form :model="state.info" size="default" ref="busRef" label-width="140px">
        <el-row>
          <el-col :span="12">
            <el-form-item label="姓名">
              <el-input v-model.trim="state.info.name" readonly></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="身份证号">
              <el-input v-model.trim="state.info.idCard" readonly></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="项目名称">
              <el-input v-model.trim="state.info.projectName" readonly></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="是否为专家组组长">
              <el-input v-model.trim="state.info.teamLeader" readonly></el-input>
            </el-form-item>
          </el-col>
        </el-row>
<!--        <el-form-item label="考评记录时间:">-->
<!--          <el-input v-model.trim="state.info.evaluateTime" readonly></el-input>-->
<!--        </el-form-item>-->
<!--        <el-form-item label="总计:">-->
<!--          <el-input v-model.trim="state.info.score" readonly></el-input>-->
<!--        </el-form-item>-->
      </el-form>
      <div>
        请对专家表现进行评分:
      </div>
      <div style="width: 100%;display: flex;align-items: center;justify-content: space-between;margin: 25px 0 15px">
        <div>
          <el-button type="primary" size="default" @click="openSelectList('1')" v-preReClick>添加加分项</el-button>
          <el-button type="default" size="default" @click="addSelect('1')" v-preReClick>自定义加分项</el-button>
      <el-form :model="state.form" ref="evaluateRef" :rules="state.formRules" label-width="140px">
        <el-divider>
          专家工作表现
        </el-divider>
        <el-form-item label="职业道德方面" prop="professionalEthics">
          <el-radio-group v-model="state.form.professionalEthics" style="width: 100%" :disabled="state.disable">
            <el-radio v-for="item in state.rateList" :label="item.value">{{ item.label }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="公正廉洁方面" prop="impartialHonest">
          <el-radio-group v-model="state.form.impartialHonest" style="width: 100%" :disabled="state.disable">
            <el-radio v-for="item in state.rateList" :label="item.value">{{ item.label }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="综合协调组织" prop="comprehensiveCoordination">
          <el-radio-group v-model="state.form.comprehensiveCoordination" style="width: 100%" :disabled="state.disable">
            <el-radio v-for="item in state.rateList" :label="item.value">{{ item.label }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="专业能力素养" prop="professionalAbility">
          <el-radio-group v-model="state.form.professionalAbility" style="width: 100%" :disabled="state.disable">
            <el-radio v-for="item in state.rateList" :label="item.value">{{ item.label }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="意见表达能力" prop="expressingOpinions">
          <el-radio-group v-model="state.form.expressingOpinions" style="width: 100%" :disabled="state.disable">
            <el-radio v-for="item in state.rateList" :label="item.value">{{ item.label }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="其他意见建议">
          <el-input v-model="state.form.others" type="textarea" :autosize="{ minRows: 2}" :readonly="state.disable"></el-input>
        </el-form-item>
        <el-form-item label="使用单位综合评价情况" label-width="180px" prop="comprehensiveEvaluation">
          <el-radio-group v-model="state.form.comprehensiveEvaluation" style="width: 100%" :disabled="state.disable">
            <el-radio v-for="item in state.rateList" :label="item.value">{{ item.label }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-divider>
          量化评分(非必填)
        </el-divider>
        <div style="width: 100%;display: flex;align-items: center;justify-content: space-between;margin: 25px 0 15px">
          <div>
            <el-button type="primary" size="default" @click="openSelectList('1')" v-preReClick :disabled="state.disable">添加加分项</el-button>
            <el-button type="default" size="default" @click="addSelect('1')" v-preReClick :disabled="state.disable">自定义加分项</el-button>
          </div>
          <div style="font-size: 14px">
            加分总计:<span style="font-weight: bolder;color: #10B981">{{addTotal}}</span> 分
          </div>
        </div>
        <div style="font-size: 14px">
          加分总计:<span style="font-weight: bolder;color: #10B981">{{addTotal}}</span> 分
        <el-table :data="state.addData" border style="width: 100%">
          <el-table-column prop="content" label="加分项"/>
          <el-table-column prop="score" label="分值">
            <template #default="scope">
              <el-input v-model.trim="scope.row.score" type="number" :readonly="state.disable"></el-input>
            </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="openDialog('edit',scope.row)">编辑</el-button>-->
              <el-button link type="danger"  @click="deleteSelect(scope.row,scope.$index,1)" :disabled="state.disable">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
        <div style="width: 100%;display: flex;align-items: center;justify-content: space-between;margin: 25px 0 15px">
          <div>
            <el-button type="primary" size="default" @click="openSelectList('2')" v-preReClick :disabled="state.disable">添加扣分项</el-button>
            <el-button type="default" size="default" @click="addSelect('2')" v-preReClick :disabled="state.disable">自定义扣分项</el-button>
          </div>
          <div style="font-size: 14px">
            扣分总计:<span style="font-weight: bolder;color: #EF4444">{{deductTotal}}</span> 分
          </div>
        </div>
      </div>
      <el-table :data="state.addData" border style="width: 100%">
        <el-table-column prop="content" label="加分项"/>
        <el-table-column prop="score" label="分值">
          <template #default="scope">
            <el-input v-model.trim="scope.row.score" type="number"></el-input>
          </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="openDialog('edit',scope.row)">编辑</el-button>-->
            <el-button link type="danger"  @click="deleteSelect(scope.row,scope.$index,1)" >删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div style="width: 100%;display: flex;align-items: center;justify-content: space-between;margin: 25px 0 15px">
        <div>
          <el-button type="primary" size="default" @click="openSelectList('2')" v-preReClick>添加扣分项</el-button>
          <el-button type="default" size="default" @click="addSelect('2')" v-preReClick>自定义扣分项</el-button>
        <el-table :data="state.deductData" border style="width: 100%">
          <el-table-column prop="content" label="扣分项"/>
          <el-table-column prop="score" label="分值">
            <template #default="scope">
              <el-input v-model.trim="scope.row.score" type="number" :readonly="state.disable"></el-input>
            </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="deleteSelect(scope.row,scope.$index,2)" :disabled="state.disable">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
        <div style="margin-top: 15px">提示:如果该专家在本项目无加分项,也无扣分项,可不填。</div>
        <div style="margin: 25px 0;font-size: 14px">
          <el-form-item label="本项目考评总计" prop="score">
            <el-input v-model.trim="state.form.score" type="number" :readonly="state.disable"><template #append>分</template></el-input>
          </el-form-item>
        </div>
        <div style="font-size: 14px">
          扣分总计:<span style="font-weight: bolder;color: #EF4444">{{deductTotal}}</span> 分
        </div>
      </div>
      <el-table :data="state.deductData" border style="width: 100%">
        <el-table-column prop="content" label="扣分项"/>
        <el-table-column prop="score" label="分值">
          <template #default="scope">
            <el-input v-model.trim="scope.row.score" type="number"></el-input>
          </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="deleteSelect(scope.row,scope.$index,2)" >删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div style="margin: 25px 0;font-size: 14px;display: flex;justify-content: right">
        本项目考评总计:<span style="font-weight: bolder;color: #2563EB">{{totalScore}}</span> 分
      </div>
      <div>提示:如果该专家在本项目无加分项,也无扣分项,直接点击“完成评分” 即可,不做任何分数更改。</div>
        <el-row>
          <el-col :span="12">
            <el-form-item label="发现重大隐患" prop="majorDangers">
              <el-input v-model.trim="state.form.majorDangers" type="number" :readonly="state.disable" placeholder="请输入正整数,没有则填0"><template #append>条</template></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="一般隐患" prop="generalHazards">
              <el-input v-model.trim="state.form.generalHazards" type="number" :readonly="state.disable" placeholder="请输入正整数,没有则填0"><template #append>条</template></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="内容描述">
          <el-input v-model="state.form.content" type="textarea" :autosize="{ minRows: 2}" :readonly="state.disable"></el-input>
        </el-form-item>
        <el-divider></el-divider>
        <el-form-item label="计费标准" prop="freightBasis">
          <el-input v-model.trim="state.form.freightBasis" :readonly="state.disable"></el-input>
        </el-form-item>
        <el-row>
          <el-col :span="12">
            <el-form-item label="计费时长" prop="billingDuration">
              <el-input v-model.trim="state.form.billingDuration" type="number" :readonly="state.disable"><template #append>小时</template></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="税后金额" prop="afterTaxAmount">
              <el-input v-model.trim="state.form.afterTaxAmount" type="number" :readonly="state.disable"><template #append>元</template></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="开户行" prop="openBank">
              <el-input v-model.trim="state.form.openBank" :readonly="state.disable"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="银行卡号" prop="bankCard">
              <el-input v-model.trim="state.form.bankCard" :readonly="state.disable"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
            <el-button type="primary" @click="confirmScore" size="default" v-preReClick>完成评分</el-button>
          <el-button type="primary" v-if="!state.disable" @click="confirmScore" size="default" v-preReClick>完成评分</el-button>
          <el-button type="primary" v-if="state.disable" @click="handleClose" size="default" v-preReClick>确定</el-button>
        </span>
      </template>
      <select-list ref="selectRef"  @refreshSelected="getSelected"></select-list>
@@ -115,27 +213,58 @@
import {getExpertEvaDetail, projectExpertDetailSave} from '@/api/backManage/evaluate'
const dialogVisible = ref(false)
const evaluateRef = ref()
const busRef = ref()
const addRef = ref()
const selectRef = ref()
const emit = defineEmits(["getList"]);
const state = reactive({
  title: '',
  disable: false,
  addData: [],
  deductData: [],
  info: {
    name: '',
    idCard: '',
    projectName: '',
    teamLeader: '',
    evaluateTime: '',
    score: ''
    teamLeader: ''
  },
  form: {
    projectExpertId: null,
    saveData: [],
    delData: [],
    score: null
    score: 100,
    professionalEthics: null,
    impartialHonest: null,
    comprehensiveCoordination: null,
    professionalAbility: null,
    expressingOpinions: null,
    others: '',
    comprehensiveEvaluation: null,
    majorDangers: null,
    generalHazards: null,
    content: '',
    freightBasis: '',
    billingDuration: null,
    afterTaxAmount: null,
    openBank: '',
    bankCard: '',
  },
  formRules: {
    score: [{required: true, message: '请输入总分', trigger: 'blur'}],
    professionalEthics: [{required: true, message: '该选项不能为空', trigger: 'blur'}],
    impartialHonest: [{required: true, message: '该选项不能为空', trigger: 'blur'}],
    comprehensiveCoordination: [{required: true, message: '该选项不能为空', trigger: 'blur'}],
    professionalAbility: [{required: true, message: '该选项不能为空', trigger: 'blur'}],
    expressingOpinions: [{required: true, message: '该选项不能为空', trigger: 'blur'}],
    comprehensiveEvaluation: [{required: true, message: '该选项不能为空', trigger: 'blur'}],
    majorDangers: [{required: true, message: '请输入重大隐患数', trigger: 'blur'}],
    generalHazards: [{required: true, message: '请输入一般隐患数', trigger: 'blur'}],
    freightBasis: [{required: true, message: '请输入计费标准', trigger: 'blur'}],
    billingDuration: [{required: true, message: '请输入计费时长', trigger: 'blur'}],
    afterTaxAmount: [{required: true, message: '请输入税后金额', trigger: 'blur'}],
    openBank: [{required: true, message: '请输入开户行', trigger: 'blur'}],
    bankCard: [{required: true, message: '请输入卡号', trigger: 'blur'}]
  },
  addVisible: false,
  addTitle: '',
@@ -148,6 +277,12 @@
    content: [{required: true, message: '请输入内容', trigger: 'blur'}],
    score: [{required: true, message: '请输入分值', trigger: 'blur'}],
  },
  rateList: [
    {label: '优秀',value: 1},
    {label: '合格',value: 2},
    {label: '基本合格',value: 3},
    {label: '不合格',value: 4}
  ]
})
const addTotal = computed(()=>{
@@ -162,24 +297,25 @@
  return Number(addTotal.value) + Number(deductTotal.value)
})
const openDialog = async (value, projectName, projectCheckTime) => {
const openDialog = async (type, value, projectName, projectCheckTime) => {
  state.info = value
  state.form.projectExpertId = value.id
  state.info.projectName = projectName
  state.info.evaluateTime = projectCheckTime
  state.info.teamLeader = state.info.teamLeader == 1 ? '是' : '否'
  if (value.evaluationState === 1) {
    state.title = '继续评分'
  if (type === 'view') {
    state.title = '查看'
    state.disable = true
    const res = await getExpertEvaDetail({projectExpertId: value.id});
    if(res.code == 200){
      state.addData = res.data.filter(i=>i.scoreType == '1')
      state.deductData = res.data.filter(i=>i.scoreType == '2')
      state.form = res.data
      state.addData = res.data.expertDetails?res.data.expertDetails.filter(i=>i.scoreType == '1'):[]
      state.deductData = res.data.expertDetails?res.data.expertDetails.filter(i=>i.scoreType == '2'):[]
    }else{
      ElMessage.warning(res.msg)
    }
    console.log(state.addData,'add')
  }else{
    state.title = '评分'
    state.disable = false
  }
  dialogVisible.value = true;
}
@@ -231,15 +367,28 @@
    name: '',
    idCard: '',
    projectName: '',
    teamLeader: '',
    evaluateTime: '',
    score: ''
    teamLeader: ''
  }
  state.form = {
    projectExpertId: null,
    saveData: [],
    delData: [],
    score: null
    score: 100,
    professionalEthics: null,
    impartialHonest: null,
    comprehensiveCoordination: null,
    professionalAbility: null,
    expressingOpinions: null,
    others: '',
    comprehensiveEvaluation: null,
    majorDangers: null,
    generalHazards: null,
    content: '',
    freightBasis: '',
    billingDuration: null,
    afterTaxAmount: null,
    openBank: '',
    bankCard: '',
  }
  state.addData = []
  state.deductData = []
@@ -270,8 +419,6 @@
const confirmScore = async ()=>{
  state.form.saveData = [...state.addData,...state.deductData]
  state.form.delData = state.form.delData.filter((id) => !state.form.saveData.some((item) => item.id === id))
  console.log(state.form,'form')
  state.form.score = totalScore.value
  const res = await projectExpertDetailSave(state.form)
  if(res.code == 200){
    ElMessage.success(res.msg)
src/views/safetyReview/expertManage/postEvaluation/components/expertList.vue
@@ -41,7 +41,9 @@
            <el-table-column label="考评总分" align="center" prop="score" />
            <el-table-column v-if="title == '专家评估'" label="操作" align="center" class-name="small-padding fixed-width">
              <template #default="scope">
                <el-button type="primary" link @click="openEvaluate(scope.row)">评分</el-button>
                <el-button v-if="scope.row.evaluationState ==0" type="primary" link @click="openEvaluate('add',scope.row)">考评与报销</el-button>
                <el-button v-if="scope.row.evaluationState ==1" type="primary" link @click="openEvaluate('view',scope.row)">查看</el-button>
                <el-button v-if="scope.row.evaluationState ==1" type="success" link @click="downloadFile(scope.row)">导出考评表</el-button>
              </template>
            </el-table-column>
          </el-table>
@@ -66,8 +68,10 @@
import {ElMessage} from "element-plus";
import Evaluate from "./evaluate";
import {
  getExpertEvaDetail,
  getProjectExpertEvaluationList,
} from "@/api/backManage/evaluate";
import {generateWordDocument} from "@/views/safetyReview/projectManage/components/exportWord";
const dialogVisible = ref(false);
const evaluateRef = ref()
const emit = defineEmits(["getList"]);
@@ -80,8 +84,15 @@
    pageSize: 10
  },
  projectName: '',
  deptName: '',
  projectCheckTime: '',
  title: ''
  title: '',
  rateList: [
    {label: '优秀',value: 1},
    {label: '合格',value: 2},
    {label: '基本合格',value: 3},
    {label: '不合格',value: 4}
  ]
})
const {tableData,total,queryParams,projectName,title,projectCheckTime} = toRefs(state)
const openDialog = async (type,value) => {
@@ -92,6 +103,7 @@
  }
  state.queryParams.id = value.id
  state.projectName = value.projectName
  state.deptName = value.deptName
  state.projectCheckTime = value.projectCheckTime
  await getEvaluationList()
  dialogVisible.value = true;
@@ -107,8 +119,48 @@
  }
}
const openEvaluate = (value)=>{
  evaluateRef.value.openDialog(value,state.projectName,state.projectCheckTime)
const downloadFile = async (val) => {
  const res = await getExpertEvaDetail({projectExpertId: val.id});
  if(res.code == 200){
    let outData = res.data
    outData.deptName = state.deptName
    outData.name = val.name
    outData.sex = val.sex == 0?'男':'女'
    outData.domain = val.domain
    outData.professionalEthics = state.rateList.find(i=>i.value == res.data.professionalEthics)?.label
    outData.impartialHonest = state.rateList.find(i=>i.value == res.data.impartialHonest)?.label
    outData.comprehensiveCoordination = state.rateList.find(i=>i.value == res.data.comprehensiveCoordination)?.label
    outData.professionalAbility = state.rateList.find(i=>i.value == res.data.professionalAbility)?.label
    outData.expressingOpinions = state.rateList.find(i=>i.value == res.data.expressingOpinions)?.label
    outData.comprehensiveEvaluation = state.rateList.find(i=>i.value == res.data.comprehensiveEvaluation)?.label
    try {
      generateWordDocument('/evaluateFile.docx',outData, outData.name + '专家考评表.docx');
    } catch (error){
      ElMessage({
        type: 'warning',
        message: '导出失败'
      });
    }
  }else{
    ElMessage.warning(res.msg)
  }
  // data.companyName = data.companyName != '' ? data.companyName: '-'
  // data.projectCheckTime = data.projectCheckTime != '' ? data.projectCheckTime: '-'
  // data.tableData = state.dataList.map(item => {
  //   return {
  //     ...item,
  //     ratingLevel: item.ratingLevel == 1 ? '一级' : item.ratingLevel == 2 ? '二级':item.ratingLevel == 3 ? '三级' : '',
  //     sex: item.sex == 0 ? '男' : '女',
  //     selectionMode: item.selectionMode == 1 ? '固定' : '随机',
  //     teamLeader: item.teamLeader == 1 ? '是' : '否',
  //   }
  // })
};
const openEvaluate = (type,value)=>{
  evaluateRef.value.openDialog(type,value,state.projectName,state.projectCheckTime)
}
const closeEvaluate = ()=>{
src/views/safetyReview/expertManage/postEvaluation/index.vue
@@ -34,7 +34,7 @@
        <el-table-column label="项目名称" align="center" prop="projectName"/>
        <el-table-column label="审批单时间" align="center" prop="projectCheckTime"/>
        <el-table-column label="结束时间" align="center" prop="projectEndTime" />
        <el-table-column label="部门" align="center" prop="deptName" />
        <el-table-column label="部门" align="center" prop="deptName"/>
        <el-table-column label="专家人数" align="center" prop="expertNum">
          <template #default="scope">
            <el-button type="primary" link @click="openDialog('view',scope.row)">{{scope.row.expertNum}}</el-button>
src/views/safetyReview/projectManage/components/exportWord.js
@@ -15,7 +15,7 @@
}
// 生成并下载 Word 文档(templatePath是word文档模版地址,data是对应的数据)
export function generateWordDocument(templatePath, data) {
export function generateWordDocument(templatePath, data, name) {
        loadFile(templatePath, function (error, content) {
            if (error) {
                throw error
@@ -42,7 +42,7 @@
                    mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
                });
                saveAs(fileWord, '专家选用审批单.docx');
                saveAs(fileWord, name);
                // // 返回生成的文档 Blob
                // resolve(fileWord);
src/views/safetyReview/projectManage/components/projectApproval.vue
@@ -381,7 +381,7 @@
const handleRemove = async (file, uploadFile) => {
}
const templatePath = '/example.docx';
const templatePath = '/example.docx'
const startGeneration = async () => {
  const data = state.dataForm
  let day = new Date(data.projectDateEnd).getTime() - new Date(data.projectDateStart).getTime();
@@ -412,7 +412,7 @@
  })
  console.log('dataList',state.dataList)
  try {
    generateWordDocument(templatePath, data);
    generateWordDocument(templatePath, data, '专家选用审批单.docx');
  } catch (error){
    ElMessage({
      type: 'warning',