From 7aec2e86f29f330f9b5f3b85d6ad82ae39c152e3 Mon Sep 17 00:00:00 2001
From: 马宇豪 <978517621@qq.com>
Date: 星期三, 13 十二月 2023 15:13:58 +0800
Subject: [PATCH] 新增

---
 src/permission.js                                                          |    2 
 src/assets/styles/index.scss                                               |    4 
 src/layout/components/Sidebar/menu.js                                      |   15 
 src/views/homePage.vue                                                     |    8 
 src/views/safetyReview/expertManage/applyRecords/index.vue                 |  231 ++++++
 src/views/safetyReview/expertManage/applyRecords/components/expertForm.vue |  808 +++++++++++++++++++++
 src/assets/styles/element-ui.scss                                          |    4 
 src/assets/logo/logo.png                                                   |    0 
 src/router/index.js                                                        |   24 
 src/utils/validate.js                                                      |    5 
 src/views/safetyReview/expertManage/fillForm/index.vue                     |  622 ++++++++++++++++
 src/views/safetyReview/baseSet/expertsType/index.vue                       |  219 +++++
 src/views/safetyReview/expertManage/experts/index.vue                      |  186 ++++
 src/layout/components/Sidebar/Logo.vue                                     |    2 
 src/api/form.js                                                            |   96 ++
 15 files changed, 2,204 insertions(+), 22 deletions(-)

