yanghao 3 dagar sedan
förälder
incheckning
539460bc87

+ 33 - 0
src/api/pms/qhse/index.ts

@@ -501,3 +501,36 @@ export const CertPersonApi = {
     return await request.get({ url: `/rq/qhse-cert-person/get?id=` + id })
   }
 }
+
+// QHSE月报 API
+export const QhseMonthReportApi = {
+  // 查询QHSE月报分页
+  getQhseMonthReportPage: async (params: any) => {
+    return await request.get({ url: `/rq/qhse-month-report/page`, params })
+  },
+
+  // 查询QHSE月报详情
+  getQhseMonthReport: async (id) => {
+    return await request.get({ url: `/rq/qhse-month-report/get?id=` + id })
+  },
+
+  // 新增QHSE月报
+  createQhseMonthReport: async (data) => {
+    return await request.post({ url: `/rq/qhse-month-report/create`, data })
+  },
+
+  // 修改QHSE月报
+  updateQhseMonthReport: async (data) => {
+    return await request.put({ url: `/rq/qhse-month-report/update`, data })
+  },
+
+  // 删除QHSE月报
+  deleteQhseMonthReport: async (id) => {
+    return await request.delete({ url: `/rq/qhse-month-report/delete?id=` + id })
+  },
+
+  // 导出QHSE月报 Excel
+  exportQhseMonthReport: async (params) => {
+    return await request.download({ url: `/rq/qhse-month-report/export-excel`, params })
+  }
+}

+ 21 - 4
src/views/pms/qhse/iotmeasuredetect/index.vue

@@ -6,6 +6,13 @@
       <ContentWrap style="border: none">
         <!-- 搜索工作栏 -->
         <el-form :model="queryParams" ref="queryFormRef" :inline="true">
+          <el-form-item label="计量器具编码" prop="measureCode">
+            <el-input
+              v-model="queryParams.measureCode"
+              placeholder="请输入计量器具编码"
+              clearable
+              class="!w-150px" />
+          </el-form-item>
           <el-form-item label="检测/校准日期" prop="detectDate">
             <el-date-picker
               v-model="queryParams.detectDate"
@@ -25,13 +32,22 @@
               class="!w-150px" />
           </el-form-item>
           <el-form-item label="检测/校准有效期" prop="validityPeriod">
-            <el-date-picker
+            <!-- <el-date-picker
               v-model="queryParams.validityPeriod"
               value-format="YYYY-MM-DD"
-              type="date"
+              type="daterange"
               placeholder="选择检测/校准有效期"
               clearable
-              class="!w-150px" />
+              class="!w-150px" /> -->
+
+            <el-date-picker
+              v-model="queryParams.validityPeriod"
+              value-format="YYYY-MM-DD HH:mm:ss"
+              type="daterange"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+              :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
+              class="!w-200px" />
           </el-form-item>
 
           <el-form-item>
@@ -173,7 +189,8 @@ const queryParams = reactive({
   validityPeriod: undefined,
   detectAmount: undefined,
   createTime: [],
-  deptId: undefined
+  deptId: undefined,
+  measureCode: undefined
 })
 const queryFormRef = ref() // 搜索的表单
 const exportLoading = ref(false) // 导出的加载中

+ 623 - 1
src/views/pms/qhse/monthlyReport/MonthlyReportAdd.vue

@@ -1,7 +1,629 @@
 <template>
