深海科学与工程研究所安全巡检系统
36a315121f466fd06cf9b13b2ffb492d98aaa46d..70d6b00181e291c342df11c9e3d95451768f455d
4 days ago 祖安之光
修改暂存
70d6b0 diff | tree
4 days ago 祖安之光
添加暂存和图片
0e5a00 diff | tree
3 files modified
1153 ■■■■■ changed files
src/api/saftyCheck/index.js 8 ●●●●● patch | view | raw | blame | history
src/views/components/formDialog.vue 535 ●●●●● patch | view | raw | blame | history
src/views/saftyCheckMng/dailyCheck/index.vue 610 ●●●●● patch | view | raw | blame | history
src/api/saftyCheck/index.js
@@ -16,6 +16,14 @@
    })
}
export function saveTemDailySafetyInspect(data) {
    return request({
        url: '/system/dailySafetyInspection/scratchpadDailySafetyInspection',
        method: 'post',
        data: data
    })
}
export function delDailySafetyInspect(params) {
    return request({
        url: '/system/dailySafetyInspection/deleteDailySafetyInspection',
src/views/components/formDialog.vue
@@ -1,62 +1,74 @@
<template>
  <div class="dynamic-form">
    <el-dialog
        v-model="dialogVisible"
        :title="state.title"
        width="50%"
        :before-close="closeDialog"
        :close-on-press-escape="false"
        :close-on-click-modal="false"
      v-model="dialogVisible"
      :title="state.title"
      width="50%"
      :before-close="closeDialog"
      :close-on-press-escape="false"
      :close-on-click-modal="false"
    >
      <el-dialog v-model="state.dialogVisible">
        <el-image style="width: 100%" :src="state.dialogImageUrl"/>
        <el-image style="width: 100%" :src="state.dialogImageUrl" />
      </el-dialog>
      <el-form
          :model="state.formData"
          size="default"
          ref="formRef"
          :rules="state.formRules"
          label-width="160px"
        :model="state.formData"
        size="default"
        ref="formRef"
        :rules="state.formRules"
        label-width="160px"
      >
        <template v-for="(item, index) in config.formItems" :key="index">
        <el-divider v-if="item.type === 'divider'" content-position="left">{{item.content}}</el-divider>
        <el-form-item
          <el-divider v-if="item.type === 'divider'" content-position="left">{{
            item.content
          }}</el-divider>
          <el-form-item
            v-else
            :label="item.label + (item.label.endsWith(':') ? '' : ':')"
            :prop="item.prop"
            :rules="item.rules"
        >
          <!-- 文件上传组件 -->
          <el-upload
          >
            <!-- 文件上传组件 -->
            <el-upload
              v-if="item.type === 'upload'"
              :action="state.uploadUrl"
              :headers="state.header"
              method="post"
              :on-success="(res, uploadFile) => handleUploadSuccess(res, uploadFile, item.prop)"
              :on-success="
                (res, uploadFile) =>
                  handleUploadSuccess(res, uploadFile, item.prop)
              "
              :on-exceed="showTip"
              :limit="item.limit || 1"
              v-model:file-list="state.fileLists[item.prop]"
              :before-upload="(rawFile) => beforeUpload(rawFile, item)"
              :on-remove="(file, uploadFiles) => handleRemove(file, uploadFiles, item.prop)"
              :on-remove="
                (file, uploadFiles) =>
                  handleRemove(file, uploadFiles, item.prop)
              "
              :accept="item.accept || '.doc,.docx,.pdf,.jpg,.jpeg,.png'"
              :disabled="state.title === '查看' || item.disabled"
              :list-type="item.uploadType == 'img'?'picture-card':''"
              :list-type="item.uploadType == 'img' ? 'picture-card' : ''"
              :on-preview="handlePictureCardPreview"
          >
            <el-icon v-if="item.uploadType == 'img'"><Plus /></el-icon>
            <el-button v-else type="primary">点击上传</el-button>
            <template #tip>
              <div class="el-upload__tip" v-if="item.tip">
                {{ item.tip }}
              </div>
              <div class="el-upload__tip" v-else>
                支持上传{{ item.accept || '.doc,.docx,.pdf,.jpg,.jpeg,.png' }}格式, 尺寸小于{{ (item.maxSize || 5) }}M,最多可上传{{ item.limit || 1 }}份
              </div>
            </template>
          </el-upload>
            >
              <el-icon v-if="item.uploadType == 'img'"><Plus /></el-icon>
              <el-button v-else type="primary">点击上传</el-button>
              <template #tip>
                <div class="el-upload__tip" v-if="item.tip">
                  {{ item.tip }}
                </div>
                <div class="el-upload__tip" v-else>
                  支持上传{{
                    item.accept || ".doc,.docx,.pdf,.jpg,.jpeg,.png"
                  }}格式, 尺寸小于{{ item.maxSize || 5 }}M,最多可上传{{
                    item.limit || 1
                  }}份
                </div>
              </template>
            </el-upload>
          <!-- 多选选择框组件 -->
          <el-select
            <!-- 多选选择框组件 -->
            <el-select
              v-else-if="item.type === 'select' && item.multiple"
              v-model="state.formData[item.prop]"
              :placeholder="item.placeholder || '请选择'"
@@ -68,18 +80,22 @@
              :collapse-tags="item.collapseTags"
              :collapse-tags-tooltip="item.collapseTagsTooltip"
              :style="item.style || 'width: 100%'"
              @change="item.changeEvent ? handleEvent(item.changeEvent, state.formData[item.prop]) : null"
          >
            <el-option
              @change="
                item.changeEvent
                  ? handleEvent(item.changeEvent, state.formData[item.prop])
                  : null
              "
            >
              <el-option
                v-for="option in getOptions(item.options)"
                :key="option.value"
                :label="option.label"
                :value="option.value"
            />
          </el-select>
              />
            </el-select>
          <!-- 单选选择框组件 -->
          <el-select
            <!-- 单选选择框组件 -->
            <el-select
              v-else-if="item.type === 'select'"
              v-model="state.formData[item.prop]"
              :placeholder="item.placeholder || '请选择'"
@@ -87,18 +103,22 @@
              :clearable="item.clearable !== false"
              :filterable="item.filterable"
              :style="item.style || 'width: 100%'"
              @change="item.changeEvent ? handleEvent(item.changeEvent, state.formData[item.prop]) : null"
          >
            <el-option
              @change="
                item.changeEvent
                  ? handleEvent(item.changeEvent, state.formData[item.prop])
                  : null
              "
            >
              <el-option
                v-for="option in getOptions(item.options)"
                :key="option.value"
                :label="option.label"
                :value="option.value"
            />
          </el-select>
              />
            </el-select>
          <!-- 级联选择组件 -->
          <el-cascader
            <!-- 级联选择组件 -->
            <el-cascader
              v-else-if="item.type === 'cascader'"
              v-model="state.formData[item.prop]"
              :options="getCascaderOptions(item)"
@@ -109,12 +129,15 @@
              :filterable="item.filterable"
              :show-all-levels="item.showAllLevels !== false"
              :style="item.style || 'width: 100%'"
              @change="item.changeEvent ? handleEvent(item.changeEvent, state.formData[item.prop]) : null"
          />
              @change="
                item.changeEvent
                  ? handleEvent(item.changeEvent, state.formData[item.prop])
                  : null
              "
            />
          <!-- 日期选择器组件 -->
          <el-date-picker
            <!-- 日期选择器组件 -->
            <el-date-picker
              v-else-if="item.type === 'date'"
              v-model="state.formData[item.prop]"
              :type="item.dateType || 'date'"
@@ -122,10 +145,10 @@
              :disabled="state.title === '查看' || item.disabled"
              :value-format="item.valueFormat || 'YYYY-MM-DD'"
              :style="item.style || 'width: 100%'"
          />
            />
          <!-- 文本域组件 -->
          <el-input
            <!-- 文本域组件 -->
            <el-input
              v-else-if="item.type === 'textarea'"
              v-model="state.formData[item.prop]"
              type="textarea"
@@ -134,10 +157,10 @@
              :readonly="state.title === '查看'"
              :autosize="item.autosize || { minRows: 2 }"
              :style="item.style || 'width: 100%'"
          />
            />
          <!-- 默认文本输入框组件 -->
          <el-input
            <!-- 默认文本输入框组件 -->
            <el-input
              v-else
              v-model="state.formData[item.prop]"
              :placeholder="item.placeholder || '请输入'"
@@ -145,15 +168,29 @@
              :readonly="state.title === '查看'"
              :style="item.style || 'width: 100%'"
              :type="item.inputType || 'text'"
          />
        </el-form-item>
            />
          </el-form-item>
        </template>
      </el-form>
      <template #footer v-if="state.title !== '查看'">
        <span class="dialog-footer">
          <el-button
            type="primary"
            @click="onSave"
            v-if="state.hasSave"
            size="default"
            v-preReClick
            >暂存</el-button
          >
          <el-button @click="closeDialog" size="default">取 消</el-button>
          <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button>
          <el-button
            type="primary"
            @click="onSubmit"
            size="default"
            v-preReClick
            >确认</el-button
          >
        </span>
      </template>
    </el-dialog>
@@ -161,305 +198,362 @@
</template>
<script setup>
import { reactive, ref, nextTick } from 'vue'
import { ElMessage } from "element-plus"
import { getToken } from "@/utils/auth"
import { reactive, ref, nextTick } from "vue";
import { ElMessage } from "element-plus";
import { getToken } from "@/utils/auth";
// 定义props
const props = defineProps({
  config: {
    type: Object,
    required: true,
    default: () => ({})
    default: () => ({}),
  },
  // API相关函数
  api: {
    type: Object,
    default: () => ({})
    default: () => ({}),
  },
  // 数据加载函数
  dataLoader: {
    type: Object,
    default: () => ({})
    default: () => ({}),
  },
  // 文件上传相关配置
  uploadConfig: {
    type: Object,
    default: () => ({
      uploadUrl: import.meta.env.VITE_APP_BASE_API + '/common/upload',
      deleteUrl: '/common/deleteFile'
    })
  }
})
      uploadUrl: import.meta.env.VITE_APP_BASE_API + "/common/upload",
      deleteUrl: "/common/deleteFile",
    }),
  },
});
const emit = defineEmits(["submit", "close", "update:modelValue"])
const emit = defineEmits(["submit", "close", "update:modelValue"]);
const dialogVisible = ref(false)
const formRef = ref()
const dialogVisible = ref(false);
const formRef = ref();
const state = reactive({
  title: '',
  title: "",
  formData: {},
  formRules: {},
  uploadUrl: props.uploadConfig.uploadUrl,
  header: {
    Authorization: getToken()
    Authorization: getToken(),
  },
  fileLists: {},
  companyList: [],
  deptList: [],
  userList: [],
  dialogVisible: false,
  dialogImageUrl: ''
})
  dialogImageUrl: "",
  hasSave: false,
});
const initFormData = () => {
  const formData = {}
  state.fileLists = {}
  const formData = {};
  state.fileLists = {};
  props.config.formItems?.forEach(item => {
    if (item.type === 'select' && item.multiple) {
      formData[item.prop] = Array.isArray(item.defaultValue) ? item.defaultValue : []
  props.config.formItems?.forEach((item) => {
    if (item.type === "select" && item.multiple) {
      formData[item.prop] = Array.isArray(item.defaultValue)
        ? item.defaultValue
        : [];
    } else {
      formData[item.prop] = item.defaultValue !== undefined ? item.defaultValue : null
      formData[item.prop] =
        item.defaultValue !== undefined ? item.defaultValue : null;
    }
    if (item.type === 'upload') {
      state.fileLists[item.prop] = []
    if (item.type === "upload") {
      state.fileLists[item.prop] = [];
    }
  })
  });
  const formRules = {}
  props.config.formItems?.forEach(item => {
  const formRules = {};
  props.config.formItems?.forEach((item) => {
    if (item.rules) {
      formRules[item.prop] = item.rules
      formRules[item.prop] = item.rules;
    }
    if (item.type === 'upload' && item.required) {
      formRules[item.prop] = formRules[item.prop] || []
    if (item.type === "upload" && item.required) {
      formRules[item.prop] = formRules[item.prop] || [];
      formRules[item.prop].push({
        required: true,
        validator: (rule, value, callback) => {
          if (state.fileLists[item.prop]?.length === 0) {
            callback(new Error(`请上传${item.label}`))
            callback(new Error(`请上传${item.label}`));
          } else {
            callback()
            callback();
          }
        },
        trigger: 'blur'
      })
        trigger: "blur",
      });
    }
    if (item.type === 'select' && item.multiple && item.required) {
      formRules[item.prop] = formRules[item.prop] || []
    if (item.type === "select" && item.multiple && item.required) {
      formRules[item.prop] = formRules[item.prop] || [];
      formRules[item.prop].push({
        validator: (rule, value, callback) => {
          if (!value || value.length === 0) {
            callback(new Error(`请选择${item.label}`))
            callback(new Error(`请选择${item.label}`));
          } else {
            callback()
            callback();
          }
        },
        trigger: 'change'
      })
        trigger: "change",
      });
    }
  })
  });
  state.formData = formData
  state.formRules = formRules
}
  state.formData = formData;
  state.formRules = formRules;
};
const getOptions = (options) => {
  if (!options) return []
  if (!options) return [];
  if (typeof options === 'function') {
    return options()
  if (typeof options === "function") {
    return options();
  }
  if (Array.isArray(options)) {
    return options
    return options;
  }
  return []
}
  return [];
};
const getCascaderOptions = (item) => {
  if (!item.options) return []
  if (!item.options) return [];
  if (typeof item.options === 'function') {
    return item.options()
  if (typeof item.options === "function") {
    return item.options();
  }
  if (Array.isArray(item.options)) {
    return item.options
    return item.options;
  }
  if (item.options && typeof item.options === 'object' && 'value' in item.options) {
    return item.options.value
  if (
    item.options &&
    typeof item.options === "object" &&
    "value" in item.options
  ) {
    return item.options.value;
  }
  return []
}
  return [];
};
const beforeUpload = (rawFile, item) => {
  const maxSize = item.maxSize || 5
  const maxSize = item.maxSize || 5;
  if (rawFile.size / 1024 / 1024 > maxSize) {
    ElMessage.warning(`文件大小不能超过${maxSize}M`)
    return false
    ElMessage.warning(`文件大小不能超过${maxSize}M`);
    return false;
  }
  return true
}
  return true;
};
const handleUploadSuccess = (res, uploadFile, prop) => {
  if (res.code === 200) {
    ElMessage.success('上传成功')
    ElMessage.success("上传成功");
  } else {
    state.fileLists[prop] = state.fileLists[prop].filter(file => file.uid !== uploadFile.uid)
    ElMessage.warning(res.message || '文件上传失败')
    state.fileLists[prop] = state.fileLists[prop].filter(
      (file) => file.uid !== uploadFile.uid,
    );
    ElMessage.warning(res.message || "文件上传失败");
  }
  state.formData[prop] = state.fileLists[prop].filter(i=>i.status == 'success').map(item=>{
    return item.response.fileName
  }).join(',')
}
  state.formData[prop] = state.fileLists[prop]
    .filter((i) => i.status == "success")
    .map((item) => {
      return item.response.fileName;
    })
    .join(",");
};
const handleRemove = async (file, uploadFiles, prop) => {
  try {
    if(file.uid){
      state.fileLists[prop] = state.fileLists[prop].filter(f => f.uid !== file.uid)
    }else{
      state.fileLists[prop] = state.fileLists[prop].filter(f => f.url !== file.url)
    if (file.uid) {
      state.fileLists[prop] = state.fileLists[prop].filter(
        (f) => f.uid !== file.uid,
      );
    } else {
      state.fileLists[prop] = state.fileLists[prop].filter(
        (f) => f.url !== file.url,
      );
    }
    state.formData[prop] = state.fileLists[prop].filter(i=>i.status == 'success').map(item=>{
      return item.response.fileName
    }).join(',')
    ElMessage.success('文件已删除')
    state.formData[prop] = state.fileLists[prop]
      .filter((i) => i.status == "success")
      .map((item) => {
        return item.response.fileName;
      })
      .join(",");
    ElMessage.success("文件已删除");
  } catch (error) {
    console.error('删除文件时出错:', error)
    ElMessage.warning('文件删除失败')
    console.error("删除文件时出错:", error);
    ElMessage.warning("文件删除失败");
  }
}
};
const handlePictureCardPreview = (uploadFile) => {
  state.dialogImageUrl = uploadFile.url
  state.dialogVisible = true
}
  state.dialogImageUrl = uploadFile.url;
  state.dialogVisible = true;
};
const showTip = () => {
  ElMessage.warning('超出文件上传数量')
}
  ElMessage.warning("超出文件上传数量");
};
const handleEvent = async (eventName, value) => {
  try {
    if (eventName === 'getUserListByRole' && props.dataLoader.getUserListByRole) {
      const userList = await props.dataLoader.getUserListByRole(value)
      state.userList = userList
      const userItem = props.config.formItems.find(item => item.prop === 'reformUserId')
    if (
      eventName === "getUserListByRole" &&
      props.dataLoader.getUserListByRole
    ) {
      const userList = await props.dataLoader.getUserListByRole(value);
      state.userList = userList;
      const userItem = props.config.formItems.find(
        (item) => item.prop === "reformUserId",
      );
      if (userItem) {
        userItem.options = () => userList.map(user => ({
          value: user.userId,
          label: user.nickName
        }))
        state.formData.reformUserId = null
        await nextTick()
        userItem.options = () =>
          userList.map((user) => ({
            value: user.userId,
            label: user.nickName,
          }));
        state.formData.reformUserId = null;
        await nextTick();
      }
    }
  } catch (error) {
    console.error('事件处理失败:', error)
    ElMessage.error('数据加载失败')
    console.error("事件处理失败:", error);
    ElMessage.error("数据加载失败");
  }
}
};
const openDialog = async (type, initialData) => {
  state.title = type === 'add' ? '新增' : type === 'edit' ? '编辑' : type === 'rectify' ? '整改' : '查看'
  initFormData()
const openDialog = async (type, initialData, hasSave) => {
  state.title =
    type === "add"
      ? "新增"
      : type === "edit"
        ? "编辑"
        : type === "rectify"
          ? "整改"
          : "查看";
  state.hasSave = hasSave
  initFormData();
  try {
    if (props.dataLoader.loadInitialData) {
      const initialData = await props.dataLoader.loadInitialData(id)
      Object.assign(state, initialData)
      const initialData = await props.dataLoader.loadInitialData(id);
      Object.assign(state, initialData);
    }
  } catch (error) {
    console.error('无初始数据:', error)
    console.error("无初始数据:", error);
  }
  if (initialData) {
    Object.keys(state.formData).forEach(key => {
    Object.keys(state.formData).forEach((key) => {
      if (key in initialData) {
        const item = props.config.formItems.find(i => i.prop === key)
        if (item && item.type === 'select' && item.multiple) {
          state.formData[key] = Array.isArray(initialData[key]) ? initialData[key] : (initialData[key] ? [initialData[key]] : [])
        const item = props.config.formItems.find((i) => i.prop === key);
        if (item && item.type === "select" && item.multiple) {
          state.formData[key] = Array.isArray(initialData[key])
            ? initialData[key]
            : initialData[key]
              ? [initialData[key]]
              : [];
        } else {
          state.formData[key] = initialData[key]
          state.formData[key] = initialData[key];
        }
      }
    })
    state.formData.id = initialData.id || null
    });
    state.formData.id = initialData.id || null;
    props.config.formItems?.forEach(item => {
      if (item.type === 'upload' && initialData[item.prop]) {
        state.fileLists[item.prop] = [{
          url: initialData[item.prop],
          name: item.label || '文件'
        }]
        state.fileLists[item.prop] = initialData[item.prop].split(',').map(i=>{
          return {
            url: import.meta.env.VITE_APP_BASE_API + i,
            status: 'success',
            name: item.label || '文件',
            response: {
              fileName: i
            }
          }
        })
    props.config.formItems?.forEach((item) => {
      if (item.type === "upload" && initialData[item.prop]) {
        state.fileLists[item.prop] = [
          {
            url: initialData[item.prop],
            name: item.label || "文件",
          },
        ];
        state.fileLists[item.prop] = initialData[item.prop]
          .split(",")
          .map((i) => {
            return {
              url: import.meta.env.VITE_APP_BASE_API + i,
              status: "success",
              name: item.label || "文件",
              response: {
                fileName: i,
              },
            };
          });
      }
    })
    });
  }
  dialogVisible.value = true
  dialogVisible.value = true;
  await nextTick()
}
};
// 提交表单
const onSubmit = async () => {
  try {
    const valid = await formRef.value.validate()
    const valid = await formRef.value.validate();
    if (valid) {
      const submitData = { ...state.formData };
      const submitData = { ...state.formData }
      props.config.formItems?.forEach(item => {
        if (item.type === 'select' && item.multiple &&
            Array.isArray(submitData[item.prop]) &&
            submitData[item.prop].length === 0) {
          submitData[item.prop] = null
      props.config.formItems?.forEach((item) => {
        if (
          item.type === "select" &&
          item.multiple &&
          Array.isArray(submitData[item.prop]) &&
          submitData[item.prop].length === 0
        ) {
          submitData[item.prop] = null;
        }
      })
      });
      emit('submit', submitData, state.title)
      emit("submit", submitData, state.title);
    }else{
      ElMessage.error("请完善表单内容");
    }
  } catch (error) {
    console.error('表单验证失败:', error)
    ElMessage.error('请完善表单内容')
    console.error("表单验证失败:", error);
    ElMessage.error("请完善表单内容");
  }
}
};
const onSave = async () => {
  const submitData = { ...state.formData };
  props.config.formItems?.forEach((item) => {
    if (
      item.type === "select" &&
      item.multiple &&
      Array.isArray(submitData[item.prop]) &&
      submitData[item.prop].length === 0
    ) {
      submitData[item.prop] = null;
    }
  });
  emit("onSave", submitData, state.title);
};
const closeDialog = () => {
  formRef.value.clearValidate()
  formRef.value.resetFields()
  dialogVisible.value = false
}
  if (formRef.value) {
    formRef.value.clearValidate();
    formRef.value.resetFields();
  }
  dialogVisible.value = false;
};
defineExpose({
  openDialog,
  closeDialog
})
  closeDialog,
});
initFormData()
initFormData();
</script>
<style scoped lang="scss">
@@ -474,7 +568,6 @@
  color: #606266;
  margin-top: 7px;
}
:deep(.el-select__tags) {
  white-space: nowrap;
src/views/saftyCheckMng/dailyCheck/index.vue
@@ -1,106 +1,174 @@
<template>
  <div class="app-container">
    <div style="display: flex;justify-content: space-between">
      <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" >
    <div style="display: flex; justify-content: space-between">
      <el-form
        :inline="true"
        style="display: flex; align-items: center; flex-wrap: wrap"
      >
        <el-form-item>
          <el-button
              type="primary"
              plain
              icon="Plus"
              @click="openDialog('add',{})"
          >新增</el-button>
            type="primary"
            plain
            icon="Plus"
            @click="openDialog('add', {})"
            >新增</el-button
          >
        </el-form-item>
        <el-form-item label="被检查部门/研究组:" >
<!--          <el-select v-model="queryParams.researchGroup" placeholder="请选择" clearable>-->
<!--            <el-option-->
<!--                v-for="item in deptList"-->
<!--                :key="item.deptId"-->
<!--                :label="item.deptName"-->
<!--                :value="item.deptId">-->
<!--            </el-option>-->
<!--          </el-select>-->
          <el-cascader v-model="queryParams.researchGroup" placeholder="请选择" :options="deptList" :show-all-levels="false" :props="{value: 'deptId',label: 'deptName',children: 'children',emitPath: false,checkStrictly: true}"/>
        <el-form-item label="被检查部门/研究组:">
          <!--          <el-select v-model="queryParams.researchGroup" placeholder="请选择" clearable>-->
          <!--            <el-option-->
          <!--                v-for="item in deptList"-->
          <!--                :key="item.deptId"-->
          <!--                :label="item.deptName"-->
          <!--                :value="item.deptId">-->
          <!--            </el-option>-->
          <!--          </el-select>-->
          <el-cascader
            v-model="queryParams.researchGroup"
            placeholder="请选择"
            :options="deptList"
            :show-all-levels="false"
            :props="{
              value: 'deptId',
              label: 'deptName',
              children: 'children',
              emitPath: false,
              checkStrictly: true,
            }"
          />
        </el-form-item>
        <el-form-item label="参加检查人员" >
          <el-input v-model.trim="queryParams.checkUser" placeholder="参加检查人员"></el-input>
        <el-form-item label="参加检查人员">
          <el-input
            v-model.trim="queryParams.checkUser"
            placeholder="参加检查人员"
          ></el-input>
        </el-form-item>
        <el-form-item label="检查类型" >
          <el-select v-model="queryParams.checkType" placeholder="请选择" clearable>
        <el-form-item label="检查类型">
          <el-select
            v-model="queryParams.checkType"
            placeholder="请选择"
            clearable
          >
            <el-option
                v-for="item in checkTypeList"
                :key="item.value"
                :label="item.label"
                :value="item.value">
              v-for="item in checkTypeList"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="隐患" >
          <el-select v-model="queryParams.haveMainHazard" placeholder="请选择" clearable>
        <el-form-item label="隐患">
          <el-select
            v-model="queryParams.haveMainHazard"
            placeholder="请选择"
            clearable
          >
            <el-option :key="1" label="有" :value="1"></el-option>
            <el-option :key="0" label="无" :value="0"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="检查日期" >
        <el-form-item label="检查日期">
          <el-date-picker
              v-model="checkDate"
              type="daterange"
              value-format="YYYY-MM-DD"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
            v-model="checkDate"
            type="daterange"
            value-format="YYYY-MM-DD"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
          />
        </el-form-item>
        <el-form-item >
        <el-form-item>
          <el-button type="primary" @click="getList">查询</el-button>
          <el-button type="primary" plain @click="reset">重置</el-button>