diff --git a/src/api/form.js b/src/api/form.js
new file mode 100644
index 0000000..78913d3
--- /dev/null
+++ b/src/api/form.js
@@ -0,0 +1,96 @@
+import request from '@/utils/request'
+
+// 获取专家列表
+export function getExpertsList(params) {
+  return request({
+    url: '/system/expert_info/list',
+    method: 'get',
+    params: params
+  })
+}
+
+// 获取专家列表
+export function delExpert(id) {
+  return request({
+    url: '/expert/info/del/'+id,
+    method: 'get'
+  })
+}
+
+// 提交表单
+export function addExpertInfo(data) {
+  return request({
+    url: '/system/expert_info/add',
+    method: 'post',
+    data: data
+  })
+}
+
+// 提交表单
+export function modExpertInfo(data) {
+  return request({
+    url: '/system/expert_info/mod',
+    method: 'put',
+    data: data
+  })
+}
+
+// 上传
+export function uploadFile(data) {
+  return request({
+    url: '/system/common/uploadFile',
+    method: 'post',
+    data: data
+  })
+}
+
+// 分页获取专家类型
+export function getExpertTypes() {
+  return request({
+    url: '/system/expert_classify/tree',
+    method: 'get',
+  })
+}
+
+// 添加专家类型
+export function addType(data) {
+  return request({
+    url: '/system/expert_classify/add',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改专家类型
+export function updateType(data) {
+  return request({
+    url: '/system/expert_classify/mod',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除专家类型
+export function delExpertType(id) {
+  return request({
+    url: '/system/expert_classify/del/'+id,
+    method: 'delete'
+  })
+}
+
+// 根据id获取专家信息
+export function getInfo(id) {
+  return request({
+    url: '/system/expert_info/detail/'+id,
+    method: 'get'
+  })
+}
+
+// 评定
+export function changeApprove(data) {
+  return request({
+    url: '/system/expert_info/changeApprove',
+    method: 'post',
+    data: data
+  })
+}
\ No newline at end of file
diff --git a/src/assets/logo/logo.png b/src/assets/logo/logo.png
index e263760..1f640a8 100644
--- a/src/assets/logo/logo.png
+++ b/src/assets/logo/logo.png
Binary files differ
diff --git a/src/assets/styles/element-ui.scss b/src/assets/styles/element-ui.scss
index 44e17fa..09aa07c 100644
--- a/src/assets/styles/element-ui.scss
+++ b/src/assets/styles/element-ui.scss
@@ -109,8 +109,8 @@
 .el-table{
   border-radius: .6rem !important;
   font-size: 1rem !important;
-  -webkit-box-shadow: 0 8px 15px rgba(0,21,41,.08);
-  box-shadow: 0 8px 15px rgba(0,21,41,.08);
+  -webkit-box-shadow: 8px 8px 15px rgba(0,21,41,.08), -8px -8px 15px #fff;
+  box-shadow: 8px 8px 15px rgba(0,21,41,.08), -8px -8px 15px #fff;
 }
 
 .el-table .el-table__cell{
diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss
index eaec52a..c28ac66 100644
--- a/src/assets/styles/index.scss
+++ b/src/assets/styles/index.scss
@@ -191,9 +191,9 @@
 }
 
 .blueFont{
-  color: #5175C0;
+  color: #385ca7;
 }
 
 .blueBg{
-  background: #5175C0;
+  background: #385ca7;
 }
\ No newline at end of file
diff --git a/src/layout/components/Sidebar/Logo.vue b/src/layout/components/Sidebar/Logo.vue
index 6b29184..0ad526a 100644
--- a/src/layout/components/Sidebar/Logo.vue
+++ b/src/layout/components/Sidebar/Logo.vue
@@ -72,7 +72,7 @@
       color: #fff;
       font-weight: 600;
       line-height: 50px;
-      font-size: 14px;
+      font-size: 16px;
       font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
       vertical-align: middle;
     }
diff --git a/src/layout/components/Sidebar/menu.js b/src/layout/components/Sidebar/menu.js
index e0c6940..740cd71 100644
--- a/src/layout/components/Sidebar/menu.js
+++ b/src/layout/components/Sidebar/menu.js
@@ -40,17 +40,17 @@
         },
         {
             path: '/expertManage',
-            redirect: '/userManage/supervise',
+            redirect: '/expertManage/experts',
             meta: { title: '厅专家库管理',icon: 'form'},
             children: [
                 {
-                    path: 'expert',
-                    name: 'expert',
+                    path: 'experts',
+                    name: 'experts',
                     meta: { title: '厅专家库',icon: 'form'}
                 },
                 {
-                    path: 'record',
-                    name: 'record',
+                    path: 'applyRecords',
+                    name: 'applyRecords',
                     meta: { title: '专家申请记录',icon: 'form'}
                 }
             ]
@@ -66,6 +66,11 @@
                     meta: { title: '评价类型管理',icon: 'form'}
                 },
                 {
+                    path: 'expertsType',
+                    name: 'expertsType',
+                    meta: { title: '专家类型管理',icon: 'form'}
+                },
+                {
                     path: 'business',
                     name: 'business',
                     meta: { title: '业务范围',icon: 'form'}
diff --git a/src/permission.js b/src/permission.js
index dc79d74..b3da443 100644
--- a/src/permission.js
+++ b/src/permission.js
@@ -11,7 +11,7 @@
 
 NProgress.configure({ showSpinner: false });
 
-const whiteList = ['/homePage'];
+const whiteList = ['/homePage','/fillForm'];
 
 router.beforeEach((to, from, next) => {
   NProgress.start()
diff --git a/src/router/index.js b/src/router/index.js
index 9a2c07b..e9967eb 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -52,7 +52,11 @@
     component: () => import('@/views/error/401'),
     hidden: true
   },
-
+  {
+    path: '/fillForm',
+    component: () => import('@/views/safetyReview/expertManage/fillForm/index.vue'),
+    hidden: true
+  },
   {
     path: '/expertUser',
     component: () => import('@/views/safetyReview/userManage/expertUsers/index.vue'),
@@ -154,19 +158,19 @@
   {
     path: '/expertManage',
     component: Layout,
-    redirect: '/expertManage/expert',
+    redirect: '/expertManage/experts',
     meta: { title: '厅专家库管理'},
     children: [
       {
-        path: 'expert',
-        component: () => import('@/views/index'),
+        path: 'experts',
+        component: () => import('@/views/safetyReview/expertManage/experts/index.vue'),
         name: 'expert',
         meta: { title: '厅专家库',icon: 'form'}
       },
       {
-        path: 'record',
-        component: () => import('@/views/index'),
-        name: 'record',
+        path: 'applyRecords',
+        component: () => import('@/views/safetyReview/expertManage/applyRecords/index.vue'),
+        name: 'applyRecords',
         meta: { title: '专家申请记录',icon: 'form'}
       },
       {
@@ -190,6 +194,12 @@
         meta: { title: '评价类型管理',icon: 'form'}
       },
       {
+        path: 'expertsType',
+        component: () => import('@/views/safetyReview/baseSet/expertsType/index.vue'),
+        name: 'expertsType',
+        meta: { title: '专家类型管理',icon: 'form'}
+      },
+      {
         path: 'business',
         component: () => import('@/views/safetyReview/baseSet/business/index.vue'),
         name: 'business',
diff --git a/src/utils/validate.js b/src/utils/validate.js
index 9a72225..e78759b 100644
--- a/src/utils/validate.js
+++ b/src/utils/validate.js
@@ -108,3 +108,8 @@
   }
   return Array.isArray(arg)
 }
+
+export function verifyIdCard(val) {
+  var regex = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
+  return regex.test(val)
+}
\ No newline at end of file
diff --git a/src/views/homePage.vue b/src/views/homePage.vue
index ae5bf05..0418459 100644
--- a/src/views/homePage.vue
+++ b/src/views/homePage.vue
@@ -215,7 +215,7 @@
           height: 100%;
           padding: 0 50px;
           color: #ffffff;
-          background-color: #5175C0;
+          background-color: #385ca7;
           font-size: 20px;
           text-decoration: none;
           display: flex;
@@ -224,11 +224,11 @@
           cursor: pointer;
 
           &:hover{
-            background: #425f9f;
+            background: #294582;
           }
         }
         .active{
-          background: #425f9f;
+          background: #385ca7;
         }
       }
     }
@@ -257,7 +257,7 @@
   width: 100%;
   text-align: center;
   color: #fff;
-  background: #5175C0;
+  background: #385ca7;
   font-family: "PingFang SC";
   font-size: 12px;
   letter-spacing: 1px;
diff --git a/src/views/safetyReview/baseSet/expertsType/index.vue b/src/views/safetyReview/baseSet/expertsType/index.vue
new file mode 100644
index 0000000..55ecca9
--- /dev/null
+++ b/src/views/safetyReview/baseSet/expertsType/index.vue
@@ -0,0 +1,219 @@
+<template>
+  <div class="app-container">
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          :icon="Plus"
+          @click="handleAdd"
+        >新增</el-button>
+      </el-col>
+<!--      <el-col :span="1.5">-->
+<!--        <el-button-->
+<!--          type="success"-->
+<!--          plain-->
+<!--          icon="el-icon-edit"-->
+<!--          size="mini"-->
+<!--          :disabled="single"-->
+<!--          @click="handleUpdate"-->
+<!--          v-hasPermi="['system:post:edit']"-->
+<!--        >修改</el-button>-->
+<!--      </el-col>-->
+<!--      <el-col :span="1.5">-->
+<!--        <el-button-->
+<!--          type="danger"-->
+<!--          plain-->
+<!--          icon="el-icon-delete"-->
+<!--          size="mini"-->
+<!--          :disabled="multiple"-->
+<!--          @click="handleDelete"-->
+<!--          v-hasPermi="['system:post:remove']"-->
+<!--        >删除</el-button>-->
+<!--      </el-col>-->
+<!--      <el-col :span="1.5">-->
+<!--        <el-button-->
+<!--          type="warning"-->
+<!--          plain-->
+<!--          icon="el-icon-download"-->
+<!--          size="mini"-->
+<!--          @click="handleExport"-->
+<!--          v-hasPermi="['system:post:export']"-->
+<!--        >导出</el-button>-->
+<!--      </el-col>-->
+<!--      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>-->
+    </el-row>
+
+    <el-table v-loading="state.loading" :data="state.expertList" :tree-props="{children: 'children', hasChildren: 'hasChildren'}" :border="true">
+      <el-table-column label="分类名称" align="center" prop="classifyName" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-button type="primary" link @click="handleUpdate(scope.row)">修改</el-button>
+          <el-button type="danger" link @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <el-dialog :title="state.title" v-model="state.open" width="500px" append-to-body>
+      <el-form ref="formRef" :model="state.form" :rules="state.rules" label-width="80px">
+        <el-form-item label="父级" v-if="state.title == '添加分类'" prop="parentId">
+          <el-cascader
+            v-model="state.form.parentId"
+            :options="state.expertList"
+            :props="{ expandTrigger: 'hover', value: 'id',label: 'classifyName',emitPath: false,checkStrictly: true }"
+            @change="handleChange"></el-cascader>
+        </el-form-item>
+        <el-form-item label="分类名称" prop="classifyName">
+          <el-input v-model="state.form.classifyName" placeholder="请输入分类名称" />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm(formRef)">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import {getExpertTypes, delExpertType, addType, updateType} from "@/api/form"
+import {onMounted, reactive, ref, toRefs} from "vue";
+import {ElMessage, ElMessageBox} from "element-plus"
+import { Plus } from '@element-plus/icons-vue'
+const state = reactive({
+  loading: true,
+  total: 0,
+  expertList: [],
+  title: "",
+  open: false,
+  form: {
+    parentId: null,
+    id: null,
+    classifyName: ''
+  },
+  rules: {
+    classifyName: [
+      { required: true, message: "分类名称不能为空", trigger: "blur" }
+    ]
+  }
+})
+const formRef = ref()
+
+  onMounted(()=>{
+    getList()
+  })
+    /** 查询岗位列表 */
+  const getList = async()=> {
+      state.loading = true;
+      const res = await getExpertTypes()
+      if(res.code == 200){
+        state.expertList = res.data
+      }else{
+        ElMessage.warning(res.message)
+      }
+      state.loading = false;
+    }
+    // 取消按钮
+    const cancel=()=> {
+      state.open = false;
+      reset();
+    }
+    const handleChange=(value)=> {
+      console.log(value);
+    }
+    // 表单重置
+    const reset=()=> {
+      state.form = {
+        parentId: 0,
+        id: null,
+        classifyName: ''
+      }
+    }
+
+    const handleAdd=()=> {
+      reset();
+      state.open = true;
+      state.title = "添加分类";
+    }
+
+    const handleUpdate=(row)=> {
+      reset();
+      console.log(row,'row')
+      state.form.id = row.id;
+      state.form.classifyName = row.classifyName;
+      state.form.parentId = findParentNodeById(state.expertList,row.id)
+      console.log(state.form,'form')
+      state.open = true;
+      state.title = "修改分类";
+    }
+
+    const submitForm = async(formEl)=> {
+      await formEl.validate(async (valid, fields) => {
+        if (valid) {
+          if (state.title == '修改分类') {
+            updateType(state.form).then(res => {
+              if(res.code == 200){
+                ElMessage.success('修改成功')
+                state.open = false;
+                getList();
+              }else{
+                ElMessage.warning(res.message)
+              }
+            });
+          } else {
+            const {classifyId,...data} = state.form
+            addType(data).then(res => {
+              if(res.code == 200){
+                ElMessage.success('添加成功')
+                state.open = false;
+                getList();
+              }else{
+                ElMessage.warning(res.message)
+              }
+            });
+          }
+        }
+      });
+    }
+
+    const handleDelete=(row)=> {
+      const classifyId = row.id;
+      ElMessageBox.confirm(
+          '是否删除类名为【' + row.classifyName + '】及其所包含的所有分类数据?',
+          '提示',
+          {
+            confirmButtonText: '确定',
+            cancelButtonText: '取消',
+            type: 'warning',
+          })
+          .then(async() => {
+            const res = await delExpertType(classifyId)
+            if(res.code == 200){
+              getList();
+              ElMessage.success('删除成功')
+            }else{
+              ElMessage.warning(res.message)
+            }
+          })
+    }
+
+    const findParentNodeById=(data, value)=> {
+      for (const node of data) {
+        if (node.id === value) {
+          return null; // 已经是根节点,没有父级节点
+        }
+        if (node.children) {
+          for (const child of node.children) {
+            if (child.id === value) {
+              return node.id; // 返回当前节点的ID作为父级ID
+            }
+          }
+          const foundNode = findParentNodeById(node.children, value);
+          if (foundNode !== null) {
+            return foundNode; // 返回找到的父级ID
+          }
+        }
+      }
+      return null;
+    }
+</script>
diff --git a/src/views/safetyReview/expertManage/applyRecords/components/expertForm.vue b/src/views/safetyReview/expertManage/applyRecords/components/expertForm.vue
new file mode 100644
index 0000000..32790b9
--- /dev/null
+++ b/src/views/safetyReview/expertManage/applyRecords/components/expertForm.vue
@@ -0,0 +1,808 @@
+<template>
+    <div class="notice">
+        <el-dialog
+            v-model="dialogVisible"
+            :title="state.title"
+            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>
+                <el-col :span="20">
+                  <el-form-item label="专业类别" prop="profession">
+                    <el-cascader
+                        :disabled="state.disable"
+                        style="width: 100%"
+                        v-model="state.form.profession"
+                        :options="state.expertsType"
+                        :props="{ expandTrigger: 'hover',value: 'id',label: 'classifyName' }"
+                        @change="professionChange"></el-cascader>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <!--        <el-row>-->
+              <!--          <el-col :span="20">-->
+              <!--            <el-form-item label="填报日期" prop="date">-->
+              <!--              <el-date-picker-->
+              <!--                style="width: 100%"-->
+              <!--                v-model="form.date"-->
+              <!--                type="date"-->
+              <!--                placeholder="选择日期">-->
+              <!--              </el-date-picker>-->
+              <!--            </el-form-item>-->
+              <!--          </el-col>-->
+              <!--        </el-row>-->
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="姓名" prop="name">
+                    <el-input v-model="state.form.name" :readonly="state.disable"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="性别" prop="sex">
+                    <el-radio-group v-model="state.form.sex" :disabled="state.disable">
+                      <el-radio :label="0">男</el-radio>
+                      <el-radio :label="1">女</el-radio>
+                    </el-radio-group>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="出生日期" prop="birthday">
+                    <el-date-picker
+                        style="width: 100%"
+                        v-model="state.form.birthday"
+                        value-format="YYYY-MM-DD 00:00:00"
+                        type="date"
+                        placeholder="选择日期" :disabled="state.disable">
+                    </el-date-picker>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="联系电话" prop="phone">
+                    <el-input v-model="state.form.phone" :readonly="state.disable"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="职称" prop="title">
+                    <!--              <el-select v-model="form.title" placeholder="请选择" style="width: 100%">-->
+                    <!--                <el-option-->
+                    <!--                  v-for="item in professionalList"-->
+                    <!--                  :key="item.value"-->
+                    <!--                  :label="item.label"-->
+                    <!--                  :value="item.value">-->
+                    <!--                </el-option>-->
+                    <!--              </el-select>-->
+                    <el-input v-model="state.form.title" :readonly="state.disable"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="证件照" prop="electronicPhoto">
+                    <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>
+                        <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传1张</div>
+                      </template>
+                    </el-upload>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="身份证号" prop="idCard">
+                    <el-input v-model="state.form.idCard" :readonly="state.disable"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="在岗情况" prop="dutyStatus">
+                    <el-radio-group v-model="state.form.dutyStatus" :disabled="state.disable">
+                      <el-radio :label="0">在岗</el-radio>
+                      <el-radio :label="1">退休</el-radio>
+                    </el-radio-group>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="单位全称" prop="companyName">
+                    <el-input v-model="state.form.companyName" :readonly="state.disable"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="单位地址">
+                    <el-input v-model="state.form.companyAddress" :readonly="state.disable"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="所在部门">
+                    <el-input v-model="state.form.deptName" :readonly="state.disable"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="职务">
+                    <el-input v-model="state.form.job" :readonly="state.disable"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="单位电话">
+                    <el-input v-model="state.form.companyTelephone" :readonly="state.disable"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="传真号码">
+                    <el-input v-model="state.form.faxNum" :readonly="state.disable"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="电子邮箱">
+                    <el-input v-model="state.form.email" :readonly="state.disable"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="毕业学校">
+                    <el-input v-model="state.form.graduationSchool" :readonly="state.disable"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="最高学历" prop="degree">
+                    <el-input v-model="state.form.degree" :readonly="state.disable"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="所学专业">
+                    <el-input v-model="state.form.speciality" :readonly="state.disable"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="现从事的专业及方向">
+                    <el-input v-model="state.form.currentProfession" :readonly="state.disable"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="支撑方向_安全生产" prop="supportDirectionSafety">
+                    <!--              <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>-->
+                    <el-checkbox-group v-model="state.form.supportDirectionSafety" :disabled="state.disable">
+                      <el-checkbox v-for="item in state.directionList" :label="item.value" :key="item.value">{{ item.label }}</el-checkbox>
+                    </el-checkbox-group>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="支撑方向_防灾减灾救灾" prop="supportDirectionPrevention">
+                    <!--              <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>-->
+                    <el-checkbox-group v-model="state.form.supportDirectionPrevention" :disabled="state.disable">
+                      <el-checkbox v-for="item in state.directionList" :label="item.value" :key="item.value">{{ item.label }}</el-checkbox>
+                    </el-checkbox-group>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="支撑方向_应急救援" prop="supportDirectionEmergency">
+                    <!--              <el-radio-group v-model="form.supportDirectionEmergency">-->
+                    <!--                <el-radio v-for="item in directionList" :label="item.value" :key="item.value">{{ item.label }}</el-radio>-->
+                    <!--              </el-radio-group>-->
+                    <el-checkbox-group v-model="state.form.supportDirectionEmergency" :disabled="state.disable">
+                      <el-checkbox v-for="item in state.directionList" :label="item.value" :key="item.value">{{ item.label }}</el-checkbox>
+                    </el-checkbox-group>
+                  </el-form-item>
+                </el-col>
+              </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>
+                      <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="发明、著作、学术论文情况(何时、何地出版或发表)">
+                    <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.inventionList" 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="受过何种奖励">
+                    <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.rewardList" 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="应急管理相关工作主要业绩及研究成果">
+                    <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.achievementList" 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="专家本人意见">
+                    <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>
+                      </template>
+                    </el-upload>
+                  </el-form-item>
+                </el-col>
+              </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.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>
+                      </template>
+                    </el-upload>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="补充说明">
+                    <el-input v-model="state.form.remark" type="textarea" :autosize="{ minRows: 2}" :readonly="state.disable"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+            </el-form>
+            <el-dialog v-model="imgDialog">
+              <img w-full :src="state.dialogImageUrl" alt="">
+            </el-dialog>
+          </div>
+            <template #footer>
+              <span class="dialog-footer" v-if="state.title == '新增' || state.title == '编辑'">
+                  <el-button @click="handleClose" size="default">取 消</el-button>
+                  <el-button type="primary" @click="onSubmit(ruleFormRef)" size="default" v-preReClick>确认</el-button>
+              </span>
+              <span class="dialog-footer" v-if="state.title == '评定'">
+                  <el-button type="danger" size="default" @click="assess(3)"  v-preReClick>评定驳回</el-button>
+                  <el-button type="primary" @click="assess(2)" size="default" v-preReClick>评定通过</el-button>
+              </span>
+            </template>
+        </el-dialog>
+    </div>
+</template>
+<script setup>
+import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue'
+import {ElMessage, ElMessageBox} from "element-plus"
+import {verifyPhone, verifyIdCard} from "../../../../../utils/validate"
+import {addExpertInfo, getExpertTypes, getInfo, modExpertInfo, uploadFile, changeApprove} from "@/api/form"
+import {delPic} from "@/api/login"
+import { getToken } from "@/utils/auth"
+import {Base64} from "js-base64"
+const emit = defineEmits(["getList"])
+const dialogVisible = ref(false)
+const imgDialog = ref(false)
+const ruleFormRef = ref()
+var validatePass = (rule, value, callback) => {
+  if (state.fileList.length == 0) {
+    callback(new Error('请上传证件照'));
+  } else {
+    callback();
+  }
+}
+let validatePhone = (rule, value, callback)=>{
+  if(value === ''){
+    callback(new Error('请输入手机号'))
+  }else{
+    if(!verifyPhone(value)){
+      callback(new Error('手机号格式有误'))
+    }else{
+      callback()
+    }
+  }
+}
+let verifyId = (rule, value, callback)=>{
+  if(value === ''){
+    callback(new Error('请输入身份证号'))
+  }else{
+    if(!verifyIdCard(value)){
+      callback(new Error('身份证号格式有误'))
+    }else{
+      callback()
+    }
+  }
+}
+
+const state = reactive({
+  form:{
+    id: null,
+    name:'',
+    sex:'',
+    profession: [],
+    bigClassify:null,
+    smallClassify: null,
+    birthday: '',
+    phone:'',
+    title: '',
+    electronicPhoto: '',
+    idCard: '',
+    dutyStatus: null,
+    companyName: '',
+    companyAddress: '',
+    deptName: '',
+    job: '',
+    companyTelephone: '',
+    faxNum: '',
+    email: '',
+    graduationSchool: '',
+    degree: '',
+    speciality: '',
+    currentProfession: '',
+    supportDirectionSafety: [],
+    supportDirectionPrevention: [],
+    supportDirectionEmergency: [],
+    resumeKey: '',
+    paperSituationKey: '',
+    rewardKey: '',
+    achievementKey: '',
+    personalOpinionKey: '',
+    recommendUnitOpinionKey: '',
+    remark: '',
+    source: 2
+  },
+  hasDeleteFile: false,
+  disable: false,
+  expertsType: [],
+  directionList: [
+    {
+      value: 1,
+      label: '现场检查'
+    },
+    {
+      value: 2,
+      label: '调查评估'
+    },
+    {
+      value: 3,
+      label: '咨询服务'
+    },
+    {
+      value: 4,
+      label: '教育培训'
+    },
+    {
+      value: 5,
+      label: '其他'
+    }
+  ],
+  uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile',
+  header: {
+    Authorization: 'Bearer ' + getToken()
+  },
+  fileList: [],
+  resumeList: [],
+  inventionList: [],
+  rewardList: [],
+  achievementList: [],
+  proAdviceList: [],
+  adviceList: [],
+  dialogImageUrl: '',
+  rules:{
+    name:[{ required: true, message: '请填写姓名', trigger: 'blur' }],
+    sex:[{ required: true, message: '请选择性别', trigger: 'blur' }],
+    profession: [{ required: true, message: '请选择专业类别', trigger: 'blur' }],
+    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' }],
+    idCard: [{ required: true, validator: verifyId, trigger: 'blur' }],
+    dutyStatus: [{ required: true, message: '请选择在岗情况', trigger: 'blur' }],
+    companyName: [{ required: true, message: '请填写单位全称', trigger: 'blur' }],
+    degree: [{ required: true, message: '请填写最高学历', trigger: 'blur' }]
+  }
+})
+
+  onMounted(()=>{
+  })
+
+  const openDialog = (type, value) => {
+    state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : type ==='view' ?'查看':'评定'
+    getExpertsType()
+      if(type == 'edit'||type=='view'||type=='assess'){
+        getInfo(value.id).then((res)=>{
+          if(res.code == 200){
+            if(res.data) {
+              const val = res.data
+              for(let i in state.form) {
+                if (validKey(i, val)) {
+                  state.form[i] = val[i]
+                }
+              }
+              state.form.profession[0] = val.bigClassify
+              state.form.profession[1] = val.smallClassify
+              if(val.supportDirectionSafety){
+                state.form.supportDirectionSafety = val.supportDirectionSafety.split(',').map(i=>Number(i))
+              }
+              if(val.supportDirectionPrevention){
+                state.form.supportDirectionPrevention = val.supportDirectionPrevention.split(',').map(i=>Number(i))
+              }
+              if(val.supportDirectionEmergency){
+                state.form.supportDirectionEmergency = val.supportDirectionEmergency.split(',').map(i=>Number(i))
+              }
+              state.fileList.push({
+                name: state.form.electronicPhoto,
+                url: import.meta.env.VITE_APP_BASE_API + '/' + state.form.electronicPhoto,
+              })
+              if(state.form.resumeKey !== ''){
+                state.resumeList = state.form.resumeKey.split(',').map(i=>{
+                  return {
+                    name: i,
+                    url: import.meta.env.VITE_APP_BASE_API + '/' + i,
+                  }
+                })
+              }
+              if(state.form.paperSituationKey !== ''){
+                state.inventionList = state.form.paperSituationKey.split(',').map(i=>{
+                  return {
+                    name: i,
+                    url: import.meta.env.VITE_APP_BASE_API + '/' + i,
+                  }
+                })
+              }
+              if(state.form.rewardKey !== ''){
+                state.rewardList = state.form.rewardKey.split(',').map(i=>{
+                  return {
+                    name: i,
+                    url: import.meta.env.VITE_APP_BASE_API + '/' + i,
+                  }
+                })
+              }
+              if(state.form.achievementKey !== ''){
+                state.achievementList = state.form.achievementKey.split(',').map(i=>{
+                  return {
+                    name: i,
+                    url: import.meta.env.VITE_APP_BASE_API + '/' + i,
+                  }
+                })
+              }
+              if(state.form.personalOpinionKey !== ''){
+                state.proAdviceList = state.form.personalOpinionKey.split(',').map(i=>{
+                  return {
+                    name: i,
+                    url: import.meta.env.VITE_APP_BASE_API + '/' + i,
+                  }
+                })
+              }
+              if(state.form.recommendUnitOpinionKey !== ''){
+                state.adviceList = state.form.recommendUnitOpinionKey.split(',').map(i=>{
+                  return {
+                    name: i,
+                    url: import.meta.env.VITE_APP_BASE_API + '/' + i,
+                  }
+                })
+              }
+            }
+            dialogVisible.value = true
+          }else{
+            ElMessage.warning('数据获取失败:'+res.message)
+          }
+        })
+        if(type == 'edit'){
+          state.disable = false
+        }else{
+          state.disable = true
+        }
+      }else{
+        state.disable = false
+        dialogVisible.value = true
+      }
+  }
+
+  const validKey=(key,obj)=>{
+    return key in obj
+  }
+
+  const assess = (num)=>{
+    ElMessageBox.confirm(
+        '确定对该专家进行此审批操作?',
+        '提示',
+        {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning',
+        })
+        .then(async() => {
+          const res = await changeApprove({id:state.form.id,state: num})
+          if(res.code == 200){
+            ElMessage({
+              type: 'success',
+              message: '审批成功'
+            });
+            emit('getList')
+            dialogVisible.value = false
+          }else{
+            ElMessage({
+              type: 'warning',
+              message: res.message
+            });
+          }
+        })
+  }
+
+  const getExpertsType = async ()=>{
+    const res = await getExpertTypes()
+    if(res.code == 200){
+      state.expertsType = res.data
+    }else{
+      ElMessage({
+        type: 'warning',
+        message: res.message
+      });
+    }
+  }
+
+  const professionChange=(value)=> {
+    console.log(value,'val')
+  }
+
+
+
+  // 图片上传
+  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
+    imgDialog.value = true;
+  }
+
+  const handleAvatarSuccess = (res, uploadFile,type) => {
+    if(res.code == 200){
+      if(type == '证件照'){
+        state.form.electronicPhoto = res.data.path
+      }else{
+        uploadFile.name = res.data.path
+      }
+    }else{
+      ElMessage({
+        type: 'warning',
+        message: '文件上传失败'
+      })
+    }
+  }
+
+  const handleRemove = (file, uploadFiles,type) => {
+    ElMessageBox.confirm(
+        '该操作将永久删除此文件内容,是否继续?',
+        '提示',
+        {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning',
+        })
+        .then(async() => {
+          let path = ''
+          if(type == '证件照'){
+            path = state.form.electronicPhoto
+          }else{
+            path = file.name
+          }
+          const res = await delPic({path: path})
+          if(res.code == 200){
+            ElMessage({
+              type: 'success',
+              message: '文件已删除'
+            })
+            state.hasDeleteFile = true
+          }else{
+            ElMessage({
+              type: 'warning',
+              message: res.message
+            })
+          }
+        })
+  }
+
+const onSubmit = async (formEl)=> {
+  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.bigClassify = data.profession[0]
+      data.smallClassify = data.profession[1]
+      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(',')
+      data.achievementKey = state.achievementList.map(i=>i.name).join(',')
+      data.personalOpinionKey = state.proAdviceList.map(i=>i.name).join(',')
+      data.recommendUnitOpinionKey = state.adviceList.map(i=>i.name).join(',')
+      delete data.profession
+      if(state.title == '新增'){
+        delete data.id
+        const res= await addExpertInfo(data)
+        if(res.code == 200){
+          ElMessage.success(res.message)
+          state.fileList = []
+          state.resumeList = []
+          state.inventionList = []
+          state.rewardList = []
+          state.achievementList = []
+          state.proAdviceList = []
+          state.adviceList = []
+          emit('getList')
+          state.hasDeleteFile = false
+          dialogVisible.value = false
+        }else{
+          ElMessage.warning(res.message)
+        }
+      }else{
+        const res= await modExpertInfo(data)
+        if(res.code == 200){
+          ElMessage.success(res.message)
+          state.fileList = []
+          state.resumeList = []
+          state.inventionList = []
+          state.rewardList = []
+          state.achievementList = []
+          state.proAdviceList = []
+          state.adviceList = []
+          emit('getList')
+          state.hasDeleteFile = false
+          dialogVisible.value = false
+        }else{
+          ElMessage.warning(res.message)
+        }
+      }
+    } else {
+      ElMessage.warning('请完善必填信息')
+    }
+  })
+}
+
+const handleClose = () => {
+    if(state.hasDeleteFile == false){
+      ruleFormRef.value.clearValidate()
+      state.form={
+        id: null,
+        name:'',
+        sex:'',
+        profession: [],
+        bigClassify:null,
+        smallClassify: null,
+        birthday: '',
+        phone:'',
+        title: '',
+        electronicPhoto: '',
+        idCard: '',
+        dutyStatus: null,
+        companyName: '',
+        companyAddress: '',
+        deptName: '',
+        job: '',
+        companyTelephone: '',
+        faxNum: '',
+        email: '',
+        graduationSchool: '',
+        degree: '',
+        speciality: '',
+        currentProfession: '',
+        supportDirectionSafety: [],
+        supportDirectionPrevention: [],
+        supportDirectionEmergency: [],
+        resumeKey: '',
+        paperSituationKey: '',
+        rewardKey: '',
+        achievementKey: '',
+        personalOpinionKey: '',
+        recommendUnitOpinionKey: '',
+        remark: '',
+        source: 2
+      }
+      state.fileList = []
+      state.resumeList = []
+      state.inventionList = []
+      state.rewardList = []
+      state.achievementList = []
+      state.proAdviceList = []
+      state.adviceList = []
+      dialogVisible.value = false;
+    }else{
+      onSubmit()
+    }
+}
+
+defineExpose({
+    openDialog,
+  getExpertsType
+})
+
+</script>
+
+<style scoped lang="scss">
+.notice{
+    :deep(.el-form .el-form-item__label) {
+        font-size: 15px;
+    }
+    .file {
+        display: flex;
+        flex-direction: column;
+        align-items: flex-start;
+    }
+}
+</style>
diff --git a/src/views/safetyReview/expertManage/applyRecords/index.vue b/src/views/safetyReview/expertManage/applyRecords/index.vue
new file mode 100644
index 0000000..0da6ec7
--- /dev/null
+++ b/src/views/safetyReview/expertManage/applyRecords/index.vue
@@ -0,0 +1,231 @@
+<template>
+    <div class="app-container">
+      <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+        <el-form-item label="专业类别">
+          <el-cascader
+              v-model="classiFy"
+              :options="expertTypes"
+              :props="{ expandTrigger: 'hover', value: 'id',label: 'classifyName'}"
+              @change="handleChange"></el-cascader>
+        </el-form-item>
+        <el-form-item label="在岗情况" prop="dutyStatus">
+          <el-select v-model="queryParams.dutyStatus" placeholder="岗位状态" clearable>
+            <el-option :key="0" label="在岗" :value="0"/>
+            <el-option :key="1" label="退休" :value="1"/>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="时间范围" prop="searchTime">
+          <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>
+          <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+        </el-form-item>
+      </el-form>
+
+      <el-row :gutter="10" class="mb8">
+        <el-col :span="1.5">
+          <el-button type="primary" plain :icon="Plus" @click="openDialog('add',{})">新增</el-button>
+        </el-col>
+<!--            <el-col :span="1.5">-->
+<!--              <el-button-->
+<!--                type="warning"-->
+<!--                plain-->
+<!--                icon="el-icon-download"-->
+<!--                size="mini"-->
+<!--                @click="handleExport"-->
+<!--              >导出</el-button>-->
+<!--            </el-col>-->
+      </el-row>
+      <el-table v-loading="loading" :data="expertList" :border="true">
+        <el-table-column type="index" width="55" align="center" />
+        <el-table-column label="姓名" align="center" prop="name" />
+        <el-table-column label="出生日期" align="center" prop="birthday" />
+        <el-table-column label="学历" align="center" prop="degree" />
+        <el-table-column label="职称" align="center" prop="title"/>
+        <el-table-column label="专业" align="center" prop="speciality" />
+        <el-table-column label="推荐类别组别" align="center">
+          <template #default="scope">
+            {{findNodeById(expertTypes,scope.row.bigClassify)}}/{{findNodeById(expertTypes,scope.row.smallClassify)}}
+          </template>
+        </el-table-column>
+        <el-table-column label="联系电话" align="center" prop="phone"/>
+        <el-table-column label="申请时间" align="center" prop="createTime">
+          <template #default="scope">
+            {{scope.row.createTime?scope.row.createTime.substring(0,10):''}}
+          </template>
+        </el-table-column>
+        <el-table-column label="评定状态" align="center" prop="state">
+          <template #default="scope">
+            <el-tag :type="scope.row.state==0?'info':scope.row.state==1?'':scope.row.state==2?'success':scope.row.state==3?'danger':'warning'">
+              {{scope.row.state==0?'暂存':scope.row.state==1?'审核中':scope.row.state==2?'审核通过':scope.row.state==3?'审核驳回':scope.row.state==4?'已作废':'--'}}
+            </el-tag>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-button type="primary" link @click="openDialog('view',scope.row)">查看</el-button>
+            <el-button type="primary" link @click="openDialog('edit',scope.row)">编辑</el-button>
+            <el-button type="primary" v-if="scope.row.state !== 2 && scope.row.state !== 4" link @click="openDialog('assess',scope.row)">评定</el-button>
+            <el-button type="danger" link @click="handleDelete(scope.row)"
+            >删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination
+          v-show="total > 0"
+          :total="total"
+          v-model:page="queryParams.pageNum"
+          v-model:limit="queryParams.pageSize"
+          @pagination="getList"
+      />
+      <expert-form ref="expertFormRef" @getList="getList"></expert-form>
+    </div>
+</template>
+
+<script setup>
+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 { Plus } from '@element-plus/icons-vue'
+
+const loading = ref(false);
+const data = reactive({
+  showSearch: true,
+  total: 0,
+  expertTypes: [],
+  expertList: [],
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    bigClassify: null,
+    smallClassify: null,
+    dutyStatus: null,
+    params: {
+      startTime: '',
+      endTime: ''
+    }
+  },
+  classiFy: [],
+  searchTime: []
+});
+
+const { showSearch,total, expertTypes,expertList,queryParams,classiFy,searchTime} = toRefs(data);
+const expertFormRef = ref()
+onMounted(()=>{
+  getList()
+  getTypes()
+})
+
+onUnmounted(()=>{
+
+})
+
+const getTypes = async()=> {
+  const res = await getExpertTypes()
+  if(res.code == 200){
+    data.expertTypes = res.data
+  }else{
+    ElMessage.warning(res.msg)
+  }
+}
+
+const handleChange=(value)=> {
+  console.log(value)
+}
+const changeTime=(value)=>{
+  console.log(value)
+}
+
+const findNodeById = (data,value)=> {
+  for (const node of data) {
+    if (node.id === value) {
+      return node.classifyName;
+    }
+    if (node.children) {
+      const foundNode = findNodeById(node.children, value);
+      if (foundNode) {
+        return foundNode;
+      }
+    }
+  }
+  return null;
+}
+
+const handleQuery=()=> {
+  data.queryParams.pageNum = 1
+  if(data.classiFy.length>0){
+    data.queryParams.bigClassify = data.classiFy[0]
+    data.queryParams.smallClassify = data.classiFy[1]
+  }
+  if(data.searchTime.length>0){
+    data.queryParams.params.startTime = data.searchTime[0]
+    data.queryParams.params.endTime = data.searchTime[1]
+  }
+  getList()
+}
+
+const getList = async () => {
+  loading.value = true;
+  const res = await getExpertsList(data.queryParams)
+  if(res.code == 200){
+    data.expertList = res.data.list
+    data.total = res.data.total
+  }else{
+    ElMessage.warning(res.msg)
+  }
+  loading.value = false;
+}
+
+const openDialog = (type, value) => {
+  expertFormRef.value.openDialog(type, value)
+
+}
+
+const handleDelete = (val) => {
+    ElMessageBox.confirm(
+        '确定删除此条数据?',
+        '提示',
+        {
+            confirmButtonText: '确定',
+            cancelButtonText: '取消',
+            type: 'warning',
+        })
+        .then( async() => {
+            const res = await delExpert(val.id)
+            if(res.code == 200){
+              ElMessage.success('数据删除成功')
+              getList()
+            }else{
+              ElMessage.warning(res.message)
+            }
+        })
+}
+const resetQuery=()=> {
+  data.queryParams = {
+    pageNum: 1,
+    pageSize: 10,
+    bigClassify: null,
+    smallClassify: null,
+    dutyStatus: null,
+    params: {
+      startTime: '',
+      endTime: ''
+    }
+  };
+  data.classiFy = []
+  data.searchTime = []
+  handleQuery()
+}
+
+</script>
diff --git a/src/views/safetyReview/expertManage/experts/index.vue b/src/views/safetyReview/expertManage/experts/index.vue
new file mode 100644
index 0000000..ff3e984
--- /dev/null
+++ b/src/views/safetyReview/expertManage/experts/index.vue
@@ -0,0 +1,186 @@
+<template>
+    <div class="app-container">
+      <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+        <el-form-item label="专业类别">
+          <el-cascader
+              v-model="classiFy"
+              :options="expertTypes"
+              :props="{ expandTrigger: 'hover', value: 'id',label: 'classifyName'}"
+              @change="handleChange"></el-cascader>
+        </el-form-item>
+        <el-form-item label="在岗情况" prop="dutyStatus">
+          <el-select v-model="queryParams.dutyStatus" placeholder="岗位状态" clearable>
+            <el-option :key="0" label="在岗" :value="0"/>
+            <el-option :key="1" label="退休" :value="1"/>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="时间范围" prop="searchTime">
+          <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>
+          <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+          <el-button icon="Refresh" @click="resetQuery">重置</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-column label="姓名" align="center" prop="name" />
+        <el-table-column label="出生日期" align="center" prop="birthday" />
+        <el-table-column label="学历" align="center" prop="degree" />
+        <el-table-column label="职称" align="center" prop="title"/>
+        <el-table-column label="专业" align="center" prop="speciality" />
+        <el-table-column label="推荐类别组别" align="center">
+          <template #default="scope">
+            {{findNodeById(expertTypes,scope.row.bigClassify)}}/{{findNodeById(expertTypes,scope.row.smallClassify)}}
+          </template>
+        </el-table-column>
+        <el-table-column label="联系电话" align="center" prop="phone"/>
+        <el-table-column label="申请时间" align="center" prop="createTime">
+          <template #default="scope">
+            {{scope.row.createTime?scope.row.createTime.substring(0,10):''}}
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-button type="primary" link @click="openDialog('view',scope.row)">查看</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination
+          v-show="total > 0"
+          :total="total"
+          v-model:page="queryParams.pageNum"
+          v-model:limit="queryParams.pageSize"
+          @pagination="getList"
+      />
+      <expert-form ref="expertFormRef" @getList="getList"></expert-form>
+    </div>
+</template>
+
+<script setup>
+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 { Plus } from '@element-plus/icons-vue'
+
+const loading = ref(false);
+const data = reactive({
+  showSearch: true,
+  total: 0,
+  expertTypes: [],
+  expertList: [],
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    state: 2,
+    bigClassify: null,
+    smallClassify: null,
+    dutyStatus: null,
+    params: {
+      startTime: '',
+      endTime: ''
+    }
+  },
+  classiFy: [],
+  searchTime: []
+});
+
+const { showSearch,total, expertTypes,expertList,queryParams,classiFy,searchTime} = toRefs(data);
+const expertFormRef = ref()
+onMounted(()=>{
+  getList()
+  getTypes()
+})
+
+onUnmounted(()=>{
+
+})
+
+const getTypes = async()=> {
+  const res = await getExpertTypes()
+  if(res.code == 200){
+    data.expertTypes = res.data
+  }else{
+    ElMessage.warning(res.msg)
+  }
+}
+
+const handleChange=(value)=> {
+  console.log(value)
+}
+const changeTime=(value)=>{
+  console.log(value)
+}
+
+const findNodeById = (data,value)=> {
+  for (const node of data) {
+    if (node.id === value) {
+      return node.classifyName;
+    }
+    if (node.children) {
+      const foundNode = findNodeById(node.children, value);
+      if (foundNode) {
+        return foundNode;
+      }
+    }
+  }
+  return null;
+}
+
+const handleQuery=()=> {
+  data.queryParams.pageNum = 1
+  if(data.classiFy.length>0){
+    data.queryParams.bigClassify = data.classiFy[0]
+    data.queryParams.smallClassify = data.classiFy[1]
+  }
+  if(data.searchTime.length>0){
+    data.queryParams.params.startTime = data.searchTime[0]
+    data.queryParams.params.endTime = data.searchTime[1]
+  }
+  getList()
+}
+
+const getList = async () => {
+  loading.value = true;
+  const res = await getExpertsList(data.queryParams)
+  if(res.code == 200){
+    data.expertList = res.data.list
+    data.total = res.data.total
+  }else{
+    ElMessage.warning(res.msg)
+  }
+  loading.value = false;
+}
+
+const openDialog = (type, value) => {
+  expertFormRef.value.openDialog(type, value);
+}
+
+const resetQuery=()=> {
+  data.queryParams = {
+    pageNum: 1,
+    pageSize: 10,
+    state: 2,
+    bigClassify: null,
+    smallClassify: null,
+    dutyStatus: null,
+    params: {
+      startTime: '',
+      endTime: ''
+    }
+  };
+  data.classiFy = []
+  data.searchTime = []
+  handleQuery()
+}
+
+</script>
diff --git a/src/views/safetyReview/expertManage/fillForm/index.vue b/src/views/safetyReview/expertManage/fillForm/index.vue
new file mode 100644
index 0000000..2e08534
--- /dev/null
+++ b/src/views/safetyReview/expertManage/fillForm/index.vue
@@ -0,0 +1,622 @@
+<template>
+    <div class="form-container">
+          <div class="main-title" style="font-size: 24px;font-weight: bolder;text-align: center;margin: 40px 0">专家信息录入</div>
+          <div class="main_form">
+            <el-form :model="state.form" :rules="state.rules" ref="ruleFormRef" label-width="200px">
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="专业类别" prop="profession">
+                    <el-cascader
+                        style="width: 100%"
+                        v-model="state.form.profession"
+                        :options="state.expertsType"
+                        :props="{ expandTrigger: 'hover',value: 'id',label: 'classifyName' }"
+                        @change="professionChange"></el-cascader>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <!--        <el-row>-->
+              <!--          <el-col :span="20">-->
+              <!--            <el-form-item label="填报日期" prop="date">-->
+              <!--              <el-date-picker-->
+              <!--                style="width: 100%"-->
+              <!--                v-model="form.date"-->
+              <!--                type="date"-->
+              <!--                placeholder="选择日期">-->
+              <!--              </el-date-picker>-->
+              <!--            </el-form-item>-->
+              <!--          </el-col>-->
+              <!--        </el-row>-->
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="姓名" prop="name">
+                    <el-input v-model="state.form.name"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="性别" prop="sex">
+                    <el-radio-group v-model="state.form.sex">
+                      <el-radio :label="0">男</el-radio>
+                      <el-radio :label="1">女</el-radio>
+                    </el-radio-group>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="出生日期" prop="birthday">
+                    <el-date-picker
+                        style="width: 100%"
+                        v-model="state.form.birthday"
+                        value-format="YYYY-MM-DD 00:00:00"
+                        type="date"
+                        placeholder="选择日期">
+                    </el-date-picker>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="联系电话" prop="phone">
+                    <el-input v-model="state.form.phone"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="职称" prop="title">
+                    <!--              <el-select v-model="form.title" placeholder="请选择" style="width: 100%">-->
+                    <!--                <el-option-->
+                    <!--                  v-for="item in professionalList"-->
+                    <!--                  :key="item.value"-->
+                    <!--                  :label="item.label"-->
+                    <!--                  :value="item.value">-->
+                    <!--                </el-option>-->
+                    <!--              </el-select>-->
+                    <el-input v-model="state.form.title"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="证件照" prop="electronicPhoto">
+                    <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>
+                        <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传1张</div>
+                      </template>
+                    </el-upload>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="身份证号" prop="idCard">
+                    <el-input v-model="state.form.idCard"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="在岗情况" prop="dutyStatus">
+                    <el-radio-group v-model="state.form.dutyStatus">
+                      <el-radio :label="0">在岗</el-radio>
+                      <el-radio :label="1">退休</el-radio>
+                    </el-radio-group>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="单位全称" prop="companyName">
+                    <el-input v-model="state.form.companyName"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="单位地址">
+                    <el-input v-model="state.form.companyAddress"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="所在部门">
+                    <el-input v-model="state.form.deptName"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="职务">
+                    <el-input v-model="state.form.job"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="单位电话">
+                    <el-input v-model="state.form.companyTelephone"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="传真号码">
+                    <el-input v-model="state.form.faxNum"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="电子邮箱">
+                    <el-input v-model="state.form.email"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="毕业学校">
+                    <el-input v-model="state.form.graduationSchool"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="最高学历" prop="degree">
+                    <el-input v-model="state.form.degree"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="所学专业">
+                    <el-input v-model="state.form.speciality"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="现从事的专业及方向">
+                    <el-input v-model="state.form.currentProfession"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="支撑方向_安全生产" prop="supportDirectionSafety">
+                    <!--              <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>-->
+                    <el-checkbox-group v-model="state.form.supportDirectionSafety">
+                      <el-checkbox v-for="item in state.directionList" :label="item.value" :key="item.value">{{ item.label }}</el-checkbox>
+                    </el-checkbox-group>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="支撑方向_防灾减灾救灾" prop="supportDirectionPrevention">
+                    <!--              <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>-->
+                    <el-checkbox-group v-model="state.form.supportDirectionPrevention">
+                      <el-checkbox v-for="item in state.directionList" :label="item.value" :key="item.value">{{ item.label }}</el-checkbox>
+                    </el-checkbox-group>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row>
+                <el-col :span="20">
+                  <el-form-item label="支撑方向_应急救援" prop="supportDirectionEmergency">
+                    <!--              <el-radio-group v-model="form.supportDirectionEmergency">-->
+                    <!--                <el-radio v-for="item in directionList" :label="item.value" :key="item.value">{{ item.label }}</el-radio>-->
+                    <!--              </el-radio-group>-->
+                    <el-checkbox-group v-model="state.form.supportDirectionEmergency">
+                      <el-checkbox v-for="item in state.directionList" :label="item.value" :key="item.value">{{ item.label }}</el-checkbox>
+                    </el-checkbox-group>
+                  </el-form-item>
+                </el-col>
+              </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>
+                      <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="发明、著作、学术论文情况(何时、何地出版或发表)">
+                    <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.inventionList" 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="受过何种奖励">
+                    <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.rewardList" 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="应急管理相关工作主要业绩及研究成果">
+                    <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.achievementList" 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="专家本人意见">
+                    <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-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="推荐单位意见">
+                    <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-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="补充说明">
+                    <el-input v-model="state.form.remark" type="textarea" :autosize="{ minRows: 2}"></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+            </el-form>
+            <el-dialog v-model="imgDialog">
+              <img w-full :src="state.dialogImageUrl" alt="">
+            </el-dialog>
+          </div>
+      <div style="width: 100%;display: flex;justify-content: center;margin: 20px 0">
+        <el-button type="primary" @click="onSubmit(ruleFormRef)" size="large" v-preReClick style="width: 40%">确认</el-button>
+      </div>
+    </div>
+</template>
+<script setup>
+import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue'
+import {ElMessage, ElMessageBox} from "element-plus"
+import {verifyPhone, verifyIdCard} from "../../../../utils/validate"
+import {addExpertInfo, getExpertTypes, uploadFile} from "@/api/form"
+import {delPic} from "@/api/login"
+import { getToken } from "@/utils/auth"
+import {Base64} from "js-base64"
+
+const imgDialog = ref(false)
+const ruleFormRef = ref()
+var validatePass = (rule, value, callback) => {
+  if (state.fileList.length == 0) {
+    callback(new Error('请上传证件照'));
+  } else {
+    callback();
+  }
+}
+let validatePhone = (rule, value, callback)=>{
+  if(value === ''){
+    callback(new Error('请输入手机号'))
+  }else{
+    if(!verifyPhone(value)){
+      callback(new Error('手机号格式有误'))
+    }else{
+      callback()
+    }
+  }
+}
+let verifyId = (rule, value, callback)=>{
+  if(value === ''){
+    callback(new Error('请输入身份证号'))
+  }else{
+    if(!verifyIdCard(value)){
+      callback(new Error('身份证号格式有误'))
+    }else{
+      callback()
+    }
+  }
+}
+
+const state = reactive({
+  form:{
+    name:'',
+    sex:'',
+    profession: [],
+    bigClassify:null,
+    smallClassify: null,
+    birthday: '',
+    phone:'',
+    title: '',
+    electronicPhoto: '',
+    idCard: '',
+    dutyStatus: null,
+    companyName: '',
+    companyAddress: '',
+    deptName: '',
+    job: '',
+    companyTelephone: '',
+    faxNum: '',
+    email: '',
+    graduationSchool: '',
+    degree: '',
+    speciality: '',
+    currentProfession: '',
+    supportDirectionSafety: [],
+    supportDirectionPrevention: [],
+    supportDirectionEmergency: [],
+    resumeKey: '',
+    paperSituationKey: '',
+    rewardKey: '',
+    achievementKey: '',
+    personalOpinionKey: '',
+    recommendUnitOpinionKey: '',
+    remark: '',
+    source: 1
+  },
+  expertsType: [],
+  directionList: [
+    {
+      value: 1,
+      label: '现场检查'
+    },
+    {
+      value: 2,
+      label: '调查评估'
+    },
+    {
+      value: 3,
+      label: '咨询服务'
+    },
+    {
+      value: 4,
+      label: '教育培训'
+    },
+    {
+      value: 5,
+      label: '其他'
+    }
+  ],
+  uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile',
+  header: {
+    Authorization: 'Bearer ' + getToken()
+  },
+  fileList: [],
+  resumeList: [],
+  inventionList: [],
+  rewardList: [],
+  achievementList: [],
+  proAdviceList: [],
+  adviceList: [],
+  dialogImageUrl: '',
+  rules:{
+    name:[{ required: true, message: '请填写姓名', trigger: 'blur' }],
+    sex:[{ required: true, message: '请选择性别', trigger: 'blur' }],
+    profession: [{ required: true, message: '请选择专业类别', trigger: 'blur' }],
+    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' }],
+    idCard: [{ required: true, validator: verifyId, trigger: 'blur' }],
+    dutyStatus: [{ required: true, message: '请选择在岗情况', trigger: 'blur' }],
+    companyName: [{ required: true, message: '请填写单位全称', trigger: 'blur' }],
+    degree: [{ required: true, message: '请填写最高学历', trigger: 'blur' }]
+  }
+})
+
+  onMounted(()=>{
+    getExpertsType()
+  })
+
+  const getExpertsType = async ()=>{
+    const res = await getExpertTypes()
+    if(res.code == 200){
+      state.expertsType = res.data
+    }else{
+      ElMessage({
+        type: 'warning',
+        message: res.message
+      });
+    }
+  }
+
+  const professionChange=(value)=> {
+    console.log(value,'val')
+  }
+
+
+
+  // 图片上传
+  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
+    imgDialog.value = true;
+  }
+
+  const handleAvatarSuccess = (res, uploadFile,type) => {
+    if(res.code == 200){
+      if(type == '证件照'){
+        state.form.electronicPhoto = res.data.path
+      }else{
+        uploadFile.name = res.data.path
+      }
+    }else{
+      ElMessage({
+        type: 'warning',
+        message: '文件上传失败'
+      })
+    }
+  }
+
+  const handleRemove = (file, uploadFiles,type) => {
+    ElMessageBox.confirm(
+        '该操作将永久删除此文件内容,是否继续?',
+        '提示',
+        {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning',
+        })
+        .then(async() => {
+          let path = ''
+          if(type == '证件照'){
+            path = state.form.electronicPhoto
+          }else{
+            path = file.name
+          }
+          const res = await delPic({path: path})
+          if(res.code == 200){
+            ElMessage({
+              type: 'success',
+              message: '文件已删除'
+            })
+          }else{
+            ElMessage({
+              type: 'warning',
+              message: res.message
+            })
+          }
+        })
+  }
+
+const onSubmit = async (formEl)=> {
+  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.bigClassify = data.profession[0]
+      data.smallClassify = data.profession[1]
+      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(',')
+      data.achievementKey = state.achievementList.map(i=>i.name).join(',')
+      data.personalOpinionKey = state.proAdviceList.map(i=>i.name).join(',')
+      data.recommendUnitOpinionKey = state.adviceList.map(i=>i.name).join(',')
+      delete data.profession
+      delete data.id
+      const res= await addExpertInfo(data)
+      if(res.code == 200){
+        ElMessage.success(res.message)
+        state.form = {
+          name:'',
+          sex:'',
+          profession: [],
+          bigClassify:null,
+          smallClassify: null,
+          birthday: '',
+          phone:'',
+          title: '',
+          electronicPhoto: '',
+          idCard: '',
+          dutyStatus: null,
+          companyName: '',
+          companyAddress: '',
+          deptName: '',
+          job: '',
+          companyTelephone: '',
+          faxNum: '',
+          email: '',
+          graduationSchool: '',
+          degree: '',
+          speciality: '',
+          currentProfession: '',
+          supportDirectionSafety: [],
+          supportDirectionPrevention: [],
+          supportDirectionEmergency: [],
+          resumeKey: '',
+          paperSituationKey: '',
+          rewardKey: '',
+          achievementKey: '',
+          personalOpinionKey: '',
+          recommendUnitOpinionKey: '',
+          remark: '',
+          source: 1
+        }
+        state.fileList = []
+        state.resumeList = []
+        state.inventionList = []
+        state.rewardList = []
+        state.achievementList = []
+        state.proAdviceList = []
+        state.adviceList = []
+      }else{
+        ElMessage.warning(res.message)
+      }
+    } else {
+      ElMessage.warning('请完善必填信息')
+    }
+  })
+}
+
+</script>
+
+<style scoped lang="scss">
+.form-container{
+    padding: 20px;
+
+    :deep(.el-form .el-form-item__label) {
+        font-size: 15px;
+    }
+    .file {
+        display: flex;
+        flex-direction: column;
+        align-items: flex-start;
+    }
+}
+</style>

--
Gitblit v1.9.2