董国庆
2026-03-26 f7cf1ec08f5d8622fdb4dc18183740de336068bb
修改文档问题
9个文件已修改
858 ■■■■■ 已修改文件
screen/src/App.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/utils/request.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/header/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/hiddenDanger/index.vue 547 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/login/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/personnelOnDuty/index.vue 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/planOfAudit/index.vue 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/projectHome/index.vue 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/projectList/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/App.vue
@@ -82,6 +82,7 @@
            }
          })
        }
        sessionStorage.setItem('projectType', type)
      })
    }
    if (!sessionStorage.getItem('token')) {
screen/src/utils/request.js
@@ -40,7 +40,7 @@
        window.location.replace('/')
      }
      if (res.data.code === 500) {
        return Promise.reject(res.data.data)
        return Promise.reject(res.data.msg || '服务器错误')
      }
      Message({
        message: res.data.msg || '服务器错误',
screen/src/view/header/index.vue
@@ -170,6 +170,7 @@
          path: '/home'
        })
      }
      sessionStorage.setItem('projectType', userType)
    },
    updateDateTime () {
      const now = new Date()
screen/src/view/hiddenDanger/index.vue
@@ -317,9 +317,7 @@
            <div
              class="btnColor cursor-pointer"
              :class="
                !row.pictures || row.pictures.length === 0
                  ? 'disableColor'
                  : ''
                !row.pictures || row.pictures.length === 0 ? 'disableColor' : ''
              "
              @click="handlePreviewImages(row.pictures)"
            >
@@ -647,27 +645,27 @@
</template>
<script>
import HeaderBox from '../header/index.vue'
import moment from 'moment'
import HeaderBox from "../header/index.vue";
import moment from "moment";
import {
  getProjectList,
  getHiddenDangerListByType,
  getHiddenDangerDetailByType,
  editResponsiblePersonByType
} from './service'
import { errorLevelMap, errorReviewStateMap } from '@/utils/riskSourceMap'
  editResponsiblePersonByType,
} from "./service";
import { errorLevelMap, errorReviewStateMap } from "@/utils/riskSourceMap";
export default {
  components: { HeaderBox },
  props: {},
  data () {
  data() {
    return {
      // Tab 相关
      activeTab: 1, // 1=重大隐患 2=安全隐患 3=设备隐患
      // 路由参数
      projectId: null, // 项目ID,如果有则是项目端使用
      projectName: '', // 项目名称
      projectName: "", // 项目名称
      isClient: false, // 是否委托方端
      routeType: null,
@@ -679,14 +677,14 @@
        level: null, // 隐患等级:0=一级 1=二级 2=三级 3=四级
        startTime: null, // 开始时间
        endTime: null, // 结束时间
        content: '' // 搜索内容
        content: "", // 搜索内容
      },
      // 日期选择
      startDateTime: null,
      endDateTime: null,
      startDateTxt: '',
      endDateTxt: '',
      startDateTxt: "",
      endDateTxt: "",
      // 保存从路由获取的时间参数,用于切换tab时保留
      routeStartTime: null,
@@ -706,213 +704,226 @@
      // 弹窗相关
      updatePeople: false,
      peopleName: '',
      peopleName: "",
      currentEditRow: null, // 当前编辑的行数据
      detailVisible: false,
      detailData: null, // 详情数据
      currentRow: null, // 当前查看详情的列表行数据
      activeName: 'first',
      activeName: "first",
      previewVisible: false,
      previewImages: [], // 预览图片列表
      // sessionStorage 配置
      bigHiddenDangerConfig: null, // 重大隐患配置:1开启 2关闭
      generalHiddenDangerConfig: null, // 一般隐患配置:1开启 2关闭
      projectCategory: null
    }
      projectCategory: null,
      projectType: sessionStorage.getItem("projectType"), //1委托方 2项目方
    };
  },
  computed: {
    // 是否是项目端(有projectId参数)
    isProjectMode () {
      return this.routeType === 2
    isProjectMode() {
      return this.routeType === 2;
    },
    // 是否是委托方端(没有projectId参数)
    isClientMode () {
      return this.routeType !== 2
    isClientMode() {
      return this.routeType !== 2;
    },
    hideProjectHeader () {
      return this.isProjectMode
    hideProjectHeader() {
      return this.isProjectMode;
    },
    hideSearchArea () {
      return this.hideProjectHeader
    hideSearchArea() {
      return this.hideProjectHeader;
    },
    // 当前隐患类型(根据activeTab判断)
    currentType () {
    currentType() {
      // 1=重大隐患(暂无对应type) 2=安全隐患(type=1) 3=设备隐患(type=2)
      if (this.activeTab === 2) return 1
      if (this.activeTab === 3) return 2
      return null
      if (this.activeTab === 2) return 1;
      if (this.activeTab === 3) return 2;
      return null;
    },
    // 是否显示隐患类型筛选(仅重大隐患显示)
    showTypeFilter () {
      return this.activeTab === 1
    showTypeFilter() {
      return this.activeTab === 1;
    },
    // 是否显示隐患等级筛选(安全和设备隐患显示)
    showLevelFilter () {
      return this.activeTab !== 1
    showLevelFilter() {
      return this.activeTab !== 1;
    },
    // 是否显示整改状态筛选
    showReformedFilter () {
    showReformedFilter() {
      // activeTab: 1=重大隐患 2=安全隐患 3=设备隐患
      // bigHiddenDangerConfig: 1开启 2关闭
      // generalHiddenDangerConfig: 1开启 2关闭
      if (this.bigHiddenDangerConfig === 2) {
        return false
        return false;
      } else if (this.generalHiddenDangerConfig === 2) {
        return this.activeTab === 1
        return this.activeTab === 1;
      } else {
        return true
        return true;
      }
    }
    },
  },
  watch: {
    // 监听 tab 切换
    activeTab: {
      handler (newVal) {
      handler(newVal) {
        // 切换 tab 时重置筛选条件并重新加载数据
        this.resetSearchForm()
        this.pageNum = 1
        this.loadTableData()
      }
        this.resetSearchForm();
        this.pageNum = 1;
        this.loadTableData();
      },
    },
    // 监听开始时间
    startDateTime: {
      handler (newVal) {
      handler(newVal) {
        if (newVal) {
          this.startDateTxt = moment(newVal).format('YYYY年MM月DD日 HH:mm:ss')
          this.startDateTxt = moment(newVal).format("YYYY年MM月DD日 HH:mm:ss");
          this.searchForm.startTime = moment(newVal).format(
            'YYYY-MM-DD HH:mm:ss'
          )
            "YYYY-MM-DD HH:mm:ss"
          );
          // 更新保存的路由时间
          this.routeStartTime = this.searchForm.startTime
          this.routeStartTime = this.searchForm.startTime;
          // 选择时间后自动请求
          this.handleSelectChange()
          this.handleSelectChange();
        } else {
          this.startDateTxt = ''
          this.searchForm.startTime = null
          this.startDateTxt = "";
          this.searchForm.startTime = null;
        }
      }
      },
    },
    // 监听结束时间
    endDateTime: {
      handler (newVal) {
      handler(newVal) {
        if (newVal) {
          this.endDateTxt = moment(newVal).format('YYYY年MM月DD日 HH:mm:ss')
          this.endDateTxt = moment(newVal).format("YYYY年MM月DD日 HH:mm:ss");
          this.searchForm.endTime = moment(newVal).format(
            'YYYY-MM-DD HH:mm:ss'
          )
            "YYYY-MM-DD HH:mm:ss"
          );
          // 更新保存的路由时间
          this.routeEndTime = this.searchForm.endTime
          this.routeEndTime = this.searchForm.endTime;
          // 选择时间后自动请求
          this.handleSelectChange()
          this.handleSelectChange();
        } else {
          this.endDateTxt = ''
          this.searchForm.endTime = null
          this.endDateTxt = "";
          this.searchForm.endTime = null;
        }
      }
    }
      },
    },
  },
  created () {
  created() {
    // 从 sessionStorage 读取配置
    this.loadConfigFromsessionStorage()
    this.loadConfigFromsessionStorage();
    // 从路由获取参数
    if (this.$route.query.activeTab) {
      this.activeTab = Number(this.$route.query.activeTab)
      this.activeTab = Number(this.$route.query.activeTab);
    }
    if (this.$route.query.projectId) {
      this.projectId = this.$route.query.projectId
      this.searchForm.projectId = this.$route.query.projectId
      this.projectId = this.$route.query.projectId;
      this.searchForm.projectId = this.$route.query.projectId;
    }
    if (this.$route.query.projectName) {
      this.projectName = this.$route.query.projectName
      this.projectName = this.$route.query.projectName;
    }
    if (this.$route.query.projectCategory) {
      this.projectCategory = this.$route.query.projectCategory
      this.projectCategory = this.$route.query.projectCategory;
    }
    if (this.$route.query.type) {
      this.routeType = Number(this.$route.query.type)
      this.routeType = Number(this.$route.query.type);
    }
    // 接收从 home 页面传递过来的时间参数并回填
    if (this.$route.query.startTime) {
      this.routeStartTime = this.$route.query.startTime
      this.startDateTime = new Date(this.$route.query.startTime)
      this.searchForm.startTime = this.$route.query.startTime
      this.routeStartTime = this.$route.query.startTime;
      this.startDateTime = new Date(this.$route.query.startTime);
      this.searchForm.startTime = this.$route.query.startTime;
    }
    if (this.$route.query.endTime) {
      this.routeEndTime = this.$route.query.endTime
      this.endDateTime = new Date(this.$route.query.endTime)
      this.searchForm.endTime = this.$route.query.endTime
      this.routeEndTime = this.$route.query.endTime;
      this.endDateTime = new Date(this.$route.query.endTime);
      this.searchForm.endTime = this.$route.query.endTime;
    }
    // 判断是否委托方端:通过 type 判断(type==2 为项目端)
    this.isClient = this.routeType !== 2
    this.isClient = this.routeType !== 2;
    // 初始化下拉选项
    this.initOptions()
    this.initOptions();
    // 加载项目列表(如果不是项目端)
    // if (!this.isProjectMode) { isProjectMode
    this.loadProjectList()
    this.loadProjectList();
    // }
    // 加载表格数据
    this.loadTableData()
    this.loadTableData();
  },
  mounted () {},
  mounted() {},
  methods: {
    // 从 sessionStorage 加载配置
    loadConfigFromsessionStorage () {
    loadConfigFromsessionStorage() {
      try {
        const bigHiddenDanger = sessionStorage.getItem('bigHiddenDanger')
        const generalHiddenDanger = sessionStorage.getItem('generalHiddenDanger')
        const bigHiddenDanger = sessionStorage.getItem("bigHiddenDanger");
        const generalHiddenDanger = sessionStorage.getItem(
          "generalHiddenDanger"
        );
        // 转换为数字类型,默认为开启(1)
        this.bigHiddenDangerConfig = bigHiddenDanger
          ? Number(bigHiddenDanger)
          : 1
          : 1;
        this.generalHiddenDangerConfig = generalHiddenDanger
          ? Number(generalHiddenDanger)
          : 1
          : 1;
      } catch (error) {
        console.error('加载配置失败:', error)
        console.error("加载配置失败:", error);
        // 默认都开启
        this.bigHiddenDangerConfig = 1
        this.generalHiddenDangerConfig = 1
        this.bigHiddenDangerConfig = 1;
        this.generalHiddenDangerConfig = 1;
      }
    },
    // 初始化下拉选项
    initOptions () {
      // 整改状态选项
      this.reformedOptions = [
        { label: '未整改', value: 0 },
        { label: '部分整改', value: 1 },
        { label: '已整改', value: 2 },
        { label: '未复查', value: 3 }
      ]
    initOptions() {
      if (this.projectType == 1) {
        this.reformedOptions = [
          { label: "未复查", value: 0 },
          { label: "未整改", value: 1 },
          { label: "部分整改", value: 2 },
          { label: "已整改", value: 3 },
        ];
      } else {
        // 整改状态选项
        this.reformedOptions = [
          { label: "未整改", value: 0 },
          { label: "部分整改", value: 1 },
          { label: "已整改", value: 2 },
          { label: "未复查", value: 3 },
        ];
      }
      // 隐患等级选项
      this.levelOptions = [
        { label: '一级隐患', value: 0 },
        { label: '二级隐患', value: 1 },
        { label: '三级隐患', value: 2 },
        { label: '四级隐患', value: 3 }
      ]
        { label: "一级隐患", value: 0 },
        { label: "二级隐患", value: 1 },
        { label: "三级隐患", value: 2 },
        { label: "四级隐患", value: 3 },
      ];
    },
    // 重置搜索表单
    resetSearchForm () {
    resetSearchForm() {
      this.searchForm = {
        projectId: this.projectId || null,
        state: null,
@@ -920,210 +931,210 @@
        level: null,
        startTime: this.routeStartTime || null, // 保留路由传递的开始时间
        endTime: this.routeEndTime || null, // 保留路由传递的结束时间
        content: ''
      }
        content: "",
      };
      // 保留时间选择器的值
      if (this.routeStartTime) {
        this.startDateTime = new Date(this.routeStartTime)
        this.startDateTime = new Date(this.routeStartTime);
      } else {
        this.startDateTime = null
        this.startDateTime = null;
      }
      if (this.routeEndTime) {
        this.endDateTime = new Date(this.routeEndTime)
        this.endDateTime = new Date(this.routeEndTime);
      } else {
        this.endDateTime = null
        this.endDateTime = null;
      }
    },
    // 加载项目列表
    async loadProjectList () {
    async loadProjectList() {
      try {
        // 从 sessionStorage 获取 userInfo
        const userInfoStr = sessionStorage.getItem('userInfo')
        const userInfoStr = sessionStorage.getItem("userInfo");
        if (!userInfoStr) {
          console.error('未找到用户信息')
          return
          console.error("未找到用户信息");
          return;
        }
        const clientId = sessionStorage.getItem('clientId')
        const clientId = sessionStorage.getItem("clientId");
        if (!clientId) {
          console.error('用户信息中未找到 clientId')
          return
          console.error("用户信息中未找到 clientId");
          return;
        }
        const activeTabIndex = Number(sessionStorage.getItem('activeTab')) - 1
        const activeTabIndex = Number(sessionStorage.getItem("activeTab")) - 1;
        const res = await getProjectList({
          clientId: clientId,
          projectCategory: ['ongoing', 'fixed'][activeTabIndex]
        })
          projectCategory: ["ongoing", "fixed"][activeTabIndex],
        });
        if (res && res) {
          this.projectList = res.map((item) => ({
            label: item.name,
            value: item.id
          }))
            value: item.id,
          }));
        }
      } catch (error) {
        console.error('加载项目列表失败:', error)
        console.error("加载项目列表失败:", error);
      }
    },
    // 加载表格数据
    async loadTableData () {
      this.loading = true
    async loadTableData() {
      this.loading = true;
      try {
        const params = {
          pageNum: this.pageNum,
          pageSize: this.pageSize,
          category: 2,
          ...this.searchForm
        }
          ...this.searchForm,
        };
        // 项目端:使用 currentType(根据 Tab 自动判断)
        // 委托方:
        //   - 重大隐患 Tab:使用 searchForm.type(用户选择的隐患类型筛选)
        //   - 安全/设备 Tab:不需要传 type(已经通过不同接口区分)
        console.log('this.isClient', this.isClient)
        console.log("this.isClient", this.isClient);
        if (!this.isClient) {
          // 项目端:传递 type
          params.type = this.currentType || this.searchForm.type
          params.type = this.currentType || this.searchForm.type;
          if (this.activeTab === 1) {
            params.category = 1
            params.category = 1;
          }
        } else {
          params.clientId = sessionStorage.getItem('clientId')
          params.clientId = sessionStorage.getItem("clientId");
          if (this.projectCategory) {
            params.category = sessionStorage.getItem('activeTab')
            params.category = sessionStorage.getItem("activeTab");
          }
          // 委托方:只在重大隐患 Tab 且用户选择了类型时传递 type
          if (this.activeTab === 1 && this.searchForm.type) {
            params.type = this.searchForm.type
            params.category = 1
            params.type = this.searchForm.type;
            params.category = 1;
          }
        }
        // 过滤掉空值
        Object.keys(params).forEach((key) => {
          if (params[key] === null || params[key] === '') {
            delete params[key]
          if (params[key] === null || params[key] === "") {
            delete params[key];
          }
        })
        });
        // 使用统一方法,自动根据用户类型和Tab调用对应接口
        const res = await getHiddenDangerListByType(
          params,
          this.activeTab,
          this.isClient
        )
        );
        if (res) {
          this.tableData = res.records || []
          this.total = res.total || 0
          this.tableData = res.records || [];
          this.total = res.total || 0;
        }
      } catch (error) {
        console.error('加载表格数据失败:', error)
        this.$message.error('加载数据失败')
        console.error("加载表格数据失败:", error);
        this.$message.error("加载数据失败");
      } finally {
        this.loading = false
        this.loading = false;
      }
    },
    // 搜索
    handleSearch () {
      this.pageNum = 1
      this.loadTableData()
    handleSearch() {
      this.pageNum = 1;
      this.loadTableData();
    },
    // 选择器改变时自动请求
    handleSelectChange () {
      this.pageNum = 1
      this.loadTableData()
    handleSelectChange() {
      this.pageNum = 1;
      this.loadTableData();
    },
    // 清除选择器
    clearSelect (field) {
      this.searchForm[field] = null
      this.handleSelectChange()
    clearSelect(field) {
      this.searchForm[field] = null;
      this.handleSelectChange();
    },
    // 清除日期时间
    clearDateTime (type) {
      if (type === 'start') {
        this.startDateTime = null
        this.startDateTxt = ''
        this.searchForm.startTime = null
        this.routeStartTime = null // 清除保存的路由时间
    clearDateTime(type) {
      if (type === "start") {
        this.startDateTime = null;
        this.startDateTxt = "";
        this.searchForm.startTime = null;
        this.routeStartTime = null; // 清除保存的路由时间
      } else {
        this.endDateTime = null
        this.endDateTxt = ''
        this.searchForm.endTime = null
        this.routeEndTime = null // 清除保存的路由时间
        this.endDateTime = null;
        this.endDateTxt = "";
        this.searchForm.endTime = null;
        this.routeEndTime = null; // 清除保存的路由时间
      }
      this.handleSelectChange()
      this.handleSelectChange();
    },
    // 点击日期选择器
    handleClick (type) {
    handleClick(type) {
      if (type === 1) {
        this.$refs.datetime1.focus()
        this.$refs.datetime1.focus();
      } else {
        this.$refs.datetime2.focus()
        this.$refs.datetime2.focus();
      }
    },
    // 获取隐患等级文本
    getLevelText (level) {
      return this.levelOptions[level].label || '-'
    getLevelText(level) {
      return this.levelOptions[level].label || "-";
    },
    // 获取整改状态文本
    getReformedText (state) {
      return ['未整改', '部分整改', '已整改', '未复查'][state]
    getReformedText(state) {
      return ["未整改", "部分整改", "已整改", "未复查"][state];
    },
    // 预览图片
    handlePreviewImages (userFiles) {
    handlePreviewImages(userFiles) {
      if (!userFiles || userFiles.length === 0) {
        this.$message.warning('暂无图片')
        return
        this.$message.warning("暂无图片");
        return;
      }
      // this.previewImages = userFiles.map((file) => file.url || file.name);
      const baseUrl = process.env.VUE_APP_IMAGE_BASE_URL || ''
      const baseUrl = process.env.VUE_APP_IMAGE_BASE_URL || "";
      this.previewImages = userFiles.map((file) => {
        let img = file.url || file.name
        img = img.split('.')[0] || img
        let img = file.url || file.name;
        img = img.split(".")[0] || img;
        // 如果图片已经是完整URL,直接返回;否则添加前缀
        if (img.startsWith('http://') || img.startsWith('https://')) {
          return img
        if (img.startsWith("http://") || img.startsWith("https://")) {
          return img;
        }
        return baseUrl + '/project/download/' + img
      })
      this.previewVisible = true
        return baseUrl + "/project/download/" + img;
      });
      this.previewVisible = true;
    },
    // 编辑责任人
    handleEditPeople (row) {
      this.currentEditRow = row
      this.peopleName = row.responsiblePerson || ''
      this.updatePeople = true
    handleEditPeople(row) {
      this.currentEditRow = row;
      this.peopleName = row.responsiblePerson || "";
      this.updatePeople = true;
    },
    // 关闭编辑责任人弹窗
    closeUpdatePeople () {
      this.updatePeople = false
      this.peopleName = ''
      this.currentEditRow = null
    closeUpdatePeople() {
      this.updatePeople = false;
      this.peopleName = "";
      this.currentEditRow = null;
    },
    // 保存责任人
    async saveUpdatePeople () {
    async saveUpdatePeople() {
      if (!this.peopleName) {
        this.$message({
          message: '请输入责任人',
          type: 'warning'
        })
        return
          message: "请输入责任人",
          type: "warning",
        });
        return;
      }
      try {
@@ -1131,91 +1142,91 @@
        await editResponsiblePersonByType(
          {
            id: this.currentEditRow.id,
            responsiblePerson: this.peopleName
            responsiblePerson: this.peopleName,
          },
          this.isClient
        )
        );
        this.$message({
          message: '保存成功',
          type: 'success'
        })
          message: "保存成功",
          type: "success",
        });
        // 更新表格数据
        this.currentEditRow.responsiblePerson = this.peopleName
        this.closeUpdatePeople()
        this.currentEditRow.responsiblePerson = this.peopleName;
        this.closeUpdatePeople();
      } catch (error) {
        console.error('保存责任人失败:', error)
        this.$message.error('保存失败')
        console.error("保存责任人失败:", error);
        this.$message.error("保存失败");
      }
    },
    // 查看详情
    async handleViewDetail (row) {
    async handleViewDetail(row) {
      try {
        // 保存当前行数据
        this.currentRow = row
        this.currentRow = row;
        // 使用统一方法
        const res = await getHiddenDangerDetailByType(row.id, this.isClient)
        const res = await getHiddenDangerDetailByType(row.id, this.isClient);
        if (res && res) {
          this.detailData = res
          this.detailVisible = true
          this.activeName = 'first'
          this.detailData = res;
          this.detailVisible = true;
          this.activeName = "first";
        }
      } catch (error) {
        console.error('加载详情失败:', error)
        this.$message.error('加载详情失败')
        console.error("加载详情失败:", error);
        this.$message.error("加载详情失败");
      }
    },
    // 切换详情 tab
    handleClickTab (tab) {
      this.activeName = tab.name
    handleClickTab(tab) {
      this.activeName = tab.name;
    },
    // 获取复查记录标签
    getReviewRecordsLabel () {
    getReviewRecordsLabel() {
      if (!this.detailData || !this.detailData.errorReview) {
        return '复查记录(无)'
        return "复查记录(无)";
      }
      return '复查记录'
      return "复查记录";
    },
    // 获取复查状态文本
    getReviewStateText (state) {
    getReviewStateText(state) {
      const stateMap = {
        0: '未整改',
        1: '部分整改',
        2: '已整改',
        3: '未复查'
      }
      return stateMap[state] || '-'
        0: "未整改",
        1: "部分整改",
        2: "已整改",
        3: "未复查",
      };
      return stateMap[state] || "-";
    },
    // 预览复查图片(需要添加前缀)
    handlePreviewReviewImages (imgArray) {
    handlePreviewReviewImages(imgArray) {
      if (!imgArray || imgArray.length === 0) {
        this.$message.warning('暂无图片')
        return
        this.$message.warning("暂无图片");
        return;
      }
      // 图片没有前缀,需要根据实际情况添加图片服务器地址前缀
      // 假设图片服务器地址为 process.env.VUE_APP_IMG_BASE_URL 或者其他配置
      const baseUrl = process.env.VUE_APP_IMAGE_BASE_URL || ''
      const baseUrl = process.env.VUE_APP_IMAGE_BASE_URL || "";
      this.previewImages = imgArray.map((img) => {
        img = img.split('.')[0] || img
        img = img.split(".")[0] || img;
        // 如果图片已经是完整URL,直接返回;否则添加前缀
        if (img.startsWith('http://') || img.startsWith('https://')) {
          return img
        if (img.startsWith("http://") || img.startsWith("https://")) {
          return img;
        }
        return baseUrl + '/project/download/' + img
      })
      this.previewVisible = true
        return baseUrl + "/project/download/" + img;
      });
      this.previewVisible = true;
    },
    // 获取问题数量名称(取第一条数据的 name)
    getNumberFactorName () {
    getNumberFactorName() {
      if (
        this.detailData &&
        this.detailData.numberFactors &&
@@ -1223,20 +1234,20 @@
      ) {
        try {
          const firstItem =
            typeof this.detailData.numberFactors[0] === 'string'
            typeof this.detailData.numberFactors[0] === "string"
              ? JSON.parse(this.detailData.numberFactors[0])
              : this.detailData.numberFactors[0]
          return firstItem.name || '-'
              : this.detailData.numberFactors[0];
          return firstItem.name || "-";
        } catch (error) {
          console.error('解析 numberFactors 失败:', error)
          return '-'
          console.error("解析 numberFactors 失败:", error);
          return "-";
        }
      }
      return '-'
      return "-";
    },
    // 获取扣除分数(取第一条数据的 deductPoint)
    getNumberFactorDeductPoint () {
    getNumberFactorDeductPoint() {
      if (
        this.detailData &&
        this.detailData.numberFactors &&
@@ -1244,23 +1255,23 @@
      ) {
        try {
          const firstItem =
            typeof this.detailData.numberFactors[0] === 'string'
            typeof this.detailData.numberFactors[0] === "string"
              ? JSON.parse(this.detailData.numberFactors[0])
              : this.detailData.numberFactors[0]
          const deductPoint = firstItem.deductPoint
              : this.detailData.numberFactors[0];
          const deductPoint = firstItem.deductPoint;
          return deductPoint !== undefined && deductPoint !== null
            ? deductPoint
            : '-'
            : "-";
        } catch (error) {
          console.error('解析 numberFactors 失败:', error)
          return '-'
          console.error("解析 numberFactors 失败:", error);
          return "-";
        }
      }
      return '-'
      return "-";
    },
    // 获取附加加分(取第一条数据的 additionPoint)
    getNumberFactorAdditionPoint () {
    getNumberFactorAdditionPoint() {
      if (
        this.detailData &&
        this.detailData.numberFactors &&
@@ -1268,40 +1279,40 @@
      ) {
        try {
          const firstItem =
            typeof this.detailData.numberFactors[0] === 'string'
            typeof this.detailData.numberFactors[0] === "string"
              ? JSON.parse(this.detailData.numberFactors[0])
              : this.detailData.numberFactors[0]
          const additionPoint = firstItem.additionPoint
              : this.detailData.numberFactors[0];
          const additionPoint = firstItem.additionPoint;
          return additionPoint !== undefined && additionPoint !== null
            ? additionPoint
            : '-'
            : "-";
        } catch (error) {
          console.error('解析 numberFactors 失败:', error)
          return '-'
          console.error("解析 numberFactors 失败:", error);
          return "-";
        }
      }
      return '-'
      return "-";
    },
    // 返回
    backFun () {
      this.$router.go(-1)
    backFun() {
      this.$router.go(-1);
    },
    // 分页-每页条数改变
    handleSizeChange (val) {
      this.pageSize = val
      this.pageNum = 1
      this.loadTableData()
    handleSizeChange(val) {
      this.pageSize = val;
      this.pageNum = 1;
      this.loadTableData();
    },
    // 分页-当前页改变
    handleCurrentChange (val) {
      this.pageNum = val
      this.loadTableData()
    }
  }
}
    handleCurrentChange(val) {
      this.pageNum = val;
      this.loadTableData();
    },
  },
};
</script>
<style scoped lang="less">
input::placeholder {
@@ -1514,7 +1525,7 @@
}
.bgColor66 {
  background: rgba(255, 123, 0, .8) !important;
  background: rgba(255, 123, 0, 0.8) !important;
}
.bgColor77 {
  background: rgba(255, 123, 0, 0.5) !important;
screen/src/view/login/index.vue
@@ -285,6 +285,7 @@
                        path: '/home'
                      })
                    }
                    sessionStorage.setItem('projectType', this.userInfo.type)
                  })
                }
              }
@@ -292,6 +293,11 @@
          })
          .catch((err) => {
            this.refreshCaptcha()
            Message({
              message: err,
              type: 'error'
            })
          })
      }
    },
@@ -369,6 +375,7 @@
              path: '/home'
            })
          }
          sessionStorage.setItem('projectType', this.userInfo.type)
          sessionStorage.setItem('userInfo', JSON.stringify(this.userInfo))
          sessionStorage.setItem('token', this.token)
        })