<!--          <el-button type="primary">导出</el-button>-->
          <!--          <el-button type="primary">导出</el-button>-->
        </el-form-item>
      </el-form>
    </div>
    <!-- 表格数据 -->
    <el-table v-loading="loading" :data="dataList" :border="true">
      <el-table-column type="index" label="序号"></el-table-column>
      <el-table-column prop="checkDate" align="center" label="检查时间"/>
      <el-table-column prop="checkPlace" align="center" label="检查地点"/>
      <el-table-column prop="checkRoom" align="center" label="检查房间号"/>
      <el-table-column prop="checkUser" align="center" label="参加检查人员"/>
      <el-table-column prop="researchGroupName" align="center" label="被检查部门/研究组">
      <el-table-column prop="checkDate" align="center" label="检查时间" />
      <el-table-column prop="checkPlace" align="center" label="检查地点" />
      <el-table-column prop="checkRoom" align="center" label="检查房间号" />
      <el-table-column prop="checkUser" align="center" label="参加检查人员" />
      <el-table-column
        prop="researchGroupName"
        align="center"
        label="被检查部门/研究组"
      >
        <template #default="scope">
          {{ scope.row.dailySafetyInspectionDepts.filter(item=>item.deptName && item.deptName !== '').map(i=>i.deptName).join('、') }}
          {{
            scope.row.dailySafetyInspectionDepts
              .filter((item) => item.deptName && item.deptName !== "")
              .map((i) => i.deptName)
              .join("、")
          }}
        </template>
      </el-table-column>
      <el-table-column prop="checkContent" align="center" label="检查内容"/>
      <el-table-column prop="checkContent" align="center" label="检查内容" />
      <el-table-column label="操作" align="center">
        <template #default="scope">
          <el-button link type="primary" @click="openDialog('view',scope.row)">查看</el-button>
          <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button>
          <el-button link type="primary" @click="downloadFile(scope.row)">导出</el-button>
          <el-button v-if="isAuthority" link type="danger" @click="handleDelete(scope.row)">删除</el-button>
          <el-button link type="primary" @click="openDialog('view', scope.row)"
            >查看</el-button
          >
          <el-button link type="primary" @click="openDialog('edit', scope.row)"
            >编辑</el-button
          >
          <el-button link type="primary" @click="downloadFile(scope.row)"
            >导出</el-button
          >
          <el-button
            v-if="isAuthority"
            link
            type="danger"
            @click="handleDelete(scope.row)"
            >删除</el-button
          >
        </template>
      </el-table-column>
    </el-table>
    <pagination
        v-show="total > 0"
        :total="total"
        v-model:page="queryParams.pageNum"
        v-model:limit="queryParams.pageSize"
        @pagination="getList"
      v-show="total > 0"
      :total="total"
      v-model:page="queryParams.pageNum"
      v-model:limit="queryParams.pageSize"
      @pagination="getList"
    />
    <form-dialog ref="dialogRef" :config="formConfig" :data-loader="dataLoader" :api="api" @submit="handleSubmit"></form-dialog>
    <form-dialog
      ref="dialogRef"
      :config="formConfig"
      :data-loader="dataLoader"
      :api="api"
      @submit="handleSubmit"
      @onSave="handleSave"
    ></form-dialog>
  </div>