-  <div>addddd</div>
+  <div class="monthly-report-add">
+    <el-form
+      ref="formRef"
+      :model="formData"
+      :rules="formRules"
+      label-width="180px"
+      class="report-form">
+      <!-- 1. 基本信息 -->
+      <el-card class="form-section" shadow="hover">
+        <template #header>
+          <div class="section-header">
+            <Icon icon="ep:document" class="mr-5px" />
+            <span>基本信息</span>
+          </div>
+        </template>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="部门名称" prop="deptId">
+              <el-input
+                v-model="deptName"
+                placeholder="请选择部门"
+                readonly
+                @click="openDeptSelect">
+                <template #suffix>
+                  <Icon icon="ep:search" class="cursor-pointer" />
+                </template>
+              </el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="月报标题" prop="title">
+              <el-input v-model="formData.title" placeholder="请输入月报标题" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="年月" prop="yearMonth">
+              <el-date-picker
+                v-model="formData.yearMonth"
+                type="month"
+                placeholder="选择年月"
+                format="YYYY-MM"
+                value-format="YYYY-MM"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-card>
+
+      <!-- 2. 人工时和安全行驶公里数 -->
+      <el-card class="form-section" shadow="hover">
+        <template #header>
+          <div class="section-header">
+            <Icon icon="ep:user" class="mr-5px" />
+            <span>人工时和安全行驶公里数</span>
+          </div>
+        </template>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="员工人数" prop="employee">
+              <el-input-number
+                v-model="formData.employee"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="分包商人数" prop="subcontractors">
+              <el-input-number
+                v-model="formData.subcontractors"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="安全行驶里程数(公里)" prop="drivingMileage">
+              <el-input-number
+                v-model="formData.drivingMileage"
+                :min="0"
+                :precision="2"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="总人工时数(小时)" prop="totalManHours">
+              <el-input-number
+                v-model="formData.totalManHours"
+                :min="0"
+                :precision="2"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-card>
+
+      <!-- 3. QHSE被动性指标统计 -->
+      <el-card class="form-section" shadow="hover">
+        <template #header>
+          <div class="section-header">
+            <Icon icon="ep:warning" class="mr-5px" />
+            <span>QHSE被动性指标统计</span>
+          </div>
+        </template>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="无事故累计天数" prop="withoutAccident">
+              <el-input-number
+                v-model="formData.withoutAccident"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="死亡事故(起)" prop="fatality">
+              <el-input-number
+                v-model="formData.fatality"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="损失工时事故(起)" prop="injury">
+              <el-input-number
+                v-model="formData.injury"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="工作受限事件(起)" prop="restrictedCase">
+              <el-input-number
+                v-model="formData.restrictedCase"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="医疗处理事件(起)" prop="medicalCase">
+              <el-input-number
+                v-model="formData.medicalCase"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="急救箱事件(起)" prop="firstAidCase">
+              <el-input-number
+                v-model="formData.firstAidCase"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="交通事故(起)" prop="vehicleAccident">
+              <el-input-number
+                v-model="formData.vehicleAccident"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="未遂事件(起)" prop="nearMiss">
+              <el-input-number
+                v-model="formData.nearMiss"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="泄漏事件(起)" prop="spill">
+              <el-input-number
+                v-model="formData.spill"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="违反保命规则的次数(次)" prop="lifeSavingRules">
+              <el-input-number
+                v-model="formData.lifeSavingRules"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-card>
+
+      <!-- 4. QHSE主动性指标统计 -->
+      <el-card class="form-section" shadow="hover">
+        <template #header>
+          <div class="section-header">
+            <Icon icon="ep:checked" class="mr-5px" />
+            <span>QHSE主动性指标统计</span>
+          </div>
+        </template>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="班前会(次)" prop="toolboxTalk">
+              <el-input-number
+                v-model="formData.toolboxTalk"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="QHSE管理委员会会议(次)" prop="committeeMeeting">
+              <el-input-number
+                v-model="formData.committeeMeeting"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="QHSE月度例会(次)" prop="monthlyMeeting">
+              <el-input-number
+                v-model="formData.monthlyMeeting"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="公司级隐患排查(次)" prop="companyHazard">
+              <el-input-number
+                v-model="formData.companyHazard"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="QHSE检查(次)" prop="qhseInspection">
+              <el-input-number
+                v-model="formData.qhseInspection"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="安全观察卡(张)" prop="socCards">
+              <el-input-number
+                v-model="formData.socCards"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="工作许可审核(份)" prop="ptwAudit">
+              <el-input-number
+                v-model="formData.ptwAudit"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="工作安全分析(次)" prop="jsa">
+              <el-input-number
+                v-model="formData.jsa"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="演练次数" prop="drills">
+              <el-input-number
+                v-model="formData.drills"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="QHSE培训次数" prop="training">
+              <el-input-number
+                v-model="formData.training"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="QHSE培训人次" prop="participantsTraining">
+              <el-input-number
+                v-model="formData.participantsTraining"
+                :min="0"
+                :precision="0"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="QHSE培训学时数(小时)" prop="trainingsHours">
+              <el-input-number
+                v-model="formData.trainingsHours"
+                :min="0"
+                :precision="2"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-card>
+
+      <!-- 5. 环境数据 -->
+      <el-card class="form-section" shadow="hover">
+        <template #header>
+          <div class="section-header">
+            <Icon icon="ep:sunrise" class="mr-5px" />
+            <span>环境数据</span>
+          </div>
+        </template>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="水消耗(吨)" prop="waterConsumption">
+              <el-input-number
+                v-model="formData.waterConsumption"
+                :min="0"
+                :precision="2"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="柴油消耗(升)" prop="dieselConsumption">
+              <el-input-number
+                v-model="formData.dieselConsumption"
+                :min="0"
+                :precision="2"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="用电量(千瓦·小时)" prop="electricityConsumption">
+              <el-input-number
+                v-model="formData.electricityConsumption"
+                :min="0"
+                :precision="2"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="天然气消耗量(立方米)" prop="naturalGasConsumption">
+              <el-input-number
+                v-model="formData.naturalGasConsumption"
+                :min="0"
+                :precision="2"
+                controls-position="right"
+                style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-card>
+
+      <!-- 6. 其他信息 -->
+      <el-card class="form-section" shadow="hover">
+        <template #header>
+          <div class="section-header">
+            <Icon icon="ep:info-filled" class="mr-5px" />
+            <span>其他信息</span>
+          </div>
+        </template>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="工单填报人" prop="dutyPerson">
+              <el-input
+                v-model="dutyPersonName"
+                placeholder="请选择填报人"
+                readonly
+                @click="openUserSelect">
+                <template #suffix>
+                  <Icon icon="ep:search" class="cursor-pointer" />
+                </template>
+              </el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="备注" prop="remark">
+              <el-input
+                v-model="formData.remark"
+                type="textarea"
+                :rows="4"
+                placeholder="请输入备注信息" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-card>
+
+      <!-- 操作按钮 -->
+      <div class="form-actions">
+        <el-button @click="handleCancel">取消</el-button>
+        <el-button type="primary" @click="handleSubmit" :loading="submitLoading"> 提交 </el-button>
+      </div>
+    </el-form>
+
+    <!-- 部门选择弹窗 -->
+    <DeptSelectForm ref="deptSelectFormRef" :multiple="false" @confirm="handleDeptConfirm" />
+
+    <!-- 用户选择弹窗 -->
+    <UserSelectForm ref="userSelectFormRef" @confirm="handleUserConfirm" />
+  </div>
 </template>
 
 <script setup lang="ts">