screen/src/view/personnelOnDuty/index.vue
@@ -21,7 +21,6 @@
            v-model="planId"
            placeholder="请选择检查计划"
            class="flex1"
            clearable
            @change="handleSearch"
          >
            <el-option
@@ -32,10 +31,17 @@
            >
            </el-option>
          </el-select>
          <img
            src="../../assets/img/down-circle@2x.png"
            class="w--15 h--16 shrink0"
          />
          <div class="flex a-center gap--5">
            <i
              @click.stop="clearPlanId"
              class="el-icon-circle-close c-fff cursor-pointer"
              v-show="planId"
            />
            <img
              src="../../assets/img/down-circle@2x.png"
              class="w--15 h--16 shrink0"
            />
          </div>
        </div>
        <div
          class="flex a-center j-between pl--18 pr--15 h--40 relative w--300 bgcolor1 searchBox"
@@ -45,7 +51,6 @@
            v-model="positionId"
            placeholder="请选择岗位"
            class="flex1"
            clearable
            @change="handleSearch"
          >
            <el-option
@@ -56,70 +61,103 @@
            >
            </el-option>
          </el-select>
          <img
            src="../../assets/img/down-circle@2x.png"
            class="w--15 h--16 shrink0"
          />
          <div class="flex a-center gap--5">
            <i
              @click.stop="clearPositionId"
              class="el-icon-circle-close c-fff cursor-pointer"
              v-show="positionId"
            />
            <img
              src="../../assets/img/down-circle@2x.png"
              class="w--15 h--16 shrink0"
            />
          </div>
        </div>
        <div
          @click="handleClick(1)"
          class="flex a-center j-between px--20 w--300 h--40 relative bgcolor1 picker"
        >
          <el-date-picker
            v-model="startTime"
            ref="datetime1"
            type="datetime"
            type="date"
            placeholder=""
            @change="handleSearch"
          >
          </el-date-picker>
          <div
            class="absolute w100 h100 flex a-center c-fff fs--14 SHS"
            style="width: calc(100% - 20px)"
            @click.stop="handleClick(1)"
            class="absolute h100 flex a-center c-fff fs--14 SHS pointer-events-none"
            style="left: 20px; right: 60px; z-index: 1"
            v-if="startTimeTxt"
          >
            {{ startTimeTxt }}
          </div>
          <div
            @click.stop="handleClick(1)"
            v-else
            class="absolute w100 h100 flex a-center c-fff fs--14 SHSR"
            class="absolute h100 flex a-center c-fff fs--14 SHSR pointer-events-none"
            style="left: 20px; right: 60px; z-index: 1"
          >
            请选择开始时间
            请选择开始日期
          </div>
          <img
            src="../../assets/img/home/Shape@2x (6).png"
            class="w--13 h--13 shrink0"
          />
          <div
            class="flex a-center gap--5"
            style="position: relative; z-index: 2"
          >
            <i
              @click.stop="clearStartTime"
              class="el-icon-circle-close c-fff cursor-pointer"
              v-show="startTime"
            />
            <img
              @click="handleClick(1)"
              src="../../assets/img/home/Shape@2x (6).png"
              class="w--13 h--13 shrink0 cursor-pointer"
            />
          </div>
        </div>
        <div
          @click="handleClick(2)"
          class="flex a-center j-between px--20 w--300 h--40 relative bgcolor1 picker"
        >
          <el-date-picker
            v-model="endTime"
            ref="datetime2"
            type="datetime"
            type="date"
            placeholder=""
            @change="handleSearch"
          >
          </el-date-picker>
          <div
            class="absolute w100 h100 flex a-center c-fff fs--14 SHS"
            style="width: calc(100% - 20px)"
            @click.stop="handleClick(2)"
            class="absolute h100 flex a-center c-fff fs--14 SHS pointer-events-none"
            style="left: 20px; right: 60px; z-index: 1"
            v-if="endTimeTxt"
          >
            {{ endTimeTxt }}
          </div>
          <div
            @click.stop="handleClick(2)"
            v-else
            class="absolute w100 h100 flex a-center c-fff fs--14 SHSR"
            class="absolute h100 flex a-center c-fff fs--14 SHSR pointer-events-none"
            style="left: 20px; right: 60px; z-index: 1"
          >
            请选择结束时间
            请选择结束日期
          </div>
          <img
            src="../../assets/img/home/Shape@2x (6).png"
            class="w--13 h--13 shrink0"
          />
          <div
            class="flex a-center gap--5"
            style="position: relative; z-index: 2"
          >
            <i
              @click.stop="clearEndTime"
              class="el-icon-circle-close c-fff cursor-pointer"
              v-show="endTime"
            />
            <img
              @click="handleClick(2)"
              src="../../assets/img/home/Shape@2x (6).png"
              class="w--13 h--13 shrink0 cursor-pointer"
            />
          </div>
        </div>
        <div
          class="flex a-center j-between w--300 pl--20 h--40 relative bgcolor1 searchBox"
