zhouwx
2025-01-08 9e03b447fa15fa3fa0e468ca42a4bb7b4eac1e3b
导出报告
已修改4个文件
已添加2个文件
272 ■■■■■ 文件已修改
public/static/exampleScience.docx 补丁 | 查看 | 原始文档 | blame | 历史
src/views/analyse/applyReview/components/reportDialog.vue 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/analyse/assessApply/components/reportDialog.vue 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/analyse/assessApply/index.ts 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/experiment/developing/components/exportWord.js 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/user/component/userDialog.vue 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/static/exampleScience.docx
Binary files differ
src/views/analyse/applyReview/components/reportDialog.vue
@@ -24,7 +24,8 @@
<!--                                <el-radio :label="5">特种设备类</el-radio>-->
<!--                                <el-radio :label="6">其他类</el-radio>-->
<!--                            </el-radio-group>-->
                            {{reportDialogState.experimentTypeList.find(i=>i.id === reportDialogState.reportForm.experimentType)?.name}}
<!--                            {{reportDialogState.experimentTypeList.find(i=>i.id === reportDialogState.reportForm.experimentType)?.name}}-->
                          {{typeValue}}
                        </td>
                    </tr>
                    <tr>
@@ -209,6 +210,7 @@
              <span class="dialog-footer" style="padding-top:10px;text-align: center !important;">
                <el-button @click="reportDialogState.reportDialogVisible = !reportDialogState.reportDialogVisible" size="default">取 消</el-button>
                <el-button type="primary" v-if="!reportDialogState.disabled" @click="onSubmitProject()" size="default">提交审批</el-button>
                <el-button type="primary" v-if="reportDialogState.disabled" @click="startGeneration()" size="default">导出评估报告</el-button>
              </span>
            </template>
        </el-dialog>