+import { reactive, ref } from 'vue'
+import { useRouter } from 'vue-router'
+import { FormInstance, FormRules } from 'element-plus'
+import { QhseMonthReportApi } from '@/api/pms/qhse'
+import DeptSelectForm from '@/components/DeptSelectForm/index.vue'
+import UserSelectForm from '@/components/UserSelectForm/index.vue'
+
 defineOptions({ name: 'MonthlyReportAdd' })
+
+const router = useRouter()
+const message = useMessage()
+
+// 表单引用
+const formRef = ref<FormInstance>()
+const submitLoading = ref(false)
+
+// 表单数据
+const formData = reactive({
+  title: '',
+  yearMonth: '',
+  deptId: 0,
+  employee: '0',
+  subcontractors: '0',
+  drivingMileage: '0',
+  totalManHours: '0',
+  withoutAccident: '0',
+  fatality: '0',
+  injury: '0',
+  restrictedCase: '0',
+  medicalCase: '0',
+  firstAidCase: '0',
+  vehicleAccident: '0',
+  nearMiss: '0',
+  spill: '0',
+  lifeSavingRules: '0',
+  toolboxTalk: '0',
+  committeeMeeting: '0',
+  monthlyMeeting: '0',
+  companyHazard: '0',
+  qhseInspection: '0',
+  socCards: '0',
+  ptwAudit: '0',
+  jsa: '0',
+  drills: '0',
+  training: '0',
+  participantsTraining: '0',
+  trainingsHours: '0',
+  waterConsumption: '0',
+  dieselConsumption: '0',
+  electricityConsumption: '0',
+  naturalGasConsumption: '0',
+  dutyPerson: 0,
+  remark: ''
+})
+
+// 表单校验规则
+const formRules = reactive<FormRules>({
+  title: [{ required: true, message: '月报标题不能为空', trigger: 'blur' }],
+  yearMonth: [{ required: true, message: '年月不能为空', trigger: 'change' }],
+  deptId: [{ required: true, message: '部门不能为空', trigger: 'change' }],
+  dutyPerson: [{ required: true, message: '工单填报人不能为空', trigger: 'change' }]
+})
+
+// 部门名称显示
+const deptName = ref('')
+
+// 填报人名称显示
+const dutyPersonName = ref('')
+
+// 部门选择弹窗引用
+const deptSelectFormRef = ref()
+
+// 用户选择弹窗引用
+const userSelectFormRef = ref()
+
+/** 打开部门选择 */
+const openDeptSelect = () => {
+  deptSelectFormRef.value?.open()
+}
+
+/** 部门选择确认 */
+const handleDeptConfirm = async (deptList: any[]) => {
+  if (deptList && deptList.length > 0) {
+    const dept = deptList[0]
+    formData.deptId = dept.id
+    deptName.value = dept.name
+  }
+}
+
+/** 打开用户选择 */
+const openUserSelect = () => {
+  userSelectFormRef.value?.open()
+}
+
+/** 用户选择确认 */
+const handleUserConfirm = (userId: any, userList: any[]) => {
+  if (userList && userList.length > 0) {
+    const user = userList[0]
+    formData.dutyPerson = user.id
+    dutyPersonName.value = user.nickname
+  }
+}
+
+/** 提交表单 */
+const handleSubmit = async () => {
+  if (!formRef.value) return
+
+  // 校验表单
+  const valid = await formRef.value.validate()
+  if (!valid) return
+
+  submitLoading.value = true
+  try {
+    await QhseMonthReportApi.createQhseMonthReport(formData)
+    message.success('新增成功')
+    // 返回列表页或上一页
+    router.back()
+  } catch (error) {
+    console.error('提交失败:', error)
+  } finally {
+    submitLoading.value = false
+  }
+}
+
+/** 取消 */
+const handleCancel = () => {
+  router.back()
+}
 </script>
+
+<style scoped lang="scss">
+.monthly-report-add {
+  padding: 20px;
+
+  .report-form {
+    max-width: 1400px;
+    margin: 0 auto;
+
+    .form-section {
+      margin-bottom: 20px;
+
+      :deep(.el-card__header) {
+        padding: 15px 20px;
+        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+        color: white;
+      }
+
+      .section-header {
+        display: flex;
+        align-items: center;
+        font-size: 16px;
+        font-weight: 600;
+      }
+    }
+
+    .form-actions {
+      display: flex;
+      justify-content: center;
+      gap: 20px;
+      padding: 20px 0;
+      margin-top: 20px;
+      border-top: 1px solid #e4e7ed;
+
+      .el-button {
+        min-width: 120px;
+      }
+    }
+  }
+}
+</style>