</template>
<script setup>
import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
import {ElMessage, ElMessageBox} from "element-plus";
import {
  getCurrentInstance,
  onMounted,
  onUnmounted,
  reactive,
  ref,
  toRefs,
} from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import Cookies from "js-cookie";
import FormDialog from "@/views/components/formDialog"
import FormDialog from "@/views/components/formDialog";
import useUserStore from "@/store/modules/user";
import {generateWordDocument} from "@/utils/exportWord";
import {listDept} from "@/api/system/dept";
import {listUser} from "@/api/system/user";
import {delDailySafetyInspect, getDailySafetyInspectList, saveDailySafetyInspect} from "@/api/saftyCheck";
import { generateWordDocument } from "@/utils/exportWord";
import { listDept } from "@/api/system/dept";
import { listUser } from "@/api/system/user";
import {
  delDailySafetyInspect,
  getDailySafetyInspectList,
  saveDailySafetyInspect,
  saveTemDailySafetyInspect,
} from "@/api/saftyCheck";
const { proxy } = getCurrentInstance();
const loading = ref(false);
const dialogRef = ref();
@@ -109,11 +177,11 @@
    pageNum: 1,
    pageSize: 10,
    researchGroup: null,
    checkUser: '',
    checkUser: "",
    checkType: null,
    haveMainHazard: null,
    checkBeginDate: '',
    checkEndDate: ''
    checkBeginDate: "",
    checkEndDate: "",
  },
  originDeptList: [],
  dataList: [],