@@ -128,10 +166,15 @@
            v-model="searchText"
            placeholder="请输入搜索内容"
            class="flex1"
            clearable
            @keyup.enter.native="handleSearch"
          >
          </el-input>
          <i
            @click.stop="clearSearchText"
            class="el-icon-circle-close c-fff cursor-pointer"
            v-show="searchText"
            style="position: absolute; right: 90px; z-index: 2;"
          />
          <div class="btn SHSR" @click="handleSearch">搜索</div>
        </div>
      </div>
@@ -407,7 +450,7 @@
    startTime: {
      handler (newVal) {
        if (newVal) {
          this.startTimeTxt = moment(newVal).format('YYYY年MM月DD日 HH:mm:ss')
          this.startTimeTxt = moment(newVal).format('YYYY年MM月DD日')
        } else {
          this.startTimeTxt = ''
        }
@@ -417,7 +460,7 @@
    endTime: {
      handler (newVal) {
        if (newVal) {
          this.endTimeTxt = moment(newVal).format('YYYY年MM月DD日 HH:mm:ss')
          this.endTimeTxt = moment(newVal).format('YYYY年MM月DD日')
        } else {
          this.endTimeTxt = ''
        }
@@ -479,11 +522,11 @@
        if (this.positionId) params.positionId = this.positionId
        if (this.startTime) {
          params.startTime = moment(this.startTime).format(
            'YYYY-MM-DD HH:mm:ss'
            'YYYY-MM-DD 00:00:00'
          )
        }
        if (this.endTime) {
          params.endTime = moment(this.endTime).format('YYYY-MM-DD HH:mm:ss')
          params.endTime = moment(this.endTime).format('YYYY-MM-DD 23:59:59')
        }
        if (this.searchText) params.remark = this.searchText
@@ -504,6 +547,36 @@
    handleSearch () {
      this.currentPage = 1
      this.getTableData()
    },
    // 清除计划
    clearPlanId () {
      this.planId = null
      this.handleSearch()
    },
    // 清除岗位
    clearPositionId () {
      this.positionId = null
      this.handleSearch()
    },
    // 清除开始时间
    clearStartTime () {
      this.startTime = null
      this.handleSearch()
    },
    // 清除结束时间
    clearEndTime () {
      this.endTime = null
      this.handleSearch()
    },
    // 清除搜索内容
    clearSearchText () {
      this.searchText = ''
      this.handleSearch()
    },
    // 分页大小改变
@@ -656,6 +729,19 @@
    display: none;
  }
  ::v-deep .el-select__caret {
    display: none;
  }
  .el-icon-circle-close {
    font-size: 16px;
    transition: color 0.3s;
    &:hover {
      color: #00ebfc;
    }
  }
  .btn {
    position: absolute;
    top: -2px;
screen/src/view/planOfAudit/index.vue
@@ -21,7 +21,7 @@
            v-model="planType"
            placeholder="请选择计划类型"
            class="flex1"
            clearable
            @change="handleSearch"
          >
            <el-option
              v-for="item in planOptions"
@@ -31,13 +31,19 @@
            >
            </el-option>
          </el-select>
          <img
            src="../../assets/img/down-circle@2x.png"
            class="w--15 h--16 shrink0"
          />
          <div class="flex a-center gap--5" style="position: relative; z-index: 2;">
            <i
              @click.stop="clearPlanType"
              class="el-icon-circle-close c-fff cursor-pointer"
              v-show="planType !== '' && planType !== null && planType !== undefined"
            />
            <img
              src="../../assets/img/down-circle@2x.png"
              class="w--15 h--16 shrink0 pointer-events-none"
            />
          </div>
        </div>
        <div
          @click="handleClick(1)"
          class="flex a-center j-between px--20 w--300 h--40 relative bgcolor1 picker"
        >
          <el-date-picker
@@ -45,28 +51,40 @@
            ref="datetime1"
            type="datetime"
            placeholder=""
            clearable
            @change="handleSearch"
          >
          </el-date-picker>
          <div
            class="absolute w100 h100 flex a-center c-fff fs--14 SHS"
            style="width: calc(100% - 20px)"
            @click.stop="handleClick(1)"
            class="absolute h100 flex a-center c-fff fs--14 SHS pointer-events-none"
            style="left: 20px; right: 60px; z-index: 1;"
            v-if="startTimeTxt"
          >
            {{ startTimeTxt }}
          </div>
          <div
            @click.stop="handleClick(1)"
            v-else
            class="absolute w100 h100 flex a-center c-fff fs--14 SHSR"
            class="absolute h100 flex a-center c-fff fs--14 SHSR pointer-events-none"
            style="left: 20px; right: 60px; z-index: 1;"
          >
            请选择开始日期
          </div>
          <img
            src="../../assets/img/home/Shape@2x (6).png"
            class="w--13 h--13 shrink0"
          />
          <div class="flex a-center gap--5" style="position: relative; z-index: 2;">
            <i
              @click.stop="clearStartTime"
              class="el-icon-circle-close c-fff cursor-pointer"
              v-show="startTime"
            />
            <img
              @click="handleClick(1)"
              src="../../assets/img/home/Shape@2x (6).png"
              class="w--13 h--13 shrink0 cursor-pointer"
            />
          </div>
        </div>
        <div
          @click="handleClick(2)"
          class="flex a-center j-between px--20 w--300 h--40 relative bgcolor1 picker"
        >
          <el-date-picker
@@ -74,25 +92,38 @@
            ref="datetime2"
            type="datetime"
            placeholder=""
            clearable
            @change="handleSearch"
          >
          </el-date-picker>
          <div
            class="absolute w100 h100 flex a-center c-fff fs--14 SHS"
            style="width: calc(100% - 20px)"
            @click.stop="handleClick(2)"
            class="absolute h100 flex a-center c-fff fs--14 SHS pointer-events-none"
            style="left: 20px; right: 60px; z-index: 1;"
            v-if="endTimeTxt"
          >
            {{ endTimeTxt }}
          </div>
          <div
            @click.stop="handleClick(2)"
            v-else
            class="absolute w100 h100 flex a-center c-fff fs--14 SHSR"
            class="absolute h100 flex a-center c-fff fs--14 SHSR pointer-events-none"
            style="left: 20px; right: 60px; z-index: 1;"
          >
            请选择结束日期
          </div>
          <img
            src="../../assets/img/home/Shape@2x (6).png"
            class="w--13 h--13 shrink0"
          />
          <div class="flex a-center gap--5" style="position: relative; z-index: 2;">
            <i
              @click.stop="clearEndTime"
              class="el-icon-circle-close c-fff cursor-pointer"
              v-show="endTime"
            />
            <img
              @click="handleClick(2)"
              src="../../assets/img/home/Shape@2x (6).png"
              class="w--13 h--13 shrink0 cursor-pointer"
            />
          </div>
        </div>
        <div
          class="flex a-center j-between w--300 pl--20 h--40 relative bgcolor1 searchBox"
@@ -102,6 +133,7 @@
            placeholder="请输入搜索内容"
            class="flex1"
            clearable
            @clear="handleSearch"
            @keyup.enter.native="handleSearch"
          />
          <div @click="handleSearch" class="btn SHSR">搜索</div>
@@ -877,6 +909,24 @@
      this.$refs[`datetime${type}`].focus()
    },
    // 清除计划类型
    clearPlanType () {
      this.planType = ''
      this.handleSearch()
    },
    // 清除开始时间
    clearStartTime () {
      this.startTime = null
      this.handleSearch()
    },
    // 清除结束时间
    clearEndTime () {
      this.endTime = null
      this.handleSearch()
    },
    // 返回
    backFun () {
      this.$router.go(-1)
screen/src/view/projectHome/index.vue
@@ -109,7 +109,7 @@
                  <div class="label dept">
                    设备租赁单位
                    <el-tooltip
                      v-if="filteredRentalUnits.length > 0"
                      v-if="filteredRentalUnits.length > 1"
                      placement="top"
                      effect="dark"
                    >
@@ -130,19 +130,19 @@
                      }}</span>
                    </el-tooltip>
                  </div>
                  <!-- <div class="value">
                  <div class="value" v-if="filteredProperties.length ==1">
                    {{
                      filteredProperties[0][
                        "工程起重机械租赁单位"
                      ] || "-"
                    }}
                  </div> -->
                  </div>
                </div>
                <div class="flex1 flex">
                  <div class="label">
                    联系人
                    <el-tooltip
                      v-if="filteredContacts.length > 0"
                      v-if="filteredContacts.length > 1"
                      placement="top"
                      effect="dark"
                    >
@@ -165,11 +165,11 @@
                      }}</span>
                    </el-tooltip>
                  </div>
                  <!-- <div class="value">
                  <div class="value" v-if="filteredContacts.length ==1">
                    {{
                      filteredProperties[0]["联系电话"] || "-"
                    }}
                  </div> -->
                  </div>
                </div>
              </div>
              <div class="info-item11">
