马宇豪
2023-07-13 01f3e49f3763a25ef67a4c3e5786491703a1aece
特殊作业对接修改
29 files modified
11 files added
5616 ■■■■ changed files
src/api/specialWorkSystem/specialIndex/index.ts 9 ●●●● patch | view | raw | blame | history
src/api/specialWorkSystem/workApply/index.ts 81 ●●●●● patch | view | raw | blame | history
src/api/specialWorkSystem/workProcess/index.ts 8 ●●●● patch | view | raw | blame | history
src/api/specialWorkSystem/workerManage/index.ts 32 ●●●●● patch | view | raw | blame | history
src/api/systemManage/user/index.ts 46 ●●●●● patch | view | raw | blame | history
src/router/route.ts 40 ●●●●● patch | view | raw | blame | history
src/views/doublePrevent/riskCheckManage/hiddenManagement/hiddenReport/index.vue 2 ●●● patch | view | raw | blame | history
src/views/newHome/index.vue 1 ●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workTicket/sbtj/index.vue 401 ●●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workTicket/sqjl/index.vue 111 ●●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workTicket/wdsq/components/jsaReportDialog.vue 379 ●●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workTicket/wdsq/index.vue 554 ●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workTicket/zysq/components/broken.vue 172 ●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workTicket/zysq/components/fire.vue 101 ●●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workTicket/zysq/components/ground.vue 144 ●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workTicket/zysq/components/height.vue 100 ●●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workTicket/zysq/components/hoist.vue 100 ●●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workTicket/zysq/components/plate.vue 159 ●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workTicket/zysq/components/power.vue 101 ●●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workTicket/zysq/components/space.vue 97 ●●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workTicket/zysq/components/workSelect.vue 184 ●●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workTicket/zysq/index.vue 65 ●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workerManage/aqyBase/index.vue 339 ●●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workerManage/component/userDialog.vue 279 ●●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workerManage/guardianBase/index.vue 339 ●●●●● patch | view | raw | blame | history
src/views/newSpecialWorkSystem/workerManage/operatorBase/index.vue 339 ●●●●● patch | view | raw | blame | history
src/views/specialWorkSystem/alarm/zyyjjl/index.vue 22 ●●●● patch | view | raw | blame | history
src/views/specialWorkSystem/process/components/dialogPermitNo.vue 9 ●●●●● patch | view | raw | blame | history
src/views/specialWorkSystem/process/zyjcgl/index.vue 130 ●●●● patch | view | raw | blame | history
src/views/specialWorkSystem/specialIndex/components/videoDetail.vue 194 ●●●●● patch | view | raw | blame | history
src/views/specialWorkSystem/specialIndex/components/workRecord.vue 161 ●●●●● patch | view | raw | blame | history
src/views/specialWorkSystem/specialIndex/index.vue 337 ●●●● patch | view | raw | blame | history
src/views/specialWorkSystem/workTicket/zysq/components/broken.vue 2 ●●● patch | view | raw | blame | history
src/views/specialWorkSystem/workTicket/zysq/components/ground.vue 2 ●●● patch | view | raw | blame | history
src/views/specialWorkSystem/workTicket/zysq/components/plate.vue 2 ●●● patch | view | raw | blame | history
src/views/system/appVersion/index.vue 4 ●●●● patch | view | raw | blame | history
src/views/system/user/component/ctfDialog.vue 355 ●●●●● patch | view | raw | blame | history
src/views/system/user/component/dialogCertificate.vue 198 ●●●●● patch | view | raw | blame | history
src/views/system/user/component/userDialog.vue 3 ●●●● patch | view | raw | blame | history
src/views/system/user/index.vue 14 ●●●● patch | view | raw | blame | history
src/api/specialWorkSystem/specialIndex/index.ts
@@ -24,7 +24,14 @@
        },
        getMydepList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/page/my-dep/list`,
                url: import.meta.env.VITE_API_URL + `/specialwork9step/working/page/my-dep/list`,
                method: 'post',
                data: data
            });
        },
        getWorkRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialwork9step/work/log`,
                method: 'post',
                data: data
            });
src/api/specialWorkSystem/workApply/index.ts
@@ -29,6 +29,42 @@
            });
        },
        // 上传研判报告
        uploadJsaReport: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialwork9step/work/apply/risk/assessment`,
                method: 'post',
                data: data
            });
        },
        // 查看研判报告
        viewJsaReport: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialwork9step/work/risk/assessment/record`,
                method: 'post',
                data: data
            });
        },
        // 新正式办票
        checkTicket: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialwork9step/work/apply/ticket/processing`,
                method: 'post',
                data: data
            });
        },
        // 新作废办票
        abolishTicket: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialwork9step/work/apply/abolish`,
                method: 'post',
                data: data
            });
        },
        // 获取基础数据
        getFormData: (type: number) => {
            return request({
@@ -213,6 +249,24 @@
            });
        },
        // 获取八种作业
        getOtherWork: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialwork9step/work/involve/other/work/list`,
                method: 'post',
                data: data
            });
        },
        // 查看作业票
        viewTicket: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialwork9step/work/view`,
                method: 'post',
                data: data
            });
        },
        // 查询进度
        getStatus: (data: object) => {
            return request({
@@ -226,6 +280,15 @@
        getAllStatus: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/others/view`,
                method: 'post',
                data: data
            });
        },
        // 作业验收
        acceptWork: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialwork9step/working/accept`,
                method: 'post',
                data: data
            });
@@ -286,6 +349,22 @@
                method: 'post',
                data: data
            });
        }
        },
        // 申报统计饼图
        getSbtjPie: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialwork9step/statistic/workType`,
                method: 'post',
                data: data
            });
        },
        // 申报统计饼图
        getSbtjTable: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialwork9step/statistic/dep`,
                method: 'post',
                data: data
            });
        },
    };
}
src/api/specialWorkSystem/workProcess/index.ts
@@ -14,7 +14,7 @@
        // 分页获取检查列表
        getCheckListPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/process/check/page/list`,
                url: import.meta.env.VITE_API_URL + `/specialwork9step/process/check/page/list`,
                method: 'post',
                data: data
            });
@@ -32,7 +32,7 @@
        // 检查上报
        postCheckReport: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/process/check/report`,
                url: import.meta.env.VITE_API_URL + `/specialwork9step/process/check/report`,
                method: 'post',
                data: data
            });
@@ -41,7 +41,7 @@
        // 获取可上报作业列表
        postReportList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/process/workApply/list`,
                url: import.meta.env.VITE_API_URL + `/specialwork9step/process/workApply/list`,
                method: 'post',
                data: data
            });
@@ -50,7 +50,7 @@
        // 获取预警记录
        postAlertList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/process/warning/page/list`,
                url: import.meta.env.VITE_API_URL + `/specialwork9step/process/warning/page/list`,
                method: 'post',
                data: data
            });