@@ -122,266 +190,330 @@
  checkTypeList: [
    {
      value: 1,
      label: '综合检查'
      label: "综合检查",
    },
    {
      value: 2,
      label: '部门检查'
      label: "部门检查",
    },
    {
      value: 3,
      label: '实验室自查'
      label: "实验室自查",
    },
    {
      value: 4,
      label: '专项检查'
    }
      label: "专项检查",
    },
  ],
  total: 0,
  formConfig: {
    formItems: [
      {
        label: '检查时间',
        prop: 'checkDate',
        type: 'date',
        dateType: 'date',
        valueFormat: 'YYYY-MM-DD',
        rules: [{ required: true, message: '请选择日期', trigger: 'blur' }]
        label: "检查时间",
        prop: "checkDate",
        type: "date",
        dateType: "date",
        valueFormat: "YYYY-MM-DD",
        rules: [{ required: true, message: "请选择日期", trigger: "blur" }],
      },
      {
        label: '参加检查人员',
        prop: 'checkUser',
        type: 'text',
        rules: [{ required: true, message: '请输入人员', trigger: 'blur' }],
        label: "参加检查人员",
        prop: "checkUser",
        type: "text",
        rules: [{ required: true, message: "请输入人员", trigger: "blur" }],
      },
      {
        label: '检查地点',
        prop: 'checkPlace',
        type: 'text',
        rules: [{ required: true, message: '请输入地点', trigger: 'blur' }]
        label: "检查地点",
        prop: "checkPlace",
        type: "text",
        rules: [{ required: true, message: "请输入地点", trigger: "blur" }],
      },
      {
        label: '检查房间号',
        prop: 'checkRoom',
        type: 'text',
        rules: [{ required: true, message: '请输入房间号', trigger: 'blur' }]
        label: "检查房间号",
        prop: "checkRoom",
        type: "text",
        rules: [{ required: true, message: "请输入房间号", trigger: "blur" }],
      },
      {
        label: '被检查部门/研究组',
        prop: 'dailySafetyInspectionDepts',
        type: 'cascader',
        label: "被检查部门/研究组",
        prop: "dailySafetyInspectionDepts",
        type: "cascader",
        showAllLevels: false,
        props: {
          value: 'deptId',
          label: 'deptName',
          children: 'children',
          value: "deptId",
          label: "deptName",
          children: "children",
          emitPath: false,
          checkStrictly: true,
          multiple: true
          multiple: true,
        },
        rules: [{ required: true, message: '请选择部门', trigger: 'blur' }],
        options: () => state.deptList
        rules: [{ required: true, message: "请选择部门", trigger: "blur" }],
        options: () => state.deptList,
      },
      {
        label: '检查类型',
        prop: 'checkType',
        type: 'select',
        label: "检查类型",
        prop: "checkType",
        type: "select",
        filterable: true,
        rules: [{ required: true, message: '请选择检查类型', trigger: 'change' }],
        options: () => state.checkTypeList
        rules: [
          { required: true, message: "请选择检查类型", trigger: "change" },
        ],
        options: () => state.checkTypeList,
      },
      {
        label: '检查内容',
        prop: 'checkContent',
        type: 'textarea',
        label: "检查内容",
        prop: "checkContent",
        type: "textarea",
        autosize: { minRows: 3 },
        rules: [{ required: true, message: '请输入检查内容', trigger: 'blur' }]
        rules: [{ required: true, message: "请输入检查内容", trigger: "blur" }],
      },
      {
        label: '存在的主要隐患/问题',
        prop: 'mainHazard',
        type: 'textarea',
        placeholder: '没有则填“无”',
        label: "存在的主要隐患/问题",
        prop: "mainHazard",
        type: "textarea",
        placeholder: "没有则填“无”",
        autosize: { minRows: 3 },
        rules: [{ required: true, message: '请输入存在的主要隐患/问题', trigger: 'blur' }]
        rules: [
          {
            required: true,
            message: "请输入存在的主要隐患/问题",
            trigger: "blur",
          },
        ],
      },
      {
        label: '整改措施',
        prop: 'rectificationMeasures',
        type: 'textarea',
        placeholder: '没有则填“无”',
        label: "整改措施",
        prop: "rectificationMeasures",
        type: "textarea",
        placeholder: "没有则填“无”",
        autosize: { minRows: 3 },
        rules: [{ required: true, message: '请输入整改措施', trigger: 'blur' }]
        rules: [{ required: true, message: "请输入整改措施", trigger: "blur" }],
      },
      {
        label: '复查结果',
        prop: 'examinationResults',
        type: 'textarea',
        label: "复查结果",
        prop: "examinationResults",
        type: "textarea",
        autosize: { minRows: 3 },
        rules: [{ required: true, message: '请输入复查结果', trigger: 'blur' }]
        rules: [{ required: true, message: "请输入复查结果", trigger: "blur" }],
      },
      {
        label: '复查人员',
        prop: 'reCheckUser',
        type: 'text',
        rules: [{ required: true, message: '请输入复查人员', trigger: 'blur' }]
        label: "复查人员",
        prop: "reCheckUser",
        type: "text",
        rules: [{ required: true, message: "请输入复查人员", trigger: "blur" }],
      },
      {
        label: '复查时间',
        prop: 'reCheckDate',
        type: 'date',
        dateType: 'date',
        valueFormat: 'YYYY-MM-DD',
        rules: [{ required: true, message: '请选择复查时间', trigger: 'blur' }]
        label: "复查时间",
        prop: "reCheckDate",
        type: "date",
        dateType: "date",
        valueFormat: "YYYY-MM-DD",
        rules: [{ required: true, message: "请选择复查时间", trigger: "blur" }],
      },
      {
        label: '备注',
        prop: 'remark',
        type: 'textarea',
        autosize: { minRows: 3 }
      }
    ]
        label: "检查图片",
        prop: "checkPics",
        type: "upload",
        uploadType: "img",
        limit: 3,
        maxSize: 5,
        accept: "image/*",
        tip: "支持上传图片格式,尺寸小于5M,最多可上传3份",
      },
      {
        label: "备注",
        prop: "remark",
        type: "textarea",
        autosize: { minRows: 3 },
      },
    ],
  },
  dataLoader: {},
  api: {},
  checkDate: [],
  isAuthority: false
  isAuthority: false,
});
const { queryParams, total, dataList,deptList, userList, formConfig, dataLoader, api, checkTypeList, checkDate, isAuthority } = toRefs(state);
const userStore = useUserStore()
onMounted(async ()=>{
  await getList()
  await getDeptList()
  await getUserList()
  if(userStore.roles.includes('admin') || userStore.roles.includes('sys_admin') || userStore.roles.includes('place_safety_officer')){
    state.isAuthority = true
  }else{
    state.isAuthority = false
const {
  queryParams,
  total,
  dataList,
  deptList,
  userList,
  formConfig,
  dataLoader,
  api,
  checkTypeList,
  checkDate,
  isAuthority,
} = toRefs(state);
const userStore = useUserStore();
onMounted(async () => {
  await getList();
  await getDeptList();
  await getUserList();
  if (
    userStore.roles.includes("admin") ||
    userStore.roles.includes("sys_admin") ||
    userStore.roles.includes("place_safety_officer")
  ) {
    state.isAuthority = true;
  } else {
    state.isAuthority = false;
  }
})
});
onUnmounted(()=>{
})
onUnmounted(() => {});
function getDeptList() {
  listDept().then(response => {
    state.originDeptList = response.data
    state.deptList = proxy.handleTree(response.data, "deptId")
  })
  listDept().then((response) => {
    state.originDeptList = response.data;
    state.deptList = proxy.handleTree(response.data, "deptId");
  });
}
function getUserList() {
  listUser({pageNum: 1,pageSize: 999}).then(res => {
  listUser({ pageNum: 1, pageSize: 999 }).then((res) => {
    state.userList = res.rows;
  })
};
  });
}
const getList = async () => {
  loading.value = true
  state.queryParams.checkBeginDate = state.checkDate[0] || ''
  state.queryParams.checkEndDate = state.checkDate[1] || ''
  const res = await getDailySafetyInspectList(state.queryParams)
  if(res.code == 200){
    state.dataList = res.rows || []
    state.total = res.total
  }else{
    ElMessage.warning(res.msg)
  loading.value = true;
  state.queryParams.checkBeginDate = state.checkDate[0] || "";
  state.queryParams.checkEndDate = state.checkDate[1] || "";
  const res = await getDailySafetyInspectList(state.queryParams);
  if (res.code == 200) {
    state.dataList = res.rows || [];
    state.total = res.total;
  } else {
    ElMessage.warning(res.msg);
  }
  loading.value = false
}
  loading.value = false;
};
const downloadFile = async (val)=>{
    let tableData = val
    try {
      generateWordDocument('/dailyCheckSheet.docx', tableData, '日常安全检查记录表.docx');
    } catch (error){
      ElMessage({
        type: 'warning',
        message: '导出失败'
      });
    }
}
const openDialog = (type, value) => {
  const initalData = JSON.parse(JSON.stringify(value))
  if (initalData.dailySafetyInspectionDepts && Array.isArray(initalData.dailySafetyInspectionDepts)) {
    initalData.dailySafetyInspectionDepts = initalData.dailySafetyInspectionDepts.map(item => item.deptId)
const downloadFile = async (val) => {
  let tableData = val;
  try {
    generateWordDocument(
      "/dailyCheckSheet.docx",
      tableData,
      "日常安全检查记录表.docx",
    );
  } catch (error) {
    ElMessage({
      type: "warning",
      message: "导出失败",
    });
  }
  dialogRef.value.openDialog(type, initalData)
}
};
const openDialog = async (type, value) => {
  const initalData = JSON.parse(JSON.stringify(value));
  if (
    initalData.dailySafetyInspectionDepts &&
    Array.isArray(initalData.dailySafetyInspectionDepts)
  ) {
    initalData.dailySafetyInspectionDepts =
      initalData.dailySafetyInspectionDepts.map((item) => item.deptId);
  }
  dialogRef.value.openDialog(type, initalData, true);
};
/** 重置新增的表单以及其他数据  */
const reset= async()=> {
const reset = async () => {
  state.queryParams = {
    pageNum: 1,
    pageSize: 10,
    researchGroup: null,
    checkUser: '',
    checkUser: "",
    checkType: null,
    haveMainHazard: null,
    checkBeginDate: '',
    checkEndDate: ''
  }
  state.checkDate = []
  await getList()
}
    checkBeginDate: "",
    checkEndDate: "",
  };
  state.checkDate = [];
  await getList();
};
const handleDelete = (val) => {
  ElMessageBox.confirm(
      '确定删除此条数据?',
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
      .then( async() => {
        const res = await delDailySafetyInspect({id: val.id})
        if(res.code == 200){
          ElMessage.success('数据删除成功')
          await getList()
        }else{
          ElMessage.warning(res.msg)
        }
      })
}
  ElMessageBox.confirm("确定删除此条数据?", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    const res = await delDailySafetyInspect({ id: val.id });
    if (res.code == 200) {
      ElMessage.success("数据删除成功");
      await getList();
    } else {
      ElMessage.warning(res.msg);
    }
  });
};
const handleSubmit = async (data, type) => {
  const params = JSON.parse(JSON.stringify(data))
  console.log(params.dailySafetyInspectionDepts,555)
  params.dailySafetyInspectionDepts = params.dailySafetyInspectionDepts.map(i=>{
    return {
      deptId: i,
      deptName: state.originDeptList.find(item=>item.deptId == i)?.deptName
    }
  })
  const params = JSON.parse(JSON.stringify(data));
  params.dailySafetyInspectionDepts = params.dailySafetyInspectionDepts.map(
    (i) => {
      return {
        deptId: i,
        deptName: state.originDeptList.find((item) => item.deptId == i)
          ?.deptName,
      };
    },
  );
  // params.reCheckUser = state.userList.find(i=>i.userId == params.reCheckUserId)?.nickName
  // 调用API保存数据
  if (type === '新增') {
    delete params.id
    const res = await saveDailySafetyInspect(params)
    if(res.code == 200){
      ElMessage.success(res.msg)
      await handleClose()
      await getList()
    }else{
      ElMessage.warning(res.msg)
  if (type === "新增") {
    delete params.id;
    const res = await saveDailySafetyInspect(params);
    if (res.code == 200) {
      ElMessage.success(res.msg);
      await handleClose();
      await getList();
    } else {
      ElMessage.warning(res.msg);
    }
  } else {
    const res = await saveDailySafetyInspect(params)
    if(res.code == 200){
      ElMessage.success(res.msg)
      await handleClose()
      await getList()
    }else{
      ElMessage.warning(res.msg)
    const res = await saveDailySafetyInspect(params);
    if (res.code == 200) {
      ElMessage.success(res.msg);
      await handleClose();
      await getList();
    } else {
      ElMessage.warning(res.msg);
    }
  }
}
};
const handleSave = async (data) => {
  const params = JSON.parse(JSON.stringify(data));
  if (
    params.dailySafetyInspectionDepts &&
    Array.isArray(params.dailySafetyInspectionDepts)
  ) {
    params.dailySafetyInspectionDepts = params.dailySafetyInspectionDepts.map(
      (i) => {
        return {
          deptId: i,
          deptName: state.originDeptList.find((item) => item.deptId == i)
            ?.deptName,
        };
      },
    );
  }
  const res = await saveTemDailySafetyInspect(params);
  if (res.code == 200) {
    ElMessage.success(res.msg);
    await handleClose();
    await getList();
  } else {
    ElMessage.warning(res.msg);
  }
};
const handleClose = () => {
  dialogRef.value.closeDialog()
}
  dialogRef.value.closeDialog();
};
</script>