@@ -1343,9 +1343,24 @@
          }
          const satellite = new AMap.TileLayer.Satellite();
          // 获取经纬度
          let center = [104.065617, 30.65695]; // 默认中心点
          let longitude = null;
          let latitude = null;
          if (this.projectInfo && this.projectInfo.addressInfo) {
            longitude = Number(this.projectInfo.addressInfo.longitude);
            latitude = Number(this.projectInfo.addressInfo.latitude);
            if (!isNaN(longitude) && !isNaN(latitude) && longitude !== 0 && latitude !== 0) {
              center = [longitude, latitude];
            }
          }
          this.mapView = new AMap.Map("projectContainer", {
            zoom: 17,
            center: [104.065617, 30.65695],
            center: center,
            layers: [satellite],
          });
@@ -1443,10 +1458,18 @@
      // 1) 优先使用后端返回的经纬度(如果有)
      const info = this.projectInfo.addressInfo || {};
      const lonLatStr = typeof info.lonLat === "string" ? info.lonLat : "";
      const lonLatParts = lonLatStr.split(",");
      const lng = lonLatParts[0] ? Number(lonLatParts[0]) : null;
      const lat = lonLatParts[1] ? Number(lonLatParts[1]) : null;
      let lng = null;
      let lat = null;
      if (info.longitude && info.latitude) {
        lng = Number(info.longitude);
        lat = Number(info.latitude);
      } else {
        const lonLatStr = typeof info.lonLat === "string" ? info.lonLat : "";
        const lonLatParts = lonLatStr.split(",");
        lng = lonLatParts[0] ? Number(lonLatParts[0]) : null;
        lat = lonLatParts[1] ? Number(lonLatParts[1]) : null;
      }
      if (tryRenderMarker(lng, lat)) {
        return;
@@ -2374,7 +2397,7 @@
    }
    .dept {
      width: 100px;
      width: 75px;
    }
    .time {
screen/src/view/projectList/index.vue
@@ -46,7 +46,7 @@
          </div>
        </div>
        <div
          class="flex a-center j-between pl--18 pr--15 h--40 relative w--300 bgcolor1 searchBox"
          class="flex a-center j-between pl--18 pr--15 h--40 relative w--300 bgcolor1 searchBox" v-if="projectCategory=='ongoing'"
        >
          <el-select
            filterable
@@ -506,7 +506,7 @@
      projectTypeOptions: [
        { label: '房建', value: 0 },
        { label: '市政', value: 1 },
        { label: '固定资产', value: 2 }
        // { label: '固定资产', value: 2 }
      ], // 项目类型下拉列表
      riskLevelOptions: [
        { label: '拒绝接受风险', value: 0 },
@@ -746,6 +746,7 @@
          projectName: row.name
        }
      })
      sessionStorage.setItem('projectType', 2)
      if (!sessionStorage.getItem('userInfo')) {
        sessionStorage.setItem('userInfo', JSON.stringify({ type: 1 }))
      }