src/api/specialWorkSystem/workerManage/index.ts
New file
@@ -0,0 +1,32 @@
import request from '/@/utils/request';
export function workerManageApi() {
    return {
        // 分页获取作业人列表
        getOperatorListPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/operator/page/list`,
                method: 'post',
                data: data
            });
        },
        // 分页获取安全员列表
        getHeaderListPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/header/page/list`,
                method: 'post',
                data: data
            });
        },
        // 分页获取监护人列表
        getGuardianListPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/guardian/page/list`,
                method: 'post',
                data: data
            });
        },
    };
}
src/api/systemManage/user/index.ts
@@ -41,11 +41,55 @@
                method: 'get'
            });
        },
        getAllUser: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/list`,
                method: 'get'
            });
        }
        },
        // 获取图片上传路径
        getPresignUrl: (name: string) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/file/getPresignUrl`,
                method: 'post',
                data: { prefixName: name.split('.')[0], suffixName: name.split('.')[1] }
            });
        },
        // 根据uid获取用户证书
        getCtf: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/cert/list`,
                method: 'post',
                data: data
            });
        },
        addCtf: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/cert/add`,
                method: 'post',
                data: data
            });
        },
        // v1
        modCtf: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/cert/update`,
                method: 'post',
                data: data
            });
        },
        delCtf: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/cert/delete`,
                method: 'post',
                data: data
            });
        },
    };
}
src/router/route.ts
@@ -111,45 +111,5 @@
        meta: {
            title: '安全物资与设备'
        }
    },
    {
        path: '/dhzy',
        name: 'dhzy',
        component: () => import('/@/views/newSpecialWorkSystem/workTicket/zysq/index.vue'),
        meta: {
            title: '作业申请'
        }
    },
    {
        path: '/wdsq1',
        name: 'wdsq1',
        component: () => import('/@/views/newSpecialWorkSystem/workTicket/wdsq/index.vue'),
        meta: {
            title: '我的申请'
        }
    },
    {
        path: '/sqjl1',
        name: 'sqjl1',
        component: () => import('/@/views/newSpecialWorkSystem/workTicket/sqjl/index.vue'),
        meta: {
            title: '申请记录'
        }
    },
    {
        path: '/sbtj',
        name: 'sbtj',
        component: () => import('/@/views/newSpecialWorkSystem/workTicket/sbtj/index.vue'),
        meta: {
            title: '申报统计'
        }
    },
    {
        path: '/aqy',
        name: 'aqy',
        component: () => import('/@/views/newSpecialWorkSystem/workerManage/aqyBase/index.vue'),
        meta: {
            title: '安全员管理'
        }
    }
];
src/views/doublePrevent/riskCheckManage/hiddenManagement/hiddenReport/index.vue
@@ -261,7 +261,7 @@
        };
        // 删除
        const onDelProductionDevice = (row: any) => {
            ElMessageBox.confirm(`此操作将永久该条隐患,是否继续?`, '提示', {
            ElMessageBox.confirm(`此操作将永久删除该条隐患,是否继续?`, '提示', {
                confirmButtonText: '确认',
                cancelButtonText: '取消',
                type: 'warning'
src/views/newHome/index.vue
@@ -383,6 +383,7 @@
        //调用菜单方法
        const renderMenu = throttle(() => {
          // debugger
            renderFun();
        }, 2000);
src/views/newSpecialWorkSystem/workTicket/sbtj/index.vue
New file
@@ -0,0 +1,401 @@
<template>
    <div class="home-container">
      <div style="height: 100%">
          <div class="homeCard">
            <div class="topChart">
              <div class="chart-item">
                <div class="chart-tit">
                  <span class="tit">申报特殊作业类别分布图</span>
                </div>
                <div class="chart" :id="zyfb"></div>
                <div style="width: 100%;text-align: center">
                  <el-radio-group v-model="days1" @change="(value)=>changeTime1(value)">
                    <el-radio-button v-for="item in timeList" :label='item.value' border>{{item.label}}</el-radio-button>
                  </el-radio-group>
                </div>
              </div>
            </div>
            <div class="topChart">
              <div class="chart-item">
                <div class="chart-tit">
                  <span class="tit">各事业部申报特殊作业情况</span>
                  <div class="filter-part">
                    <el-select v-model="days2" size="large" :teleported="false" @change="changeTime2()">
                      <el-option
                          v-for="item in timeList"
                          :key="item.value"
                          :label="item.label"
                          :value="item.value"
                      />
                    </el-select>
                  </div>
                </div>
                <el-table :data="tableData" style="width: 100%" :header-cell-style="{ background: '#fafafa' }">
                  <el-table-column property="seDepName" label="事业部" align="center"/>
                  <el-table-column property="totalCount" label="总数" align="center"/>
                  <el-table-column v-for="workType in workTypes" :key="workType.workType" :label="workType.workTypeDesc" :prop="`list.${workType.workType - 1}.count`"></el-table-column>
                </el-table>
              </div>
            </div>
          </div>
      </div>
    </div>
</template>
<script lang="ts">
import {toRefs, reactive, defineComponent, ref, onMounted, defineAsyncComponent} from 'vue';
import { storeToRefs } from 'pinia';
import { initBackEndControlRoutes } from '/@/router/backEnd';
import { useUserInfo } from '/@/stores/userInfo';
import { Session } from '/@/utils/storage';
import { useRouter } from 'vue-router';
import * as echarts from "echarts";
import {specialIndexApi} from "/@/api/specialWorkSystem/specialIndex";
import {ElMessage} from "element-plus/es";
import {workApplyApi} from "/@/api/specialWorkSystem/workApply";
// 定义接口来定义对象的类型
interface stateType {
  startTime1: string
  startTime2: string
  endTime: string
  tableData: Array<any>
  days1: number
  days2: number
  timeList: Array<timeType>
  workTypes: Array<any>
}
interface timeType{
  label: string,
  value: number
}
export default defineComponent({
    name: 'sbtj',
    components: {
    },
    setup() {
        const userInfo = useUserInfo();
        const { userInfos } = storeToRefs(userInfo);
        const router = useRouter();
        const zyfb = ref("eChartZyfb" + Date.now() + Math.random())
        const state = reactive<stateType>({
          startTime1: '',
          startTime2: '',
          days1: 30,
          days2: 30,
          endTime: '',
          tableData: [],
          timeList:[
            {
              label: '昨日',
              value: 1
            },
            {
              label: '近七天',
              value: 7
            },
            {
              label: '近30天',
              value: 30
            },
            {
              label: '近180天',
              value: 180
            }
          ],
          workTypes: [ // 定义工作类型的列表
            { workType: 1, workTypeDesc: '动火作业' },
            { workType: 2, workTypeDesc: '受限空间作业' },
            { workType: 3, workTypeDesc: '吊装作业' },
            { workType: 4, workTypeDesc: '动土作业' },
            { workType: 5, workTypeDesc: '断路作业' },
            { workType: 6, workTypeDesc: '高处作业' },
            { workType: 7, workTypeDesc: '临时用电作业' },
            { workType: 8, workTypeDesc: '盲板抽堵作业' },
          ],
        });
        // 折线图
        const renderMenu = async (value: string) => {
            Session.set('projectId', value);
            userInfos.value.projectId = value;
            await initBackEndControlRoutes();
        };
        // 页面载入时执行方法
        onMounted(() => {
          initTime()
          getTypePie()
          getTableData()
        });
      const getTypePie = async ()=>{
        const data = {
          startTime: state.startTime1,
          endTime:state.endTime
        }
        let res = await workApplyApi().getSbtjPie(data);
        if (res.data.code === '200') {
          if(res.data.data && res.data.data.length>0){
            const pieData = res.data.data.map(({workTypeDesc,count})=>({ name: workTypeDesc,value: count}))
            initZyfb(pieData)
          }
          else{
            initZyfb([])
          }
        } else {
          ElMessage({
            type: 'warning',
            message: res.data.msg
          });
        }
      }
      const getTableData = async ()=>{
        const data = {
          startTime: state.startTime2,
          endTime:state.endTime
        }
        let res = await workApplyApi().getSbtjTable(data);
        if (res.data.code === '200') {
          state.tableData = res.data.data
        } else {
          ElMessage({
            type: 'warning',
            message: res.data.msg
          });
        }
      }
      const initTime =()=>{
        state.startTime1 = getPeriod(30)
        state.startTime2 = getPeriod(30)
        state.endTime = formatDate(new Date())
      }
      const getPeriod =(num)=> {
        const currentDate = new Date();
        const startTime = new Date();
        startTime.setDate(currentDate.getDate() - num);
        return formatDate(startTime)
      }
      const formatDate =(date)=> {
        const year = date.getFullYear().toString();
        const month = ('0' + (date.getMonth() + 1)).slice(-2);
        const day = ('0' + date.getDate()).slice(-2);
        return `${year}-${month}-${day} 00:00:00`;
      }
      const changeTime1=(value:number)=>{
        state.startTime1 = getPeriod(value)
        getTypePie()
      }
      const changeTime2=()=>{
        state.startTime2 = getPeriod(state.days2)
        getTableData()
      }
      type EChartsOption = echarts.EChartsOption
      const initZyfb =(data:Array<any>)=>{
        let dom = document.getElementById(zyfb.value);
        let myChart = echarts.init(dom);
        let option: EChartsOption;
        option = {
          tooltip: {
            trigger: 'item'
          },
          legend: {
            orient: 'horizontal',
            itemStyle: {
              borderWidth: 0 // 设置图例边框宽度为0
            }
          },
          series: [
            {
              name: '作业分布',
              type: 'pie',
              radius: ['40%', '70%'],
              center: ['50%', '52%'],
              avoidLabelOverlap: false,
              itemStyle: {
                borderRadius: 1,
                borderColor: '#fff',
                borderWidth: 1
              },
              label: {
                show: true,
                position: 'outside',
                overflow: 'truncate',
                borderWidth: 0,
              },
              labelLine: {
                show: true,    // 显示指示线
                lineStyle: {
                  color: '#ccc',
                  width: 1,
                  type: 'solid'
                }
              },
              emphasis: {
                itemStyle: {
                  shadowBlur: 10,
                  shadowOffsetX: 0,
                  shadowColor: 'rgba(0, 0, 0, 0.5)'
                },
              },
              data: data
            }
          ]
        }
        option && myChart.setOption(option);
        window.addEventListener("resize",function (){
          myChart.resize();
        });
      }
        return {
            zyfb,
          changeTime1,
          changeTime2,
            ...toRefs(state)
        };
    }
});
</script>
<style scoped lang="scss">
$homeNavLengh: 8;
.home-container {
    height: calc(100vh - 144px);
    box-sizing: border-box;
    overflow: hidden;
    .homeCard {
        width: 100%;
        padding: 20px;
        box-sizing: border-box;
        border-radius: 4px;
      .topChart{
        width: 100%;
        height: calc(50vh - 102px);
        display: flex;
        justify-content: space-between;
        align-items: flex-start;
        margin-bottom: 20px;
        &:last-of-type{
          margin-bottom: 0;
        }
        .chart-item{
          width: 100%;
          height: 100%;
          position: relative;
          background: #fff;
          padding: 20px;
          .chart-tit{
            width: 100%;
            display: flex;
            align-items: flex-start;
            justify-content: space-between;
            margin-bottom: 20px;
            .tit{
              font-size: 1.33rem;
              font-weight: bolder;
              white-space: nowrap;
            }
            .filter-part{
              display: flex;
              align-items: center;
              justify-content: right;
              :deep(.el-cascader){
                width: 35% !important;
              }
              .el-select{
                width: 100% !important;
              }
              .el-switch{
                width: 25% !important;
                :deep(.el-switch__core){
                  width: 100% !important;
                }
              }
            }
            .filter-part2{
              :deep(.el-cascader){
                width: 100% !important;
              }
            }
          }
          .chart{
            width: 100%;
            height: 80%;
            .el-table{
              height: 90% !important;
              :deep(.el-table__inner-wrapper){
                height: 100% !important;
                .el-table__header-wrapper {
                  height: 20% !important;
                  .el-table__header{
                    height: 100% !important;
                    th{
                      height: 100% !important;
                      padding: 0 0 !important;
                      .cell{
                        white-space: nowrap;
                        overflow: hidden;
                        text-overflow: ellipsis;
                      }
                    }
                  }
                }
                .el-table__body-wrapper {
                  height: 80% !important;
                  .el-scrollbar__view{
                    height: 100% !important;
                    .el-table__body{
                      height: 100% !important;
                      tbody{
                        height: 100% !important;
                        .el-table__row{
                          height: 25% !important;
                          td{
                            height: 25% !important;
                            padding: 0 0 !important;
                            .left-info{
                              display: flex;
                              align-items: center;
                            }
                            .cell{
                              white-space: nowrap;
                              overflow: hidden;
                              text-overflow: ellipsis;
                            }
                            .el-button{
                              padding: 0 !important;
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
          :deep(.active-ring-info){
            .active-ring-name{
              font-size: 1.5rem !important;
              text-align: center;
            }
          }
        }
      }
    }
}
</style>
src/views/newSpecialWorkSystem/workTicket/sqjl/index.vue
@@ -4,28 +4,46 @@
<!--            <el-tab-pane label="申请中" name="1">-->
                <div style="height: 100%">
                    <el-row class="homeCard">
                     <div class="basic-line" style="display:flex;white-space:nowrap;line-height: 40px">
                        <span>时间筛选:</span>
                        <el-date-picker v-model="timeRange" value-format="YYYY-MM-DD HH:mm:ss" type="datetimerange" @change="giveTime()" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" />
                      </div>
                      <div class="basic-line" style="display:flex;white-space:nowrap;line-height: 40px">
                        <span>负责人:</span>
                        <el-input v-model="searPara.headUserName" placeholder="负责人"/>
                      </div>
                      <div class="basic-line">
                        <span>事业部:</span>
                        <el-select v-model="searPara.secondDepId">
                          <el-option
                              v-for="item in dep4List"
                              :key="item.id"
                              :label="item.name"
                              :value="item.id"
                          />
                        </el-select>
                      </div>
                      <div class="basic-line">
                        <span>作业类型:</span>
                        <el-col :span="10">
                            <div class="grid-content topInfo">
                                <el-select v-model="searchWord">
                                    <el-option
                                            v-for="item in workType"
                                            :key="item.id"
                                            :label="item.name"
                                            :value="item.id"
                                    />
                                </el-select>
                                <el-button type="primary" @click="searchRecord">查询</el-button>
                                <el-button plain @click="clearSearch">重置</el-button>
                            </div>
                        </el-col>
                        <el-select v-model="searPara.workType">
                          <el-option
                              v-for="item in workType"
                              :key="item.id"
                              :label="item.name"
                              :value="item.id"
                          />
                        </el-select>
                      </div>
                      <div style="margin-left: 20px">
                        <el-button type="primary" @click="searchRecord">查询</el-button>
                        <el-button plain @click="clearSearch">重置</el-button>
                      </div>
                    </el-row>
                    <div class="homeCard">
                        <div class="main-card">
                            <el-row class="cardTop">
                                <el-col :span="12" class="mainCardBtn">
                                    <el-button type="primary" :icon="Plus" size="default" @click="toApply()">申请</el-button>
                                    <el-button type="primary" :icon="Plus" size="default" @click="toApply()">新增申报</el-button>
                                    <!--                                    <el-button type="danger" :icon="Delete" size="default">删除</el-button>-->
                                    <!--                                    <el-button type="success" size="default">设置分类</el-button>-->
                                </el-col>
@@ -76,10 +94,10 @@
                                </el-table-column>
                                <el-table-column fixed="right" label="操作" align="center" width="300">
                                    <template #default="scope">
                                        <el-button link type="danger" size="small" :icon="Delete" @click="deleteRecordBtn(scope.row)">作废</el-button>
<!--                                        <el-button link type="danger" size="small" :icon="Delete" @click="deleteRecordBtn(scope.row)">作废</el-button>-->
                                        <el-button link type="primary" size="small" :icon="View" @click="viewRecord(scope.row)">查看</el-button>
                                        <el-button link type="success" size="small" :icon="Finished">修改</el-button>
                                        <el-button link type="success" size="small" :icon="Download">正式办票</el-button>
<!--                                        <el-button link type="success" size="small" :icon="Finished">修改</el-button>-->
<!--                                        <el-button link type="success" size="small" :icon="Download">正式办票</el-button>-->
<!--                                        <el-button :disabled="scope.row.status == 7 ? false : true" link type="primary" size="small" :icon="Download" @click="downLoadBtn(scope.row)">导出作业票</el-button>-->
                                    </template>
                                </el-table-column>
@@ -265,7 +283,6 @@
    deleteId: null | number;
    downLoadId: null | number;
    downLoadName: string;
    searchWord: string;
    totalSize1: number;
    activeName: string;
    addRecord: {};
@@ -276,6 +293,9 @@
    departmentList: Array<any>;
    departmentRecursionList: Array<DepartmentState>;
    statusList: Array<any>;
    dep4List: Array<type>;
    searPara: {}
    timeRange: Array<string>;
}
interface type {
    id: number;
@@ -303,7 +323,13 @@
            departmentList: [],
            departmentRecursionList: [],
            chosenIndex: null,
            searchWord: '',
            searPara:{
              startTime: '',
              endTime: '',
              workType: null,
              headUserName: '',
              secondDepId: null
            },
            applyData: [],
            workTimeList: [],
            multipleSelection: [],
@@ -322,6 +348,12 @@
            downLoadId: null,
            downLoadName: '',
            deleteArr: [],
            dep4List: [
              {id:49,name:'电石事业部'},
              {id:50,name:'电力事业部'},
              {id:48,name:'有机化工事业部'},
              {id:32,name:'甲醇事业部'}
            ],
            workType: [
                { id: 1, name: '动火作业' },
                { id: 2, name: '受限空间作业' },
@@ -377,13 +409,19 @@
              value: 9,
              label: '安全措施确认,培训交底中'
            }
          ]
          ],
          timeRange: []
        });
        interface User {
            name: string;
            list: [];
            info: string;
      const giveTime = () => {
        if (state.timeRange && state.timeRange !== null) {
          state.searPara.startTime = state.timeRange[0];
          state.searPara.endTime = state.timeRange[1];
        } else {
          state.searPara.startTime = '';
          state.searPara.endTime = '';
        }
      };
        // 刷新
        const reLoadData = async () => {
@@ -427,7 +465,7 @@
        // 分页获取
        const getListByPage = async () => {
            const data = { pageSize: state.pageSize1, pageIndex: state.pageIndex1, searchParams: { workType: state.searchWord } };
            const data = { pageSize: state.pageSize1, pageIndex: state.pageIndex1, searchParams: state.searPara };
            let res = await workApplyApi().getAllNewApplyListPage(data);
            if (res.data.code === '200') {
                state.applyData = JSON.parse(JSON.stringify(res.data.data));
@@ -467,18 +505,18 @@
        // 关键词查询记录
        const searchRecord = async () => {
            if (state.searchWord == '') {
                ElMessage({
                    type: 'warning',
                    message: '请输入查询关键词'
                });
            } else {
                getListByPage();
            }
            getListByPage();
        };
        // 重置搜索
        const clearSearch = async () => {
            state.searchWord = '';
            state.timeRange = []
            state.searPara = {
              startTime: '',
              endTime: '',
              workType: null,
              headUserName: '',
              secondDepId: null
            };
            getListByPage();
        };
@@ -601,6 +639,7 @@
            Plus,
            Finished,
            Download,
            giveTime,
            reLoadData,
            toApply,
            handleClick,
src/views/newSpecialWorkSystem/workTicket/wdsq/components/jsaReportDialog.vue
New file
@@ -0,0 +1,379 @@
<template>
    <div class="system-add-menu-container">
        <el-dialog v-model="ifShowApproveRuleDialog" :title="title" :close-on-click-modal="false" @close="clearFile()">
            <el-form v-if="disabled" :model="jsaForm" label-width="170px" ref="jsaFormRef" :rules="jsaFormRules">
                <el-row :gutter="20">
                    <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
                      <el-form-item label="jsa风险研判结论" prop="judgeRecord">
                        <el-input
                            v-model="jsaForm.judgeRecord"
                            :autosize="{ minRows: 3 }"
                            type="textarea"
                            placeholder="请输入jsa风险研判结论"
                        />
                      </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
                      <el-form-item label="风险研判报告记录附件" prop="judgePicturePath">
                        <el-upload accept="image/*" :auto-upload="true" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='imgLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" list-type="picture-card" :before-remove="beforeRemove" :before-upload="getUploadUrl">
                          <el-icon><Plus /></el-icon>
                          <template #tip>
                            <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传3张</div>
                          </template>
                        </el-upload>
                      </el-form-item>
                    </el-col>
                </el-row>
            </el-form>
            <template #footer>
                <div v-show="disabled" class="dialog-footer">
                    <el-button type="warning" @click="ifShowApproveRuleDialog = false" size="default" plain>取消</el-button>
                    <el-button type="primary" @click="submitApproveRule()" size="default">确认</el-button>
                </div>
            </template>
          <div class="d-container" v-if="!disabled">
            <div class="d-row">
              <div class="d-tit">jsa风险研判结论</div><div class="d-cont">{{detail.judgeRecord}}</div>
            </div>
            <div class="d-row">
              <div class="d-tit">风险研判报告记录附件</div>
              <div class="d-cont">
                <el-image v-for="item in detail.judgePicturePath?.split(',')" :preview-src-list="[item]" style="width: 150px; height: 150px;margin-right: 50px;margin-bottom: 20px" :src="item" fit="cover" />
              </div>
            </div>
            <div class="d-row">
              <div class="d-tit">研判人</div><div class="d-cont">{{detail.judgeUname}}</div>
            </div>
            <div class="d-row">
              <div class="d-tit">研判时间</div><div class="d-cont">{{detail.judgeTime}}</div>
            </div>
          </div>
        </el-dialog>
    </div>
</template>
<script lang="ts">
import { reactive, toRefs, ref } from 'vue';
import { ElMessage } from 'element-plus/es';
import { approveRuleApi } from '/@/api/specialWorkSystem/approveRule';
import { Edit, View, Plus, Delete, Refresh, Search, Download } from '@element-plus/icons-vue';
import {ElMessageBox, UploadProps} from "element-plus";
import {workApplyApi} from "/@/api/specialWorkSystem/workApply";
import axios from "axios";
interface dataState {
    title: string;
    disabled: boolean;
    ifShowApproveRuleDialog: boolean;
    jsaForm: {
        workApplyId: number | null;
        judgeRecord: string
        judgePicturePath: Array<string>
    };
    jsaFormRules: {};
    fileList: Array<file>,
    uploadUrl: string,
    dialogVisible: Boolean,
    dialogImageUrl: string | null,
    imgLimit: number,
    detail:{}
}
interface file {
  url: string
}
export default {
    name: 'jsaReportDialog',
    components: { Plus },
    setup(props: any, context: any) {
        const jsaFormRef = ref();
        const approveLevelDialogRef = ref();
        const state = reactive<dataState>({
            title: '',
            disabled: true,
            ifShowApproveRuleDialog: false,
            jsaForm: {
              workApplyId: null,
              judgeRecord: '',
              judgePicturePath: []
            },
            jsaFormRules: {
              judgeRecord: [{ required: true, message: '请填写jsa风险研判结论', trigger: 'blur' }],
              judgePicturePath: [{ required: true, message: '请上传风险研判报告附件', trigger: 'blur' }]
            },
            fileList: [],
            imgLimit: 3,
            uploadUrl: '',
            dialogVisible: false,
            dialogImageUrl: null,
            detail: {}
        });
        const showReportDialog = (type: string, value: {}) => {
            state.ifShowApproveRuleDialog = true;
            if (type === '上传') {
                state.disabled = true;
                state.title = '上传风险研判报告';
                console.log(value.id,'id')
                state.jsaForm = {
                  workApplyId: value.id,
                  judgeRecord: '',
                  judgePicturePath: []
                };
            } else {
                state.disabled = false;
                state.title = '查看风险研判报告';
                getReport(value.id.toString())
            }
        };
        const getReport = async(id:string) => {
          let res = await workApplyApi().viewJsaReport({id:id});
          if (res.data.code === '200') {
            state.detail = res.data.data
          } else {
            ElMessage({
              type: 'warning',
              message: res.data.msg
            });
          }
        }
        const submitApproveRule = () => {
            jsaFormRef.value.validate(async (valid: Boolean) => {
                if (valid) {
                    state.jsaForm.judgePicturePath = state.jsaForm.judgePicturePath.join(',')
                    let res = await workApplyApi().uploadJsaReport(state.jsaForm);
                    if (res.data.code === '200') {
                        ElMessage({
                            type: 'success',
                            message: '研判报告上传成功',
                            duration: 2000
                        });
                        state.ifShowApproveRuleDialog = false;
                        state.jsaForm.judgePicturePath = []
                        state.fileList = []
                        context.emit('refresh');
                    } else {
                        ElMessage({
                            type: 'warning',
                            message: res.data.msg
                        });
                      state.jsaForm.judgePicturePath = state.jsaForm.judgePicturePath.split(',')
                    }
                } else {
                    ElMessage({
                        type: 'warning',
                        message: '请完善基本信息'
                    });
                }
            });
        };
      const handlePreview: UploadProps['onPreview'] = (uploadFile) => {
        console.log(uploadFile);
      };
      const handlePictureCardPreview = (uploadFile: { url: string }) => {
        state.dialogImageUrl = uploadFile.url!;
        state.dialogVisible = true;
      };
      const getUploadUrl = async (rawFile: any) => {
        // const fileSize = rawFile.size / 1024 / 1024 < 5 ? '1' : '0'
        if(rawFile.size / 1024 / 1024 > 5){
          ElMessage({
            type: 'warning',
            message: '文件大小不能超过5M。'
          });
          return Promise.reject(false)
        }else{
          const res = await workApplyApi().getUpload9Url(rawFile.name);
          state.jsaForm.judgePicturePath.push(res.data.data.fileName)
          state.uploadUrl = res.data.data.uploadUrl;
        }
      };
      const upload = async (params: any) => {
        let reader = new FileReader();
        reader.readAsArrayBuffer(params.file);
        reader.onload = async () => {
          axios
              .put(state.uploadUrl, reader.result, {
                header: { 'Content-Type': 'multipart/form-data' }
              })
              .then(() => {
                // if (state.fileList.length === 2) {
                //     state.fileList.splice(0, 1);
                // }
                console.log(state.jsaForm.judgePicturePath,'judgePicturePath')
              });
        };
      };
      const beforeRemove = (file: {}, fileList: []) => {
        if (file && file.status === "success") {
          const result = new Promise((resolve, reject) => {
            ElMessageBox.confirm('此操作将删除该图片, 是否继续?', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            })
                .then(() => {
                  const list = JSON.parse(JSON.stringify(state.jsaForm.judgePicturePath))
                  fileList.map((item, index) => {
                    if (item.uid === file.uid) {
                      fileList.splice(index, 1)
                      state.jsaForm.judgePicturePath.splice(index, 1)
                      // 请求删除接口
                      deletePic(list[index])
                    }
                  })
                })
                .catch(() => {
                  reject(false);
                });
          });
          return result;
        }
      };
      // 删除图片接口
      const deletePic = async(fileName:string)=>{
        const res = await workApplyApi().deleteFile({fileName: fileName})
        if (res.data.code === '200') {
          ElMessage({
            type: 'success',
            message: '删除成功!'
          });
        } else {
          ElMessage({
            type: 'warning',
            message: res.data.msg
          });
        }
      }
      const showTip =()=>{
        ElMessage({
          type: 'warning',
          message: '超出文件上传数量'
        });
      }
      const clearFile = ()=>{
        state.fileList = []
      }
        return {
            ...toRefs(state),
            Plus,
            jsaFormRef,
            approveLevelDialogRef,
            getReport,
            submitApproveRule,
            showReportDialog,
            handlePreview,
            getUploadUrl,
            upload,
            showTip,
            handlePictureCardPreview,
            beforeRemove,
          clearFile
        };
    }
};
</script>
<style scoped lang="scss">
$homeNavLengh: 8;
.home-container {
    height: calc(100vh - 144px);
    box-sizing: border-box;
    overflow: hidden;
    .homeCard {
        width: 100%;
        padding: 20px;
        box-sizing: border-box;
        background: #fff;
        border-radius: 4px;
        .main-card {
            width: 100%;
            height: 100%;
            .cardTop {
                display: flex;
                align-items: center;
                justify-content: space-between;
                margin-bottom: 20px;
                .mainCardBtn {
                    margin: 0;
                }
            }
            .pageBtn {
                height: 60px;
                display: flex;
                align-items: center;
                justify-content: right;
                .demo-pagination-block + .demo-pagination-block {
                    margin-top: 10px;
                }
                .demo-pagination-block .demonstration {
                    margin-bottom: 16px;
                }
            }
        }
        &:last-of-type {
            height: calc(100% - 100px);
        }
    }
    .el-row {
        display: flex;
        align-items: center;
        margin-bottom: 20px;
        &:last-child {
            margin-bottom: 0;
        }
        .grid-content {
            align-items: center;
            min-height: 36px;
        }
        .topInfo {
            display: flex;
            align-items: center;
            font-size: 16px;
            font-weight: bold;
            & > div {
                white-space: nowrap;
                margin-right: 20px;
            }
        }
    }
}
.d-container{
  width: 100%;
  .d-row{
    width: 100%;
    display: flex;
    align-items: flex-start;
    .d-tit{
      width: 150px;
      text-align: right;
      padding-right: 12px;
    }
    .d-cont{
      width: calc(100% - 150px);
      border: 1px solid #dcdfe6;
      margin-bottom: 22px;
      border-radius: var(--el-input-border-radius,var(--el-border-radius-base));
      padding: 5px 11px;
    }
  }
}
:deep(.el-date-editor) {
    width: 100%;
}
</style>
src/views/newSpecialWorkSystem/workTicket/wdsq/index.vue
@@ -4,30 +4,46 @@
<!--            <el-tab-pane label="申请中" name="1">-->
                <div style="height: 100%">
                    <el-row class="homeCard">
                      <div class="basic-line" style="display:flex;white-space:nowrap;line-height: 40px">
                        <span>时间筛选:</span>
                        <el-date-picker v-model="timeRange" value-format="YYYY-MM-DD HH:mm:ss" type="datetimerange" @change="giveTime()" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" />
                      </div>
                      <div class="basic-line" style="display:flex;white-space:nowrap;line-height: 40px">
                        <span>负责人:</span>
                        <el-input v-model="searPara.headUserName" placeholder="负责人"/>
                      </div>
                      <div class="basic-line">
                        <span>事业部:</span>
                        <el-select v-model="searPara.secondDepId">
                          <el-option
                              v-for="item in dep4List"
                              :key="item.id"
                              :label="item.name"
                              :value="item.id"
                          />
                        </el-select>
                      </div>
                      <div class="basic-line">
                        <span>作业类型:</span>
                        <el-col :span="10">
                            <div class="grid-content topInfo">
                                <el-select v-model="searchWord">
                                    <el-option
                                            v-for="item in workType"
                                            :key="item.id"
                                            :label="item.name"
                                            :value="item.id"
                                    />
                                </el-select>
                                <el-button type="primary" @click="searchRecord">查询</el-button>
                                <el-button plain @click="clearSearch">重置</el-button>
                            </div>
                        </el-col>
                        <el-select v-model="searPara.workType">
                          <el-option
                              v-for="item in workType"
                              :key="item.id"
                              :label="item.name"
                              :value="item.id"
                          />
                        </el-select>
                      </div>
                      <div style="margin-left: 20px">
                        <el-button type="primary" @click="searchRecord">查询</el-button>
                        <el-button plain @click="clearSearch">重置</el-button>
                      </div>
                    </el-row>
                    <div class="homeCard">
                        <div class="main-card">
                            <el-row class="cardTop">
                                <el-col :span="12" class="mainCardBtn">
                                    <el-button type="primary" :icon="Plus" size="default" @click="toApply()">申请</el-button>
                                    <!--                                    <el-button type="danger" :icon="Delete" size="default">删除</el-button>-->
                                    <!--                                    <el-button type="success" size="default">设置分类</el-button>-->
                                </el-col>
                                <el-button type="primary" :icon="Refresh" size="default" @click="reLoadData()" />
                            </el-row>
@@ -71,15 +87,18 @@
                                </el-table-column>
                                <el-table-column label="风险研判" align="center">
                                    <template #default="scope">
                                        <el-tag>{{ statusList.find(i=>i.value === scope.row.status)?.label }}</el-tag>
                                        <el-button v-if="scope.row.status == 0" link type="primary" size="small" @click="openReport('上传', scope.row)">上传研判报告</el-button>
                                        <el-tag type="danger" v-else-if="scope.row.status == -1">已废止</el-tag>
                                        <el-button v-else link type="primary" size="small" @click="openReport('查看', scope.row)">查看研判报告</el-button>
                                    </template>
                                </el-table-column>
                                <el-table-column fixed="right" label="操作" align="center" width="300">
                                    <template #default="scope">
                                        <el-button link type="danger" size="small" :icon="Delete" @click="deleteRecordBtn(scope.row)">作废</el-button>
                                        <el-button link type="primary" size="small" :icon="View" @click="viewRecord(scope.row)">查看</el-button>
                                        <el-button link type="success" size="small" :icon="Finished">修改</el-button>
                                        <el-button link type="success" size="small" :icon="Download">正式办票</el-button>
                                        <span v-if="scope.row.status == -1">已废止</span>
                                        <el-button v-if="scope.row.status == 0 || scope.row.status == 1" link type="danger" size="small" :icon="Delete" @click="abortRecordBtn(scope.row)">作废</el-button>
                                        <el-button v-if="scope.row.status !== -1" link type="primary" size="small" :icon="View" @click="viewRecord(scope.row)">查看</el-button>
<!--                                        <el-button link type="success" size="small" :icon="Finished">修改</el-button>-->
                                        <el-button v-if="scope.row.status == 1" link type="success" size="small" :icon="Download" @click="checkTicket(scope.row)">正式办票</el-button>
<!--                                        <el-button :disabled="scope.row.status == 7 ? false : true" link type="primary" size="small" :icon="Download" @click="downLoadBtn(scope.row)">导出作业票</el-button>-->
                                    </template>
                                </el-table-column>
@@ -108,127 +127,7 @@
                      </span>
                    </template>
                </el-dialog>
                <el-dialog v-model="dialogStatus" title="作业申请进度" width="60%">
                    <el-form v-if="approveInfo.operators.length > 0" style="margin-bottom: 40px">
                        <el-form-item label="申请作业人">
                            <el-input v-model="approveInfo.operators" readonly type="textarea" />
                        </el-form-item>
                    </el-form>
                    <div style="display: flex; flex-direction: column-reverse">
                        <div v-for="(item, index) in approveInfo.approvalSteps" class="stepItem">
                            <div class="stepNum">{{ item.stepSerial }}</div>
                            <div class="stepCard">
                                <el-card class="box-card" shadow="always">
                                    <div class="text">
                                        审批结果:<span class="bold-text">{{ item.approvalResultDesc }}</span>
                                    </div>
                                    <div class="text">
                                        审批类型:<span class="bold-text">{{ item.typeDesc }}</span>
                                    </div>
                                    <div class="text" v-if="item.auditTypeDesc">
                                        审批类型:<span class="bold-text">{{ item.auditTypeDesc }}</span>
                                    </div>
                                    <div class="text" v-show="item.startApprovalTime != null">
                                        开始时间:<span>{{ item.startApprovalTime }}</span>
                                    </div>
                                    <div class="approveUnit">
                                        <div class="item-tit"><span>审批人</span><span>审批状态</span></div>
                                        <div class="item-cont" v-for="i in item.stepUnits">
                                            <span>{{ i.approvalUname }}</span
                                            ><span>{{ i.resultDesc }}</span>
                                        </div>
                                    </div>
                                    <div class="approveItem">
                                        <div class="item-tit">
                                            <span>审批项目</span>
<!--                                            <span>类型</span>-->
                                            <div>措施标准</div>
                                        </div>
                                        <div class="item-cont" v-for="i in item.stepItems">
                                            <span>{{ i.itemName }}</span>
<!--                                            <span>{{ i.typeDesc }}</span>-->
                                            <div v-if="i.measure !== null">
                                                <div>
                                                    <span>作业类型:</span><span>{{ i.measure.workTypeDesc }}</span>
                                                </div>
                                                <div>
                                                    <span>措施内容:</span><span>{{ i.measure.context }}</span>
                                                </div>
                                            </div>
                                            <div v-if="i.stand !== null">
                                                <div>
                                                    <span>标题名称:</span><span>{{ i.stand.title }}</span>
                                                </div>
                                                <div>
                                                    <span>标准内容:</span><span>{{ i.stand.typeDesc }}</span>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="text" v-show="item.expFinishApprovalTime && item.expFinishApprovalTime != null">
                                        期望结束时间:<span>{{ item.expFinishApprovalTime }}</span>
                                    </div>
                                    <div class="text" v-show="item.finishApprovalTime != null">
                                        结束时间:<span>{{ item.finishApprovalTime }}</span>
                                    </div>
                                </el-card>
                            </div>
                        </div>
                    </div>
                </el-dialog>
                <el-dialog v-model="deleteDialog" title="提示" width="30%" center>
                    <span>您确定要取消该条申请吗?</span>
                    <template #footer>
                        <span class="dialog-footer">
                            <el-button @click="deleteDialog = false" size="default">取消</el-button>
                            <el-button type="primary" @click="conFirmDelete" size="default">确认</el-button>
                        </span>
                    </template>
                </el-dialog>
                <el-dialog v-model="downLoadDialog" title="提示" width="30%" center>
                    <span>您确定要导出该条记录吗?</span>
                    <template #footer>
                                <span class="dialog-footer">
                                    <el-button @click="downLoadDialog = false" size="default">取消</el-button>
                                    <el-button type="primary" @click="conFirmDownLoad" size="default">确认</el-button>
                                </span>
                    </template>
                </el-dialog>
<!--            </el-tab-pane>-->
<!--            <el-tab-pane label="已通过" name="2">-->
<!--                <div style="height: 100%">-->
<!--                    <el-row class="homeCard">-->
<!--                        <el-col :span="8">-->
<!--                            <div class="grid-content topInfo">-->
<!--                                <el-input v-model="searchWord" placeholder="作业证名称"></el-input>-->
<!--                                <el-button type="primary">查询</el-button>-->
<!--                                <el-button plain>重置</el-button>-->
<!--                            </div>-->
<!--                        </el-col>-->
<!--                    </el-row>-->
<!--                    <div class="homeCard">-->
<!--                        <div class="main-card">-->
<!--                            <el-table ref="multipleTableRef" :data="passedData" style="width: 100%" height="calc(100% - 48px)" :header-cell-style="{ background: '#fafafa' }" @selection-change="handleSelectionChange">-->
<!--                                <el-table-column type="selection" width="55" />-->
<!--                                <el-table-column type="index" label="编号" width="200" />-->
<!--                                <el-table-column property="level" label="作业证等级" width="180" sortable />-->
<!--                                <el-table-column property="applyDate" label="申请日期" sortable />-->
<!--                                <el-table-column property="name" label="申请人" width="180" />-->
<!--                                <el-table-column property="department" label="申请部门" width="180" />-->
<!--                                <el-table-column label="申请状态" width="180">-->
<!--                                    <template #default="scope">-->
<!--                                        <el-tag type="success">{{ scope.row.status }}</el-tag>-->
<!--                                    </template>-->
<!--                                </el-table-column>-->
<!--                            </el-table>-->
<!--                            <div class="pageBtn">-->
<!--                                <el-pagination v-model:currentPage="pageIndex2" v-model:page-size="pageSize2" :page-sizes="[10, 15]" small="false" background layout="total, sizes, prev, pager, next, jumper" :total="totalSize2" @size-change="handleSizeChange2" @current-change="handleCurrentChange2" />-->
<!--                            </div>-->
<!--                        </div>-->
<!--                    </div>-->
<!--                </div>-->
<!--            </el-tab-pane>-->
<!--        </el-tabs>-->
                <report-log ref="reportDialogRef" @refresh="getListByPage"></report-log>
    </div>
</template>
@@ -241,7 +140,7 @@
import { useRouter } from 'vue-router';
import { Edit, View, Plus, Delete, Refresh, Search, Finished, Download } from '@element-plus/icons-vue';
import { ElTable } from 'element-plus';
import { FormInstance, FormRules, ElMessage } from 'element-plus';
import { FormInstance, FormRules, ElMessage, ElMessageBox } from 'element-plus';
import { workApplyApi } from '/@/api/specialWorkSystem/workApply';
import type { TabsPaneContext } from 'element-plus';
import {teamManageApi} from "/@/api/systemManage/basicDateManage/personShiftManage/teamManage";
@@ -257,15 +156,11 @@
    approveInfo: Object;
    dialogDetails: boolean;
    dialogStatus: boolean;
    deleteDialog: boolean;
    downLoadDialog: boolean;
    pageIndex1: number;
    pageSize1: number;
    chosenIndex: null | number;
    deleteId: null | number;
    downLoadId: null | number;
    downLoadName: string;
    searchWord: string;
    totalSize1: number;
    activeName: string;
    addRecord: {};
@@ -276,6 +171,9 @@
    departmentList: Array<any>;
    departmentRecursionList: Array<DepartmentState>;
    statusList: Array<any>;
    searPara: {}
    timeRange: Array<string>;
    dep4List: Array<type>;
}
interface type {
    id: number;
@@ -288,20 +186,14 @@
export default defineComponent({
    name: 'myApply',
    components: {
        // fire: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/fireLog.vue')),
        // space: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/spaceLog.vue')),
        // hoist: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/hoistLog.vue')),
        // ground: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/groundLog.vue')),
        // broken: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/brokenLog.vue')),
        // height: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/heightLog.vue')),
        // power: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/powerLog.vue')),
        // plate: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/plateLog.vue'))
      detailLog: defineAsyncComponent(() => import('/@/views/newSpecialWorkSystem/workTicket/wdsq/components/detailLog.vue'))
      detailLog: defineAsyncComponent(() => import('/@/views/newSpecialWorkSystem/workTicket/wdsq/components/detailLog.vue')),
      reportLog: defineAsyncComponent(() => import('/@/views/newSpecialWorkSystem/workTicket/wdsq/components/jsaReportDialog.vue'))
    },
    setup() {
        const userInfo = useUserInfo();
        const { userInfos } = storeToRefs(userInfo);
        const router = useRouter();
        const reportDialogRef = ref();
        const state = reactive<stateType>({
            pageIndex1: 1,
            pageSize1: 10,
@@ -311,7 +203,14 @@
            departmentList: [],
            departmentRecursionList: [],
            chosenIndex: null,
            searchWord: '',
            searPara:{
              startTime: '',
              endTime: '',
              workType: null,
              headUserName: '',
              secondDepId: null
            },
            timeRange: [],
            applyData: [],
            workTimeList: [],
            multipleSelection: [],
@@ -321,12 +220,9 @@
            },
            dialogDetails: false,
            dialogStatus: false,
            deleteDialog: false,
            downLoadDialog: false,
            addRecord: {},
            details: {},
            statusInfo: {},
            deleteId: null,
            downLoadId: null,
            downLoadName: '',
            deleteArr: [],
@@ -340,6 +236,12 @@
                { id: 7, name: '临时用电作业' },
                { id: 8, name: '盲板抽堵作业' }
            ],
          dep4List: [
            {id:49,name:'电石事业部'},
            {id:50,name:'电力事业部'},
            {id:48,name:'有机化工事业部'},
            {id:32,name:'甲醇事业部'}
          ],
          statusList: [
            {
              value: -1,
@@ -387,11 +289,15 @@
            }
          ]
        });
        interface User {
            name: string;
            list: [];
            info: string;
        }
        const giveTime = () => {
          if (state.timeRange && state.timeRange !== null) {
            state.searPara.startTime = state.timeRange[0];
            state.searPara.endTime = state.timeRange[1];
          } else {
            state.searPara.startTime = '';
            state.searPara.endTime = '';
          }
        };
        // 刷新
        const reLoadData = async () => {
@@ -435,7 +341,7 @@
        // 分页获取
        const getListByPage = async () => {
            const data = { pageSize: state.pageSize1, pageIndex: state.pageIndex1, searchParams: { workType: state.searchWord } };
            const data = { pageSize: state.pageSize1, pageIndex: state.pageIndex1, searchParams: state.searPara };
            let res = await workApplyApi().getNewApplyListPage(data);
            if (res.data.code === '200') {
                state.applyData = JSON.parse(JSON.stringify(res.data.data));
@@ -475,19 +381,19 @@
        // 关键词查询记录
        const searchRecord = async () => {
            if (state.searchWord == '') {
                ElMessage({
                    type: 'warning',
                    message: '请输入查询关键词'
                });
            } else {
                getListByPage();
            }
          getListByPage();
        };
        // 重置搜索
        const clearSearch = async () => {
            state.searchWord = '';
            getListByPage();
          state.timeRange = []
          state.searPara = {
            startTime: '',
            endTime: '',
            workType: null,
            headUserName: '',
            secondDepId: null
          };
          getListByPage();
        };
        // 查看进度
@@ -510,38 +416,69 @@
            }
        };
        const deleteRecordBtn = (row) => {
            state.deleteId = row.workApplyId;
            state.deleteDialog = true;
        };
        // 取消申请方法
        const deleteRecord = async (data: any) => {
            let res = await workApplyApi().cancelApply(data);
            if (res.data.code === '200') {
                ElMessage({
        const abortRecordBtn = (row:object) => {
          ElMessageBox.confirm(
              '是否作废该项申报?',
              '申报作废',
              {
                confirmButtonText: '确认',
                cancelButtonText: '取消'
              }
          )
              .then(async () => {
                let res = await workApplyApi().abolishTicket({id: row.id});
                if (res.data.code === '200') {
                  ElMessage({
                    type: 'success',
                    message: '删除成功!'
                });
                getListByPage();
            } else {
                ElMessage({
                    message: '作废成功!'
                  });
                  getListByPage();
                } else {
                  ElMessage({
                    type: 'warning',
                    message: res.data.msg
                });
            }
                  });
                }
              })
              .catch(() => {
                console.log('取消废票')
              })
        };
        const conFirmDelete = () => {
            deleteRecord({ workApplyId: state.deleteId });
            state.deleteDialog = false;
        };
        // 正式办票
        const checkTicket = (row:object) =>{
          ElMessageBox.confirm(
              '是否进行正式办票操作?',
              '正式办票',
              {
                confirmButtonText: '确认',
                cancelButtonText: '取消'
              }
          )
              .then(async () => {
                let res = await workApplyApi().checkTicket({id: row.id});
                if (res.data.code === '200') {
                  ElMessage({
                    type: 'success',
                    message: '办票成功!'
                  });
                  getListByPage();
                } else {
                  ElMessage({
                    type: 'warning',
                    message: res.data.msg
                  });
                }
              })
              .catch(() => {
                console.log('取消办票')
              })
        }
        // 导出图表
        const downLoadBtn = (row:any) =>{
            state.downLoadId = row.workApplyId;
            state.downLoadName = row.workTypeDesc + row.workPermitNo
            state.downLoadDialog = true;
        }
        // 导出方法
@@ -567,11 +504,6 @@
        };
        const conFirmDownLoad = () => {
            downLoadRecord({ applyWorkId: state.downLoadId });
            state.downLoadDialog = false;
        };
        const handleSizeChange1 = (val: number) => {
            state.pageSize1 = val;
            getListByPage();
@@ -579,6 +511,10 @@
        const handleCurrentChange1 = (val: number) => {
            state.pageIndex1 = val;
            getListByPage();
        };
        const openReport = (type: string, value: {}) => {
          reportDialogRef.value.showReportDialog(type, value);
        };
        // 查看记录
@@ -609,18 +545,20 @@
            Plus,
            Finished,
            Download,
          reportDialogRef,
          checkTicket,
            giveTime,
            reLoadData,
            toApply,
            handleClick,
            toNames,
            searchRecord,
            clearSearch,
            openReport,
            viewRecord,
            viewStatus,
            deleteRecordBtn,
            abortRecordBtn,
            downLoadBtn,
            conFirmDelete,
            conFirmDownLoad,
            getListByPage,
            handleSizeChange1,
            handleCurrentChange1,
@@ -683,208 +621,6 @@
        }
        &:last-of-type {
            height: calc(100% - 100px);
        }
    }
    .stepItem {
        display: flex;
        align-items: flex-start;
        margin-top: 30px;
        margin-left: 30px;
        padding-bottom: 30px;
        padding-left: 40px;
        border-left: 1px solid #a0cfff;
        position: relative;
        &:first-of-type {
            margin-top: 30px;
        }
        &:first-of-type {
            margin-bottom: 0;
            border-left: none;
        }
        .stepNum {
            position: absolute;
            width: 40px;
            height: 40px;
            border-radius: 20px;
            box-sizing: border-box;
            font-size: 18px;
            color: #333;
            border: 1px solid #a0cfff;
            line-height: 38px;
            text-align: center;
            left: -20px;
            top: -30px;
            background: #d9ecff;
        }
        .stepCard {
            width: 100%;
            margin-top: -30px;
            .box-card {
                width: 100%;
                .card-header {
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    span {
                        font-weight: bold;
                        margin-left: 10px;
                    }
                }
                .text {
                    width: 100%;
                    font-size: 14px;
                    margin-bottom: 10px;
                    padding-left: 10px;
                    span {
                        color: #409eff;
                    }
                    .bold-text{
                        font-weight: bolder;
                    }
                    &:last-of-type {
                        margin-bottom: 0;
                    }
                }
                .approveUnit {
                    width: 100%;
                    font-size: 14px;
                    margin-bottom: 20px;
                    padding: 10px 15px;
                    border: 1px solid #fff;
                    background: #ecf8ff;
                    border-radius: 6px;
                    .item-tit {
                        width: 100%;
                        display: flex;
                        color: #409eff;
                        align-items: flex-start;
                        justify-content: space-between;
                        padding-bottom: 10px;
                        border-bottom: 1px solid #a0cfff;
                        & > span {
                            flex: 1;
                            &:last-of-type{
                                text-align: center;
                            }
                        }
                        & > div {
                            flex: 1;
                            text-align: center;
                        }
                    }
                    .item-cont {
                        width: 100%;
                        display: flex;
                        align-items: center;
                        justify-content: space-between;
                        padding: 10px 0;
                        border-bottom: 1px solid #c6e2ff;
                        & > span {
                            flex: 1;
                            &:last-of-type{
                                text-align: center;
                            }
                        }
                        & > div {
                            flex: 1;
                            text-align: center;
                            & > div {
                                text-align: left;
                                width: 100%;
                                display: flex;
                                justify-content: center;
                                align-items: center;
                                span {
                                    width: 45%;
                                    &:first-of-type {
                                        width: 30%;
                                    }
                                }
                            }
                        }
                        &:last-of-type {
                            border-bottom: 0;
                        }
                    }
                }
                .approveItem {
                    width: 100%;
                    font-size: 14px;
                    margin-bottom: 20px;
                    padding: 10px 15px;
                    background: #ecf8ff;
                    border: 1px solid #fff;
                    border-radius: 6px;
                    .item-tit {
                        width: 100%;
                        display: flex;
                        color: #409eff;
                        align-items: flex-start;
                        justify-content: space-between;
                        padding-bottom: 10px;
                        border-bottom: 1px solid #a0cfff;
                        & > span {
                            flex: 1;
                        }
                        & > div {
                            flex: 2;
                            text-align: center;
                        }
                    }
                    .item-cont {
                        width: 100%;
                        display: flex;
                        align-items: center;
                        justify-content: space-between;
                        padding: 10px 0;
                        border-bottom: 1px solid #c6e2ff;
                        & > span {
                            flex: 1;
                        }
                        & > div {
                            flex: 2;
                            text-align: center;
                            & > div {
                                text-align: left;
                                width: 100%;
                                display: flex;
                                justify-content: center;
                                align-items: flex-start;
                                margin-bottom: 10px;
                                span {
                                    width: 50%;
                                    &:first-of-type {
                                        width: 25%;
                                    }
                                }
                            }
                        }
                        &:last-of-type {
                            border-bottom: 0;
                        }
                    }
                }
            }
        }
        &:hover .card-header {
            color: #0098f5;
        }
        &:hover .stepNum {
            border: 2px solid #0098f5;
            color: #0098f5;
        }
    }
    .el-row {
src/views/newSpecialWorkSystem/workTicket/zysq/components/broken.vue
@@ -94,15 +94,19 @@
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
        <el-col :span="12" class="valueSelect">
          <el-form-item label="关联其他特殊作业" prop="involveOtherWork">
            <el-select v-model="form.involveOtherWork" multiple clearable>
              <el-option
                  v-for="item in otherWorkList"
                  :key="item.value"
                  :label="item.label"
                  :value="item.label"
              />
<!--            <el-select v-model="form.involveOtherWork" multiple clearable>-->
<!--              <el-option-->
<!--                  v-for="item in otherWorkList"-->
<!--                  :key="item.value"-->
<!--                  :label="item.label"-->
<!--                  :value="item.label"-->
<!--              />-->
<!--            </el-select>-->
            <el-select v-model="form.involveOtherWork" multiple clearable :teleported="false" @click="openWorkSelect">
              <el-option v-for="item in otherWorks" :key="item.workApplyId" :label="item.workContent" :value="item.workApplyId">
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
@@ -132,10 +136,10 @@
          </el-col>
          <el-col :span="12">
            <el-form-item label="断路地段示意图" prop="workDetail.bcPath">
              <el-upload accept="image/*" :auto-upload="true" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='imgLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" list-type="picture-card" :on-remove="handleRemove" :before-remove="beforeRemove" :before-upload="getUploadUrl">
              <el-upload accept="image/*" :auto-upload="true" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='imgLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" list-type="picture-card" :before-remove="beforeRemove" :before-upload="getUploadUrl">
                <el-icon><Plus /></el-icon>
                <template #tip>
                  <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传3张</div>
                  <div class="el-upload__tip">上传jpg/png图片尺寸小于2M,最多可上传3张</div>
                </template>
              </el-upload>
            </el-form-item>
@@ -203,7 +207,7 @@
        <el-row style="display: flex;justify-content: center">
          <el-table :data="safetyMeasureBasicList" style="width: 90%" border>
            <el-table-column type="index" label="序号" width="100px" align="center"/>
            <el-table-column prop="measureContent" label="安全措施" align="center"/>
            <el-table-column prop="measureContent" label="安全措施"/>
<!--            <el-table-column prop="address" label="确认人">-->
<!--              <template #default="scope">-->
@@ -304,11 +308,26 @@
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="签字人" prop="workDetail.signUid">
              <el-select v-model="form.workDetail.signUid" clearable>
                <el-option
                    v-for="item in workerList"
                    :key="item.uid"
                    :label="item.username"
                    :value="item.uid"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
            </div>
        </el-form>
        <div class="applyBtn">
            <el-button type="primary" size="large" plain @click="submitForm(ruleFormRef)">提交申报</el-button>
        </div>
    <work-select ref="workSelectRef" @refreshWorks="getSelected()"></work-select>
    </div>
</template>
@@ -322,11 +341,11 @@
    import { ElMessage, ElMessageBox } from 'element-plus'
    import type { FormInstance, FormRules } from 'element-plus'
    import { workApplyApi } from '/@/api/specialWorkSystem/workApply';
  import workSelect from "/@/views/newSpecialWorkSystem/workTicket/zysq/components/workSelect.vue";
  import {UploadProps} from "element-plus/es";
  import axios from "axios";
    interface stateType {
        form: Object,
        otherWorkList: Array<any>,
        equipmentDialog: boolean,
    props:{},
    depProps:{},
@@ -343,8 +362,8 @@
  }
    export default defineComponent({
        name: 'brokenForm',
        components: {},
        props:['departList','departList2','workerList','deviceList'],
        components: {workSelect},
        props:['departList','departList2','workerList','deviceList','otherWorks'],
        setup(props: any, context: any) {
            const userInfo = useUserInfo()
            const { userInfos } = storeToRefs(userInfo);
@@ -366,7 +385,7 @@
          workContent: '',
          workLocation: '',
          riskIdentification: '',
          involveOtherWork: '',
          involveOtherWork: [],
          safetyMeasureUids: [],
          approvalDepBasicList: [],
          acceptUid: null,
@@ -376,43 +395,10 @@
            involvedDepIds: [],
            bcReason: '',
            bcExplain: '',
            bcPath: []
            bcPath: [],
            signUid: null
          }
                },
                otherWorkList: [
                    {
                        label: "动火作业",
                        value: 1
                    },
                    {
                        label: "受限空间作业",
                        value: 2
                    },
                    {
                        label: "吊装作业",
                        value: 3
                    },
                    {
                        label: "动土作业",
                        value: 4
                    },
                    {
                        label: "断路作业",
                        value: 5
                    },
                    {
                        label: "高处作业",
                        value: 6
                    },
                    {
                        label: "临时用电作业",
                        value: 7
                    },
                    {
                        label: "盲板抽堵作业",
                        value: 8
                    }
                ],
        props:{
          expandTrigger: 'hover',
          label: 'depName',
@@ -462,13 +448,20 @@
                "workDetail.involvedDepIds": [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
        "workDetail.bcReason": [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
        "workDetail.bcExplain": [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
        "workDetail.bcPath": [{ required: true, message: '该内容不能为空', trigger: 'blur' }]
        "workDetail.bcPath": [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
        "workDetail.signUid": [{ required: true, message: '该内容不能为空', trigger: 'blur' }]
            });
      const workSelectRef = ref()
            // 页面载入时执行方法
            onMounted(() => {
      });
      const openWorkSelect = ()=>{
        workSelectRef.value.openDialog(state.form.involveOtherWork)
      }
      const getSelected = ()=>{
        state.form.involveOtherWork = workSelectRef.value.selected
      }
      const findParent = ()=>{
        state.form.seDepId = findNearestDepLevel2DepId(props.departList2,state.form.applyDepId)
        console.log(state.form.seDepId,'state.form.seDepId')
@@ -592,13 +585,13 @@
      };
      const getUploadUrl = async (rawFile: any) => {
        const fileSize = rawFile.size / 1024 / 1024 < 5 ? '1' : '0'
        if(fileSize === '0'){
        // const fileSize = rawFile.size / 1024 / 1024 < 5 ? '1' : '0'
        if(rawFile.size / 1024 / 1024 > 2){
          ElMessage({
            type: 'warning',
            message: '文件大小不能超过5M。'
            message: '文件大小不能超过2M。'
          });
          return false
          return Promise.reject(false)
        }else{
          const res = await workApplyApi().getUpload9Url(rawFile.name);
          state.form.workDetail.bcPath.push(res.data.data.fileName)
@@ -623,29 +616,31 @@
      };
      const beforeRemove = (file: {}, fileList: []) => {
        const result = new Promise((resolve, reject) => {
          ElMessageBox.confirm('此操作将删除该图片, 是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          })
              .then(() => {
                // console.log(state.workDetail.bcPath,'path')
                const list = JSON.parse(JSON.stringify(state.form.workDetail.bcPath))
                fileList.map((item,index)=>{
                  if(item.uid === file.uid){
                    fileList.splice(index,1)
                    state.form.workDetail.bcPath.splice(index,1)
                    // 请求删除接口
                    deletePic(false,list[index])
                  }
        if (file && file.status === "success") {
          const result = new Promise((resolve, reject) => {
            ElMessageBox.confirm('此操作将删除该图片, 是否继续?', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            })
                .then(() => {
                  // console.log(state.workDetail.bcPath,'path')
                  const list = JSON.parse(JSON.stringify(state.form.workDetail.bcPath))
                  fileList.map((item, index) => {
                    if (item.uid === file.uid) {
                      fileList.splice(index, 1)
                      state.form.workDetail.bcPath.splice(index, 1)
                      // 请求删除接口
                      deletePic(list[index])
                    }
                  })
                })
              })
              .catch(() => {
                reject(false);
              });
        });
        return result;
                .catch(() => {
                  reject(false);
                });
          });
          return result;
        }
      };
      // 删除图片接口
@@ -690,6 +685,9 @@
        showTip,
        handlePictureCardPreview,
        beforeRemove,
        openWorkSelect,
        getSelected,
        workSelectRef,
                Search,
                ruleFormRef,
                applyRules,
@@ -704,9 +702,13 @@
        width: 100%;
    height: 100vh;
        overflow: hidden;
        position: relative;
    overflow-y: scroll;
    padding: 0 0 120px;
    &::-webkit-scrollbar{
      width: 0;
      background-color: transparent;
    }
        .homeCard{
            width: 100%;
            padding: 20px;
@@ -716,10 +718,6 @@
            margin-bottom: 20px;
        }
        .applyBtn{
      position: fixed;
      left: 0;
      bottom: 0;
      z-index: 999;
            width: 100%;
            background: #fff;
            padding: 20px 0;
@@ -747,7 +745,11 @@
            width: 100% !important;
        }
    }
  .valueSelect{
    ::v-deep(.el-popper){
      display: none !important;
    }
  }
    .tab-i{
        margin-bottom: 15px;
src/views/newSpecialWorkSystem/workTicket/zysq/components/fire.vue
@@ -99,15 +99,11 @@
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
        <el-col :span="12" class="valueSelect">
          <el-form-item label="关联其他特殊作业" prop="involveOtherWork">
            <el-select v-model="form.involveOtherWork" multiple clearable>
              <el-option
                  v-for="item in otherWorkList"
                  :key="item.value"
                  :label="item.label"
                  :value="item.label"
              />
            <el-select v-model="form.involveOtherWork" multiple clearable :teleported="false" @click="openWorkSelect">
              <el-option v-for="item in otherWorks" :key="item.workApplyId" :label="item.workContent" :value="item.workApplyId">
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
@@ -200,7 +196,7 @@
        <el-row style="display: flex;justify-content: center">
          <el-table :data="safetyMeasureBasicList" style="width: 90%" border>
            <el-table-column type="index" label="序号" width="100px" align="center"/>
            <el-table-column prop="measureContent" label="安全措施" align="center"/>
            <el-table-column prop="measureContent" label="安全措施"/>
<!--            <el-table-column prop="address" label="确认人">-->
<!--              <template #default="scope">-->
@@ -306,6 +302,7 @@
        <div class="applyBtn">
            <el-button type="primary" size="large" plain @click="submitForm(ruleFormRef)">提交申报</el-button>
        </div>
    <work-select ref="workSelectRef" @refreshWorks="getSelected()"></work-select>
    </div>
</template>
@@ -319,10 +316,10 @@
    import { ElMessage, ElMessageBox } from 'element-plus'
    import type { FormInstance, FormRules } from 'element-plus'
    import { workApplyApi } from '/@/api/specialWorkSystem/workApply';
  import workSelect from "/@/views/newSpecialWorkSystem/workTicket/zysq/components/workSelect.vue";
    interface stateType {
        form: Object,
        workLevelList: Array<any>,
        otherWorkList: Array<any>,
        equipmentDialog: boolean,
    props:{},
    depProps:{},
@@ -330,8 +327,8 @@
    }
    export default defineComponent({
        name: 'fireForm',
        components: {},
        props:['departList','departList2','workerList','deviceList'],
        components: {workSelect},
        props:['departList','departList2','workerList','deviceList','otherWorks'],
        setup(props: any, context: any) {
            const userInfo = useUserInfo()
            const { userInfos } = storeToRefs(userInfo);
@@ -353,7 +350,7 @@
          workContent: '',
          workLocation: '',
          riskIdentification: '',
          involveOtherWork: '',
          involveOtherWork: [],
          safetyMeasureUids: [],
          approvalDepBasicList: [],
          acceptUid: null,
@@ -375,40 +372,6 @@
                    {
                        label: "特级动火作业",
                        value: 3
                    }
                ],
                otherWorkList: [
                    {
                        label: "动火作业",
                        value: 1
                    },
                    {
                        label: "受限空间作业",
                        value: 2
                    },
                    {
                        label: "吊装作业",
                        value: 3
                    },
                    {
                        label: "动土作业",
                        value: 4
                    },
                    {
                        label: "断路作业",
                        value: 5
                    },
                    {
                        label: "高处作业",
                        value: 6
                    },
                    {
                        label: "临时用电作业",
                        value: 7
                    },
                    {
                        label: "盲板抽堵作业",
                        value: 8
                    }
                ],
        props:{
@@ -446,11 +409,20 @@
        startOrEndUids: [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
                "workDetail.workMethod": [{ required: true, message: '该内容不能为空', trigger: 'blur' }]
            });
      const workSelectRef = ref()
            // 页面载入时执行方法
            onMounted(() => {
        getBasicData()
      });
      const openWorkSelect = ()=>{
        workSelectRef.value.openDialog(state.form.involveOtherWork)
      }
      const getSelected = ()=>{
        state.form.involveOtherWork = workSelectRef.value.selected
      }
      const findParent = ()=>{
        state.form.seDepId = findNearestDepLevel2DepId(props.departList2,state.form.applyDepId)
@@ -494,6 +466,7 @@
      }
      const submitForm = async (formEl: FormInstance | undefined) => {
        console.log(state.form.involveOtherWork,555)
        if (!formEl) return
        await formEl.validate(async (valid, fields) => {
          if (valid) {
@@ -506,9 +479,9 @@
                return
              }
            }
            if(Array.isArray(state.form.involveOtherWork)){
              state.form.involveOtherWork = state.form.involveOtherWork.join(',')
            }
            // if(Array.isArray(state.form.involveOtherWork)){
            //   state.form.involveOtherWork = state.form.involveOtherWork.join(',')
            // }
            const res = await workApplyApi().submitFireApply(state.form)
            if (res.data.code === '200') {
              ElMessage({
@@ -522,7 +495,7 @@
                type: 'warning',
                message: res.data.msg
              });
              state.form.involveOtherWork = state.form.involveOtherWork.split(',')
              // state.form.involveOtherWork = state.form.involveOtherWork.split(',')
            }
          } else {
            console.log('error submit!', fields)
@@ -532,12 +505,10 @@
      const findNearestDepLevel2DepId = (data, targetDepId) => {
        let nearestDepId = null;
        const traverseTree = (node) => {
          if (node.depId === targetDepId) {
            return true;
          }
          if (node.children && node.children.length > 0) {
            for (const child of node.children) {
              const found = traverseTree(child);
@@ -549,14 +520,11 @@
              }
            }
          }
          return false;
        };
        for (const root of data) {
          traverseTree(root);
        }
        return nearestDepId;
      };
@@ -574,6 +542,9 @@
        isFirstRow,
        submitForm,
        findParent,
        openWorkSelect,
        getSelected,
        workSelectRef,
                Search,
                ruleFormRef,
                applyRules,
@@ -588,9 +559,12 @@
        width: 100%;
    height: 100vh;
        overflow: hidden;
        position: relative;
    overflow-y: scroll;
    padding: 0 0 120px;
    &::-webkit-scrollbar{
      width: 0;
      background-color: transparent;
    }
        .homeCard{
            width: 100%;
            padding: 20px;
@@ -598,12 +572,9 @@
            background: #fff;
            border-radius: 4px;
            margin-bottom: 20px;
      position: relative;
        }
        .applyBtn{
      position: fixed;
      left: 0;
      bottom: 0;
      z-index: 999;
            width: 100%;
            background: #fff;
            padding: 20px 0;
@@ -631,7 +602,11 @@
            width: 100% !important;
        }
    }
  .valueSelect{
    ::v-deep(.el-popper){
      display: none !important;
    }
  }
    .tab-i{
        margin-bottom: 15px;
src/views/newSpecialWorkSystem/workTicket/zysq/components/ground.vue
@@ -63,15 +63,19 @@
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
          <el-col :span="12" class="valueSelect">
            <el-form-item label="关联其他特殊作业" prop="involveOtherWork">
              <el-select v-model="form.involveOtherWork" multiple clearable>
                <el-option
                    v-for="item in otherWorkList"
                    :key="item.value"
                    :label="item.label"
                    :value="item.label"
                />
<!--              <el-select v-model="form.involveOtherWork" multiple clearable>-->
<!--                <el-option-->
<!--                    v-for="item in otherWorkList"-->
<!--                    :key="item.value"-->
<!--                    :label="item.label"-->
<!--                    :value="item.label"-->
<!--                />-->
<!--              </el-select>-->
              <el-select v-model="form.involveOtherWork" multiple clearable :teleported="false" @click="openWorkSelect">
                <el-option v-for="item in otherWorks" :key="item.workApplyId" :label="item.workContent" :value="item.workApplyId">
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
@@ -115,10 +119,10 @@
          </el-col>
          <el-col :span="12">
            <el-form-item label="作业简图" prop="workDetail.gbPath">
              <el-upload accept="image/*" :auto-upload="true" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='imgLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" list-type="picture-card" :on-remove="handleRemove" :before-remove="beforeRemove" :before-upload="getUploadUrl">
              <el-upload accept="image/*" :auto-upload="true" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='imgLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" list-type="picture-card" :before-remove="beforeRemove" :before-upload="getUploadUrl">
                <el-icon><Plus /></el-icon>
                <template #tip>
                  <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传3张</div>
                  <div class="el-upload__tip">上传jpg/png图片尺寸小于2M,最多可上传3张</div>
                </template>
              </el-upload>
            </el-form-item>
@@ -186,7 +190,7 @@
        <el-row style="display: flex;justify-content: center">
          <el-table :data="safetyMeasureBasicList" style="width: 90%" border>
            <el-table-column type="index" label="序号" width="100px" align="center"/>
            <el-table-column prop="measureContent" label="安全措施" align="center"/>
            <el-table-column prop="measureContent" label="安全措施"/>
<!--            <el-table-column prop="address" label="确认人">-->
<!--              <template #default="scope">-->
@@ -287,11 +291,26 @@
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="签字人" prop="workDetail.signUid">
              <el-select v-model="form.workDetail.signUid" clearable>
                <el-option
                    v-for="item in workerList"
                    :key="item.uid"
                    :label="item.username"
                    :value="item.uid"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
            </div>
        </el-form>
        <div class="applyBtn">
            <el-button type="primary" size="large" plain @click="submitForm(ruleFormRef)">提交申报</el-button>
        </div>
    <work-select ref="workSelectRef" @refreshWorks="getSelected()"></work-select>
    <el-dialog v-model="dialogVisible">
      <img w-full :src="dialogImageUrl" alt="Preview Image" />
    </el-dialog>
@@ -308,10 +327,10 @@
  import {ElMessage, ElMessageBox, UploadProps, UploadUserFile} from 'element-plus'
    import type { FormInstance, FormRules } from 'element-plus'
    import { workApplyApi } from '/@/api/specialWorkSystem/workApply';
  import workSelect from "/@/views/newSpecialWorkSystem/workTicket/zysq/components/workSelect.vue";
  import axios from "axios";
    interface stateType {
        form: Object,
        otherWorkList: Array<any>,
        equipmentDialog: boolean,
    props:{},
    depProps:{},
@@ -327,8 +346,8 @@
  }
    export default defineComponent({
        name: 'groundForm',
        components: {},
        props:['departList','departList2','workerList','deviceList'],
        components: {workSelect},
        props:['departList','departList2','workerList','deviceList','otherWorks'],
        setup(props: any, context: any) {
            const userInfo = useUserInfo()
            const { userInfos } = storeToRefs(userInfo);
@@ -349,7 +368,7 @@
          workContent: '',
          workLocation: '',
          riskIdentification: '',
          involveOtherWork: '',
          involveOtherWork: [],
          safetyMeasureUids: [],
          approvalDepBasicList: [],
          acceptUid: null,
@@ -357,43 +376,10 @@
          cameraIds: [],
          workDetail: {
            gbDesc: '',
            gbPath: []
            gbPath: [],
            signUid: null
          }
                },
                otherWorkList: [
                    {
                        label: "动火作业",
                        value: 1
                    },
                    {
                        label: "受限空间作业",
                        value: 2
                    },
                    {
                        label: "吊装作业",
                        value: 3
                    },
                    {
                        label: "动土作业",
                        value: 4
                    },
                    {
                        label: "断路作业",
                        value: 5
                    },
                    {
                        label: "高处作业",
                        value: 6
                    },
                    {
                        label: "临时用电作业",
                        value: 7
                    },
                    {
                        label: "盲板抽堵作业",
                        value: 8
                    }
                ],
        props:{
          expandTrigger: 'hover',
          label: 'depName',
@@ -432,13 +418,20 @@
        acceptUid: [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
        startOrEndUids: [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
                "workDetail.gbDesc": [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
        "workDetail.gbPath": [{ required: true, message: '该内容不能为空', trigger: 'blur' }]
        "workDetail.gbPath": [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
        "workDetail.signUid": [{ required: true, message: '该内容不能为空', trigger: 'blur' }]
            });
      const workSelectRef = ref()
            // 页面载入时执行方法
            onMounted(() => {
      });
      const openWorkSelect = ()=>{
        workSelectRef.value.openDialog(state.form.involveOtherWork)
      }
      const getSelected = ()=>{
        state.form.involveOtherWork = workSelectRef.value.selected
      }
      const findParent = ()=>{
        state.form.seDepId = findNearestDepLevel2DepId(props.departList2,state.form.applyDepId)
        console.log(state.form.seDepId,'state.form.seDepId')
@@ -560,18 +553,17 @@
        state.dialogVisible = true;
      };
      const getUploadUrl = async (rawFile: any) => {
        const fileSize = rawFile.size / 1024 / 1024 < 5 ? '1' : '0'
        if(fileSize === '0'){
      const getUploadUrl = async(rawFile: any) => {
        if(rawFile.size / 1024 / 1024 > 2){
          ElMessage({
            type: 'warning',
            message: '文件大小不能超过5M。'
            message: '文件大小不能超过2M。'
          });
          return false
          return Promise.reject(false)
        }else{
          const res = await workApplyApi().getUpload9Url(rawFile.name);
          const res = await workApplyApi().getUpload9Url(rawFile.name)
          state.form.workDetail.gbPath.push(res.data.data.fileName)
          state.uploadUrl = res.data.data.uploadUrl;
          state.uploadUrl = res.data.data.uploadUrl
        }
      };
@@ -587,12 +579,12 @@
                // if (state.fileList.length === 2) {
                //     state.fileList.splice(0, 1);
                // }
                console.log(state.form.workDetail.gbPath,'gbpath')
              });
        };
      };
      const beforeRemove = (file: {}, fileList: []) => {
        if (file && file.status === "success") {
          const result = new Promise((resolve, reject) => {
            ElMessageBox.confirm('此操作将删除该图片, 是否继续?', '提示', {
              confirmButtonText: '确定',
@@ -602,21 +594,22 @@
                .then(() => {
                  // console.log(state.workDetail.gbPath,'path')
                  const list = JSON.parse(JSON.stringify(state.form.workDetail.gbPath))
                  fileList.map((item,index)=>{
                    if(item.uid === file.uid){
                      fileList.splice(index,1)
                      state.form.workDetail.gbPath.splice(index,1)
                  fileList.map((item, index) => {
                    if (item.uid === file.uid) {
                      fileList.splice(index, 1)
                      state.form.workDetail.gbPath.splice(index, 1)
                      // 请求删除接口
                      deletePic(false,list[index])
                      deletePic(list[index])
                    }
                  })
                  console.log(state.form.workDetail.gbPath,'gbpath')
                  console.log(state.form.workDetail.gbPath, 'gbpath')
                })
                .catch(() => {
                  reject(false);
                });
          });
          return result;
        }
      };
      // 删除图片接口
@@ -662,6 +655,9 @@
        showTip,
        handlePictureCardPreview,
        beforeRemove,
        openWorkSelect,
        getSelected,
        workSelectRef,
                Search,
                ruleFormRef,
                applyRules,
@@ -676,9 +672,11 @@
        width: 100%;
    height: 100vh;
        overflow: hidden;
        position: relative;
    overflow-y: scroll;
    padding: 0 0 120px;
    &::-webkit-scrollbar{
      width: 0;
      background-color: transparent;
    }
        .homeCard{
            width: 100%;
            padding: 20px;
@@ -688,10 +686,6 @@
            margin-bottom: 20px;
        }
        .applyBtn{
      position: fixed;
      left: 0;
      bottom: 0;
      z-index: 999;
            width: 100%;
            background: #fff;
            padding: 20px 0;
@@ -719,7 +713,11 @@
            width: 100% !important;
        }
    }
  .valueSelect{
    ::v-deep(.el-popper){
      display: none !important;
    }
  }
    .tab-i{
        margin-bottom: 15px;
src/views/newSpecialWorkSystem/workTicket/zysq/components/height.vue
@@ -98,15 +98,19 @@
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
        <el-col :span="12" class="valueSelect">
          <el-form-item label="关联其他特殊作业" prop="involveOtherWork">
            <el-select v-model="form.involveOtherWork" multiple clearable>
              <el-option
                  v-for="item in otherWorkList"
                  :key="item.value"
                  :label="item.label"
                  :value="item.label"
              />
<!--            <el-select v-model="form.involveOtherWork" multiple clearable>-->
<!--              <el-option-->
<!--                  v-for="item in otherWorkList"-->
<!--                  :key="item.value"-->
<!--                  :label="item.label"-->
<!--                  :value="item.label"-->
<!--              />-->
<!--            </el-select>-->
            <el-select v-model="form.involveOtherWork" multiple clearable :teleported="false" @click="openWorkSelect">
              <el-option v-for="item in otherWorks" :key="item.workApplyId" :label="item.workContent" :value="item.workApplyId">
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
@@ -174,7 +178,7 @@
        <el-row style="display: flex;justify-content: center">
          <el-table :data="safetyMeasureBasicList" style="width: 90%" border>
            <el-table-column type="index" label="序号" width="100px" align="center"/>
            <el-table-column prop="measureContent" label="安全措施" align="center"/>
            <el-table-column prop="measureContent" label="安全措施"/>
          </el-table>
        </el-row>
        <el-row>
@@ -250,6 +254,7 @@
        <div class="applyBtn">
            <el-button type="primary" size="large" plain @click="submitForm(ruleFormRef)">提交申报</el-button>
        </div>
    <work-select ref="workSelectRef" @refreshWorks="getSelected()"></work-select>
    </div>
</template>
@@ -263,10 +268,10 @@
    import { ElMessage, ElMessageBox } from 'element-plus'
    import type { FormInstance, FormRules } from 'element-plus'
    import { workApplyApi } from '/@/api/specialWorkSystem/workApply';
  import workSelect from "/@/views/newSpecialWorkSystem/workTicket/zysq/components/workSelect.vue";
    interface stateType {
        form: Object,
        workLevelList: Array<any>,
        otherWorkList: Array<any>,
        equipmentDialog: boolean,
    props:{},
    depProps:{},
@@ -274,8 +279,8 @@
    }
    export default defineComponent({
        name: 'heightForm',
        components: {},
        props:['departList','departList2','workerList','deviceList'],
        components: {workSelect},
        props:['departList','departList2','workerList','deviceList','otherWorks'],
        setup(props: any, context: any) {
            const userInfo = useUserInfo()
            const { userInfos } = storeToRefs(userInfo);
@@ -296,7 +301,7 @@
          workContent: '',
          workLocation: '',
          riskIdentification: '',
          involveOtherWork: '',
          involveOtherWork: [],
          safetyMeasureUids: [],
          approvalDepBasicList: [],
          acceptUid: null,
@@ -324,40 +329,6 @@
            value: 7
          }
        ],
                otherWorkList: [
                    {
                        label: "动火作业",
                        value: 1
                    },
                    {
                        label: "受限空间作业",
                        value: 2
                    },
                    {
                        label: "吊装作业",
                        value: 3
                    },
                    {
                        label: "动土作业",
                        value: 4
                    },
                    {
                        label: "断路作业",
                        value: 5
                    },
                    {
                        label: "高处作业",
                        value: 6
                    },
                    {
                        label: "临时用电作业",
                        value: 7
                    },
                    {
                        label: "盲板抽堵作业",
                        value: 8
                    }
                ],
        props:{
          expandTrigger: 'hover',
          label: 'depName',
@@ -392,12 +363,18 @@
        startOrEndUids: [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
                "workDetail.hight": [{ required: true, message: '该内容不能为空', trigger: 'blur' }]
            });
      const workSelectRef = ref()
            // 页面载入时执行方法
            onMounted(() => {
      });
      const openWorkSelect = ()=>{
        workSelectRef.value.openDialog(state.form.involveOtherWork)
      }
      const getSelected = ()=>{
        state.form.involveOtherWork = workSelectRef.value.selected
      }
      const findParent = ()=>{
        state.form.seDepId = findNearestDepLevel2DepId(props.departList2,state.form.applyDepId)
      }
@@ -451,9 +428,9 @@
                return
              }
            }
            if(Array.isArray(state.form.involveOtherWork)){
              state.form.involveOtherWork = state.form.involveOtherWork.join(',')
            }
            // if(Array.isArray(state.form.involveOtherWork)){
            //   state.form.involveOtherWork = state.form.involveOtherWork.join(',')
            // }
            const res = await workApplyApi().submitHeightApply(state.form)
            if (res.data.code === '200') {
              ElMessage({
@@ -467,7 +444,7 @@
                type: 'warning',
                message: res.data.msg
              });
              state.form.involveOtherWork = state.form.involveOtherWork.split(',')
              // state.form.involveOtherWork = state.form.involveOtherWork.split(',')
            }
          } else {
            console.log('error submit!', fields)
@@ -519,6 +496,9 @@
        isFirstRow,
        submitForm,
        findParent,
        openWorkSelect,
        getSelected,
        workSelectRef,
                Search,
                ruleFormRef,
                applyRules,
@@ -533,9 +513,11 @@
        width: 100%;
    height: 100vh;
        overflow: hidden;
        position: relative;
    overflow-y: scroll;
    padding: 0 0 120px;
    &::-webkit-scrollbar{
      width: 0;
      background-color: transparent;
    }
        .homeCard{
            width: 100%;
            padding: 20px;
@@ -545,10 +527,6 @@
            margin-bottom: 20px;
        }
        .applyBtn{
      position: fixed;
      left: 0;
      bottom: 0;
      z-index: 999;
            width: 100%;
            background: #fff;
            padding: 20px 0;
@@ -576,7 +554,11 @@
            width: 100% !important;
        }
    }
  .valueSelect{
    ::v-deep(.el-popper){
      display: none !important;
    }
  }
    .tab-i{
        margin-bottom: 15px;
src/views/newSpecialWorkSystem/workTicket/zysq/components/hoist.vue
@@ -108,15 +108,19 @@
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
        <el-col :span="12" class="valueSelect">
          <el-form-item label="关联其他特殊作业" prop="involveOtherWork">
            <el-select v-model="form.involveOtherWork" multiple clearable>
              <el-option
                  v-for="item in otherWorkList"
                  :key="item.value"
                  :label="item.label"
                  :value="item.label"
              />
<!--            <el-select v-model="form.involveOtherWork" multiple clearable>-->
<!--              <el-option-->
<!--                  v-for="item in otherWorkList"-->
<!--                  :key="item.value"-->
<!--                  :label="item.label"-->
<!--                  :value="item.label"-->
<!--              />-->
<!--            </el-select>-->
            <el-select v-model="form.involveOtherWork" multiple clearable :teleported="false" @click="openWorkSelect">
              <el-option v-for="item in otherWorks" :key="item.workApplyId" :label="item.workContent" :value="item.workApplyId">
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
@@ -209,7 +213,7 @@
        <el-row style="display: flex;justify-content: center">
          <el-table :data="safetyMeasureBasicList" style="width: 90%" border>
            <el-table-column type="index" label="序号" width="100px" align="center"/>
            <el-table-column prop="measureContent" label="安全措施" align="center"/>
            <el-table-column prop="measureContent" label="安全措施"/>
<!--            <el-table-column prop="address" label="确认人">-->
<!--              <template #default="scope">-->
@@ -315,6 +319,7 @@
        <div class="applyBtn">
            <el-button type="primary" size="large" plain @click="submitForm(ruleFormRef)">提交申报</el-button>
        </div>
    <work-select ref="workSelectRef" @refreshWorks="getSelected()"></work-select>
    </div>
</template>
@@ -328,10 +333,10 @@
    import { ElMessage, ElMessageBox } from 'element-plus'
    import type { FormInstance, FormRules } from 'element-plus'
    import { workApplyApi } from '/@/api/specialWorkSystem/workApply';
  import workSelect from "/@/views/newSpecialWorkSystem/workTicket/zysq/components/workSelect.vue";
    interface stateType {
        form: Object,
        workLevelList: Array<any>,
        otherWorkList: Array<any>,
        equipmentDialog: boolean,
    props:{},
    depProps:{},
@@ -339,8 +344,8 @@
    }
    export default defineComponent({
        name: 'hoistForm',
        components: {},
        props:['departList','departList2','workerList','deviceList'],
        components: {workSelect},
        props:['departList','departList2','workerList','deviceList','otherWorks'],
        setup(props: any, context: any) {
            const userInfo = useUserInfo()
            const { userInfos } = storeToRefs(userInfo);
@@ -362,7 +367,7 @@
          workContent: '',
          workLocation: '',
          riskIdentification: '',
          involveOtherWork: '',
          involveOtherWork: [],
          safetyMeasureUids: [],
          approvalDepBasicList: [],
          acceptUid: null,
@@ -388,40 +393,6 @@
            value: 10
          }
        ],
                otherWorkList: [
                    {
                        label: "动火作业",
                        value: 1
                    },
                    {
                        label: "受限空间作业",
                        value: 2
                    },
                    {
                        label: "吊装作业",
                        value: 3
                    },
                    {
                        label: "动土作业",
                        value: 4
                    },
                    {
                        label: "断路作业",
                        value: 5
                    },
                    {
                        label: "高处作业",
                        value: 6
                    },
                    {
                        label: "临时用电作业",
                        value: 7
                    },
                    {
                        label: "盲板抽堵作业",
                        value: 8
                    }
                ],
        props:{
          expandTrigger: 'hover',
          label: 'depName',
@@ -459,12 +430,18 @@
        "workDetail.weightMass": [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
        "workDetail.solicitorUids": [{ required: true, message: '该内容不能为空', trigger: 'blur' }]
            });
      const workSelectRef = ref()
            // 页面载入时执行方法
            onMounted(() => {
      });
      const openWorkSelect = ()=>{
        workSelectRef.value.openDialog(state.form.involveOtherWork)
      }
      const getSelected = ()=>{
        state.form.involveOtherWork = workSelectRef.value.selected
      }
      const findParent = ()=>{
        state.form.seDepId = findNearestDepLevel2DepId(props.departList2,state.form.applyDepId)
        console.log(state.form.seDepId,'state.form.seDepId')
@@ -519,9 +496,9 @@
                return
              }
            }
            if(Array.isArray(state.form.involveOtherWork)){
              state.form.involveOtherWork = state.form.involveOtherWork.join(',')
            }
            // if(Array.isArray(state.form.involveOtherWork)){
            //   state.form.involveOtherWork = state.form.involveOtherWork.join(',')
            // }
            state.form.workDetail.solicitorUids = state.form.workDetail.solicitorUids.join(',')
            const res = await workApplyApi().submitHoistApply(state.form)
            if (res.data.code === '200') {
@@ -536,7 +513,7 @@
                type: 'warning',
                message: res.data.msg
              });
              state.form.involveOtherWork = state.form.involveOtherWork.split(',')
              // state.form.involveOtherWork = state.form.involveOtherWork.split(',')
              state.form.workDetail.solicitorUids = state.form.workDetail.solicitorUids.split(',')
            }
          } else {
@@ -589,6 +566,9 @@
        isFirstRow,
        submitForm,
        findParent,
        openWorkSelect,
        getSelected,
        workSelectRef,
                Search,
                ruleFormRef,
                applyRules,
@@ -603,9 +583,11 @@
        width: 100%;
    height: 100vh;
        overflow: hidden;
        position: relative;
    overflow-y: scroll;
    padding: 0 0 120px;
    &::-webkit-scrollbar{
      width: 0;
      background-color: transparent;
    }
        .homeCard{
            width: 100%;
            padding: 20px;
@@ -615,10 +597,6 @@
            margin-bottom: 20px;
        }
        .applyBtn{
      position: fixed;
      left: 0;
      bottom: 0;
      z-index: 999;
            width: 100%;
            background: #fff;
            padding: 20px 0;
@@ -646,7 +624,11 @@
            width: 100% !important;
        }
    }
  .valueSelect{
    ::v-deep(.el-popper){
      display: none !important;
    }
  }
    .tab-i{
        margin-bottom: 15px;
src/views/newSpecialWorkSystem/workTicket/zysq/components/plate.vue
@@ -132,10 +132,10 @@
          </el-col>
          <el-col :span="12">
            <el-form-item label="盲板位置示意图" prop="workDetail.bpLocationMapPath">
              <el-upload accept="image/*" :auto-upload="true" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='imgLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" list-type="picture-card" :on-remove="handleRemove" :before-remove="beforeRemove" :before-upload="getUploadUrl">
              <el-upload accept="image/*" :auto-upload="true" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='imgLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" list-type="picture-card" :before-remove="beforeRemove" :before-upload="getUploadUrl">
                <el-icon><Plus /></el-icon>
                <template #tip>
                  <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传3张</div>
                  <div class="el-upload__tip">上传jpg/png图片尺寸小于2M,最多可上传3张</div>
                </template>
              </el-upload>
            </el-form-item>
@@ -154,15 +154,19 @@
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
        <el-col :span="12" class="valueSelect">
          <el-form-item label="关联其他特殊作业" prop="involveOtherWork">
            <el-select v-model="form.involveOtherWork" multiple clearable>
              <el-option
                  v-for="item in otherWorkList"
                  :key="item.value"
                  :label="item.label"
                  :value="item.label"
              />
<!--            <el-select v-model="form.involveOtherWork" multiple clearable>-->
<!--              <el-option-->
<!--                  v-for="item in otherWorkList"-->
<!--                  :key="item.value"-->
<!--                  :label="item.label"-->
<!--                  :value="item.label"-->
<!--              />-->
<!--            </el-select>-->
            <el-select v-model="form.involveOtherWork" multiple clearable :teleported="false" @click="openWorkSelect">
              <el-option v-for="item in otherWorks" :key="item.workApplyId" :label="item.workContent" :value="item.workApplyId">
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
@@ -282,7 +286,7 @@
        <el-row style="display: flex;justify-content: center">
          <el-table :data="safetyMeasureBasicList" style="width: 90%" border>
            <el-table-column type="index" label="序号" width="100px" align="center"/>
            <el-table-column prop="measureContent" label="安全措施" align="center"/>
            <el-table-column prop="measureContent" label="安全措施"/>
          </el-table>
        </el-row>
        <el-row>
@@ -358,6 +362,7 @@
        <div class="applyBtn">
            <el-button type="primary" size="large" plain @click="submitForm(ruleFormRef)">提交申报</el-button>
        </div>
    <work-select ref="workSelectRef" @refreshWorks="getSelected()"></work-select>
    </div>
</template>
@@ -371,12 +376,12 @@
    import { ElMessage, ElMessageBox } from 'element-plus'
    import type { FormInstance, FormRules } from 'element-plus'
    import { workApplyApi } from '/@/api/specialWorkSystem/workApply';
  import workSelect from "/@/views/newSpecialWorkSystem/workTicket/zysq/components/workSelect.vue";
  import {UploadProps} from "element-plus/es";
  import axios from "axios";
    interface stateType {
        form: Object,
        workLevelList: Array<any>,
        otherWorkList: Array<any>,
        equipmentDialog: boolean,
    props:{},
    depProps:{},
@@ -392,8 +397,8 @@
  }
    export default defineComponent({
        name: 'fireForm',
        components: {},
        props:['departList','departList2','workerList','deviceList'],
        components: {workSelect},
        props:['departList','departList2','workerList','deviceList','otherWorks'],
        setup(props: any, context: any) {
            const userInfo = useUserInfo()
            const { userInfos } = storeToRefs(userInfo);
@@ -414,7 +419,7 @@
          workContent: '',
          workLocation: '',
          riskIdentification: '',
          involveOtherWork: '',
          involveOtherWork: [],
          safetyMeasureUids: [],
          approvalDepBasicList: [],
          acceptUid: null,
@@ -444,40 +449,6 @@
            value: 12
          }
        ],
                otherWorkList: [
                    {
                        label: "动火作业",
                        value: 1
                    },
                    {
                        label: "受限空间作业",
                        value: 2
                    },
                    {
                        label: "吊装作业",
                        value: 3
                    },
                    {
                        label: "动土作业",
                        value: 4
                    },
                    {
                        label: "断路作业",
                        value: 5
                    },
                    {
                        label: "高处作业",
                        value: 6
                    },
                    {
                        label: "临时用电作业",
                        value: 7
                    },
                    {
                        label: "盲板抽堵作业",
                        value: 8
                    }
                ],
        props:{
          expandTrigger: 'hover',
          label: 'depName',
@@ -527,11 +498,18 @@
        "workDetail.preparedByName": [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
        "workDetail.preparedTime": [{ required: true, message: '该内容不能为空', trigger: 'blur' }]
            });
      const workSelectRef = ref()
            // 页面载入时执行方法
            onMounted(() => {
      });
      const openWorkSelect = ()=>{
        workSelectRef.value.openDialog(state.form.involveOtherWork)
      }
      const getSelected = ()=>{
        state.form.involveOtherWork = workSelectRef.value.selected
      }
      const findParent = ()=>{
        state.form.seDepId = findNearestDepLevel2DepId(props.departList2,state.form.applyDepId)
@@ -587,9 +565,9 @@
                return
              }
            }
            if(Array.isArray(state.form.involveOtherWork)){
              state.form.involveOtherWork = state.form.involveOtherWork.join(',')
            }
            // if(Array.isArray(state.form.involveOtherWork)){
            //   state.form.involveOtherWork = state.form.involveOtherWork.join(',')
            // }
            state.form.workDetail.bpLocationMapPath = state.form.workDetail.bpLocationMapPath.join(',')
            const res = await workApplyApi().submitPlateApply(state.form)
            if (res.data.code === '200') {
@@ -606,7 +584,7 @@
                type: 'warning',
                message: res.data.msg
              });
              state.form.involveOtherWork = state.form.involveOtherWork.split(',')
              // state.form.involveOtherWork = state.form.involveOtherWork.split(',')
              state.form.workDetail.bpLocationMapPath = state.form.workDetail.bpLocationMapPath.split(',')
            }
          } else {
@@ -655,13 +633,13 @@
      };
      const getUploadUrl = async (rawFile: any) => {
        const fileSize = rawFile.size / 1024 / 1024 < 5 ? '1' : '0'
        if(fileSize === '0'){
        // const fileSize = rawFile.size / 1024 / 1024 < 5 ? '1' : '0'
        if(rawFile.size / 1024 / 1024 > 2){
          ElMessage({
            type: 'warning',
            message: '文件大小不能超过5M。'
            message: '文件大小不能超过2M。'
          });
          return false
          return Promise.reject(false)
        }else{
          const res = await workApplyApi().getUpload9Url(rawFile.name);
          state.form.workDetail.bpLocationMapPath.push(res.data.data.fileName)
@@ -686,29 +664,31 @@
      };
      const beforeRemove = (file: {}, fileList: []) => {
        const result = new Promise((resolve, reject) => {
          ElMessageBox.confirm('此操作将删除该图片, 是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          })
              .then(() => {
                // console.log(state.workDetail.bpLocationMapPath,'path')
                const list = JSON.parse(JSON.stringify(state.form.workDetail.bpLocationMapPath))
                fileList.map((item,index)=>{
                  if(item.uid === file.uid){
                    fileList.splice(index,1)
                    state.form.workDetail.bpLocationMapPath.splice(index,1)
                    // 请求删除接口
                    deletePic(false,list[index])
                  }
        if (file && file.status === "success") {
          const result = new Promise((resolve, reject) => {
            ElMessageBox.confirm('此操作将删除该图片, 是否继续?', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            })
                .then(() => {
                  // console.log(state.workDetail.bpLocationMapPath,'path')
                  const list = JSON.parse(JSON.stringify(state.form.workDetail.bpLocationMapPath))
                  fileList.map((item, index) => {
                    if (item.uid === file.uid) {
                      fileList.splice(index, 1)
                      state.form.workDetail.bpLocationMapPath.splice(index, 1)
                      // 请求删除接口
                      deletePic(list[index])
                    }
                  })
                })
              })
              .catch(() => {
                reject(false);
              });
        });
        return result;
                .catch(() => {
                  reject(false);
                });
          });
          return result;
        }
      };
      // 删除图片接口
@@ -754,6 +734,9 @@
        showTip,
        handlePictureCardPreview,
        beforeRemove,
        openWorkSelect,
        getSelected,
        workSelectRef,
                Search,
                ruleFormRef,
                applyRules,
@@ -768,9 +751,11 @@
        width: 100%;
    height: 100vh;
        overflow: hidden;
        position: relative;
    overflow-y: scroll;
    padding: 0 0 120px;
    &::-webkit-scrollbar{
      width: 0;
      background-color: transparent;
    }
        .homeCard{
            width: 100%;
            padding: 20px;
@@ -780,10 +765,6 @@
            margin-bottom: 20px;
        }
        .applyBtn{
      position: fixed;
      left: 0;
      bottom: 0;
      z-index: 999;
            width: 100%;
            background: #fff;
            padding: 20px 0;
@@ -811,7 +792,11 @@
            width: 100% !important;
        }
    }
  .valueSelect{
    ::v-deep(.el-popper){
      display: none !important;
    }
  }
    .tab-i{
        margin-bottom: 15px;
src/views/newSpecialWorkSystem/workTicket/zysq/components/power.vue
@@ -122,15 +122,19 @@
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
        <el-col :span="12" class="valueSelect">
          <el-form-item label="关联其他特殊作业" prop="involveOtherWork">
            <el-select v-model="form.involveOtherWork" multiple clearable>
              <el-option
                  v-for="item in otherWorkList"
                  :key="item.value"
                  :label="item.label"
                  :value="item.label"
              />
<!--            <el-select v-model="form.involveOtherWork" multiple clearable>-->
<!--              <el-option-->
<!--                  v-for="item in otherWorkList"-->
<!--                  :key="item.value"-->
<!--                  :label="item.label"-->
<!--                  :value="item.label"-->
<!--              />-->
<!--            </el-select>-->
            <el-select v-model="form.involveOtherWork" multiple clearable :teleported="false" @click="openWorkSelect">
              <el-option v-for="item in otherWorks" :key="item.workApplyId" :label="item.workContent" :value="item.workApplyId">
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
@@ -223,7 +227,7 @@
        <el-row style="display: flex;justify-content: center">
          <el-table :data="safetyMeasureBasicList" style="width: 90%" border>
            <el-table-column type="index" label="序号" width="100px" align="center"/>
            <el-table-column prop="measureContent" label="安全措施" align="center"/>
            <el-table-column prop="measureContent" label="安全措施"/>
<!--            <el-table-column prop="address" label="确认人">-->
<!--              <template #default="scope">-->
@@ -329,6 +333,7 @@
        <div class="applyBtn">
            <el-button type="primary" size="large" plain @click="submitForm(ruleFormRef)">提交申报</el-button>
        </div>
    <work-select ref="workSelectRef" @refreshWorks="getSelected()"></work-select>
    </div>
</template>
@@ -342,9 +347,9 @@
    import { ElMessage, ElMessageBox } from 'element-plus'
    import type { FormInstance, FormRules } from 'element-plus'
    import { workApplyApi } from '/@/api/specialWorkSystem/workApply';
  import workSelect from "/@/views/newSpecialWorkSystem/workTicket/zysq/components/workSelect.vue";
    interface stateType {
        form: Object,
        otherWorkList: Array<any>,
        equipmentDialog: boolean,
    props:{},
    depProps:{},
@@ -352,8 +357,8 @@
    }
    export default defineComponent({
        name: 'powerForm',
        components: {},
        props:['departList','departList2','workerList','deviceList'],
        components: {workSelect},
        props:['departList','departList2','workerList','deviceList','otherWorks'],
        setup(props: any, context: any) {
            const userInfo = useUserInfo()
            const { userInfos } = storeToRefs(userInfo);
@@ -375,7 +380,7 @@
          workContent: '',
          workLocation: '',
          riskIdentification: '',
          involveOtherWork: '',
          involveOtherWork: [],
          safetyMeasureUids: [],
          approvalDepBasicList: [],
          acceptUid: null,
@@ -388,40 +393,6 @@
            electricityUids: []
          }
                },
                otherWorkList: [
                    {
                        label: "动火作业",
                        value: 1
                    },
                    {
                        label: "受限空间作业",
                        value: 2
                    },
                    {
                        label: "吊装作业",
                        value: 3
                    },
                    {
                        label: "动土作业",
                        value: 4
                    },
                    {
                        label: "断路作业",
                        value: 5
                    },
                    {
                        label: "高处作业",
                        value: 6
                    },
                    {
                        label: "临时用电作业",
                        value: 7
                    },
                    {
                        label: "盲板抽堵作业",
                        value: 8
                    }
                ],
        props:{
          expandTrigger: 'hover',
          label: 'depName',
@@ -460,12 +431,17 @@
        "workDetail.equipmentAndPower": [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
        "workDetail.electricityUids": [{ required: true, message: '该内容不能为空', trigger: 'blur' }]
            });
      const workSelectRef = ref()
            // 页面载入时执行方法
            onMounted(() => {
      });
      const openWorkSelect = ()=>{
        workSelectRef.value.openDialog(state.form.involveOtherWork)
      }
      const getSelected = ()=>{
        state.form.involveOtherWork = workSelectRef.value.selected
      }
      const findParent = ()=>{
        state.form.seDepId = findNearestDepLevel2DepId(props.departList2,state.form.applyDepId)
        console.log(state.form.seDepId,'state.form.seDepId')
@@ -520,9 +496,9 @@
                return
              }
            }
            if(Array.isArray(state.form.involveOtherWork)){
              state.form.involveOtherWork = state.form.involveOtherWork.join(',')
            }
            // if(Array.isArray(state.form.involveOtherWork)){
            //   state.form.involveOtherWork = state.form.involveOtherWork.join(',')
            // }
            state.form.workDetail.electricityUids = state.form.workDetail.electricityUids.join(',')
            const res = await workApplyApi().submitPowerApply(state.form)
            if (res.data.code === '200') {
@@ -537,7 +513,7 @@
                type: 'warning',
                message: res.data.msg
              });
              state.form.involveOtherWork = state.form.involveOtherWork.split(',')
              // state.form.involveOtherWork = state.form.involveOtherWork.split(',')
              state.form.workDetail.electricityUids = state.form.workDetail.electricityUids.split(',')
            }
          } else {
@@ -590,6 +566,9 @@
        isFirstRow,
        submitForm,
        findParent,
        openWorkSelect,
        getSelected,
        workSelectRef,
                Search,
                ruleFormRef,
                applyRules,
@@ -604,9 +583,11 @@
        width: 100%;
    height: 100vh;
        overflow: hidden;
        position: relative;
    overflow-y: scroll;
    padding: 0 0 120px;
    &::-webkit-scrollbar{
      width: 0;
      background-color: transparent;
    }
        .homeCard{
            width: 100%;
            padding: 20px;
@@ -616,10 +597,6 @@
            margin-bottom: 20px;
        }
        .applyBtn{
      position: fixed;
      left: 0;
      bottom: 0;
      z-index: 999;
            width: 100%;
            background: #fff;
            padding: 20px 0;
@@ -647,7 +624,11 @@
            width: 100% !important;
        }
    }
  .valueSelect{
    ::v-deep(.el-popper){
      display: none !important;
    }
  }
    .tab-i{
        margin-bottom: 15px;
src/views/newSpecialWorkSystem/workTicket/zysq/components/space.vue
@@ -99,15 +99,11 @@
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
        <el-col :span="12" class="valueSelect">
          <el-form-item label="关联其他特殊作业" prop="involveOtherWork">
            <el-select v-model="form.involveOtherWork" multiple clearable>
              <el-option
                  v-for="item in otherWorkList"
                  :key="item.value"
                  :label="item.label"
                  :value="item.label"
              />
            <el-select v-model="form.involveOtherWork" multiple clearable :teleported="false" @click="openWorkSelect">
              <el-option v-for="item in otherWorks" :key="item.workApplyId" :label="item.workContent" :value="item.workApplyId">
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
@@ -200,7 +196,7 @@
        <el-row style="display: flex;justify-content: center">
          <el-table :data="safetyMeasureBasicList" style="width: 90%" border>
            <el-table-column type="index" label="序号" width="100px" align="center"/>
            <el-table-column prop="measureContent" label="安全措施" align="center"/>
            <el-table-column prop="measureContent" label="安全措施"/>
          </el-table>
        </el-row>
        <el-row>
@@ -276,11 +272,12 @@
        <div class="applyBtn">
            <el-button type="primary" size="large" plain @click="submitForm(ruleFormRef)">提交申报</el-button>
        </div>
    <work-select ref="workSelectRef" @refreshWorks="getSelected()"></work-select>
    </div>
</template>
<script lang="ts">
    import { toRefs, reactive, defineComponent, ref, defineAsyncComponent, onMounted } from 'vue';
import {toRefs, reactive, defineComponent, ref, defineAsyncComponent, onMounted, onUnmounted} from 'vue';
    import { storeToRefs } from 'pinia';
    import { initBackEndControlRoutes } from '/@/router/backEnd';
    import {useUserInfo} from "/@/stores/userInfo";
@@ -289,9 +286,9 @@
    import { ElMessage, ElMessageBox } from 'element-plus'
    import type { FormInstance, FormRules } from 'element-plus'
    import { workApplyApi } from '/@/api/specialWorkSystem/workApply';
  import workSelect from "/@/views/newSpecialWorkSystem/workTicket/zysq/components/workSelect.vue";
    interface stateType {
        form: Object,
        otherWorkList: Array<any>,
        equipmentDialog: boolean,
    props:{},
    depProps:{},
@@ -299,8 +296,8 @@
    }
    export default defineComponent({
        name: 'spaceForm',
        components: {},
        props:['departList','departList2','workerList','deviceList'],
        components: {workSelect},
        props:['departList','departList2','workerList','deviceList', 'otherWorks'],
        setup(props: any, context: any) {
            const userInfo = useUserInfo()
            const { userInfos } = storeToRefs(userInfo);
@@ -322,7 +319,7 @@
          workContent: '',
          workLocation: '',
          riskIdentification: '',
          involveOtherWork: '',
          involveOtherWork: [],
          safetyMeasureUids: [],
          approvalDepBasicList: [],
          acceptUid: null,
@@ -333,40 +330,6 @@
            csOriginalName: ''
          }
                },
                otherWorkList: [
                    {
                        label: "动火作业",
                        value: 1
                    },
                    {
                        label: "受限空间作业",
                        value: 2
                    },
                    {
                        label: "吊装作业",
                        value: 3
                    },
                    {
                        label: "动土作业",
                        value: 4
                    },
                    {
                        label: "断路作业",
                        value: 5
                    },
                    {
                        label: "高处作业",
                        value: 6
                    },
                    {
                        label: "临时用电作业",
                        value: 7
                    },
                    {
                        label: "盲板抽堵作业",
                        value: 8
                    }
                ],
        props:{
          expandTrigger: 'hover',
          label: 'depName',
@@ -403,10 +366,19 @@
                "workDetail.csName": [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
        "workDetail.csOriginalName": [{ required: true, message: '该内容不能为空', trigger: 'blur' }]
            });
      const workSelectRef = ref()
            // 页面载入时执行方法
            onMounted(() => {
      });
      const openWorkSelect = ()=>{
        workSelectRef.value.openDialog(state.form.involveOtherWork)
      }
      const getSelected = ()=>{
        state.form.involveOtherWork = workSelectRef.value.selected
      }
      const findParent = ()=>{
        state.form.seDepId = findNearestDepLevel2DepId(props.departList2,state.form.applyDepId)
@@ -461,9 +433,9 @@
                return
              }
            }
            if(Array.isArray(state.form.involveOtherWork)){
              state.form.involveOtherWork = state.form.involveOtherWork.join(',')
            }
            // if(Array.isArray(state.form.involveOtherWork)){
            //   state.form.involveOtherWork = state.form.involveOtherWork.join(',')
            // }
            const res = await workApplyApi().submitSpaceApply(state.form)
            if (res.data.code === '200') {
              ElMessage({
@@ -477,7 +449,7 @@
                type: 'warning',
                message: res.data.msg
              });
              state.form.involveOtherWork = state.form.involveOtherWork.split(',')
              // state.form.involveOtherWork = state.form.involveOtherWork.split(',')
            }
          } else {
            console.log('error submit!', fields)
@@ -529,6 +501,9 @@
        isFirstRow,
        submitForm,
        findParent,
        openWorkSelect,
        getSelected,
        workSelectRef,
                Search,
                ruleFormRef,
                applyRules,
@@ -543,9 +518,11 @@
        width: 100%;
    height: 100vh;
        overflow: hidden;
        position: relative;
    overflow-y: scroll;
    padding: 0 0 120px;
    &::-webkit-scrollbar{
      width: 0;
      background-color: transparent;
    }
        .homeCard{
            width: 100%;
            padding: 20px;
@@ -555,10 +532,6 @@
            margin-bottom: 20px;
        }
        .applyBtn{
      position: fixed;
      left: 0;
      bottom: 0;
      z-index: 999;
            width: 100%;
            background: #fff;
            padding: 20px 0;
@@ -586,7 +559,11 @@
            width: 100% !important;
        }
    }
  .valueSelect{
    ::v-deep(.el-popper){
      display: none !important;
    }
  }
    .tab-i{
        margin-bottom: 15px;
src/views/newSpecialWorkSystem/workTicket/zysq/components/workSelect.vue
New file
@@ -0,0 +1,184 @@
<template>
  <el-dialog :title="title" v-model="isShowDialog" width="80%">
    <el-row style="margin-bottom: 20px">
      <div class="basic-line" style="display:flex;white-space:nowrap;line-height: 40px">
        <span>作业编号:</span>
        <el-input v-model="searPara.workPermitNo" placeholder="作业编号"/>
      </div>
      <div class="basic-line">
        <span>作业类型:</span>
        <el-select v-model="searPara.workType">
          <el-option
              v-for="item in workType"
              :key="item.value"
              :label="item.label"
              :value="item.value"
          />
        </el-select>
      </div>
      <div style="margin-left: 20px">
        <el-button type="primary" @click="getData">查询</el-button>
        <el-button plain @click="clearSearch">重置</el-button>
      </div>
    </el-row>
    <el-table ref="TableRef" :data="otherWorks" style="width: 100%" border @selection-change="handleSelectionChange" :row-key="(row) => { return row.workApplyId }">
      <el-table-column type="selection" width="55" />
<!--            <el-table-column type="index" label="序号" width="60" />-->
      <el-table-column prop="workTypeDesc" label="作业类型" show-overflow-tooltip></el-table-column>
      <el-table-column prop="workLevelDesc" label="作业等级" show-overflow-tooltip></el-table-column>
      <el-table-column prop="workPermitNo" label="作业编号" show-overflow-tooltip></el-table-column>
      <el-table-column prop="workLocation" label="作业地点" show-overflow-tooltip></el-table-column>
      <el-table-column prop="workContent" label="作业内容" show-overflow-tooltip></el-table-column>
<!--            <el-table-column label="操作" width="150">-->
<!--              <template #default="scope">-->
<!--                <el-button size="small" text type="primary" @click="onOpenDialogRef('新增', '')">新增</el-button>-->
<!--                <el-button size="small" text type="primary" @click="onOpenDialogRef('修改', scope.row)">修改</el-button>-->
<!--                <el-button size="small" style="color: red" text type="primary" @click="onRowDel(scope.row)">删除</el-button>-->
<!--              </template>-->
<!--            </el-table-column>-->
    </el-table>
      <template #footer>
          <span class="dialog-footer">
              <el-button @click="isShowDialog = !isShowDialog" size="default">取 消</el-button>
              <el-button type="primary" v-throttle @click="onSubmit" size="default">确 定</el-button>
          </span>
      </template>
  </el-dialog>
</template>
<script lang="ts">
import { reactive, toRefs, onMounted, defineComponent, ref } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import { userApi } from '/@/api/systemManage/user';
import {workApplyApi} from "/@/api/specialWorkSystem/workApply";
// 定义接口来定义对象的类型
interface type {}
interface WorkSelectState {
    title: string
    isShowDialog: boolean
    searPara: object
    otherWorks: []
  workType: Array<any>
  selected: Array<any>
}
interface User {
}
export default defineComponent({
    name: 'workSelect',
    setup(props, context) {
        const userRef = ref()
        const state = reactive<WorkSelectState>({
            title: '',
            isShowDialog: false,
            searPara: {
              workPermitNo: '',
              workType: null
            },
            otherWorks: [],
            selected: [],
            workType: [
              {
                label: "动火作业",
                value: 1
              },
              {
                label: "受限空间作业",
                value: 2
              },
              {
                label: "吊装作业",
                value: 3
              },
              {
                label: "动土作业",
                value: 4
              },
              {
                label: "断路作业",
                value: 5
              },
              {
                label: "高处作业",
                value: 6
              },
              {
                label: "临时用电作业",
                value: 7
              },
              {
                label: "盲板抽堵作业",
                value: 8
              }
            ]
        });
        const TableRef = ref()
      const multipleSelection = ref<User[]>([])
        // 打开弹窗
        const openDialog = (works: Array<String>) => {
          state.isShowDialog = true
          getData().then(()=>refreshTableSelection(works))
        };
        const refreshTableSelection = (works) => {
            if (TableRef.value) {
              for (let i = 0; i < state.otherWorks.length; i++) {
                if (works.includes(state.otherWorks[i].workApplyId)){
                  TableRef.value.toggleRowSelection(state.otherWorks[i], true)
                } else{
                  TableRef.value.toggleRowSelection(state.otherWorks[i], false)
                }
              }
            }
        }
        // 获取相关作业列表
        const getData = async () => {
          let res = await workApplyApi().getOtherWork(state.searPara);
          if (res.data.code === '200') {
            state.otherWorks = JSON.parse(JSON.stringify(res.data.data))
          } else {
            ElMessage({
              type: 'warning',
              message: res.data.msg
            });
          }
        };
      const clearSearch = ()=>{
        state.searPara = {
          workPermitNo: '',
          workType: null
        }
        getData()
      }
      const handleSelectionChange = (val: User[]) => {
        multipleSelection.value = val
        state.selected = JSON.parse(JSON.stringify(val)).map(i=>i.workApplyId)
      }
      const onSubmit = ()=>{
        context.emit('refreshWorks')
        state.selected = []
        clearSearch()
        state.isShowDialog = false
      }
        // 页面加载时
        onMounted(() => {});
        return {
            userRef,
          TableRef,
            handleSelectionChange,
            openDialog,
            getData,
            clearSearch,
            onSubmit,
            ...toRefs(state)
        };
    }
});
</script>
src/views/newSpecialWorkSystem/workTicket/zysq/index.vue
@@ -1,29 +1,29 @@
<template>
    <div class="home-container">
        <el-tabs type="border-card" @tab-change="switchTab" v-model="activeName" @tab-click="handleClick">
        <el-tabs type="border-card" v-model="activeName" @tab-click="handleClick">
            <el-tab-pane label="动火作业" name="fire">
                <fire-form ref="fire" :workerList = allWorkers :deviceList = allDevices :departList=departmentList :departList2=departmentList2></fire-form>
                <fire-form ref="fire" :workerList = allWorkers :deviceList = allDevices :departList=departmentList :departList2=departmentList2 :otherWorks="otherWorks"></fire-form>
            </el-tab-pane>
            <el-tab-pane label="受限空间作业" name="space">
                <space-form ref="space" :workerList = allWorkers :departList = departmentList :departList2=departmentList2 :deviceList = allDevices></space-form>
                <space-form ref="space" :workerList = allWorkers :departList = departmentList :departList2=departmentList2 :deviceList = allDevices :otherWorks="otherWorks"></space-form>
            </el-tab-pane>
            <el-tab-pane label="吊装作业" name="hoist">
                <hoist-form ref="hoist" :workerList = allWorkers :departList = departmentList :departList2=departmentList2 :deviceList = allDevices></hoist-form>
                <hoist-form ref="hoist" :workerList = allWorkers :departList = departmentList :departList2=departmentList2 :deviceList = allDevices :otherWorks="otherWorks"></hoist-form>
            </el-tab-pane>
            <el-tab-pane label="动土作业" name="ground">
                <ground-form ref="ground" :workerList = allWorkers :departList = departmentList :departList2=departmentList2 :deviceList = allDevices></ground-form>
                <ground-form ref="ground" :workerList = allWorkers :departList = departmentList :departList2=departmentList2 :deviceList = allDevices :otherWorks="otherWorks"></ground-form>
            </el-tab-pane>
            <el-tab-pane label="断路作业" name="broken">
                <broken-form ref="broken" :workerList = allWorkers :departList = departmentList :departList2=departmentList2 :deviceList = allDevices></broken-form>
                <broken-form ref="broken" :workerList = allWorkers :departList = departmentList :departList2=departmentList2 :deviceList = allDevices :otherWorks="otherWorks"></broken-form>
            </el-tab-pane>
            <el-tab-pane label="高处作业" name="height">
                <height-form ref="height" :workerList = allWorkers :departList = departmentList :departList2=departmentList2 :deviceList = allDevices></height-form>
                <height-form ref="height" :workerList = allWorkers :departList = departmentList :departList2=departmentList2 :deviceList = allDevices :otherWorks="otherWorks"></height-form>
            </el-tab-pane>
            <el-tab-pane label="临时用电作业" name="power">
                <power-form ref="power" :workerList = allWorkers :departList = departmentList :departList2=departmentList2 :deviceList = allDevices></power-form>
                <power-form ref="power" :workerList = allWorkers :departList = departmentList :departList2=departmentList2 :deviceList = allDevices :otherWorks="otherWorks"></power-form>
            </el-tab-pane>
            <el-tab-pane label="盲板抽堵作业" name="plate">
                <plate-form ref="plate" :workerList = allWorkers :departList = departmentList :departList2=departmentList2 :deviceList = allDevices></plate-form>
                <plate-form ref="plate" :workerList = allWorkers :departList = departmentList :departList2=departmentList2 :deviceList = allDevices :otherWorks="otherWorks"></plate-form>
            </el-tab-pane>
        </el-tabs>
<!--    <material-dialog ref="material"></material-dialog>-->
@@ -47,6 +47,7 @@
        allWorkers: Array<any>
        departmentList: Array<any>
    departmentList2: Array<any>
    otherWorks: Array<any>
    allDevices: Array<any>
    }
    export default defineComponent({
@@ -69,6 +70,7 @@
                allWorkers: [],
                departmentList: [],
        departmentList2:[],
        otherWorks: [],
        allDevices: []
            });
      const fire = ref()
@@ -90,6 +92,15 @@
        if(tab.index == 6){power.value.getBasicData()}
        if(tab.index == 7){plate.value.getBasicData()}
      }
      // 页面载入时执行方法
      onMounted(() => {
        getAll();
        getAllDepartment();
        getAllDevice();
        getOtherWork()
      });
            // 获取用户列表
            const getAll = async ()=>{
                const res = await workApplyApi().getAllUsers()
@@ -117,6 +128,19 @@
                }
            };
      // 获取相关作业列表
      const getOtherWork = async () => {
        let res = await workApplyApi().getOtherWork({workPermitNo: '',workType: null});
        if (res.data.code === '200') {
          state.otherWorks = JSON.parse(JSON.stringify(res.data.data))
        } else {
          ElMessage({
            type: 'warning',
            message: res.data.msg
          });
        }
      };
      // 获取设备列表
      const getAllDevice = async ()=>{
        const res = await workApplyApi().getAllDevices()
@@ -130,25 +154,6 @@
        }
      };
      const switchTab = (name)=>{
        // if(name == 'fire'){fire.value.getBasicData()}
        // if(name == 'space'){space.value.getBasicData()}
        // if(name == 'hoist'){hoist.value.getBasicData()}
        // if(name == 'ground'){ground.value.getBasicData()}
        // if(name == 'broken'){broken.value.getBasicData()}
        // if(name == 'height'){height.value.getBasicData()}
        // if(name == 'power'){power.value.getBasicData()}
        // if(name == 'plate'){plate.value.getBasicData()}
      }
            // 页面载入时执行方法
            onMounted(() => {
                getAll();
                getAllDepartment();
        getAllDevice();
            });
            return {
                ...toRefs(state),
        fire,
@@ -159,8 +164,8 @@
        hoist,
        plate,
        power,
        switchTab,
        handleClick
        handleClick,
        getOtherWork
            };
        },
    });
src/views/newSpecialWorkSystem/workerManage/aqyBase/index.vue
New file
@@ -0,0 +1,339 @@
<template>
    <div class="home-container">
        <div style="height: 100%">
            <el-row class="homeCard">
                <el-cascader
                    v-model="userTableData.listQuery.searchParams.depId"
                    :props="props"
                    :options="departmentList"
                    :show-all-levels="false"
                    placeholder="请选择部门"
                    clearable
                    size="default"
                ></el-cascader>
                <el-input size="default" v-model.trim="userTableData.listQuery.searchParams.username" placeholder="请输入用户名" style="max-width: 180px;margin-left: 10px;margin-right: 10px"> </el-input>
                <el-input size="default" v-model.trim="userTableData.listQuery.searchParams.realName" placeholder="请输入真实姓名" style="max-width: 180px"> </el-input>
                <el-button size="default" type="primary" class="ml10" @click="initUserTableData">
                    <el-icon>
                        <ele-Search />
                    </el-icon>
                    查询
                </el-button>
            </el-row>
          <div class="homeCard">
            <div class="main-card">
            <el-table :data="userTableData.data" style="width: 100%" height="calc(100% - 48px)" :header-cell-style="{ background: '#fafafa' }">
                <el-table-column type="index" label="序号" width="60" />
                <el-table-column prop="username" label="用户名" show-overflow-tooltip></el-table-column>
                <el-table-column prop="realName" label="真实姓名" show-overflow-tooltip></el-table-column>
                <el-table-column prop="depName" label="部门" show-overflow-tooltip></el-table-column>
                <el-table-column prop="phone" label="手机号" show-overflow-tooltip></el-table-column>
                <el-table-column prop="email" label="证书编号" show-overflow-tooltip></el-table-column>
                <el-table-column prop="gmtCreate" label="证书有效期至" show-overflow-tooltip></el-table-column>
                <el-table-column label="操作" width="140">
                    <template #default="scope">
                        <el-button :disabled="scope.row.userName === 'admin'" size="small" text type="primary" @click="onOpenUserDialog('查看', scope.row)">查看</el-button>
                        <el-button size="small" text type="primary" @click="onCertificate(scope.row)">证书管理</el-button>
<!--                        <el-button style="color: red" :disabled="scope.row.userName === 'admin'" size="small" text type="primary" @click="onRowDel(scope.row)">删除</el-button>-->
                    </template>
                </el-table-column>
            </el-table>
            <div class="pageBtn">
              <el-pagination @size-change="onHandleSizeChange" small="false" @current-change="onHandleCurrentChange" class="page-position" :pager-count="5" :page-sizes="[10, 20, 30]" v-model:current-page="userTableData.listQuery.pageIndex" background v-model:page-size="userTableData.listQuery.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="userTableData.total"> </el-pagination>
            </div>
            </div>
          </div>
        </div>
        <userDialog ref="userRef" @getUserList="initUserTableData" />
        <dialog-certificate ref="ctfRef" @getUserList="initUserTableData"></dialog-certificate>
    </div>
</template>
<script lang="ts">
import { toRefs, reactive, onMounted, ref, defineComponent } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import userDialog from '/@/views/newSpecialWorkSystem/workerManage/component/userDialog.vue';
import dialogCertificate from "/@/views/system/user/component/dialogCertificate.vue";
import { userApi } from '/@/api/systemManage/user';
import { dutyApi } from '/@/api/systemManage/duty';
import { departmentApi } from '/@/api/systemManage/department';
import { useRoleApi } from '/@/api/systemManage/role';
import {workerManageApi} from "/@/api/specialWorkSystem/workerManage";
// 定义接口来定义对象的类型
interface TableDataRow {
    userName: string;
    userNickname: string;
    roleSign: string;
    department: string[];
    phone: string;
    email: string;
    sex: string;
    password: string;
    overdueTime: Date;
    status: boolean;
    describe: string;
    createTime: string;
}
interface DepartmentDataRow {}
interface TableDataState {
    userTableData: {
        data: Array<TableDataRow>;
        total: number;
        loading: boolean;
        listQuery: {
            searchParams: {
                depId: string | null;
                username: string | null;
                realName: string | null;
            };
            pageIndex: number;
            pageSize: number;
        };
    };
    departmentList: [];
    roleList: [];
    dutyList: [];
    userTypeList: Array<{id:number,name:string}>;
    props:{}
}
export default defineComponent({
    name: 'systemUser',
    components: { userDialog, dialogCertificate },
    setup() {
        const userRef = ref();
      const ctfRef = ref()
        const state = reactive<TableDataState>({
            userTableData: {
                data: [],
                total: 0,
                loading: false,
                listQuery: {
                    searchParams: {
                        depId: null,
                        username: null,
                        realName: null
                    },
                    pageIndex: 1,
                    pageSize: 10
                }
            },
            departmentList: [],
            roleList: [],
            dutyList: [],
            props: {
                label: 'depName',
                value: 'depId',
                checkStrictly: true,
                emitPath: false
            },
            userTypeList: [
                { id: 1, name: '超级管理员' },
                { id: 2, name: '管理员' },
                { id: 3, name: '普通员工' }
            ]
        });
        // 初始化表格数据
        const initUserTableData = async () => {
            let res = await workerManageApi().getHeaderListPage(state.userTableData.listQuery);
            if (res.data.code === '200') {
                state.userTableData.data = res.data.data;
                state.userTableData.total = res.data.total;
            } else {
                ElMessage({
                    type: 'warning',
                    message: res.data.msg
                });
            }
        };
        // 回显职务信息
        const parseNumber = (value: number) => {
            return state.dutyList.find((i) => i.positionId === value)?.positionName;
        };
        const getDepartmentData = async () => {
            let res = await departmentApi().getDepartmentList();
            if (res.data.code === '200') {
                state.departmentList = res.data.data;
            } else {
                ElMessage({
                    type: 'warning',
                    message: res.data.msg
                });
            }
        };
        const getRoleData = async () => {
            let res = await useRoleApi().getRoleList();
            if (res.data.code === '200') {
                state.roleList = res.data.data;
            } else {
                ElMessage({
                    type: 'warning',
                    message: res.data.msg
                });
            }
        };
        const getDutyData = async () => {
            let res = await dutyApi().getAllList({positionName: '',positionCode: ''});
            if (res.data.code === '200') {
                state.dutyList = res.data.data;
            } else {
                ElMessage({
                    type: 'warning',
                    message: res.data.msg
                });
            }
        };
        // 打开新增修改用户弹窗
        const onOpenUserDialog = (type: string, value: any) => {
            userRef.value.openDialog(type, value, state.departmentList, state.roleList, state.dutyList);
        };
      const onCertificate = (value: any)=>{
        ctfRef.value.openDialog(value);
      }
        // 删除用户
        const onRowDel = (row: TableDataRow) => {
            ElMessageBox.confirm(`此操作将永久删除账户名称:“${row.realName}”,是否继续?`, '提示', {
                confirmButtonText: '确认',
                cancelButtonText: '取消',
                type: 'warning'
            })
                .then(async () => {
                    let res = await userApi().deleteUser({ uid: row.uid });
                    if (res.data.code === '200') {
                        ElMessage({
                            type: 'success',
                            duration: 2000,
                            message: '删除成功'
                        });
                        await initUserTableData();
                    } else {
                        ElMessage({
                            type: 'warning',
                            message: res.data.msg
                        });
                    }
                })
                .catch(() => {});
        };
        // 分页改变
        const onHandleSizeChange = (val: number) => {
            state.userTableData.listQuery.pageSize = val;
            initUserTableData();
        };
        // 分页改变
        const onHandleCurrentChange = (val: number) => {
            state.userTableData.listQuery.pageIndex = val;
            initUserTableData();
        };
        // 页面加载时
        onMounted(() => {
            initUserTableData();
            getDepartmentData();
            getRoleData();
            getDutyData()
        });
        return {
            userRef,
            ctfRef,
            onOpenUserDialog,
            onCertificate,
            onRowDel,
            parseNumber,
            onHandleSizeChange,
            initUserTableData,
            onHandleCurrentChange,
            ...toRefs(state)
        };
    }
});
</script>
<style lang="scss" scoped>
.home-container {
  height: calc(100vh - 144px);
  box-sizing: border-box;
  overflow: hidden;
  .demo-tabs {
    width: 100%;
    height: 100%;
    &::v-deep(.el-tabs__content) {
      height: calc(100% - 60px);
    }
    .el-tab-pane {
      height: 100%;
    }
  }
  .homeCard {
    width: 100%;
    padding: 20px;
    box-sizing: border-box;
    background: #fff;
    border-radius: 4px;
    .main-card {
      width: 100%;
      height: 100%;
      .cardTop {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 20px;
        .mainCardBtn {
          margin: 0;
        }
      }
      .pageBtn {
        height: 60px;
        display: flex;
        align-items: center;
        justify-content: right;
        .demo-pagination-block + .demo-pagination-block {
          margin-top: 10px;
        }
        .demo-pagination-block .demonstration {
          margin-bottom: 16px;
        }
      }
    }
    &:last-of-type {
      height: calc(100% - 100px);
    }
  }
  .el-row {
    display: flex;
    align-items: center;
    margin-bottom: 20px;
    &:last-child {
      margin-bottom: 0;
    }
    .grid-content {
      align-items: center;
      min-height: 36px;
    }
    .topInfo {
      display: flex;
      align-items: center;
      font-size: 16px;
      font-weight: bold;
      & > div {
        white-space: nowrap;
        margin-right: 20px;
      }
    }
  }
  .el-card {
    border: 0;
  }
}
</style>
src/views/newSpecialWorkSystem/workerManage/component/userDialog.vue
New file
@@ -0,0 +1,279 @@
<template>
    <div class="system-add-user-container">
        <el-dialog :title="title" v-model="isShowUserDialog" width="769px">
            <el-form :model="userForm" size="default" ref="userRef" :rules="userFormRules" label-width="90px">
                <el-row :gutter="35">
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20" v-if="disabled">
                        <el-form-item label="用户名" prop="username">
                            <el-input v-model.trim="userForm.username" :disabled="disabled" placeholder="" clearable></el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="真实姓名" prop="realName">
                            <el-input v-model.trim="userForm.realName" :disabled="allDisabled" placeholder="请输入真实姓名" clearable></el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="关联角色" prop="roleIds">
                            <el-select v-model="userForm.roleIds" placeholder="请选择" clearable class="w100" multiple :disabled="allDisabled">
                                <el-option v-for="item in roleData" :key="item.roleId" :label="item.roleName" :value="item.roleId"> </el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="部门" prop="depId">
                            <el-cascader :options="departmentData" :props="{ emitPath: false, checkStrictly: true, value: 'depId', label: 'depName' }" placeholder="请选择部门" clearable class="w100" v-model="userForm.depId" :disabled="allDisabled"> </el-cascader>
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="职务" prop="positionIds">
                            <el-select v-model="userForm.positionIds" placeholder="请选择" clearable class="w100" multiple :disabled="allDisabled">
                                <el-option v-for="item in dutyData" :key="item.positionId" :label="item.positionName" :value="item.positionId"> </el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="手机号" prop="phone">
                            <el-input v-model.trim="userForm.phone" placeholder="请输入手机号" clearable :disabled="allDisabled"></el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="身份证">
                            <el-input v-model.trim="userForm.identify" placeholder="请输入身份证" clearable :disabled="allDisabled"></el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="邮箱">
                            <el-input v-model.trim="userForm.email" placeholder="请输入" clearable :disabled="allDisabled"></el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="性别" prop="gender">
                            <el-select v-model="userForm.gender" placeholder="请选择" clearable class="w100" :disabled="allDisabled">
                                <el-option v-for="item in sexList" :key="item.id" :value="item.id" :label="item.name"> </el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
<!--                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">-->
<!--                        <el-form-item label="账户过期" prop="expireTime">-->
<!--                            <el-date-picker v-model="userForm.expireTime" type="date" placeholder="请选择" class="w100"> </el-date-picker>-->
<!--                        </el-form-item>-->
<!--                    </el-col>-->
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20" v-if="!disabled">
                        <el-form-item label="账户密码" prop="password">
                            <el-input v-model.trim="userForm.password" placeholder="请输入" type="password" show-password>
                            </el-input>
                        </el-form-item>
                    </el-col>
                  <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                    <el-form-item label="用户类型" prop="type">
                      <el-select v-model="userForm.type" placeholder="请选择" clearable class="w100" :disabled="allDisabled">
                        <el-option v-for="item in userTypeList.filter(item => userForm.type === 1 ? item.id === 1 : item.id !== 1)" :key="item.id" :label="item.name" :value="item.id"> </el-option>
                      </el-select>
                    </el-form-item>
                  </el-col>
                    <!--                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">-->
                    <!--                        <el-form-item label="用户状态">-->
                    <!--                            <el-switch v-model="userForm.status" inline-prompt active-value = 1 inactive-value= 0 active-text="启" inactive-text="禁"></el-switch>-->
                    <!--                        </el-form-item>-->
                    <!--                    </el-col>-->
                </el-row>
            </el-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="isShowUserDialog = !isShowUserDialog" size="default">取 消</el-button>
                    <el-button type="primary" v-throttle @click="onSubmit" size="default" v-if="!allDisabled">确 定</el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>
<script lang="ts">
import { reactive, toRefs, onMounted, defineComponent, ref } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import { userApi } from '/@/api/systemManage/user';
// 定义接口来定义对象的类型
interface DeptData {}
interface roleData {}
interface dutyData {}
interface sexData {}
interface type {}
interface UserState {
    title: string;
    disabled: boolean;
    allDisabled: boolean;
    isShowUserDialog: boolean;
    userForm: {
        username: string;
        realName: string;
        roleIds: Array<number>
        depId: number | null;
        positionIds: Array<number>
        phone: string;
        email: string;
        gender: number | null;
        type: number | null;
        password: string;
        status: number;
        identify: string;
    };
    userFormRules:{
    },
    departmentData: Array<DeptData>;
    roleData: Array<roleData>;
    dutyData: Array<dutyData>;
    sexList: Array<sexData>;
    userTypeList: Array<type>;
}
export default defineComponent({
    name: 'user',
    setup(props, context) {
        const userRef = ref()
        const state = reactive<UserState>({
            title: '',
            disabled: false,
            allDisabled: false,
            isShowUserDialog: false,
            userForm: {
                username: '', // 账户名称
                realName: '', // 用户昵称
                roleIds: [], // 关联角色
                depId: null, // 部门
                phone: '', // 手机号
                email: '', // 邮箱
                identify: '',
                gender: null, // 性别
                password: '', // 账户密码
                positionIds: [], // 岗位
                type: null, // 用户类型
                status: 1 // 用户状态
            },
            userFormRules:{
                username: [{ required: true, message: '请填写用户名', trigger: 'blur' }],
                realName: [{ required: true, message: '请填写真实姓名', trigger: 'blur' }],
                roleIds: [{ required: true, message: '请选择用户角色', trigger: 'change' }],
                depId: [{ required: true, message: '请选择部门', trigger: 'change' }],
                positionIds: [{ required: true, message: '请选择职务', trigger: 'change' }],
                phone: [{ required: true, message: '请填写手机号', trigger: 'blur' }],
                type: [{ required: true, message: '请填写用户类型', trigger: 'blur' }],
                gender: [{ required: true, message: '请选择性别', trigger: 'change' }],
                password: [{ required: true, message: '请输入账户密码', trigger: 'blur' }],
            },
            departmentData: [], // 部门数据
            roleData: [], //角色数据
            dutyData:[], //职务数据
            sexList: [
                { id: 1, name: '男' },
                { id: 0, name: '女' }
            ],
            userTypeList: [
                { id: 1, name: '超级管理员' },
                { id: 2, name: '管理员' },
                { id: 3, name: '普通员工' }
            ],
        });
        // 打开弹窗
        const openDialog = (type: string, value: any, departmentList: [], roleList: [], dutyList:[]) => {
            state.isShowUserDialog = true;
            state.departmentData = departmentList;
            state.roleData = roleList;
            state.dutyData = dutyList
            if (type === '新增') {
                state.disabled = false
                state.allDisabled = false
                state.title = '新增用户';
                state.userForm = {
                    username: '',
                    realName: '',
                    roleIds: [],
                    depId: null,
                    phone: '',
                    email: '',
                    identify: '',
                    positionIds: [],
                    gender: null,
                    type: null,
                    password: '',
                    status: 1
                };
            } else{
              if(type === '修改'){
                state.disabled = true
                state.allDisabled = false
                state.title = '修改用户';
                state.userForm = JSON.parse(JSON.stringify(value));
                state.userForm.roleIds = JSON.parse(JSON.stringify(value)).roles?.map(obj=>obj.roleId)
                state.userForm.positionIds = JSON.parse(JSON.stringify(value)).positions?.map(obj=>obj.positionId)
              }else{
                state.disabled = true
                state.allDisabled = true
                state.title = '查看';
                state.userForm = JSON.parse(JSON.stringify(value));
                state.userForm.roleIds = JSON.parse(JSON.stringify(value)).roles?.map(obj=>obj.roleId)
                state.userForm.positionIds = JSON.parse(JSON.stringify(value)).positions?.map(obj=>obj.positionId)
              }
            }
        };
        // 新增修改
        const onSubmit = async () => {
            userRef.value.validate(async (valid:Boolean) => {
                if(valid){
                    if (state.title === '新增用户') {
                        let res = await userApi().addUser(state.userForm);
                        if (res.data.code === '200') {
                            ElMessage({
                                type: 'success',
                                message: '用户新增成功',
                                duration: 2000
                            });
                            state.isShowUserDialog = false;
                            context.emit('getUserList');
                        } else {
                            ElMessage({
                                type: 'warning',
                                message: res.data.msg
                            });
                        }
                    } else {
                        let res = await userApi().modUser(state.userForm);
                        if (res.data.code === '200') {
                            ElMessage({
                                type: 'success',
                                message: '用户修改成功',
                                duration: 2000
                            });
                            state.isShowUserDialog = false;
                            context.emit('getUserList');
                        } else {
                            ElMessage({
                                type: 'warning',
                                message: res.data.msg
                            });
                        }
                    }
                }else{
                    ElMessage({
                        type:'warning',
                        message:'请完善基本信息'
                    })
                }
            })
        };
        // 页面加载时
        onMounted(() => {});
        return {
            userRef,
            openDialog,
            onSubmit,
            ...toRefs(state)
        };
    }
});
</script>
src/views/newSpecialWorkSystem/workerManage/guardianBase/index.vue
New file
@@ -0,0 +1,339 @@
<template>
  <div class="home-container">
    <div style="height: 100%">
      <el-row class="homeCard">
        <el-cascader
            v-model="userTableData.listQuery.searchParams.depId"
            :props="props"
            :options="departmentList"
            :show-all-levels="false"
            placeholder="请选择部门"
            clearable
            size="default"
        ></el-cascader>
        <el-input size="default" v-model.trim="userTableData.listQuery.searchParams.username" placeholder="请输入用户名" style="max-width: 180px;margin-left: 10px;margin-right: 10px"> </el-input>
        <el-input size="default" v-model.trim="userTableData.listQuery.searchParams.realName" placeholder="请输入真实姓名" style="max-width: 180px"> </el-input>
        <el-button size="default" type="primary" class="ml10" @click="initUserTableData">
          <el-icon>
            <ele-Search />
          </el-icon>
          查询
        </el-button>
      </el-row>
      <div class="homeCard">
        <div class="main-card">
          <el-table :data="userTableData.data" style="width: 100%" height="calc(100% - 48px)" :header-cell-style="{ background: '#fafafa' }">
            <el-table-column type="index" label="序号" width="60" />
            <el-table-column prop="username" label="用户名" show-overflow-tooltip></el-table-column>
            <el-table-column prop="realName" label="真实姓名" show-overflow-tooltip></el-table-column>
            <el-table-column prop="depName" label="部门" show-overflow-tooltip></el-table-column>
            <el-table-column prop="phone" label="手机号" show-overflow-tooltip></el-table-column>
            <el-table-column prop="email" label="证书编号" show-overflow-tooltip></el-table-column>
            <el-table-column prop="gmtCreate" label="证书有效期至" show-overflow-tooltip></el-table-column>
            <el-table-column label="操作" width="140">
              <template #default="scope">
                <el-button :disabled="scope.row.userName === 'admin'" size="small" text type="primary" @click="onOpenUserDialog('查看', scope.row)">查看</el-button>
                <el-button size="small" text type="primary" @click="onCertificate(scope.row)">证书管理</el-button>
                <!--                        <el-button style="color: red" :disabled="scope.row.userName === 'admin'" size="small" text type="primary" @click="onRowDel(scope.row)">删除</el-button>-->
              </template>
            </el-table-column>
          </el-table>
          <div class="pageBtn">
            <el-pagination @size-change="onHandleSizeChange" small="false" @current-change="onHandleCurrentChange" class="page-position" :pager-count="5" :page-sizes="[10, 20, 30]" v-model:current-page="userTableData.listQuery.pageIndex" background v-model:page-size="userTableData.listQuery.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="userTableData.total"> </el-pagination>
          </div>
        </div>
      </div>
    </div>
    <userDialog ref="userRef" @getUserList="initUserTableData" />
    <dialog-certificate ref="ctfRef" @getUserList="initUserTableData"></dialog-certificate>
  </div>
</template>
<script lang="ts">
import { toRefs, reactive, onMounted, ref, defineComponent } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import userDialog from '/@/views/newSpecialWorkSystem/workerManage/component/userDialog.vue';
import dialogCertificate from "/@/views/system/user/component/dialogCertificate.vue";
import { userApi } from '/@/api/systemManage/user';
import { dutyApi } from '/@/api/systemManage/duty';
import { departmentApi } from '/@/api/systemManage/department';
import { useRoleApi } from '/@/api/systemManage/role';
import {workerManageApi} from "/@/api/specialWorkSystem/workerManage";
// 定义接口来定义对象的类型
interface TableDataRow {
    userName: string;
    userNickname: string;
    roleSign: string;
    department: string[];
    phone: string;
    email: string;
    sex: string;
    password: string;
    overdueTime: Date;
    status: boolean;
    describe: string;
    createTime: string;
}
interface DepartmentDataRow {}
interface TableDataState {
    userTableData: {
        data: Array<TableDataRow>;
        total: number;
        loading: boolean;
        listQuery: {
            searchParams: {
                depId: string | null;
                username: string | null;
                realName: string | null;
            };
            pageIndex: number;
            pageSize: number;
        };
    };
    departmentList: [];
    roleList: [];
    dutyList: [];
    userTypeList: Array<{id:number,name:string}>;
    props:{}
}
export default defineComponent({
    name: 'systemUser',
    components: { userDialog, dialogCertificate },
    setup() {
        const userRef = ref();
      const ctfRef = ref()
        const state = reactive<TableDataState>({
            userTableData: {
                data: [],
                total: 0,
                loading: false,
                listQuery: {
                    searchParams: {
                        depId: null,
                        username: null,
                        realName: null
                    },
                    pageIndex: 1,
                    pageSize: 10
                }
            },
            departmentList: [],
            roleList: [],
            dutyList: [],
            props: {
                label: 'depName',
                value: 'depId',
                checkStrictly: true,
                emitPath: false
            },
            userTypeList: [
                { id: 1, name: '超级管理员' },
                { id: 2, name: '管理员' },
                { id: 3, name: '普通员工' }
            ]
        });
        // 初始化表格数据
        const initUserTableData = async () => {
            let res = await workerManageApi().getGuardianListPage(state.userTableData.listQuery);
            if (res.data.code === '200') {
                state.userTableData.data = res.data.data;
                state.userTableData.total = res.data.total;
            } else {
                ElMessage({
                    type: 'warning',
                    message: res.data.msg
                });
            }
        };
        // 回显职务信息
        const parseNumber = (value: number) => {
            return state.dutyList.find((i) => i.positionId === value)?.positionName;
        };
        const getDepartmentData = async () => {
            let res = await departmentApi().getDepartmentList();
            if (res.data.code === '200') {
                state.departmentList = res.data.data;
            } else {
                ElMessage({
                    type: 'warning',
                    message: res.data.msg
                });
            }
        };
        const getRoleData = async () => {
            let res = await useRoleApi().getRoleList();
            if (res.data.code === '200') {
                state.roleList = res.data.data;
            } else {
                ElMessage({
                    type: 'warning',
                    message: res.data.msg
                });
            }
        };
        const getDutyData = async () => {
            let res = await dutyApi().getAllList({positionName: '',positionCode: ''});
            if (res.data.code === '200') {
                state.dutyList = res.data.data;
            } else {
                ElMessage({
                    type: 'warning',
                    message: res.data.msg
                });
            }
        };
        // 打开新增修改用户弹窗
        const onOpenUserDialog = (type: string, value: any) => {
            userRef.value.openDialog(type, value, state.departmentList, state.roleList, state.dutyList);
        };
      const onCertificate = (value: any)=>{
        ctfRef.value.openDialog(value);
      }
        // 删除用户
        const onRowDel = (row: TableDataRow) => {
            ElMessageBox.confirm(`此操作将永久删除账户名称:“${row.realName}”,是否继续?`, '提示', {
                confirmButtonText: '确认',
                cancelButtonText: '取消',
                type: 'warning'
            })
                .then(async () => {
                    let res = await userApi().deleteUser({ uid: row.uid });
                    if (res.data.code === '200') {
                        ElMessage({
                            type: 'success',
                            duration: 2000,
                            message: '删除成功'
                        });
                        await initUserTableData();
                    } else {
                        ElMessage({
                            type: 'warning',
                            message: res.data.msg
                        });
                    }
                })
                .catch(() => {});
        };
        // 分页改变
        const onHandleSizeChange = (val: number) => {
            state.userTableData.listQuery.pageSize = val;
            initUserTableData();
        };
        // 分页改变
        const onHandleCurrentChange = (val: number) => {
            state.userTableData.listQuery.pageIndex = val;
            initUserTableData();
        };
        // 页面加载时
        onMounted(() => {
            initUserTableData();
            getDepartmentData();
            getRoleData();
            getDutyData()
        });
        return {
            userRef,
            ctfRef,
            onOpenUserDialog,
            onCertificate,
            onRowDel,
            parseNumber,
            onHandleSizeChange,
            initUserTableData,
            onHandleCurrentChange,
            ...toRefs(state)
        };
    }
});
</script>
<style lang="scss" scoped>
.home-container {
  height: calc(100vh - 144px);
  box-sizing: border-box;
  overflow: hidden;
  .demo-tabs {
    width: 100%;
    height: 100%;
    &::v-deep(.el-tabs__content) {
      height: calc(100% - 60px);
    }
    .el-tab-pane {
      height: 100%;
    }
  }
  .homeCard {
    width: 100%;
    padding: 20px;
    box-sizing: border-box;
    background: #fff;
    border-radius: 4px;
    .main-card {
      width: 100%;
      height: 100%;
      .cardTop {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 20px;
        .mainCardBtn {
          margin: 0;
        }
      }
      .pageBtn {
        height: 60px;
        display: flex;
        align-items: center;
        justify-content: right;
        .demo-pagination-block + .demo-pagination-block {
          margin-top: 10px;
        }
        .demo-pagination-block .demonstration {
          margin-bottom: 16px;
        }
      }
    }
    &:last-of-type {
      height: calc(100% - 100px);
    }
  }
  .el-row {
    display: flex;
    align-items: center;
    margin-bottom: 20px;
    &:last-child {
      margin-bottom: 0;
    }
    .grid-content {
      align-items: center;
      min-height: 36px;
    }
    .topInfo {
      display: flex;
      align-items: center;
      font-size: 16px;
      font-weight: bold;
      & > div {
        white-space: nowrap;
        margin-right: 20px;
      }
    }
  }
  .el-card {
    border: 0;
  }
}
</style>
src/views/newSpecialWorkSystem/workerManage/operatorBase/index.vue
New file
@@ -0,0 +1,339 @@
<template>
  <div class="home-container">
    <div style="height: 100%">
      <el-row class="homeCard">
        <el-cascader
            v-model="userTableData.listQuery.searchParams.depId"
            :props="props"
            :options="departmentList"
            :show-all-levels="false"
            placeholder="请选择部门"
            clearable
            size="default"
        ></el-cascader>
        <el-input size="default" v-model.trim="userTableData.listQuery.searchParams.username" placeholder="请输入用户名" style="max-width: 180px;margin-left: 10px;margin-right: 10px"> </el-input>
        <el-input size="default" v-model.trim="userTableData.listQuery.searchParams.realName" placeholder="请输入真实姓名" style="max-width: 180px"> </el-input>
        <el-button size="default" type="primary" class="ml10" @click="initUserTableData">
          <el-icon>
            <ele-Search />
          </el-icon>
          查询
        </el-button>
      </el-row>
      <div class="homeCard">
        <div class="main-card">
          <el-table :data="userTableData.data" style="width: 100%" height="calc(100% - 48px)" :header-cell-style="{ background: '#fafafa' }">
            <el-table-column type="index" label="序号" width="60" />
            <el-table-column prop="username" label="用户名" show-overflow-tooltip></el-table-column>
            <el-table-column prop="realName" label="真实姓名" show-overflow-tooltip></el-table-column>
            <el-table-column prop="depName" label="部门" show-overflow-tooltip></el-table-column>
            <el-table-column prop="phone" label="手机号" show-overflow-tooltip></el-table-column>
            <el-table-column prop="email" label="证书编号" show-overflow-tooltip></el-table-column>
            <el-table-column prop="gmtCreate" label="证书有效期至" show-overflow-tooltip></el-table-column>
            <el-table-column label="操作" width="140">
              <template #default="scope">
                <el-button :disabled="scope.row.userName === 'admin'" size="small" text type="primary" @click="onOpenUserDialog('查看', scope.row)">查看</el-button>
                <el-button size="small" text type="primary" @click="onCertificate(scope.row)">证书管理</el-button>
                <!--                        <el-button style="color: red" :disabled="scope.row.userName === 'admin'" size="small" text type="primary" @click="onRowDel(scope.row)">删除</el-button>-->
              </template>
            </el-table-column>
          </el-table>
          <div class="pageBtn">
            <el-pagination @size-change="onHandleSizeChange" small="false" @current-change="onHandleCurrentChange" class="page-position" :pager-count="5" :page-sizes="[10, 20, 30]" v-model:current-page="userTableData.listQuery.pageIndex" background v-model:page-size="userTableData.listQuery.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="userTableData.total"> </el-pagination>
          </div>
        </div>
      </div>
    </div>
    <userDialog ref="userRef" @getUserList="initUserTableData" />
    <dialog-certificate ref="ctfRef" @getUserList="initUserTableData"></dialog-certificate>
  </div>
</template>
<script lang="ts">
import { toRefs, reactive, onMounted, ref, defineComponent } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import userDialog from '/@/views/newSpecialWorkSystem/workerManage/component/userDialog.vue';
import dialogCertificate from "/@/views/system/user/component/dialogCertificate.vue";
import { userApi } from '/@/api/systemManage/user';
import { dutyApi } from '/@/api/systemManage/duty';
import { departmentApi } from '/@/api/systemManage/department';
import { useRoleApi } from '/@/api/systemManage/role';
import {workerManageApi} from "/@/api/specialWorkSystem/workerManage";
// 定义接口来定义对象的类型
interface TableDataRow {
    userName: string;
    userNickname: string;
    roleSign: string;
    department: string[];
    phone: string;
    email: string;
    sex: string;
    password: string;
    overdueTime: Date;
    status: boolean;
    describe: string;
    createTime: string;
}
interface DepartmentDataRow {}
interface TableDataState {
    userTableData: {
        data: Array<TableDataRow>;
        total: number;
        loading: boolean;
        listQuery: {
            searchParams: {
                depId: string | null;
                username: string | null;
                realName: string | null;
            };
            pageIndex: number;
            pageSize: number;
        };
    };
    departmentList: [];
    roleList: [];
    dutyList: [];
    userTypeList: Array<{id:number,name:string}>;
    props:{}
}
export default defineComponent({
    name: 'systemUser',
    components: { userDialog, dialogCertificate },
    setup() {
        const userRef = ref();
      const ctfRef = ref()
        const state = reactive<TableDataState>({
            userTableData: {
                data: [],
                total: 0,
                loading: false,
                listQuery: {
                    searchParams: {
                        depId: null,
                        username: null,
                        realName: null
                    },
                    pageIndex: 1,
                    pageSize: 10
                }
            },
            departmentList: [],
            roleList: [],
            dutyList: [],
            props: {
                label: 'depName',
                value: 'depId',
                checkStrictly: true,
                emitPath: false
            },
            userTypeList: [
                { id: 1, name: '超级管理员' },
                { id: 2, name: '管理员' },
                { id: 3, name: '普通员工' }
            ]
        });
        // 初始化表格数据
        const initUserTableData = async () => {
            let res = await workerManageApi().getOperatorListPage(state.userTableData.listQuery);
            if (res.data.code === '200') {
                state.userTableData.data = res.data.data;
                state.userTableData.total = res.data.total;
            } else {
                ElMessage({
                    type: 'warning',
                    message: res.data.msg
                });
            }
        };
        // 回显职务信息
        const parseNumber = (value: number) => {
            return state.dutyList.find((i) => i.positionId === value)?.positionName;
        };
        const getDepartmentData = async () => {
            let res = await departmentApi().getDepartmentList();
            if (res.data.code === '200') {
                state.departmentList = res.data.data;
            } else {
                ElMessage({
                    type: 'warning',
                    message: res.data.msg
                });
            }
        };
        const getRoleData = async () => {
            let res = await useRoleApi().getRoleList();
            if (res.data.code === '200') {
                state.roleList = res.data.data;
            } else {
                ElMessage({
                    type: 'warning',
                    message: res.data.msg
                });
            }
        };
        const getDutyData = async () => {
            let res = await dutyApi().getAllList({positionName: '',positionCode: ''});
            if (res.data.code === '200') {
                state.dutyList = res.data.data;
            } else {
                ElMessage({
                    type: 'warning',
                    message: res.data.msg
                });
            }
        };
        // 打开新增修改用户弹窗
        const onOpenUserDialog = (type: string, value: any) => {
            userRef.value.openDialog(type, value, state.departmentList, state.roleList, state.dutyList);
        };
      const onCertificate = (value: any)=>{
        ctfRef.value.openDialog(value);
      }
        // 删除用户
        const onRowDel = (row: TableDataRow) => {
            ElMessageBox.confirm(`此操作将永久删除账户名称:“${row.realName}”,是否继续?`, '提示', {
                confirmButtonText: '确认',
                cancelButtonText: '取消',
                type: 'warning'
            })
                .then(async () => {
                    let res = await userApi().deleteUser({ uid: row.uid });
                    if (res.data.code === '200') {
                        ElMessage({
                            type: 'success',
                            duration: 2000,
                            message: '删除成功'
                        });
                        await initUserTableData();
                    } else {
                        ElMessage({
                            type: 'warning',
                            message: res.data.msg
                        });
                    }
                })
                .catch(() => {});
        };
        // 分页改变
        const onHandleSizeChange = (val: number) => {
            state.userTableData.listQuery.pageSize = val;
            initUserTableData();
        };
        // 分页改变
        const onHandleCurrentChange = (val: number) => {
            state.userTableData.listQuery.pageIndex = val;
            initUserTableData();
        };
        // 页面加载时
        onMounted(() => {
            initUserTableData();
            getDepartmentData();
            getRoleData();
            getDutyData()
        });
        return {
            userRef,
            ctfRef,
            onOpenUserDialog,
            onCertificate,
            onRowDel,
            parseNumber,
            onHandleSizeChange,
            initUserTableData,
            onHandleCurrentChange,
            ...toRefs(state)
        };
    }
});
</script>
<style lang="scss" scoped>
.home-container {
  height: calc(100vh - 144px);
  box-sizing: border-box;
  overflow: hidden;
  .demo-tabs {
    width: 100%;
    height: 100%;
    &::v-deep(.el-tabs__content) {
      height: calc(100% - 60px);
    }
    .el-tab-pane {
      height: 100%;
    }
  }
  .homeCard {
    width: 100%;
    padding: 20px;
    box-sizing: border-box;
    background: #fff;
    border-radius: 4px;
    .main-card {
      width: 100%;
      height: 100%;
      .cardTop {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 20px;
        .mainCardBtn {
          margin: 0;
        }
      }
      .pageBtn {
        height: 60px;
        display: flex;
        align-items: center;
        justify-content: right;
        .demo-pagination-block + .demo-pagination-block {
          margin-top: 10px;
        }
        .demo-pagination-block .demonstration {
          margin-bottom: 16px;
        }
      }
    }
    &:last-of-type {
      height: calc(100% - 100px);
    }
  }
  .el-row {
    display: flex;
    align-items: center;
    margin-bottom: 20px;
    &:last-child {
      margin-bottom: 0;
    }
    .grid-content {
      align-items: center;
      min-height: 36px;
    }
    .topInfo {
      display: flex;
      align-items: center;
      font-size: 16px;
      font-weight: bold;
      & > div {
        white-space: nowrap;
        margin-right: 20px;
      }
    }
  }
  .el-card {
    border: 0;
  }
}
</style>
src/views/specialWorkSystem/alarm/zyyjjl/index.vue
@@ -182,18 +182,18 @@
                deleteId: null,
                deleteArr: [],
                workTypeList: [
                    { id: '1', name: '动火作业' },
                    { id: '2', name: '受限空间作业' },
                    { id: '3', name: '吊装作业' },
                    { id: '4', name: '动土作业' },
                    { id: '5', name: '断路作业' },
                    { id: '6', name: '高处作业' },
                    { id: '7', name: '临时用电作业' },
                    { id: '8', name: '盲板抽堵作业' }
                    { id: 1, name: '动火作业' },
                    { id: 2, name: '受限空间作业' },
                    { id: 3, name: '吊装作业' },
                    { id: 4, name: '动土作业' },
                    { id: 5, name: '断路作业' },
                    { id: 6, name: '高处作业' },
                    { id: 7, name: '临时用电作业' },
                    { id: 8, name: '盲板抽堵作业' }
                ],
                alertTypeList: [
                    { id: '1', name: '检查' },
                    { id: '2', name: '检测' }
                    { id: 1, name: '检查' },
                    { id: 2, name: '检测' }
                ]
            });
@@ -202,7 +202,7 @@
                getListByPage();
            });
            // 分页获取班组管理列表
            // 分页获取预警列表
            const getListByPage = async () => {
                const data = { pageSize: state.pageSize, pageIndex: state.pageIndex, searchParams: { workType: state.searchType, workPermitNo: state.searchWord,warningType: state.warningType } };
                let res = await workProcessApi().postAlertList(data);
src/views/specialWorkSystem/process/components/dialogPermitNo.vue
@@ -71,7 +71,9 @@
    interface stateType {
        workPermitNo: string
        searchNo: string
        workType: number
        workType: number | null
    tableData: Array<any>
    workTypeList: Array<any>
    }
    export default defineComponent({
        name: 'permitNo',
@@ -127,7 +129,7 @@
                state.workPermitNo = currentRow.value.workPermitNo
            }
            // 获取作业编号列表
            const getAllReport = async (data)=>{
            const getAllReport = async ()=>{
                const res = await workProcessApi().postReportList({workPermitNo: state.searchNo,workType: state.workType})
                if (res.data.code === '200') {
                    state.tableData = JSON.parse(JSON.stringify(res.data.data))
@@ -187,11 +189,10 @@
        position: relative;
        .homeCard{
            width: 100%;
            padding: 20px;
            padding: 0 20px;
            box-sizing: border-box;
            background: #fff;
            border-radius: 4px;
            margin-bottom: 20px;
        }
        .applyBtn{
            width: 100%;
src/views/specialWorkSystem/process/zyjcgl/index.vue
@@ -50,11 +50,11 @@
                        <el-table-column property="info" label="描述" show-overflow-tooltip width="200" align="center"/>
                        <el-table-column property="operatorUname" label="分析人" align="center"/>
                        <el-table-column property="operationTime" label="分析时间" width="180" align="center"/>
            <el-table-column property="mcResultName" label="物资检查" width="180" align="center">
              <template #default="scope">
                <span :class="scope.row.mcResultName == '不合格' ? 'red': ''">{{ scope.row.mcResultName== null?'-':scope.row.mcResultName}}</span>
              </template>
            </el-table-column>
<!--            <el-table-column property="mcResultName" label="物资检查" width="180" align="center">-->
<!--              <template #default="scope">-->
<!--                <span :class="scope.row.mcResultName == '不合格' ? 'red': ''">{{ scope.row.mcResultName== null?'-':scope.row.mcResultName}}</span>-->
<!--              </template>-->
<!--            </el-table-column>-->
                        <el-table-column fixed="right" label="操作" align="center" width="100">
                            <template #default="scope">
                                <el-button link type="primary" size="small" :icon="View" @click="viewRecord(scope.row)">查看</el-button>
@@ -92,7 +92,8 @@
                    <el-input :class="details.checkResultDesc == '异常' ? 'red': ''" v-model="details.checkResultDesc" readonly/>
                </el-form-item>
                <el-form-item label="现场图片" v-if="details.imagePaths && details.imagePaths.length>0">
                    <el-image v-for="item in details.imagePaths" :preview-src-list="details.imagePaths" style="width: 150px; height: 150px;margin-right: 50px;margin-bottom: 20px" :src="item" fit="cover" />
<!--                    <el-image v-for="item in details.imagePaths" :preview-src-list="details.imagePaths" style="width: 150px; height: 150px;margin-right: 50px;margin-bottom: 20px" :src="item" fit="cover" />-->
          <el-image v-for="item in details.imagePaths" :preview-src-list="[item]" style="width: 150px; height: 150px;margin-right: 50px;margin-bottom: 20px" :src="item" fit="cover" />
                </el-form-item>
                <el-form-item label="描述">
                    <el-input v-model="details.info" type="textarea" readonly/>
@@ -103,9 +104,9 @@
                <el-form-item label="分析时间">
                    <el-input v-model="details.operationTime" readonly/>
                </el-form-item>
        <el-form-item label="物资检查">
          <span>{{details.mcResultName== null?'-':details.mcResultName}}</span>
        </el-form-item>
<!--        <el-form-item label="物资检查">-->
<!--          <span>{{details.mcResultName== null?'-':details.mcResultName}}</span>-->
<!--        </el-form-item>-->
            </el-form>
            <template #footer>
              <span class="dialog-footer">
@@ -116,10 +117,10 @@
        <el-dialog v-model="dialogAddRecord" title="新增" @close="closeAdd" @open="openAdd">
            <el-form :model="addRecord" label-width="120px" ref="addRef" :rules="addRules">
                <el-form-item label="作业证编号" prop="workPermitNo">
                    <el-input v-model="addRecord.workPermitNo" placeholder="作业编号须为已审批作业的编号,可点击右方按钮查询">
                        <template #append>
                            <el-button :icon="Search" @click="dialogPermitNo = true"/>
                        </template>
                    <el-input v-model="addRecord.workPermitNo" placeholder="点击选择已审批作业" @click="dialogPermitNo = true" readonly>
<!--                        <template #append>-->
<!--                            <el-button :icon="Search" @click="dialogPermitNo = true"/>-->
<!--                        </template>-->
                    </el-input>
                </el-form-item>
                <el-form-item label="作业类型" prop="workType">
@@ -142,10 +143,10 @@
                    </el-select>
                </el-form-item>
                <el-form-item label="现场照片" prop="imagePaths">
                    <el-upload accept="image/*" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='imgLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" list-type="picture-card" :on-remove="handleRemove" :before-remove="beforeRemove" :before-upload="getUploadUrl">
                    <el-upload accept="image/*" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='imgLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" list-type="picture-card" :before-remove="beforeRemove" :before-upload="getUploadUrl">
                        <el-icon><Plus /></el-icon>
                        <template #tip>
                            <div class="el-upload__tip">上传jpg/png图片尺寸小于500KB,最多可上传3张</div>
                            <div class="el-upload__tip">上传jpg/png图片尺寸小于2M,最多可上传3张</div>
                        </template>
                    </el-upload>
                </el-form-item>
@@ -163,7 +164,7 @@
        <el-dialog v-model="dialogVisible">
            <img w-full :src="dialogImageUrl" alt="Preview Image" />
        </el-dialog>
        <el-dialog v-model="dialogPermitNo" title="选择相应的作业编号">
        <el-dialog v-model="dialogPermitNo" title="选择相应的作业编号" @close="resetForm()">
            <permit-no ref="permitNoInfo"></permit-no>
            <template #footer>
              <span class="dialog-footer">
@@ -195,7 +196,6 @@
        imgLimit: number;
        fileList: Array<file>,
        uploadUrl: string,
        isOverSize: Boolean,
        dialogVisible: Boolean,
        dialogImageUrl: string | null,
        multipleSelection: Array<any>;
@@ -235,7 +235,6 @@
                chosenIndex: null,
                workPermitNo: '',
                workType: null,
                isOverSize: false,
                fileList: [],
                imgLimit: 3,
                uploadUrl: '',
@@ -273,7 +272,7 @@
            const addRef = ref<FormInstance>();
            const addRules = reactive<FormRules>({
                workPermitNo: [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
                workPermitNo: [{ required: true, message: '该内容不能为空', trigger: 'change' }],
                workType: [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
                checkContent: [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
                checkResult: [{ required: true, message: '该内容不能为空', trigger: 'blur' }],
@@ -329,19 +328,17 @@
            };
            const getUploadUrl = async (rawFile: any) => {
                const fileSize = rawFile.size / 1024 < 500 ? '1' : '0'
                if(fileSize === '0'){
                // const fileSize = rawFile.size / 1024 < 500 ? '1' : '0'
                if(rawFile.size / 1024 / 1024 > 2){
                    ElMessage({
                        type: 'warning',
                        message: '文件大小不能超过500k。'
                        message: '文件大小不能超过2M。'
                    });
                    state.isOverSize = true
                    return false
          return Promise.reject(false)
                }else{
                    const res = await workApplyApi().getUploadUrl(rawFile.name);
                    const res = await workApplyApi().getUpload9Url(rawFile.name);
                    state.addRecord.imagePaths.push(res.data.data.fileName)
                    state.uploadUrl = res.data.data.uploadUrl;
                    console.log(state.addRecord.imagePaths,state.uploadUrl,6666666666666)
                }
            };
@@ -365,50 +362,40 @@
            };
            const beforeRemove = (file: {}, fileList: []) => {
                const result = new Promise((resolve, reject) => {
                    if(!state.isOverSize){
                        ElMessageBox.confirm('此操作将删除该图片, 是否继续?', '提示', {
                            confirmButtonText: '确定',
                            cancelButtonText: '取消',
                            type: 'warning'
                        })
                                .then(() => {
                                    // console.log(state.workDetail.photos,'path')
                                    const list = JSON.parse(JSON.stringify(state.addRecord.imagePaths))
                                    fileList.map((item,index)=>{
                                        if(item.uid === file.uid){
                                            fileList.splice(index,1)
                                            state.addRecord.photos.splice(index,1)
                                            // 请求删除接口
                                            deletePic(false,list[index])
                                        }
                                    })
                                })
                                .catch(() => {
                                    reject(false);
                                });
                    }else{
                        const list = JSON.parse(JSON.stringify(state.addRecord.imagePaths))
                        fileList.map((item,index)=>{
                            if(item.uid === file.uid){
                                fileList.splice(index,1)
                                state.addRecord.photos.splice(index,1)
                                deletePic(true,list[index])
                            }
                        })
                        state.isOverSize = false
                    }
                });
                return result;
        if (file && file.status === "success") {
          const result = new Promise((resolve, reject) => {
            ElMessageBox.confirm('此操作将删除该图片, 是否继续?', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            })
                .then(() => {
                  // console.log(state.workDetail.photos,'path')
                  const list = JSON.parse(JSON.stringify(state.addRecord.imagePaths))
                  fileList.map((item, index) => {
                    if (item.uid === file.uid) {
                      fileList.splice(index, 1)
                      state.addRecord.imagePaths.splice(index, 1)
                      // 请求删除接口
                      deletePic(list[index])
                    }
                  })
                })
                .catch(() => {
                  reject(false);
                });
          });
          return result;
        }
            };
            // 删除图片接口
            const deletePic = async(isOverSize:boolean,fileName:string)=>{
            const deletePic = async(fileName:string)=>{
                const res = await workApplyApi().deleteFile({fileName: fileName})
                if (res.data.code === '200') {
                    ElMessage({
                        type: isOverSize ? 'error' : 'success',
                        message: isOverSize ? '上传失败':'删除成功!'
                        type: 'success',
                        message: '删除成功!'
                    });
                } else {
                    ElMessage({
@@ -463,12 +450,25 @@
                    if (valid) {
                        await addRecord(state.addRecord);
                        state.dialogAddRecord = false;
            state.fileList = []
                        getListByPage();
                    } else {
                        console.log('error submit!', fields);
                    }
                });
            };
      const resetForm = () =>{
        state.addRecord={
          workPermitNo: '',
          checkContent: '',
          checkResult: '',
          info: '',
          source: 2,
          imagePaths: []
        }
        state.fileList = []
      }
            const handleSizeChange = (val: number) => {
                state.pageSize = val;
@@ -493,6 +493,7 @@
            const closeAdd = () => {
                state.addRecord = {};
                state.chosenIndex = null;
        resetForm()
            };
            const openAdd = () => {
@@ -538,6 +539,7 @@
                closeAdd,
                openAdd,
                indexClear,
        resetForm,
                ...toRefs(state)
            };
        }
src/views/specialWorkSystem/specialIndex/components/videoDetail.vue
@@ -1,41 +1,46 @@
<template>
  <el-dialog v-model="videoDetailDialog" title="动火作业编号00001 实时监测详情" width="80%" center>
    <div style="margin-bottom: 20px">
      <el-button type="warning" @click="fillDialog = true">人工录入警报信息</el-button>
    </div>
  <el-dialog v-model="videoDetailDialog" :title="title" width="80%" center>
<!--    <div style="margin-bottom: 20px">-->
<!--      <el-button type="warning" @click="fillDialog = true">人工录入警报信息</el-button>-->
<!--    </div>-->
    <div class="info">
<!--      <video class="video-cont" autoplay src="https://www.bilibili.com/video/BV1UM411s7Ey/?vd_source=7700e61a97bad6ca1f7c0ecb9768d682" controls></video>-->
      <div class="left-info">
        <iframe class="video-cont" src="http://36.108.169.10:8088/808gps/open/player/video.html?lang=zh&devIdno=21125705363&&account=gtxh&password=000000"></iframe>
        <template v-for="item in videoData.approvalDeviceList">
          <iframe class="video-cont" :src="'http://36.108.169.10:8088/808gps/open/player/video.html?lang=zh&devIdno=' + item.deviceNo + '&&account=gtxh&password=000000'"></iframe>
        </template>
        <div class="chart-area">
          <div class="chart-item">
            <div class="top-tit">
              <div class="tit">基础指标数据(可燃气体浓度、氧气、一氧化碳、硫化氢按需展示):</div>
              <el-button type="warning" @click="reportDialog = true">监管异常填报</el-button>
              <div class="tit">气体分析数据:</div>
<!--              <el-button type="warning" @click="reportDialog = true">监管异常填报</el-button>-->
            </div>
            <el-table :data="basicData" style="width: 100%" border :header-cell-style="{ background: '#fafafa' }">
              <el-table-column property="type" label="类别" align="center"/>
              <el-table-column property="time" label="填报时间" align="center"/>
              <el-table-column property="name" label="填报人" align="center"/>
              <el-table-column property="number" label="值" align="center"/>
              <el-table-column property="isGood" label="是否合格" align="center">
            <el-table :data="videoData.analysisDataList" style="width: 100%" border :header-cell-style="{ background: '#fafafa' }">
              <el-table-column property="type" label="类别" align="center">
                <template #default="scope">
                  <span>{{scope.row.isGood == 0?'合格':'不合格'}}</span>
                  {{ gasData.find(i=>i.value == scope.row.type)?.name }}
                </template>
              </el-table-column>
              <el-table-column property="analysisTime" label="分析时间" align="center"/>
              <el-table-column property="analysisUname" label="分析人" align="center"/>
              <el-table-column property="data" label="值" align="center"/>
              <el-table-column property="resultDesc" label="是否合格" align="center">
<!--                <template #default="scope">-->
<!--                  <span>{{scope.row.isGood == 0?'合格':'不合格'}}</span>-->
<!--                </template>-->
              </el-table-column>
            </el-table>
          </div>
          <div class="chart-item">
            <div class="top-tit"><div class="tit">现场检查代码:</div></div>
            <el-table :data="checkData" style="width: 100%" border :header-cell-style="{ background: '#fafafa' }">
              <el-table-column property="name" label="现在检查人" align="center"/>
              <el-table-column property="time" label="检查填报时间" align="center"/>
              <el-table-column property="content" label="检查内容" align="center"/>
            <div class="top-tit"><div class="tit">现场检查数据:</div></div>
            <el-table :data="videoData.checkList" style="width: 100%" border :header-cell-style="{ background: '#fafafa' }">
              <el-table-column property="operatorUname" label="检查人" align="center"/>
              <el-table-column property="operationTime" label="检查填报时间" align="center"/>
              <el-table-column property="checkContent" label="检查内容" align="center"/>
              <el-table-column property="info" label="描述" align="center"/>
              <el-table-column property="isGood" label="是否合格" align="center">
                <template #default="scope">
                  <span>{{scope.row.isGood == 0?'合格':'不合格'}}</span>
                </template>
              <el-table-column property="checkContent" label="是否合格" align="center">
<!--                <template #default="scope">-->
<!--                  <span>{{scope.row.isGood == 0?'合格':'不合格'}}</span>-->
<!--                </template>-->
              </el-table-column>
            </el-table>
          </div>
@@ -47,33 +52,39 @@
            基础信息
          </div>
          <div class="content">
            <div>作业编号: <span>0000001</span></div>
            <div>作业部门: <span>有机化工</span></div>
            <div>作业人员: <span>王大壮(持证)</span></div>
            <div>开始时间: <span>2023-03-09 14:00:45</span></div>
            <div>结束时间: <span>2023-03-09 17:05:45</span></div>
            <div class="checkBtn">查看作业票</div>
            <div class="checkBtn">查看审批流</div>
            <div>作业编号: <span>{{videoData.workPermitNo}}</span></div>
            <div>作业部门: <span>{{videoData.workDepName}}</span></div>
            <div>作业人员: <span>{{videoData.operatorList.map(i=>i.userName).join(',')}}</span></div>
            <div>开始时间: <span>{{videoData.workStartTime}}</span></div>
            <div>结束时间: <span>{{videoData.workFinishTime}}</span></div>
            <div class="checkBtn" @click="viewTicket(videoData)">查看作业票</div>
<!--            <div class="checkBtn" @click="viewRecord(videoData.workApplyId)">查看记录</div>-->
          </div>
        </div>
        <div class="info-item">
          <div class="info-tit">
            警报信息
          </div>
          <div class="content">
            <div>设备IA自动识别警报:
              <div>无</div>
          <template v-for="item in videoData.warningList" v-if="videoData.warningList && videoData.warningList.length>0">
            <div class="content" style="padding-bottom: 15px;margin-bottom:10px;border-bottom: 1px solid #ccc">
              <div>执行人:
                <span>{{item.operatorUname}}</span>
              </div>
              <div>警报时间:
                <span>{{item.operationTime}}</span>
              </div>
              <div>警报内容:
                <div>{{item.warningContent}}</div>
              </div>
            </div>
            <div>人工录入警报信息:
              <div>无</div>
            </div>
            <div>现场检查不合格项:
              <div>1、除动火人和监护人有无其他人员在场:有信息化人员在场</div>
            </div>
          </template>
          <div v-else>
            暂无警报信息
          </div>
        </div>
      </div>
    </div>
    <Work-record ref="recordRef"></Work-record>
    <el-dialog v-model="fillDialog" title="作业全过程监测风险警报信息发现录入" width="50%" center>
      <el-form ref="reviewFormRef" :model="reviewForm" :rules="reviewRules" label-width="170px">
        <el-form-item label="风险描述:" prop="describe">
@@ -129,76 +140,91 @@
    import { Session } from '/@/utils/storage';
    import { ElMessage } from 'element-plus'
    import type { FormInstance, FormRules } from 'element-plus'
  import WorkRecord from "/@/views/specialWorkSystem/specialIndex/components/workRecord.vue";
    import { workApplyApi } from '/@/api/specialWorkSystem/workApply';
  import axios from "axios";
  import Cookies from "js-cookie";
    interface stateType {
    videoDetailDialog:boolean
    basicData: Array<any>
    checkData: Array<any>
    fillDialog: boolean
    reviewForm: object
    reportForm: object
    reportDialog: boolean
    videoData:{}
    title: string
    gasData: Array<any>
    }
    export default defineComponent({
        name: 'videoDetail',
        components: {},
        components: {WorkRecord},
        props:[],
        setup() {
            const userInfo = useUserInfo()
            const { userInfos } = storeToRefs(userInfo);
      const state = reactive<stateType>({
        videoDetailDialog: false,
        basicData:[
          {
            type: '可燃气体浓度',
            time: '2023-03-20 09:09',
            name: '李羽飞(动火分析人)',
            number: '3%LEL',
            isGood: 0
          },
          {
            type: '可燃气体浓度',
            time: '2023-03-20 09:09',
            name: '李羽飞(动火分析人)',
            number: '2.9%LEL',
            isGood: 0
          }
        ],
        checkData:[
          {
            name: '杨冬冬',
            time: '2023-03-20 09:09',
            content: '防火面罩不少于2个',
            info: '2个',
            isGood: 0
          },
          {
            name: '杨冬冬',
            time: '2023-03-20 09:09',
            content: '电源插座是否防爆',
            info: '是',
            isGood: 0
          },
          {
            name: '杨冬冬',
            time: '2023-03-20 09:09',
            content: '除动火人和监护人有无其他人员在场',
            info: '有信息化人员',
            isGood: 1
          }
        ],
        title: '',
        videoData:{},
        fillDialog: false,
        reportDialog: false,
        reviewForm: {},
        reportForm: {}
        reportForm: {},
        gasData: [
          {
            name: '有毒有害气体',
            value: 1
          },
          {
            name: '可燃气体',
            value: 2
          },
          {
            name: '氧气',
            value: 3
          }
        ]
      })
      const openDialog = ()=>{
      const recordRef = ref()
      const openDialog = (row)=>{
        state.videoData = row
        console.log(state.videoData,'data')
        state.title = row.workTypeDesc + '编号' + row.workPermitNo + '实时监测详情'
        state.videoDetailDialog = true
      }
      const viewTicket = async(row)=>{
        let res = await workApplyApi().viewTicket({id:row.workApplyId})
        if(res.data.code == 200){
          console.log(res.data,666)
        }
        axios.post(import.meta.env.VITE_API_URL + `/specialwork9step/work/down/load/pdf`,{id: row.workApplyId},{headers:{'Content-Type': 'application/json','Authorization': `${Cookies.get('token')}`,'uid':`${Cookies.get('uid')}`},responseType: 'blob'}).then(res=>{
          if (res) {
            const link = document.createElement('a')
            let blob = new Blob([res.data],{type: 'application/pdf'})
            link.style.display = "none";
            link.href = URL.createObjectURL(blob); // 创建URL
            link.setAttribute("download", row.workPermitNo + "(" + row.workTypeDesc +")作业证.pdf");
            window.open(link)
          } else {
            ElMessage({
              type: 'warning',
              message: '预览失败'
            });
          }
        })
      }
      const viewRecord = (id: string | null)=>{
        recordRef.value.openDialog(id)
      }
            return {
        recordRef,
        openDialog,
        viewTicket,
        viewRecord,
        ...toRefs(state)
            };
        },
src/views/specialWorkSystem/specialIndex/components/workRecord.vue
New file
@@ -0,0 +1,161 @@
<template>
  <el-dialog v-model="dialogVisible" title="作业记录" width="45%" center>
<!--    <el-steps :active="data.length" direction="vertical" finish-status="success">-->
<!--      <el-step v-for="item in data" :title="item.operationTitle" :icon="Edit">-->
<!--        <template #description>-->
<!--          <div>{{item.content}}</div>-->
<!--          <div>{{item.operationUtype}}:{{item.operationUname}}</div>-->
<!--          <div>{{item.operationTime}}</div>-->
<!--        </template>-->
<!--      </el-step>-->
<!--    </el-steps>-->
    <div class="item" v-for="(item,index) in data" :key="index">
      <div class="marker">
        <div class="dot"></div>
        <div class="line"></div>
      </div>
      <div class="content">
        <div class="tit">{{item.operationTitle}}<span>{{index == data.length - 1 ? '[进行中]': '[已完成]'}}</span></div>
        <div>{{item.operationUtype}}:{{item.operationUname}}</div>
        <div>操作时间:{{item.operationTime}}</div>
        <div>操作内容:{{item.content}}</div>
        <div>操作意见:{{item.approvalOpinions}}</div>
      </div>
    </div>
  </el-dialog>
</template>
<script lang="ts">
    import { toRefs, reactive, defineComponent, ref, defineAsyncComponent } from 'vue';
    import { storeToRefs } from 'pinia';
    import {useUserInfo} from "/@/stores/userInfo";
    import { Search, Edit } from '@element-plus/icons-vue'
  import {teamManageApi} from "/@/api/systemManage/basicDateManage/personShiftManage/teamManage";
  import {ElMessage} from "element-plus/es";
  import {specialIndexApi} from "/@/api/specialWorkSystem/specialIndex";
    interface stateType {
    dialogVisible: boolean
    }
    export default defineComponent({
        name: 'workRecord',
        components: {},
        props:[],
        setup() {
            const userInfo = useUserInfo()
            const { userInfos } = storeToRefs(userInfo);
      const state = reactive({
        dialogVisible: false,
        data: []
      })
      const openDialog = (id: string | null)=>{
        getWorkRecord(id)
        state.dialogVisible = true
      }
      const getWorkRecord = async (id: string | null) => {
        let res = await specialIndexApi().getWorkRecord({id:id});
        if (res.data.code === '200') {
          state.data = res.data.data
        } else {
          ElMessage({
            type: 'warning',
            message: res.data.msg
          });
        }
      }
            return {
        openDialog,
        ...toRefs(state),
                Search,
        Edit
      };
        },
    });
</script>
<style scoped lang="scss">
    .home-container {
        height: 100%;
        overflow: hidden;
        position: relative;
        .el-row{
            margin-bottom: 20px;
        }
        .el-row:last-child {
            margin-bottom: 0;
        }
        .el-input{
            width: 100% !important;
        }
        .el-date-editor::v-deep{
            width: 100%;
        }
        .el-select{
            width: 100%;
        }
        .el-cascader{
            width: 100% !important;
        }
    .item{
      display: flex;
      align-items: flex-start;
      width: 100%;
      padding-left: 50px;
      margin-bottom: 10px;
      .marker{
        display: flex;
        flex-direction: column;
        align-items: center;
        margin-right: 20px;
        .dot{
          width: 28px;
          height: 28px;
          border-radius: 50%;
          margin-bottom: 10px;
          background: #13ce66;
        }
        .line{
          width: 1px;
          height: 120px;
          background: #13ce66;
        }
      }
      .content{
        div{
          margin-bottom: 6px;
        }
        .tit{
          line-height: 28px;
          font-size: 20px;
          font-weight: bolder;
          span{
            display: inline-block;
            margin-left: 6px;
            font-size: 16px;
            color: #13ce66;
            line-height: 28px;
          }
        }
      }
      &:last-of-type{
        .dot{
          background: #409eff;
        }
        .line{
          display: none;
        }
        .tit{
          span{
            color: #409eff;
          }
        }
      }
    }
    }
</style>
src/views/specialWorkSystem/specialIndex/index.vue
@@ -126,7 +126,7 @@
          <el-col :span="5" style="display:flex;align-items: center">
            <span style="white-space: nowrap">作业状态:</span>
            <div class="grid-content topInfo">
              <el-select :teleported="false" v-model="searchParams.workStatus" size="small">
              <el-select :teleported="false" v-model="searchParams.workAllStatus" size="small">
                <el-option
                    v-for="item in workStatusList"
                    :key="item.value"
@@ -162,56 +162,86 @@
          <el-button plain @click="clearSearch" size="small">重置</el-button>
        </el-row>
        <div class="main-card">
          <el-row class="cardTop" style="justify-content: space-between">
            <el-col :span="2" class="mainCardBtn">
              <el-button type="primary" :icon="Plus" size="default" @click="toApply()">新作业申请</el-button>
            </el-col>
            <el-col :span="22" style="display: flex;justify-content: end;align-items: center">
              <div class="top-info">
                <el-icon :size="18" color="#F3001E" style="margin-right: 4px"><BellFilled /></el-icon>
                作业编号
                <div v-if="unchecked != 0">
                  <el-tooltip
                      class="box-item"
                      effect="light"
                      content="查看预警详情"
                      placement="bottom-start"
                  ><span>123456</span></el-tooltip>
                </div>
                可燃气体浓度超过18%
                ,请及时处理!
              </div>
              <el-button type="primary" :icon="Refresh" size="default" @click="reLoadData()" />
            </el-col>
          </el-row>
<!--          <el-row class="cardTop" style="justify-content: space-between">-->
<!--            <el-col :span="2" class="mainCardBtn">-->
<!--              <el-button type="primary" :icon="Plus" size="default" @click="toApply()">新作业申请</el-button>-->
<!--            </el-col>-->
<!--            <el-col :span="22" style="display: flex;justify-content: end;align-items: center">-->
<!--              <div class="top-info">-->
<!--                <el-icon :size="18" color="#F3001E" style="margin-right: 4px"><BellFilled /></el-icon>-->
<!--                作业编号-->
<!--                <div v-if="unchecked != 0">-->
<!--                  <el-tooltip-->
<!--                      class="box-item"-->
<!--                      effect="light"-->
<!--                      content="查看预警详情"-->
<!--                      placement="bottom-start"-->
<!--                  ><span>123456</span></el-tooltip>-->
<!--                </div>-->
<!--                可燃气体浓度超过18%-->
<!--                ,请及时处理!-->
<!--              </div>-->
<!--              <el-button type="primary" :icon="Refresh" size="default" @click="reLoadData()" />-->
<!--            </el-col>-->
<!--          </el-row>-->
          <el-table ref="multipleTableRef" stripe border :data="workData" style="width: 100%" :header-cell-style="{ background: '#fafafa' }">
            <el-table-column property="workPermitNo" label="作业证编号" align="center"/>
            <el-table-column property="depName" label="部门" align="center"/>
            <el-table-column property="applyer" label="申请人" align="center"/>
            <el-table-column property="finishUname" label="作业人" align="center"/>
            <el-table-column property="workDepName" label="作业单位" align="center"/>
            <el-table-column property="applyUname" label="申请人" align="center"/>
            <el-table-column property="applyDepName" label="申请单位" align="center"/>
            <el-table-column property="applyTime" label="申请时间" align="center"/>
            <el-table-column property="startUname" label="开始人" align="center">
              <template #default="scope">
                <span>{{scope.row.startUname?scope.row.startUname:'--'}}</span>
              </template>
            </el-table-column>
            <el-table-column property="finishUname" label="结束人" align="center">
              <template #default="scope">
                <span>{{scope.row.finishUname?scope.row.finishUname:'--'}}</span>
              </template>
            </el-table-column>
            <el-table-column property="workStartTime" label="作业开始时间" align="center">
              <template #default="scope">
                <span>{{scope.row.workStartTime?scope.row.workStartTime:'--'}}</span>
              </template>
            </el-table-column>
            <el-table-column property="workFinishTime" label="作业结束时间" align="center">
              <template #default="scope">
                <span>{{scope.row.workFinishTime?scope.row.workFinishTime:'--'}}</span>
              </template>
            </el-table-column>
            <el-table-column property="acceptUname" label="验收人" align="center">
              <template #default="scope">
                <span>{{scope.row.acceptUname?scope.row.acceptUname:'--'}}</span>
              </template>
            </el-table-column>
            <el-table-column property="workAcceptContent" label="验收内容" align="center">
              <template #default="scope">
                <span>{{scope.row.workAcceptContent?scope.row.workAcceptContent:'--'}}</span>
              </template>
            </el-table-column>
            <el-table-column property="workAcceptTime" label="验收时间" align="center">
              <template #default="scope">
                <span>{{scope.row.workAcceptTime?scope.row.workAcceptTime:'--'}}</span>
              </template>
            </el-table-column>
            <el-table-column property="workTypeDesc" label="作业类型" align="center"/>
            <el-table-column property="workLevelDesc" label="作业等级" align="center"/>
            <el-table-column property="gmtCreate" label="申请时间" align="center"/>
            <el-table-column property="workStartTime" label="作业开始时间" align="center"/>
            <el-table-column property="workFinishTime" label="作业结束时间" align="center"/>
            <el-table-column property="workStatusDesc" label="作业状态" align="center"/>
            <el-table-column property="reason" label="中止原因" align="center"/>
            <el-table-column label="安全预警" align="center">
            <el-table-column property="abortReason" label="中止原因" align="center">
              <template #default="scope">
                <el-tag>--</el-tag>
                <span>{{scope.row.abortReason?scope.row.abortReason:'--'}}</span>
              </template>
            </el-table-column>
            <el-table-column property="message" label="报警信息" align="center">
              <template #default="scope">
                <el-button type="text" size="small" v-if="scope.row.message == 1">查看</el-button>
                <span v-else>无</span>
              </template>
            </el-table-column>
            <el-table-column property="workAllStatusDesc" label="作业状态" align="center"/>
            <el-table-column fixed="right" label="操作" align="center" width="250">
              <template #default="scope">
                <el-button link type="primary" size="small" :icon="View" @click="viewRecord(scope.row)">查看作业票</el-button>
                <el-button link type="primary" size="small" :icon="FolderChecked" @click="handleReview(scope.row)">验收</el-button>
                <el-button link type="primary" size="small" :icon="VideoPlay" @click="openVideo(scope.row)">查看实时监控</el-button>
                <el-button link
                 v-if="scope.row.workAllStatus == -1|| scope.row.workAllStatus == 1 || scope.row.workAllStatus == 3 || scope.row.workAllStatus == 7"
                  type="primary" size="small" :icon="VideoPlay" @click="openVideo(scope.row)">查看监控视频</el-button>
                <el-button link type="primary" size="small" :icon="View" @click="viewRecord(scope.row.workApplyId)">查看记录</el-button>
                <el-button link type="primary" size="small" :icon="View" @click="viewTicket(scope.row)">查看作业票</el-button>
                <el-button link type="primary" size="small" :icon="Download" @click="downLoadTicket(scope.row)">导出作业票</el-button>
<!--                <el-button link type="primary" size="small" :icon="FolderChecked" @click="handleReview(scope.row)">验收</el-button>-->
              </template>
            </el-table-column>
          </el-table>
@@ -238,24 +268,25 @@
              </span>
      </template>
    </el-dialog>
    <el-dialog v-model="dialogReview" title="填报验收意见" center>
      <el-form ref="reviewFormRef" :model="reviewForm" :rules="reviewRules" label-width="120px">
        <el-form-item label="填报验收意见:" prop="advice">
          <el-input
              v-model="reviewForm.advice"
              :autosize="{ minRows: 4, maxRows: 10 }"
              type="textarea"
              placeholder="请填写验收意见"
          />
        </el-form-item>
      </el-form>
      <template #footer>
              <span class="dialog-footer">
                <el-button type="primary" @click="submitReview(reviewFormRef)">提交验收</el-button>
              </span>
      </template>
    </el-dialog>
<!--    <el-dialog v-model="dialogReview" title="填报验收意见" center>-->
<!--      <el-form ref="reviewFormRef" :model="reviewForm" :rules="reviewRules" label-width="120px">-->
<!--        <el-form-item label="填报验收意见:" prop="advice">-->
<!--          <el-input-->
<!--              v-model="reviewForm.advice"-->
<!--              :autosize="{ minRows: 4, maxRows: 10 }"-->
<!--              type="textarea"-->
<!--              placeholder="请填写验收意见"-->
<!--          />-->
<!--        </el-form-item>-->
<!--      </el-form>-->
<!--      <template #footer>-->
<!--              <span class="dialog-footer">-->
<!--                <el-button type="primary" @click="submitReview(reviewFormRef)">提交验收</el-button>-->
<!--              </span>-->
<!--      </template>-->
<!--    </el-dialog>-->
    <video-detail ref="videoRef"></video-detail>
    <Work-record ref="recordRef"></Work-record>
  </div>
</template>
@@ -269,16 +300,17 @@
import { Edit, View, Plus, Delete, Refresh, Search, Finished, Download, FolderChecked, VideoPlay } from '@element-plus/icons-vue';
import { ElTable, ElMessage } from 'element-plus';
import { specialIndexApi } from '/@/api/specialWorkSystem/specialIndex';
import { workApplyApi } from '/@/api/specialWorkSystem/workApply';
import type { TabsPaneContext } from 'element-plus';
import type { FormInstance, FormRules } from 'element-plus'
import {teamManageApi} from "/@/api/systemManage/basicDateManage/personShiftManage/teamManage";
import { workApplyApi } from '/@/api/specialWorkSystem/workApply'
import Cookies from 'js-cookie';
import axios from 'axios';
import * as echarts from "echarts";
import screenfull from "screenfull";
import VideoDetail from "/@/views/specialWorkSystem/specialIndex/components/videoDetail.vue";
import WorkRecord from "/@/views/specialWorkSystem/specialIndex/components/workRecord.vue";
import { BorderBox10 as DvBorderBox10 } from '@kjgl77/datav-vue3'
import {productionDeviceApi} from "/@/api/doublePreventSystem/productionDevice";
// 定义接口来定义对象的类型
interface stateType {
@@ -336,6 +368,7 @@
  name: 'specialIndex',
  components: {
    VideoDetail,
    WorkRecord,
    fire: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/fireLog.vue')),
    space: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/spaceLog.vue')),
    hoist: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/hoistLog.vue')),
@@ -354,6 +387,7 @@
    const slfx = ref("eChartSlfx" + Date.now() + Math.random())
    const zyqs = ref("eChartZyqs" + Date.now() + Math.random())
    const videoRef = ref();
    const recordRef = ref()
    const state = reactive<stateType>({
      pageIndex: 1,
      pageSize: 10,
@@ -365,9 +399,7 @@
        workPermitNo: '',
        startTime: '',
        endTime: '',
        workStatus: null,
        acceptStatus: null,
        workAnalysisStatus: null
        workAllStatus: null
      },
      dialogReview: false,
      departmentList: [],
@@ -395,83 +427,7 @@
      searchDep2: null,
      searchDep: null,
      searchDate: [],
      workData: [
        // {
        //   num: '111',
        //   dep: '部门1',
        //   applyer: '张凤',
        //   worker: '李羽飞',
        //   type: '动火作业',
        //   level: '一级',
        //   applyTime: '2023-03-08',
        //   startTime: '2023-03-08',
        //   endTime: '2023-03-08',
        //   status: 0,
        //   reason: '分析超时',
        //   warning: 0,
        //   message: 1
        // },
        // {
        //   num: '222',
        //   dep: '部门2',
        //   applyer: '张凤',
        //   worker: '李羽飞',
        //   type: '动土作业',
        //   level: '一级',
        //   applyTime: '2023-03-08',
        //   startTime: '2023-03-08',
        //   endTime: '2023-03-08',
        //   status: 1,
        //   reason: '分析超时',
        //   warning: 1,
        //   message: 0
        // },
        // {
        //   num: '333',
        //   dep: '部门3',
        //   applyer: '张凤',
        //   worker: '李羽飞',
        //   type: '动火作业',
        //   level: '一级',
        //   applyTime: '2023-03-08',
        //   startTime: '2023-03-08',
        //   endTime: '2023-03-08',
        //   status: 2,
        //   reason: '分析超时',
        //   warning: 2,
        //   message: 0
        // },
        // {
        //   num: '222',
        //   dep: '部门2',
        //   applyer: '张凤',
        //   worker: '李羽飞',
        //   type: '动土作业',
        //   level: '一级',
        //   applyTime: '2023-03-08',
        //   startTime: '2023-03-08',
        //   endTime: '2023-03-08',
        //   status: 1,
        //   reason: '分析超时',
        //   warning: 1,
        //   message: 0
        // },
        // {
        //   num: '333',
        //   dep: '部门3',
        //   applyer: '张凤',
        //   worker: '李羽飞',
        //   type: '动火作业',
        //   level: '一级',
        //   applyTime: '2023-03-08',
        //   startTime: '2023-03-08',
        //   endTime: '2023-03-08',
        //   status: 2,
        //   reason: '分析超时',
        //   warning: 2,
        //   message: 0
        // }
      ],
      workData: [],
      isFull: false,
      themeColor: '#333',
      workTimeList: [],
@@ -708,7 +664,7 @@
        },
        series: [
          {
            name: 'Access From',
            name: '',
            type: 'pie',
            radius: ['40%', '70%'],
            avoidLabelOverlap: false,
@@ -915,9 +871,7 @@
            workPermitNo: '',
            startTime: '',
            endTime: '',
            workStatus: null,
            acceptStatus: null,
            workAnalysisStatus: null
            workAllStatus: null
      }
      state.searchDate = []
      getMydepList()
@@ -933,7 +887,7 @@
    };
    // 查看记录
    const viewRecord = (row: any) => {
    const viewDetail = (row: any) => {
      state.dialogType = row.workType
      state.details = JSON.parse(JSON.stringify(row));
      if(state.details.workDetail.otherSpecialWork == '' || !state.details.workDetail.otherSpecialWork){
@@ -972,22 +926,85 @@
      state.dialogDetails = true;
    };
    const handleReview = (row)=>{
      state.dialogReview = true
    // const handleReview = (row: object)=>{
    //   state.dialogReview = true
    // }
    const openVideo = (row:object)=>{
      videoRef.value.openDialog(row)
    }
    const openVideo = ()=>{
      videoRef.value.openDialog()
    const viewRecord = (id: string | null)=>{
      recordRef.value.openDialog(id)
    }
    const submitReview = async (formEl: FormInstance | undefined) => {
      if (!formEl) return
      await formEl.validate((valid, fields) => {
        if (valid) {
          console.log('submit!')
    const viewTicket = async(row)=>{
      let res = await workApplyApi().viewTicket({id:row.workApplyId})
      if(res.data.code == 200){
        console.log(res.data,666)
      }
      axios.post(import.meta.env.VITE_API_URL + `/specialwork9step/work/down/load/pdf`,{id: row.workApplyId},{headers:{'Content-Type': 'application/json','Authorization': `${Cookies.get('token')}`,'uid':`${Cookies.get('uid')}`},responseType: 'blob'}).then(res=>{
        if (res) {
          const link = document.createElement('a')
          let blob = new Blob([res.data],{type: 'application/pdf'})
          link.style.display = "none";
          link.href = URL.createObjectURL(blob); // 创建URL
          link.setAttribute("download", row.workPermitNo + "(" + row.workTypeDesc +")作业证.pdf");
          window.open(link)
        } else {
          console.log('error submit!', fields)
          ElMessage({
            type: 'warning',
            message: '预览失败'
          });
        }
      })
    }
    // 导出方法
    const downLoadTicket = async (row) => {
      // let res = await workApplyApi().postPrinting(data);
      axios.post(import.meta.env.VITE_API_URL + `/specialwork9step/work/down/load/pdf`,{id: row.workApplyId},{headers:{'Content-Type': 'application/json','Authorization': `${Cookies.get('token')}`,'uid':`${Cookies.get('uid')}`},responseType: 'blob'}).then(res=>{
        if (res) {
          const link = document.createElement('a')
          let blob = new Blob([res.data],{type: 'application/pdf'})
          link.style.display = "none";
          link.href = URL.createObjectURL(blob); // 创建URL
          link.setAttribute("download", row.workPermitNo + "(" + row.workTypeDesc +")作业证.pdf");
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
        } else {
          ElMessage({
            type: 'warning',
            message: '导出失败'
          });
        }
      })
    }
    // const submitReview = async (formEl: FormInstance | undefined) => {
    //   if (!formEl) return
    //   await formEl.validate(async(valid, fields) => {
    //     if (valid) {
    //       let res = await workApplyApi().acceptWork(state.reviewForm);
    //       if (res.data.code === '200') {
    //         ElMessage({
    //           type: 'success',
    //           message: '作业验收成功',
    //           duration: 2000
    //         });
    //         state.dialogReview = false;
    //         await getMydepList()
    //       } else {
    //         ElMessage({
    //           type: 'warning',
    //           message: res.data.msg
    //         });
    //       }
    //     } else {
    //       console.log('error submit!', fields)
    //     }
    //   })
    // }
    // 折线图
    const renderMenu = async (value: string) => {
@@ -1008,6 +1025,7 @@
      VideoPlay,
      reviewFormRef,
      videoRef,
      recordRef,
      zyfb,
      slfx,
      zyqs,
@@ -1017,14 +1035,17 @@
      changeType2,
      changeDep3,
      toFullscreen,
      handleReview,
      // handleReview,
      openVideo,
      submitReview,
      // submitReview,
      reLoadData,
      toApply,
      searchRecord,
      clearSearch,
      viewDetail,
      viewRecord,
      viewTicket,
      downLoadTicket,
      // getListByPage,
      handleSizeChange,
      handleCurrentChange,
src/views/specialWorkSystem/workTicket/zysq/components/broken.vue
@@ -120,7 +120,7 @@
            <el-row>
                <el-col :span="24">
                    <el-form-item label="图片上传" prop="workDetail.bcPath">
                        <el-upload accept="image/*" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='imgLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" list-type="picture-card" :on-remove="handleRemove" :before-remove="beforeRemove" :before-upload="getUploadUrl">
                        <el-upload accept="image/*" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='imgLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" list-type="picture-card" :before-remove="beforeRemove" :before-upload="getUploadUrl">
                            <el-icon><Plus /></el-icon>
                            <template #tip>
                                <div class="el-upload__tip">上传jpg/png图片尺寸小于500KB,最多可上传3张</div>
src/views/specialWorkSystem/workTicket/zysq/components/ground.vue
@@ -122,7 +122,7 @@
            <el-row>
                <el-col :span="24">
                    <el-form-item label="图片上传" prop="workDetail.gbPath">
                        <el-upload accept="image/*" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='imgLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" list-type="picture-card" :on-remove="handleRemove" :before-remove="beforeRemove" :before-upload="getUploadUrl">
                        <el-upload accept="image/*" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='imgLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" list-type="picture-card" :before-remove="beforeRemove" :before-upload="getUploadUrl">
                            <el-icon><Plus /></el-icon>
                            <template #tip>
                                <div class="el-upload__tip">上传jpg/png图片尺寸小于500KB,最多可上传3张</div>
src/views/specialWorkSystem/workTicket/zysq/components/plate.vue
@@ -199,7 +199,7 @@
            <el-row>
                <el-col :span="24">
                    <el-form-item label="盲板位置图" prop="workDetail.bpLocationMapPath">
                        <el-upload accept="image/*" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='imgLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" list-type="picture-card" :on-remove="handleRemove" :before-remove="beforeRemove" :before-upload="getUploadUrl">
                        <el-upload accept="image/*" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='imgLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" list-type="picture-card" :before-remove="beforeRemove" :before-upload="getUploadUrl">
                            <el-icon><Plus /></el-icon>
                            <template #tip>
                                <div class="el-upload__tip">上传jpg/png图片尺寸小于500KB,最多可上传3张</div>
src/views/system/appVersion/index.vue
@@ -110,7 +110,7 @@
                    <el-input v-model="addRecord.name"/>
                </el-form-item>
                <el-form-item v-if="chosenIndex == null" label="上传文件" prop="objectName">
                    <el-upload :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='fileLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" :on-remove="handleRemove" :before-remove="beforeRemove" :before-upload="getUploadUrl">
                    <el-upload :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='fileLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" :before-remove="beforeRemove" :before-upload="getUploadUrl">
                        <el-button type="primary" plain>选择文件</el-button>
                        <template #tip>
                            <div class="el-upload__tip">上传APP源文件</div>
@@ -118,7 +118,7 @@
                    </el-upload>
                </el-form-item>
                <el-form-item v-else label="上传文件">
                    <el-upload :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='fileLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" :on-remove="handleRemove" :before-remove="beforeRemove" :before-upload="getUploadUrl">
                    <el-upload :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='fileLimit' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" :before-remove="beforeRemove" :before-upload="getUploadUrl">
                        <el-button type="primary" plain>选择文件</el-button>
                        <template #tip>
                            <div class="el-upload__tip">上传新版APP源文件(不上传则默认使用原版本)</div>
src/views/system/user/component/ctfDialog.vue
New file
@@ -0,0 +1,355 @@
<template>
    <div class="system-add-user-container">
        <el-dialog :title="title" v-model="isShowCtfDialog" width="769px" @close="restForm">
            <el-form :model="ctfForm" size="default" ref="ctfRef" :rules="ctfFormRules" label-width="120px">
                <el-row :gutter="35">
                    <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
                      <el-form-item label="关联角色" prop="roleId">
                        <el-select v-model="ctfForm.roleId" placeholder="请选择" clearable class="w100" :disabled="disabled">
                          <el-option v-for="item in roleData" :key="item.roleId" :label="item.roleName" :value="item.roleId"> </el-option>
                        </el-select>
                      </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
                        <el-form-item label="证书编号" prop="certNo">
                            <el-input v-model.trim="ctfForm.certNo" :disabled="disabled" placeholder="" clearable></el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
                        <el-form-item label="证书到期时间" prop="certExpiredAt">
                            <el-date-picker :disabled="disabled" v-model="ctfForm.certExpiredAt" type="date" placeholder="请选择" class="w100" value-format="YYYY-MM-DD"> </el-date-picker>
                        </el-form-item>
                    </el-col>
                  <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
                    <el-form-item label="作业类型" prop="workType">
                      <el-select v-model="ctfForm.workType" placeholder="请选择作业类型" :disabled="disabled">
                        <el-option
                            v-for="item in workTypeList"
                            :key="item.id"
                            :label="item.name"
                            :value="item.id"
                        />
                      </el-select>
                    </el-form-item>
                  </el-col>
                  <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
                    <el-form-item label="证书上传" prop="certUrl">
                      <el-upload :disabled="disabled" accept="image/*" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='1' v-model:file-list="fileList" :http-request="upload" :action="uploadUrl" list-type="picture-card" :before-remove="beforeRemove" :before-upload="getUploadUrl">
                        <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-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="isShowCtfDialog = !isShowCtfDialog" size="default">取 消</el-button>
                    <el-button type="primary" v-throttle @click="onSubmit" size="default" v-if="!disabled">确 定</el-button>
                </span>
            </template>
          <el-dialog v-model="dialogImg">
            <el-image :preview-src-list="[dialogImageUrl]" :src="dialogImageUrl" fit="cover" />
          </el-dialog>
        </el-dialog>
    </div>
</template>
<script lang="ts">
import { reactive, toRefs, onMounted, defineComponent, ref } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import { userApi } from '/@/api/systemManage/user';
import {workApplyApi} from "/@/api/specialWorkSystem/workApply";
import axios from "axios";
import {useUserInfo} from "/@/stores/userInfo";
// 定义接口来定义对象的类型
interface DeptData {}
interface roleData {}
interface dutyData {}
interface sexData {}
interface type {}
interface CtfState {
    title: string;
    disabled: boolean;
    isShowCtfDialog: boolean;
    dialogImg: boolean
    ctfForm: {
      userCertId?: string
      roleId: number| null
      certNo: string
      certExpiredAt: string
      workType: number| null
      certUrl: string
      uid: string | null
    };
    ctfFormRules:{}
    dialogImageUrl: string | null
    fileList: Array<file>
    delList: Array<any>
    uploadUrl: string
    workTypeList: Array<any>
}
interface file {
  url: string;
  uid?: string | null
  name?: string | null
  status?: string | null
}
export default defineComponent({
    name: 'ctf',
    props: ['roleData'],
    setup(props, context) {
        const userInfo = useUserInfo()
        const ctfRef = ref()
        const state = reactive<CtfState>({
            title: '',
            disabled: false,
            isShowCtfDialog: false,
            dialogImg: false,
            ctfForm: {
              userCertId: '',
              roleId: null,
              certNo: '',
              certExpiredAt: '',
              workType: null,
              certUrl: '',
              uid: ''
            },
            ctfFormRules:{
                roleId: [{ required: true, message: '请选择证书相关角色', trigger: 'blur' }],
                certNo: [{ required: true, message: '请输入证书编号', trigger: 'blur' }],
                certExpiredAt: [{ required: true, message: '请选择证书到期时间', trigger: 'change' }],
                workType: [{ required: true, message: '请选择作业类型', trigger: 'blur' }],
                certUrl: [{ required: true, message: '请上传证书', trigger: 'change' }],
            },
            dialogImageUrl: null,
            fileList: [],
            delList: [],
            uploadUrl: '',
            workTypeList: [
              { id: 1, name: '动火作业' },
              { id: 2, name: '受限空间作业' },
              { id: 3, name: '吊装作业' },
              { id: 4, name: '动土作业' },
              { id: 5, name: '断路作业' },
              { id: 6, name: '高处作业' },
              { id: 7, name: '临时用电作业' },
              { id: 8, name: '盲板抽堵作业' }
            ]
        });
        // 打开弹窗
        const openDialog = (type: string, value: any, uid: string) => {
            state.isShowCtfDialog = true;
            state.fileList = []
            if (type === 'add') {
                state.disabled = false
                state.title = '新增证书';
                state.ctfForm = {
                  roleId: null,
                  certNo: '',
                  certExpiredAt: '',
                  workType: null,
                  certUrl: '',
                  uid: uid
                };
            } else{
              for(let i in value){
                if(isValidKey(i,state.ctfForm)){
                  state.ctfForm[i] = value[i]
                }
              }
              state.ctfForm.certExpiredAt = state.ctfForm.certExpiredAt.substring(0,10)
              console.log(state.ctfForm.certExpiredAt,'time')
              state.ctfForm.userCertId = value.id
              state.fileList.push({
                uid: value.id,
                name: value.certUrl,
                status: 'success',
                url: value.certPath
              })
              if(type === 'edit'){
                state.disabled = false
                state.title = '修改证书';
                console.log(state.ctfForm,'555')
              }else{
                state.disabled = true
                state.title = '查看';
                state.ctfForm = JSON.parse(JSON.stringify(value));
              }
            }
        };
        const isValidKey =(key: string | number | symbol, data:object): key is keyof typeof data => {
          return key in data
        }
        // 新增修改
        const onSubmit = async () => {
            ctfRef.value.validate(async (valid:Boolean) => {
                if(valid){
                    if (state.title === '新增证书') {
                        let res = await userApi().addCtf(state.ctfForm);
                        if (res.data.code === '200') {
                            ElMessage({
                                type: 'success',
                                message: '证书新增成功',
                                duration: 2000
                            });
                            if(state.delList.length>0){
                              await deletePic()
                            }
                            state.isShowCtfDialog = false;
                            context.emit('refresh');
                        } else {
                            ElMessage({
                                type: 'warning',
                                message: res.data.msg
                            });
                        }
                    } else {
                        let res = await userApi().modCtf(state.ctfForm);
                        if (res.data.code === '200') {
                            ElMessage({
                                type: 'success',
                                message: '证书修改成功',
                                duration: 2000
                            });
                            if(state.delList.length>0){
                              await deletePic()
                            }
                            state.isShowCtfDialog = false;
                            context.emit('refresh');
                        } else {
                            ElMessage({
                                type: 'warning',
                                message: res.data.msg
                            });
                        }
                    }
                }else{
                    ElMessage({
                        type:'warning',
                        message:'请完善基本信息'
                    })
                }
            })
        };
      // 图片上传
      const showTip =()=>{
        ElMessage({
          type: 'warning',
          message: '超出文件上传数量'
        });
      }
      const handlePictureCardPreview = (uploadFile: { url: string }) => {
        state.dialogImageUrl = uploadFile.url!;
        state.dialogImg = true;
      };
      const getUploadUrl = async (rawFile: any) => {
        if(rawFile.size / 1024 / 1024 > 5){
          ElMessage({
            type: 'warning',
            message: '文件大小不能超过5M。'
          });
          return Promise.reject(false)
        }else{
          const res = await userApi().getPresignUrl(rawFile.name);
          state.ctfForm.certUrl = res.data.data.fileName
          state.uploadUrl = res.data.data.uploadUrl;
        }
      };
      const upload = async (params: any) => {
        let reader = new FileReader();
        reader.readAsArrayBuffer(params.file);
        reader.onload = async () => {
          axios
              .put(state.uploadUrl, reader.result, {
                header: { 'Content-Type': 'multipart/form-data' }
              })
              .then(() => {
              });
        };
      };
      const beforeRemove = (file: {}, fileList: []) => {
        if (file && file.status === "success") {
          const result = new Promise((resolve, reject) => {
            ElMessageBox.confirm('此操作将删除该图片, 是否继续?', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            })
                .then(() => {
                  // console.log(state.workDetail.photos,'path')
                  state.fileList = []
                  fileList = []
                  state.delList.push(state.ctfForm.certUrl)
                  // deletePic(state.ctfForm.certUrl)
                  state.ctfForm.certUrl = ''
                })
                .catch(() => {
                  reject(false);
                });
          });
          return result;
        }
      }
      // 删除图片接口
      const deletePic = async()=>{
        for(let i of state.delList) {
          const res = await workApplyApi().deleteFile({fileName: i})
          if (res.data.code === '200') {
            console.log('文件删除成功')
          } else {
            ElMessage({
              type: 'warning',
              message: res.data.msg
            });
          }
        }
      }
      const restForm = ()=>{
        state.ctfForm = {
          userCertId: '',
          roleId: null,
          certNo: '',
          certExpiredAt: '',
          workType: null,
          certUrl: '',
          uid: ''
        }
        state.fileList = []
        state.delList = []
      }
        // 页面加载时
        onMounted(() => {
        });
        return {
            ctfRef,
          userInfo,
          showTip,
          restForm,
            openDialog,
            onSubmit,
            handlePictureCardPreview,
            getUploadUrl,
            upload,
            beforeRemove,
            isValidKey,
            ...toRefs(state)
        };
    }
});
</script>
src/views/system/user/component/dialogCertificate.vue
New file
@@ -0,0 +1,198 @@
<template>
  <el-dialog v-model="dialogCertificate" title="证书管理">
    <el-row>
      <el-button type="primary" :icon="Plus" size="default" @click="openEdit('add',{})">新增</el-button>
    </el-row>
    <el-table
        :data="tableData"
        highlight-current-row
        style="width: 100%;margin-top: 20px"
        border
        :header-cell-style="{background: '#fafafa'}"
    >
      <el-table-column type="index" label="序号" width="80"/>
      <el-table-column property="id" label="证件Id"/>
      <el-table-column property="roleId" label="相关角色">
        <template #default="scope">
          {{ roleList.find(i=>i.roleId == scope.row.roleId)?.roleName }}
        </template>
      </el-table-column>
      <el-table-column property="workTypeDesc" label="作业类型"/>
      <el-table-column property="roleCode" label="角色编号"/>
      <el-table-column property="certNo" label="证件编号"/>
      <el-table-column fixed="right" label="操作" align="center" width="250">
        <template #default="scope">
          <el-button link type="primary" size="small" :icon="View" @click="openEdit('view',scope.row)">查看</el-button>
          <el-button link type="primary" size="small" :icon="Edit" @click="openEdit('edit', scope.row)">修改</el-button>
          <el-button link type="danger" size="small" :icon="Delete" @click="deleteRecord(scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <ctf-dialog ref="ctfRef" @refresh="getCtf()" :role-data="roleList"></ctf-dialog>
  </el-dialog>
</template>
<script lang="ts">
    import {toRefs, reactive, defineComponent, ref, defineAsyncComponent, onMounted} from 'vue';
    import { storeToRefs } from 'pinia';
    import { initBackEndControlRoutes } from '/@/router/backEnd';
    import {useUserInfo} from "/@/stores/userInfo";
    import { Session } from '/@/utils/storage';
    import { Search, Delete, Edit, View, Plus } from '@element-plus/icons-vue'
  import {ElMessage, ElMessageBox, ElTable} from 'element-plus'
    import {userApi} from "/@/api/systemManage/user";
  import ctfDialog from "/@/views/system/user/component/ctfDialog.vue";
  import {useRoleApi} from "/@/api/systemManage/role";
    interface stateType {
    dialogCertificate: boolean
    tableData: Array<any>
    roleList: Array<any>
    uid: number | null
    }
    export default defineComponent({
        name: 'dialogCertificate',
        components: {ctfDialog},
        props:[],
        setup() {
            const userInfo = useUserInfo()
            const { userInfos } = storeToRefs(userInfo);
            const state  = reactive<stateType>({
        dialogCertificate: false,
        tableData: [],
        roleList: [],
        uid: null
            });
            // 页面载入时执行方法
            onMounted(() => {
            });
      const ctfRef = ref()
      const openDialog = (value: any) => {
        state.dialogCertificate = true
        state.uid = value.uid
        getRoleData()
        getCtf()
      }
      const openEdit = (type: string,value: any)=>{
        ctfRef.value.openDialog(type,value,state.uid)
      }
      const getRoleData = async () => {
        let res = await useRoleApi().getRoleList();
        if (res.data.code === '200') {
          state.roleList = res.data.data;
        } else {
          ElMessage({
            type: 'warning',
            message: res.data.msg
          });
        }
      };
      const getCtf = async()=>{
        let res = await userApi().getCtf({uid: state.uid})
        if(res.data.code == 200){
          state.tableData = res.data.data
        }else{
          ElMessage({
            type: 'warning',
            message: res.data.msg
          })
        }
      }
      // 删除方法
      const deleteRecord = (data: any) => {
            ElMessageBox.confirm(`此操作将永久删除该条证书,是否继续?`, '提示', {
              confirmButtonText: '确认',
              cancelButtonText: '取消',
              type: 'warning'
            })
              .then(async () => {
                let res = await userApi().delCtf({userCertId: data.id});
                if (res.data.code === '200') {
                  ElMessage({
                    type: 'success',
                    message: '删除成功!'
                  });
                  await getCtf();
                } else {
                  ElMessage({
                    type: 'warning',
                    message: res.data.msg
                  });
                }
              })
              .catch(() => {});
      }
            // 折线图
            const renderMenu = async (value: string) => {
                Session.set('projectId',value)
                userInfos.value.projectId = value
                await initBackEndControlRoutes();
            };
            return {
                renderMenu,
        openDialog,
        deleteRecord,
        openEdit,
        getRoleData,
        getCtf,
        ctfRef,
                Search,
        Delete,
        Edit,
        View,
        Plus,
                ...toRefs(state),
            };
        },
    });
</script>
<style scoped lang="scss">
    .home-container {
        height: 100%;
        overflow: hidden;
        position: relative;
        .homeCard{
            width: 100%;
            padding: 0 20px;
            box-sizing: border-box;
            background: #fff;
            border-radius: 4px;
        }
        .applyBtn{
            width: 100%;
            background: #fff;
            padding-top: 15px;
            z-index: 5;
            box-shadow: 0 -3px 8px rgba(150,150,150,.1);
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .el-row{
            margin-bottom: 20px;
        }
        .el-row:last-child {
            margin-bottom: 0;
        }
        .el-input{
            width: 100% !important;
        }
        .el-date-editor::v-deep{
            width: 100%;
        }
        .el-select{
            width: 100%;
        }
        .el-cascader{
            width: 100% !important;
        }
    }
</style>
src/views/system/user/component/userDialog.vue
@@ -240,7 +240,8 @@
                            });
                        }
                    } else {
                        let res = await userApi().modUser(state.userForm);
                      const { roles, positions, ...data} = state.userForm
                        let res = await userApi().modUser(data);
                        if (res.data.code === '200') {
                            ElMessage({
                                type: 'success',
src/views/system/user/index.vue
@@ -56,10 +56,11 @@
                    </template>
                </el-table-column>
                <el-table-column prop="gmtCreate" label="创建时间" show-overflow-tooltip></el-table-column>
                <el-table-column label="操作" width="140">
                <el-table-column label="操作" width="200">
                    <template #default="scope">
                        <el-button :disabled="scope.row.userName === 'admin'" size="small" text type="primary" @click="onOpenUserDialog('查看', scope.row)">查看</el-button>
                        <el-button :disabled="scope.row.userName === 'admin'" size="small" text type="primary" @click="onOpenUserDialog('修改', scope.row)">修改</el-button>
                        <el-button size="small" text type="primary" @click="onCertificate(scope.row)">证书管理</el-button>
                        <el-button style="color: red" :disabled="scope.row.userName === 'admin'" size="small" text type="primary" @click="onRowDel(scope.row)">删除</el-button>
                    </template>
                </el-table-column>
@@ -70,6 +71,7 @@
            <br />
        </el-card>
        <userDialog ref="userRef" @getUserList="initUserTableData" />
        <dialog-certificate ref="ctfRef" @getUserList="initUserTableData"></dialog-certificate>
    </div>
</template>
@@ -77,6 +79,7 @@
import { toRefs, reactive, onMounted, ref, defineComponent } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import userDialog from '/@/views/system/user/component/userDialog.vue';
import dialogCertificate from "/@/views/system/user/component/dialogCertificate.vue";
import { userApi } from '/@/api/systemManage/user';
import { dutyApi } from '/@/api/systemManage/duty';
import { departmentApi } from '/@/api/systemManage/department';
@@ -122,9 +125,10 @@
export default defineComponent({
    name: 'systemUser',
    components: { userDialog },
    components: { userDialog,dialogCertificate },
    setup() {
        const userRef = ref();
        const ctfRef = ref()
        const state = reactive<TableDataState>({
            userTableData: {
                data: [],
@@ -214,6 +218,10 @@
            userRef.value.openDialog(type, value, state.departmentList, state.roleList, state.dutyList);
        };
        const onCertificate = (value: any)=>{
          ctfRef.value.openDialog(value);
        }
        // 删除用户
        const onRowDel = (row: TableDataRow) => {
            ElMessageBox.confirm(`此操作将永久删除账户名称:“${row.realName}”,是否继续?`, '提示', {
@@ -258,7 +266,9 @@
        });
        return {
            userRef,
            ctfRef,
            onOpenUserDialog,
            onCertificate,
            onRowDel,
            parseNumber,
            onHandleSizeChange,