@@ -223,10 +225,11 @@
import {userApi} from "/@/api/systemManage/user";
import {roomApi} from "/@/api/basic/room";
import {assessApplyApi} from "/@/api/analyse/assessApply";
import {generateWordDocument} from "/@/views/experiment/developing/components/exportWord.js";
const SelectDanger = defineAsyncComponent(() => import('./selectDanger.vue'))
const selectDangerRef = ref()
const reportFormRef = ref()
const typeValue = ref([])
const reportDialogState = reactive<ReportDialogType>({
    title: '',
    disabled: false,
@@ -252,7 +255,9 @@
        riskSourceType: [],
        description: '',
        person: [],
        process:''
        process:'',
      experimentAndType: [],
      oldRiskAssess: []
    },
    reportFormRules: {
      assessPerson: [{ required: true, message: '请填写评估人员', trigger: 'blur' }],
@@ -270,7 +275,23 @@
      {id: 4, name: '机电类'},
      {id: 5, name: '特种设备类'},
      {id: 6, name: '其它类'}
    ]
    ],
  riskSourceTypeList: [
    {id: 1, name: '化学安全'},
    {id: 2, name: '辐射安全'},
    {id: 3, name: '生物安全'},
    {id: 4, name: '机电安全'},
    {id: 5, name: '电气安全'},
    {id: 6, name: '激光安全'},
    {id: 7, name: '特种设备安全'},
    {id: 8, name: '其他安全'},
  ],
  riskLevelList: [
    {id: 1, name: '重大风险(一级)'},
    {id: 2, name: '较大风险(二级)'},
    {id: 3, name: '一般风险(三级)'},
    {id: 4, name: '低风险(四级)'},
  ],
})
const showReportDialog = (title: string, value: ProjectType, allRoomList: RoomType []) => {
@@ -319,6 +340,8 @@
        reportDialogState.reportForm[i] = res.data.data[0][i];
      }
    }
    const arr = reportDialogState.reportForm.experimentAndType.map(item => item.type.experimentType)
    typeValue.value = arr.join(',')
    console.log(reportDialogState.reportForm,'reportDialogState.reportForm')
  }else{
    ElMessage({
@@ -426,6 +449,75 @@
defineExpose({
    showReportDialog,
});
const templatePath = '/static/exampleScience.docx'
const startGeneration = async () => {
  const data = JSON.parse(JSON.stringify(reportDialogState.reportForm))
  const experimentTypeNameList = data.experimentAndType.map(item => {
    return {
      id: item.type.id,
      experimentType: item.type.experimentType
    }
  })
  const experimentTypeListExample =  JSON.parse(JSON.stringify(reportDialogState.experimentTypeList))
  experimentTypeListExample.forEach(item => {
    if(experimentTypeNameList.some(i => i.experimentType == item.name)){
      item.label = item.name
      item.checked = false
    }else {
      item.label = item.name
      item.checked = true
    }
  })
  data.typeList = experimentTypeListExample
  data.depNameList = data.dep
  const siteTest = data.experimentSite.map(item => item.siteName)
  data.siteList = siteTest.join(',')
  const riskType = data.riskSourceType.filter(item => item.status == 1)
  const riskListExample = reportDialogState.riskSourceTypeList
  riskListExample.forEach(item => {
    if(riskType.some(i => i.riskSourceType === item.name)){
      item.label = item.name
      item.checked = false
    }else {
      item.label = item.name
      item.checked = true
    }
  })
  data.riskList = riskListExample
  const level = data.assessLevel.toString().split(',')
  const levelExample =  JSON.parse(JSON.stringify(reportDialogState.riskLevelList))
  levelExample.forEach(item => {
    if(level.some(i => i == item.id)){
      item.label = item.name
      item.checked = false
    }else {
      item.label = item.name
      item.checked = true
    }
  })
  data.riskLevel = levelExample
  data.tableData = data.oldRiskAssess
  data.riskSource = data.riskSource.map(item => {
    return {
      ...item,
      description: item.description ? item.description: ''
    }
  })
  try {
    generateWordDocument(templatePath, data, `材料科学姑苏实验室安全风险评估表---${data.experimentName}.docx`);
  } catch (error){
    ElMessage({
      type: 'warning',
      message: '失败'
    });
  }
};
onMounted(() => {
    getAllPersonList();
src/views/analyse/assessApply/components/reportDialog.vue
@@ -24,7 +24,8 @@
<!--                                <el-radio :label="5">特种设备类</el-radio>-->
<!--                                <el-radio :label="6">其他类</el-radio>-->
<!--                            </el-radio-group>-->
                            {{reportDialogState.experimentTypeList.find(i=>i.id === reportDialogState.reportForm.experimentType)?.name}}
<!--                            {{reportDialogState.experimentTypeList.find(i=>i.id === reportDialogState.reportForm.experimentAndType)?.name}}-->
                          {{typeValue}}
                        </td>
                    </tr>
                    <tr>
@@ -215,6 +216,7 @@
              <span class="dialog-footer" style="padding-top:10px;text-align: center !important;">
                <el-button @click="reportDialogState.reportDialogVisible = !reportDialogState.reportDialogVisible" size="default">取 消</el-button>
                <el-button type="primary" v-if="!reportDialogState.disabled" @click="onSubmitProject()" size="default">提交审批</el-button>
                <el-button type="primary" v-if="reportDialogState.disabled" @click="startGeneration()" size="default">导出评估报告</el-button>
              </span>
            </template>
        </el-dialog>
@@ -223,13 +225,14 @@
<script setup lang="ts">
import {defineAsyncComponent, nextTick, onMounted, reactive, ref} from "vue";
import {generateWordDocument} from "/@/views/experiment/developing/components/exportWord.js";
import {ElMessage} from "element-plus";
import {projectApi} from "/@/api/experiment/project";
import {personApi} from "/@/api/basic/person";
import {userApi} from "/@/api/systemManage/user";
import {roomApi} from "/@/api/basic/room";
import {assessApplyApi} from "/@/api/analyse/assessApply";
const typeValue = ref([])
const SelectDanger = defineAsyncComponent(() => import('./selectDanger.vue'))
const selectDangerRef = ref()
const reportFormRef = ref()
@@ -258,7 +261,9 @@
        riskSourceType: [],
        description: '',
        person:[],
        process: ''
        process: '',
      experimentAndType: [],
      oldRiskAssess: []
    },
    reportFormRules: {
      assessPerson: [{ required: true, message: '请填写评估人员', trigger: 'blur' }],
@@ -276,7 +281,23 @@
      {id: 4, name: '机电类'},
      {id: 5, name: '特种设备类'},
      {id: 6, name: '其它类'}
    ]
    ],
  riskSourceTypeList: [
    {id: 1, name: '化学安全'},
    {id: 2, name: '辐射安全'},
    {id: 3, name: '生物安全'},
    {id: 4, name: '机电安全'},
    {id: 5, name: '电气安全'},
    {id: 6, name: '激光安全'},
    {id: 7, name: '特种设备安全'},
    {id: 8, name: '其他安全'},
  ],
  riskLevelList: [
    {id: 1, name: '重大风险(一级)'},
    {id: 2, name: '较大风险(二级)'},
    {id: 3, name: '一般风险(三级)'},
    {id: 4, name: '低风险(四级)'},
  ],
})
const showReportDialog = (title: string, value: ProjectType, allRoomList: RoomType []) => {
@@ -346,7 +367,9 @@
      riskSourceType: [],
      description: '',
      person:[],
      process: ''
      process: '',
      experimentAndType: [],
      oldRiskAssess: []
    }
    if(res.data.data&&res.data.data.length==0){
      ElMessage({
@@ -359,6 +382,8 @@
          reportDialogState.reportForm[i] = res.data.data[0][i];
        }
      }
      const arr = reportDialogState.reportForm.experimentAndType.map(item => item.type.experimentType)
      typeValue.value = arr.join(',')
    }
  }else{
    ElMessage({
@@ -466,6 +491,77 @@
    }
};
const templatePath = '/static/exampleScience.docx'
const startGeneration = async () => {
  const data = JSON.parse(JSON.stringify(reportDialogState.reportForm))
  const experimentTypeNameList = data.experimentAndType.map(item => {
    return {
      id: item.type.id,
      experimentType: item.type.experimentType
    }
  })
  const experimentTypeListExample =  JSON.parse(JSON.stringify(reportDialogState.experimentTypeList))
  experimentTypeListExample.forEach(item => {
    if(experimentTypeNameList.some(i => i.experimentType == item.name)){
      item.label = item.name
      item.checked = false
    }else {
      item.label = item.name
      item.checked = true
    }
  })
  data.typeList = experimentTypeListExample
  data.depNameList = data.dep
  const siteTest = data.experimentSite.map(item => item.siteName)
  data.siteList = siteTest.join(',')
  const riskType = data.riskSourceType.filter(item => item.status == 1)
  const riskListExample = reportDialogState.riskSourceTypeList
  riskListExample.forEach(item => {
    if(riskType.some(i => i.riskSourceType === item.name)){
      item.label = item.name
      item.checked = false
    }else {
      item.label = item.name
      item.checked = true
    }
  })
  data.riskList = riskListExample
  const level = data.assessLevel.toString().split(',')
  const levelExample =  JSON.parse(JSON.stringify(reportDialogState.riskLevelList))
  levelExample.forEach(item => {
    if(level.some(i => i == item.id)){
      item.label = item.name
      item.checked = false
    }else {
      item.label = item.name
      item.checked = true
    }
  })
  data.riskLevel = levelExample
  data.tableData = data.oldRiskAssess
  data.riskSource = data.riskSource.map(item => {
    return {
      ...item,
      description: item.description ? item.description: ''
    }
  })
  try {
    generateWordDocument(templatePath, data, `材料科学姑苏实验室安全风险评估表---${data.experimentName}.docx`);
  } catch (error){
    ElMessage({
      type: 'warning',
      message: '失败'
    });
  }
};
const emit = defineEmits(['refresh']);
defineExpose({
src/views/analyse/assessApply/index.ts
@@ -27,13 +27,17 @@
        riskSourceType: [],
        description: string,
        person: [],
        process: string
        process: string,
        experimentAndType: [],
        oldRiskAssess: []
    }
    reportFormRules: object
    allPersonList: Array<AllPersonListType>
    systemPersonList: Array<AllPersonListType>
    allRoomList: Array<RoomType>,
    experimentTypeList: Array<Type>
    riskSourceTypeList: Array<Type>
    riskLevelList: Array<Type>
}
declare interface DangerSourceType {
src/views/experiment/developing/components/exportWord.js
对比新文件
@@ -0,0 +1,55 @@
//引入工具
import PizZip from 'pizzip';
import Docxtemplater from 'docxtemplater';
import JSZipUtils from 'jszip-utils';
import { saveAs } from 'file-saver';
// 加载 .docx 模板文件
function loadFile(url, callback) {
    JSZipUtils.getBinaryContent(url, callback);
}
// 下载生成的文档
export function download(file, name) {
}
// 生成并下载 Word 文档(templatePath是word文档模版地址,data是对应的数据)
export function generateWordDocument(templatePath, data, name) {
        loadFile(templatePath, function (error, content) {
            if (error) {
                throw error
                return;
            }
            try {
                // 加载模板文件内容到 PizZip
                const zip = new PizZip(content);
                const doc = new Docxtemplater(zip, {
                    paragraphLoop: true,
                    linebreaks: true,
                });
                // 设置模板中的占位符数据
                doc.setData(data);
                // 渲染文档
                doc.render();
                // 生成最终的文档 Blob
                const fileWord = doc.getZip().generate({
                    type: 'blob',
                    mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
                });
                saveAs(fileWord, name);
                // // 返回生成的文档 Blob
                // resolve(fileWord);
            } catch (error) {
                console.error('Error rendering document:', error);
                throw error
            }
        });
}
src/views/system/user/component/userDialog.vue
@@ -237,6 +237,9 @@
            }
        };
      const verifyPhoneTest = (phone) => {
        return /^1[3-9]\d{9}$/.test(phone);
      }
        // 新增修改
        const onSubmit = async () => {
            userRef.value.validate(async (valid:Boolean) => {
@@ -249,7 +252,7 @@
                      });
                      return
                    }
                    if(verifyPhone(state.userForm.phone) == false){
                    if(verifyPhoneTest(state.userForm.phone) == false){
                      ElMessage({
                        type: 'warning',
                        message: '请输入正确的手机号',