| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // ==================== äººåæ¡£æ¡æ¥å£ ==================== |
| | | export function getPersonnelList(query) { |
| | | return request({ |
| | | url: '/safety/personnel/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | export function addPersonnel(data) { |
| | | return request({ |
| | | url: '/safety/personnel/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function updatePersonnel(data) { |
| | | return request({ |
| | | url: '/safety/personnel/update', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function deletePersonnel(id) { |
| | | return request({ |
| | | url: '/safety/personnel/delete/' + id, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | export function getPersonnelDetail(id) { |
| | | return request({ |
| | | url: '/safety/personnel/detail/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // ==================== 设å¤è®¾æ½æ¥å£ ==================== |
| | | export function getEquipmentList(query) { |
| | | return request({ |
| | | url: '/safety/equipment/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | export function addEquipment(data) { |
| | | return request({ |
| | | url: '/safety/equipment/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function updateEquipment(data) { |
| | | return request({ |
| | | url: '/safety/equipment/update', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function deleteEquipment(id) { |
| | | return request({ |
| | | url: '/safety/equipment/delete/' + id, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | export function getEquipmentDetail(id) { |
| | | return request({ |
| | | url: '/safety/equipment/detail/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // ==================== ä½ä¸åºåæ¥å£ ==================== |
| | | export function getWorkAreaList(query) { |
| | | return request({ |
| | | url: '/safety/workArea/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | export function addWorkArea(data) { |
| | | return request({ |
| | | url: '/safety/workArea/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function updateWorkArea(data) { |
| | | return request({ |
| | | url: '/safety/workArea/update', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function deleteWorkArea(id) { |
| | | return request({ |
| | | url: '/safety/workArea/delete/' + id, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | export function getWorkAreaDetail(id) { |
| | | return request({ |
| | | url: '/safety/workArea/detail/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | export function getAllWorkArea() { |
| | | return request({ |
| | | url: '/safety/workArea/all', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // ==================== å²ä½é£é©æ¥å£ ==================== |
| | | export function getRiskList(query) { |
| | | return request({ |
| | | url: '/safety/risk/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | export function addRisk(data) { |
| | | return request({ |
| | | url: '/safety/risk/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function updateRisk(data) { |
| | | return request({ |
| | | url: '/safety/risk/update', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function deleteRisk(id) { |
| | | return request({ |
| | | url: '/safety/risk/delete/' + id, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | export function getRiskDetail(id) { |
| | | return request({ |
| | | url: '/safety/risk/detail/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // ==================== åºæ¥èµæºæ¥å£ ==================== |
| | | export function getEmergencyList(query) { |
| | | return request({ |
| | | url: '/safety/emergency/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | export function addEmergency(data) { |
| | | return request({ |
| | | url: '/safety/emergency/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function updateEmergency(data) { |
| | | return request({ |
| | | url: '/safety/emergency/update', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function deleteEmergency(id) { |
| | | return request({ |
| | | url: '/safety/emergency/delete/' + id, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | export function getEmergencyDetail(id) { |
| | | return request({ |
| | | url: '/safety/emergency/detail/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // ==================== å¦ä¹ è®°å½æ¥å£ ==================== |
| | | export function getLearningRecordList(query) { |
| | | return request({ |
| | | url: '/safety/learning/record/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | export function getLearningStatistics() { |
| | | return request({ |
| | | url: '/safety/learning/record/statistics', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // ==================== èæ ¸æ¥åæ¥å£ ==================== |
| | | export function getAssessmentReportList(query) { |
| | | return request({ |
| | | url: '/safety/learning/report/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | export function getAssessmentReportDetail(id) { |
| | | return request({ |
| | | url: '/safety/learning/report/detail/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // ==================== æµè¯ä»»å¡æ¥å£ ==================== |
| | | export function getAssessmentTaskList(query) { |
| | | return request({ |
| | | url: '/safety/learning/assessment/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | export function startAssessment(data) { |
| | | return request({ |
| | | url: '/safety/learning/assessment/start', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function submitAssessment(data) { |
| | | return request({ |
| | | url: '/safety/learning/assessment/submit', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // ==================== å·¡æ£è®°å½æ¥å£ ==================== |
| | | export function getInspectionRecordList(query) { |
| | | return request({ |
| | | url: '/safety/inspection/record/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | export function addInspectionRecord(data) { |
| | | return request({ |
| | | url: '/safety/inspection/record/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function updateInspectionRecord(data) { |
| | | return request({ |
| | | url: '/safety/inspection/record/update', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function deleteInspectionRecord(id) { |
| | | return request({ |
| | | url: '/safety/inspection/record/delete/' + id, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // åæ¥å·¡æ£æ°æ®ï¼æ¨¡æåç³»ç»ï¼ |
| | | export function syncInspectionData() { |
| | | return request({ |
| | | url: '/safety/inspection/record/sync', |
| | | method: 'post' |
| | | }) |
| | | } |
| | | |
| | | // ==================== ç»è®¡æ¥è¡¨æ¥å£ ==================== |
| | | export function getTodayStatistics() { |
| | | return request({ |
| | | url: '/safety/inspection/statistics/today', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | export function getTrendStatistics(params) { |
| | | return request({ |
| | | url: '/safety/inspection/statistics/trend', |
| | | method: 'get', |
| | | params: params |
| | | }) |
| | | } |
| | | |
| | | export function getTypeStatistics(params) { |
| | | return request({ |
| | | url: '/safety/inspection/statistics/type', |
| | | method: 'get', |
| | | params: params |
| | | }) |
| | | } |
| | | |
| | | export function getInspectorStatistics(params) { |
| | | return request({ |
| | | url: '/safety/inspection/statistics/inspector', |
| | | method: 'get', |
| | | params: params |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // ==================== å¹è®èµææ¥å£ ==================== |
| | | export function getMaterialList(query) { |
| | | return request({ |
| | | url: '/safety/training/material/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | export function uploadMaterial(data) { |
| | | return request({ |
| | | url: '/safety/training/material/upload', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function updateMaterial(data) { |
| | | return request({ |
| | | url: '/safety/training/material/update', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function deleteMaterial(id) { |
| | | return request({ |
| | | url: '/safety/training/material/delete/' + id, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | export function getMaterialDetail(id) { |
| | | return request({ |
| | | url: '/safety/training/material/detail/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // ==================== å¹è®è®¡åæ¥å£ ==================== |
| | | export function getPlanList(query) { |
| | | return request({ |
| | | url: '/safety/training/plan/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | export function addPlan(data) { |
| | | return request({ |
| | | url: '/safety/training/plan/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function updatePlan(data) { |
| | | return request({ |
| | | url: '/safety/training/plan/update', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function deletePlan(id) { |
| | | return request({ |
| | | url: '/safety/training/plan/delete/' + id, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | export function getPlanDetail(id) { |
| | | return request({ |
| | | url: '/safety/training/plan/detail/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // ==================== å®æè®°å½æ¥å£ ==================== |
| | | export function getRecordList(query) { |
| | | return request({ |
| | | url: '/safety/training/record/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | export function addRecord(data) { |
| | | return request({ |
| | | url: '/safety/training/record/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function updateRecord(data) { |
| | | return request({ |
| | | url: '/safety/training/record/update', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function deleteRecord(id) { |
| | | return request({ |
| | | url: '/safety/training/record/delete/' + id, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | export function getRecordDetail(id) { |
| | | return request({ |
| | | url: '/safety/training/record/detail/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | export function exportRecord(query) { |
| | | return request({ |
| | | url: '/safety/training/record/export', |
| | | method: 'get', |
| | | params: query, |
| | | responseType: 'blob' |
| | | }) |
| | | } |
| | | |
| | | // è·åå¦ä¹ ç»è®¡ï¼ç¨äºåå·¥å¦ä¹ 页é¢ï¼ |
| | | export function getLearningStatistics() { |
| | | return request({ |
| | | url: '/safety/training/record/statistics', |
| | | method: 'get' |
| | | }) |
| | | } |
| | |
| | | <div class="actions"> |
| | | <el-button type="primary" @click="addPersonnel" icon="Plus">æ°å¢</el-button> |
| | | </div> |
| | | <PIMTable :column="personnelColumns" :tableData="personnelList" :page="personnelPage" @pagination="changePersonnelPage" /> |
| | | <PIMTable :column="personnelColumns" :tableData="personnelList" :page="personnelPage" @pagination="changePersonnelPage" :tableLoading="personnelLoading" /> |
| | | </div> |
| | | </el-tab-pane> |
| | | |
| | |
| | | <el-input v-model="equipmentFilters.name" placeholder="请è¾å
¥è®¾å¤åç§°" clearable style="width: 200px" /> |
| | | </el-form-item> |
| | | <el-form-item label="æå±åºå"> |
| | | <el-input v-model="equipmentFilters.area" placeholder="请è¾å
¥æå±åºå" clearable style="width: 200px" /> |
| | | <el-input v-model="equipmentFilters.areaName" placeholder="请è¾å
¥æå±åºå" clearable style="width: 200px" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="getEquipmentData">æç´¢</el-button> |
| | |
| | | <div class="actions"> |
| | | <el-button type="primary" @click="addEquipment" icon="Plus">æ°å¢</el-button> |
| | | </div> |
| | | <PIMTable :column="equipmentColumns" :tableData="equipmentList" :page="equipmentPage" @pagination="changeEquipmentPage" /> |
| | | <PIMTable :column="equipmentColumns" :tableData="equipmentList" :page="equipmentPage" @pagination="changeEquipmentPage" :tableLoading="equipmentLoading" /> |
| | | </div> |
| | | </el-tab-pane> |
| | | |
| | |
| | | <div class="actions"> |
| | | <el-button type="primary" @click="addArea" icon="Plus">æ°å¢</el-button> |
| | | </div> |
| | | <PIMTable :column="areaColumns" :tableData="areaList" :page="areaPage" @pagination="changeAreaPage" /> |
| | | <PIMTable :column="areaColumns" :tableData="areaList" :page="areaPage" @pagination="changeAreaPage" :tableLoading="areaLoading" /> |
| | | </div> |
| | | </el-tab-pane> |
| | | |
| | |
| | | <div class="actions"> |
| | | <el-button type="primary" @click="addRisk" icon="Plus">æ°å¢</el-button> |
| | | </div> |
| | | <PIMTable :column="riskColumns" :tableData="riskList" :page="riskPage" @pagination="changeRiskPage" /> |
| | | <PIMTable :column="riskColumns" :tableData="riskList" :page="riskPage" @pagination="changeRiskPage" :tableLoading="riskLoading" /> |
| | | </div> |
| | | </el-tab-pane> |
| | | |
| | |
| | | <div class="actions"> |
| | | <el-button type="primary" @click="addEmergency" icon="Plus">æ°å¢</el-button> |
| | | </div> |
| | | <PIMTable :column="emergencyColumns" :tableData="emergencyList" :page="emergencyPage" @pagination="changeEmergencyPage" /> |
| | | <PIMTable :column="emergencyColumns" :tableData="emergencyList" :page="emergencyPage" @pagination="changeEmergencyPage" :tableLoading="emergencyLoading" /> |
| | | </div> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | |
| | | <!-- äººåæ¡£æ¡å¼¹çª --> |
| | | <el-dialog :title="personnelDialog.title" v-model="personnelDialog.visible" width="600px" append-to-body> |
| | | <el-form ref="personnelFormRef" :model="personnelForm" :rules="personnelRules" label-width="100px"> |
| | | <el-form-item label="å§å" prop="name"> |
| | | <el-input v-model="personnelForm.name" placeholder="请è¾å
¥å§å" /> |
| | | </el-form-item> |
| | | <el-form-item label="é¨é¨" prop="dept"> |
| | | <el-input v-model="personnelForm.dept" placeholder="请è¾å
¥é¨é¨" /> |
| | | </el-form-item> |
| | | <el-form-item label="å²ä½" prop="post"> |
| | | <el-input v-model="personnelForm.post" placeholder="请è¾å
¥å²ä½" /> |
| | | </el-form-item> |
| | | <el-form-item label="èç³»æ¹å¼" prop="phone"> |
| | | <el-input v-model="personnelForm.phone" placeholder="请è¾å
¥èç³»æ¹å¼" /> |
| | | </el-form-item> |
| | | <el-form-item label="å
¥èæ¥æ" prop="entryDate"> |
| | | <el-date-picker v-model="personnelForm.entryDate" type="date" placeholder="éæ©å
¥èæ¥æ" value-format="YYYY-MM-DD" style="width: 100%" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-radio-group v-model="personnelForm.status"> |
| | | <el-radio :value="1">å¨è</el-radio> |
| | | <el-radio :value="0">离è</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="personnelForm.remark" type="textarea" :rows="3" placeholder="请è¾å
¥å¤æ³¨" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="personnelDialog.visible = false">å æ¶</el-button> |
| | | <el-button type="primary" @click="submitPersonnelForm" :loading="personnelDialog.loading">ç¡® å®</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- 设å¤è®¾æ½å¼¹çª --> |
| | | <el-dialog :title="equipmentDialog.title" v-model="equipmentDialog.visible" width="600px" append-to-body> |
| | | <el-form ref="equipmentFormRef" :model="equipmentForm" :rules="equipmentRules" label-width="100px"> |
| | | <el-form-item label="设å¤åç§°" prop="name"> |
| | | <el-input v-model="equipmentForm.name" placeholder="请è¾å
¥è®¾å¤åç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="è§æ ¼åå·" prop="model"> |
| | | <el-input v-model="equipmentForm.model" placeholder="请è¾å
¥è§æ ¼åå·" /> |
| | | </el-form-item> |
| | | <el-form-item label="æå±åºå" prop="areaName"> |
| | | <el-input v-model="equipmentForm.areaName" placeholder="请è¾å
¥æå±åºå" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-radio-group v-model="equipmentForm.status"> |
| | | <el-radio :value="1">æ£å¸¸</el-radio> |
| | | <el-radio :value="0">åç¨</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="equipmentForm.remark" type="textarea" :rows="3" placeholder="请è¾å
¥å¤æ³¨" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="equipmentDialog.visible = false">å æ¶</el-button> |
| | | <el-button type="primary" @click="submitEquipmentForm" :loading="equipmentDialog.loading">ç¡® å®</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- ä½ä¸åºåå¼¹çª --> |
| | | <el-dialog :title="areaDialog.title" v-model="areaDialog.visible" width="600px" append-to-body> |
| | | <el-form ref="areaFormRef" :model="areaForm" :rules="areaRules" label-width="100px"> |
| | | <el-form-item label="åºååç§°" prop="name"> |
| | | <el-input v-model="areaForm.name" placeholder="请è¾å
¥åºååç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="ä½ç½®" prop="location"> |
| | | <el-input v-model="areaForm.location" placeholder="请è¾å
¥ä½ç½®" /> |
| | | </el-form-item> |
| | | <el-form-item label="è´è´£äºº" prop="manager"> |
| | | <el-input v-model="areaForm.manager" placeholder="请è¾å
¥è´è´£äºº" /> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="areaForm.remark" type="textarea" :rows="3" placeholder="请è¾å
¥å¤æ³¨" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="areaDialog.visible = false">å æ¶</el-button> |
| | | <el-button type="primary" @click="submitAreaForm" :loading="areaDialog.loading">ç¡® å®</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- å²ä½é£é©å¼¹çª --> |
| | | <el-dialog :title="riskDialog.title" v-model="riskDialog.visible" width="600px" append-to-body> |
| | | <el-form ref="riskFormRef" :model="riskForm" :rules="riskRules" label-width="100px"> |
| | | <el-form-item label="é£é©ç±»å" prop="type"> |
| | | <el-input v-model="riskForm.type" placeholder="请è¾å
¥é£é©ç±»å" /> |
| | | </el-form-item> |
| | | <el-form-item label="é£é©ç级" prop="level"> |
| | | <el-select v-model="riskForm.level" placeholder="è¯·éæ©é£é©ç级" style="width: 100%"> |
| | | <el-option label="é«" value="high" /> |
| | | <el-option label="ä¸" value="medium" /> |
| | | <el-option label="ä½" value="low" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="å
³èå²ä½" prop="post"> |
| | | <el-input v-model="riskForm.post" placeholder="请è¾å
¥å
³èå²ä½" /> |
| | | </el-form-item> |
| | | <el-form-item label="é£é©æè¿°" prop="description"> |
| | | <el-input v-model="riskForm.description" type="textarea" :rows="3" placeholder="请è¾å
¥é£é©æè¿°" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ§å¶æªæ½" prop="controlMeasures"> |
| | | <el-input v-model="riskForm.controlMeasures" type="textarea" :rows="3" placeholder="请è¾å
¥æ§å¶æªæ½" /> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="riskForm.remark" type="textarea" :rows="3" placeholder="请è¾å
¥å¤æ³¨" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="riskDialog.visible = false">å æ¶</el-button> |
| | | <el-button type="primary" @click="submitRiskForm" :loading="riskDialog.loading">ç¡® å®</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- åºæ¥èµæºå¼¹çª --> |
| | | <el-dialog :title="emergencyDialog.title" v-model="emergencyDialog.visible" width="600px" append-to-body> |
| | | <el-form ref="emergencyFormRef" :model="emergencyForm" :rules="emergencyRules" label-width="100px"> |
| | | <el-form-item label="èµæºåç§°" prop="name"> |
| | | <el-input v-model="emergencyForm.name" placeholder="请è¾å
¥èµæºåç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="èµæºç±»å" prop="type"> |
| | | <el-input v-model="emergencyForm.type" placeholder="请è¾å
¥èµæºç±»å" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ°é" prop="quantity"> |
| | | <el-input-number v-model="emergencyForm.quantity" :min="0" style="width: 100%" /> |
| | | </el-form-item> |
| | | <el-form-item label="æå±åºå" prop="areaName"> |
| | | <el-input v-model="emergencyForm.areaName" placeholder="请è¾å
¥æå±åºå" /> |
| | | </el-form-item> |
| | | <el-form-item label="åæ¾ä½ç½®" prop="location"> |
| | | <el-input v-model="emergencyForm.location" placeholder="请è¾å
¥åæ¾ä½ç½®" /> |
| | | </el-form-item> |
| | | <el-form-item label="管ç人" prop="manager"> |
| | | <el-input v-model="emergencyForm.manager" placeholder="请è¾å
¥ç®¡ç人" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-radio-group v-model="emergencyForm.status"> |
| | | <el-radio :value="1">æ£å¸¸</el-radio> |
| | | <el-radio :value="0">缺失</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="emergencyForm.remark" type="textarea" :rows="3" placeholder="请è¾å
¥å¤æ³¨" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="emergencyDialog.visible = false">å æ¶</el-button> |
| | | <el-button type="primary" @click="submitEmergencyForm" :loading="emergencyDialog.loading">ç¡® å®</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive } from "vue"; |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import PIMTable from "@/components/PIMTable/PIMTable.vue"; |
| | | import { |
| | | getPersonnelList, |
| | | addPersonnel as addPersonnelApi, |
| | | updatePersonnel, |
| | | deletePersonnel, |
| | | getPersonnelDetail, |
| | | getEquipmentList, |
| | | addEquipment as addEquipmentApi, |
| | | updateEquipment, |
| | | deleteEquipment, |
| | | getEquipmentDetail, |
| | | getWorkAreaList, |
| | | addWorkArea as addWorkAreaApi, |
| | | updateWorkArea, |
| | | deleteWorkArea, |
| | | getWorkAreaDetail, |
| | | getRiskList, |
| | | addRisk as addRiskApi, |
| | | updateRisk, |
| | | deleteRisk, |
| | | getRiskDetail, |
| | | getEmergencyList, |
| | | addEmergency as addEmergencyApi, |
| | | updateEmergency, |
| | | deleteEmergency, |
| | | getEmergencyDetail |
| | | } from "@/api/safetyManagement/basicInfo.js"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | |
| | | defineOptions({ |
| | | name: "åºç¡ä¿¡æ¯ç®¡ç", |
| | |
| | | |
| | | const activeTab = ref("personnel"); |
| | | |
| | | // äººåæ¡£æ¡ |
| | | // ==================== äººåæ¡£æ¡ ==================== |
| | | const personnelFilters = reactive({ name: "", dept: "" }); |
| | | const personnelList = ref([]); |
| | | const personnelPage = reactive({ current: 1, size: 10, total: 0 }); |
| | | const personnelLoading = ref(false); |
| | | const personnelColumns = [ |
| | | { label: "å§å", prop: "name", align: "center" }, |
| | | { label: "é¨é¨", prop: "dept", align: "center" }, |
| | | { label: "å²ä½", prop: "post", align: "center" }, |
| | | { label: "èç³»æ¹å¼", prop: "phone", align: "center" }, |
| | | { label: "å
¥èæ¥æ", prop: "entryDate", align: "center" }, |
| | | { |
| | | label: "ç¶æ", |
| | | prop: "status", |
| | | align: "center", |
| | | dataType: "tag", |
| | | formatType: (val) => (val === 1 ? "success" : "info"), |
| | | formatData: (val) => (val === 1 ? "å¨è" : "离è") |
| | | }, |
| | | { |
| | | label: "æä½", |
| | | prop: "action", |
| | | align: "center", |
| | | dataType: "action", |
| | | operation: [ |
| | | { name: "ç¼è¾", type: "text", clickFun: (row) => handleEditPersonnel(row) }, |
| | | { name: "å é¤", type: "text", clickFun: (row) => handleDeletePersonnel(row) } |
| | | ] |
| | | } |
| | | ]; |
| | | |
| | | // 设å¤è®¾æ½ |
| | | const equipmentFilters = reactive({ name: "", area: "" }); |
| | | const personnelDialog = reactive({ visible: false, title: "", loading: false }); |
| | | const personnelFormRef = ref(null); |
| | | const personnelForm = reactive({ |
| | | id: null, |
| | | name: "", |
| | | dept: "", |
| | | post: "", |
| | | phone: "", |
| | | entryDate: "", |
| | | status: 1, |
| | | remark: "" |
| | | }); |
| | | const personnelRules = { |
| | | name: [{ required: true, message: "请è¾å
¥å§å", trigger: "blur" }], |
| | | dept: [{ required: true, message: "请è¾å
¥é¨é¨", trigger: "blur" }] |
| | | }; |
| | | |
| | | // ==================== 设å¤è®¾æ½ ==================== |
| | | const equipmentFilters = reactive({ name: "", areaName: "" }); |
| | | const equipmentList = ref([]); |
| | | const equipmentPage = reactive({ current: 1, size: 10, total: 0 }); |
| | | const equipmentLoading = ref(false); |
| | | const equipmentColumns = [ |
| | | { label: "设å¤åç§°", prop: "name", align: "center" }, |
| | | { label: "è§æ ¼åå·", prop: "model", align: "center" }, |
| | | { label: "æå±åºå", prop: "area", align: "center" }, |
| | | { label: "ç¶æ", prop: "status", align: "center" }, |
| | | { label: "æå±åºå", prop: "areaName", align: "center" }, |
| | | { |
| | | label: "ç¶æ", |
| | | prop: "status", |
| | | align: "center", |
| | | dataType: "tag", |
| | | formatType: (val) => (val === 1 ? "success" : "danger"), |
| | | formatData: (val) => (val === 1 ? "æ£å¸¸" : "åç¨") |
| | | }, |
| | | { |
| | | label: "æä½", |
| | | prop: "action", |
| | | align: "center", |
| | | dataType: "action", |
| | | operation: [ |
| | | { name: "ç¼è¾", type: "text", clickFun: (row) => handleEditEquipment(row) }, |
| | | { name: "å é¤", type: "text", clickFun: (row) => handleDeleteEquipment(row) } |
| | | ] |
| | | } |
| | | ]; |
| | | |
| | | // ä½ä¸åºå |
| | | const equipmentDialog = reactive({ visible: false, title: "", loading: false }); |
| | | const equipmentFormRef = ref(null); |
| | | const equipmentForm = reactive({ |
| | | id: null, |
| | | name: "", |
| | | model: "", |
| | | areaName: "", |
| | | status: 1, |
| | | remark: "" |
| | | }); |
| | | const equipmentRules = { |
| | | name: [{ required: true, message: "请è¾å
¥è®¾å¤åç§°", trigger: "blur" }] |
| | | }; |
| | | |
| | | // ==================== ä½ä¸åºå ==================== |
| | | const areaFilters = reactive({ name: "" }); |
| | | const areaList = ref([]); |
| | | const areaPage = reactive({ current: 1, size: 10, total: 0 }); |
| | | const areaLoading = ref(false); |
| | | const areaColumns = [ |
| | | { label: "åºååç§°", prop: "name", align: "center" }, |
| | | { label: "ä½ç½®", prop: "location", align: "center" }, |
| | | { label: "è´è´£äºº", prop: "manager", align: "center" }, |
| | | { |
| | | label: "æä½", |
| | | prop: "action", |
| | | align: "center", |
| | | dataType: "action", |
| | | operation: [ |
| | | { name: "ç¼è¾", type: "text", clickFun: (row) => handleEditArea(row) }, |
| | | { name: "å é¤", type: "text", clickFun: (row) => handleDeleteArea(row) } |
| | | ] |
| | | } |
| | | ]; |
| | | |
| | | // å²ä½é£é© |
| | | const areaDialog = reactive({ visible: false, title: "", loading: false }); |
| | | const areaFormRef = ref(null); |
| | | const areaForm = reactive({ |
| | | id: null, |
| | | name: "", |
| | | location: "", |
| | | manager: "", |
| | | remark: "" |
| | | }); |
| | | const areaRules = { |
| | | name: [{ required: true, message: "请è¾å
¥åºååç§°", trigger: "blur" }] |
| | | }; |
| | | |
| | | // ==================== å²ä½é£é© ==================== |
| | | const riskFilters = reactive({ type: "" }); |
| | | const riskList = ref([]); |
| | | const riskPage = reactive({ current: 1, size: 10, total: 0 }); |
| | | const riskLoading = ref(false); |
| | | const riskColumns = [ |
| | | { label: "é£é©ç±»å", prop: "type", align: "center" }, |
| | | { label: "é£é©ç级", prop: "level", align: "center" }, |
| | | { |
| | | label: "é£é©ç级", |
| | | prop: "level", |
| | | align: "center", |
| | | dataType: "tag", |
| | | formatType: (val) => { |
| | | if (val === 'high') return 'danger'; |
| | | if (val === 'medium') return 'warning'; |
| | | return 'success'; |
| | | }, |
| | | formatData: (val) => { |
| | | const map = { high: 'é«', medium: 'ä¸', low: 'ä½' }; |
| | | return map[val] || val; |
| | | } |
| | | }, |
| | | { label: "æè¿°", prop: "description", align: "center" }, |
| | | { |
| | | label: "æä½", |
| | | prop: "action", |
| | | align: "center", |
| | | dataType: "action", |
| | | operation: [ |
| | | { name: "ç¼è¾", type: "text", clickFun: (row) => handleEditRisk(row) }, |
| | | { name: "å é¤", type: "text", clickFun: (row) => handleDeleteRisk(row) } |
| | | ] |
| | | } |
| | | ]; |
| | | |
| | | // åºæ¥èµæº |
| | | const riskDialog = reactive({ visible: false, title: "", loading: false }); |
| | | const riskFormRef = ref(null); |
| | | const riskForm = reactive({ |
| | | id: null, |
| | | type: "", |
| | | level: "", |
| | | description: "", |
| | | post: "", |
| | | controlMeasures: "", |
| | | remark: "" |
| | | }); |
| | | const riskRules = { |
| | | type: [{ required: true, message: "请è¾å
¥é£é©ç±»å", trigger: "blur" }], |
| | | level: [{ required: true, message: "è¯·éæ©é£é©ç级", trigger: "change" }] |
| | | }; |
| | | |
| | | // ==================== åºæ¥èµæº ==================== |
| | | const emergencyFilters = reactive({ name: "" }); |
| | | const emergencyList = ref([]); |
| | | const emergencyPage = reactive({ current: 1, size: 10, total: 0 }); |
| | | const emergencyLoading = ref(false); |
| | | const emergencyColumns = [ |
| | | { label: "èµæºåç§°", prop: "name", align: "center" }, |
| | | { label: "ç±»å", prop: "type", align: "center" }, |
| | | { label: "æ°é", prop: "quantity", align: "center" }, |
| | | { label: "åæ¾ä½ç½®", prop: "location", align: "center" }, |
| | | { |
| | | label: "ç¶æ", |
| | | prop: "status", |
| | | align: "center", |
| | | dataType: "tag", |
| | | formatType: (val) => (val === 1 ? "success" : "danger"), |
| | | formatData: (val) => (val === 1 ? "æ£å¸¸" : "缺失") |
| | | }, |
| | | { |
| | | label: "æä½", |
| | | prop: "action", |
| | | align: "center", |
| | | dataType: "action", |
| | | operation: [ |
| | | { name: "ç¼è¾", type: "text", clickFun: (row) => handleEditEmergency(row) }, |
| | | { name: "å é¤", type: "text", clickFun: (row) => handleDeleteEmergency(row) } |
| | | ] |
| | | } |
| | | ]; |
| | | |
| | | const handleTabChange = () => { |
| | | // 忢tabæ¶å è½½å¯¹åºæ°æ® |
| | | const emergencyDialog = reactive({ visible: false, title: "", loading: false }); |
| | | const emergencyFormRef = ref(null); |
| | | const emergencyForm = reactive({ |
| | | id: null, |
| | | name: "", |
| | | type: "", |
| | | quantity: 0, |
| | | areaName: "", |
| | | location: "", |
| | | manager: "", |
| | | status: 1, |
| | | remark: "" |
| | | }); |
| | | const emergencyRules = { |
| | | name: [{ required: true, message: "请è¾å
¥èµæºåç§°", trigger: "blur" }], |
| | | type: [{ required: true, message: "请è¾å
¥èµæºç±»å", trigger: "blur" }] |
| | | }; |
| | | |
| | | const getPersonnelData = () => {}; |
| | | const resetPersonnelFilters = () => { personnelFilters.name = ""; personnelFilters.dept = ""; }; |
| | | const addPersonnel = () => {}; |
| | | const changePersonnelPage = ({ page, limit }) => { personnelPage.current = page; personnelPage.size = limit; }; |
| | | // ==================== éç¨æ¹æ³ ==================== |
| | | const loadData = () => { |
| | | switch (activeTab.value) { |
| | | case 'personnel': |
| | | getPersonnelData(); |
| | | break; |
| | | case 'equipment': |
| | | getEquipmentData(); |
| | | break; |
| | | case 'workArea': |
| | | getAreaData(); |
| | | break; |
| | | case 'risk': |
| | | getRiskData(); |
| | | break; |
| | | case 'emergency': |
| | | getEmergencyData(); |
| | | break; |
| | | } |
| | | }; |
| | | |
| | | const getEquipmentData = () => {}; |
| | | const resetEquipmentFilters = () => { equipmentFilters.name = ""; equipmentFilters.area = ""; }; |
| | | const addEquipment = () => {}; |
| | | const changeEquipmentPage = ({ page, limit }) => { equipmentPage.current = page; equipmentPage.size = limit; }; |
| | | const handleTabChange = () => { |
| | | loadData(); |
| | | }; |
| | | |
| | | const getAreaData = () => {}; |
| | | const resetAreaFilters = () => { areaFilters.name = ""; }; |
| | | const addArea = () => {}; |
| | | const changeAreaPage = ({ page, limit }) => { areaPage.current = page; areaPage.size = limit; }; |
| | | |
| | | const getRiskData = () => {}; |
| | | const resetRiskFilters = () => { riskFilters.type = ""; }; |
| | | const addRisk = () => {}; |
| | | const changeRiskPage = ({ page, limit }) => { riskPage.current = page; riskPage.size = limit; }; |
| | | |
| | | const getEmergencyData = () => {}; |
| | | const resetEmergencyFilters = () => { emergencyFilters.name = ""; }; |
| | | const addEmergency = () => {}; |
| | | const changeEmergencyPage = ({ page, limit }) => { emergencyPage.current = page; emergencyPage.size = limit; }; |
| | | // ==================== äººåæ¡£æ¡æ¹æ³ ==================== |
| | | const getPersonnelData = async () => { |
| | | personnelLoading.value = true; |
| | | try { |
| | | const res = await getPersonnelList({ |
| | | pageNum: personnelPage.current, |
| | | pageSize: personnelPage.size, |
| | | ...personnelFilters |
| | | }); |
| | | if (res.code === 200) { |
| | | personnelList.value = res.data.rows || res.data.records || []; |
| | | personnelPage.total = res.data.total || 0; |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·åäººåæ¡£æ¡å¤±è´¥'); |
| | | } finally { |
| | | personnelLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const resetPersonnelFilters = () => { |
| | | personnelFilters.name = ""; |
| | | personnelFilters.dept = ""; |
| | | personnelPage.current = 1; |
| | | getPersonnelData(); |
| | | }; |
| | | |
| | | const changePersonnelPage = ({ page, limit }) => { |
| | | personnelPage.current = page; |
| | | personnelPage.size = limit; |
| | | getPersonnelData(); |
| | | }; |
| | | |
| | | const resetPersonnelForm = () => { |
| | | personnelForm.id = null; |
| | | personnelForm.name = ""; |
| | | personnelForm.dept = ""; |
| | | personnelForm.post = ""; |
| | | personnelForm.phone = ""; |
| | | personnelForm.entryDate = ""; |
| | | personnelForm.status = 1; |
| | | personnelForm.remark = ""; |
| | | }; |
| | | |
| | | const addPersonnel = () => { |
| | | resetPersonnelForm(); |
| | | personnelDialog.title = "æ°å¢äººåæ¡£æ¡"; |
| | | personnelDialog.visible = true; |
| | | }; |
| | | |
| | | const handleEditPersonnel = async (row) => { |
| | | resetPersonnelForm(); |
| | | try { |
| | | const res = await getPersonnelDetail(row.id); |
| | | if (res.code === 200) { |
| | | Object.assign(personnelForm, res.data); |
| | | personnelDialog.title = "ç¼è¾äººåæ¡£æ¡"; |
| | | personnelDialog.visible = true; |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·åäººåæ¡£æ¡è¯¦æ
失败'); |
| | | } |
| | | }; |
| | | |
| | | const handleDeletePersonnel = (row) => { |
| | | ElMessageBox.confirm(`确认å é¤äººå "${row.name}" åï¼`, "æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning" |
| | | }).then(async () => { |
| | | try { |
| | | const res = await deletePersonnel(row.id); |
| | | if (res.code === 200) { |
| | | ElMessage.success("å 餿å"); |
| | | getPersonnelData(); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error("å é¤å¤±è´¥"); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const submitPersonnelForm = async () => { |
| | | const valid = await personnelFormRef.value.validate().catch(() => false); |
| | | if (!valid) return; |
| | | |
| | | personnelDialog.loading = true; |
| | | try { |
| | | const api = personnelForm.id ? updatePersonnel : addPersonnelApi; |
| | | const res = await api(personnelForm); |
| | | if (res.code === 200) { |
| | | ElMessage.success(personnelForm.id ? "ä¿®æ¹æå" : "æ°å¢æå"); |
| | | personnelDialog.visible = false; |
| | | getPersonnelData(); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error(personnelForm.id ? "ä¿®æ¹å¤±è´¥" : "æ°å¢å¤±è´¥"); |
| | | } finally { |
| | | personnelDialog.loading = false; |
| | | } |
| | | }; |
| | | |
| | | // ==================== 设å¤è®¾æ½æ¹æ³ ==================== |
| | | const getEquipmentData = async () => { |
| | | equipmentLoading.value = true; |
| | | try { |
| | | const res = await getEquipmentList({ |
| | | pageNum: equipmentPage.current, |
| | | pageSize: equipmentPage.size, |
| | | ...equipmentFilters |
| | | }); |
| | | if (res.code === 200) { |
| | | equipmentList.value = res.data.rows || res.data.records || []; |
| | | equipmentPage.total = res.data.total || 0; |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·å设å¤è®¾æ½å¤±è´¥'); |
| | | } finally { |
| | | equipmentLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const resetEquipmentFilters = () => { |
| | | equipmentFilters.name = ""; |
| | | equipmentFilters.areaName = ""; |
| | | equipmentPage.current = 1; |
| | | getEquipmentData(); |
| | | }; |
| | | |
| | | const changeEquipmentPage = ({ page, limit }) => { |
| | | equipmentPage.current = page; |
| | | equipmentPage.size = limit; |
| | | getEquipmentData(); |
| | | }; |
| | | |
| | | const resetEquipmentForm = () => { |
| | | equipmentForm.id = null; |
| | | equipmentForm.name = ""; |
| | | equipmentForm.model = ""; |
| | | equipmentForm.areaName = ""; |
| | | equipmentForm.status = 1; |
| | | equipmentForm.remark = ""; |
| | | }; |
| | | |
| | | const addEquipment = () => { |
| | | resetEquipmentForm(); |
| | | equipmentDialog.title = "æ°å¢è®¾å¤è®¾æ½"; |
| | | equipmentDialog.visible = true; |
| | | }; |
| | | |
| | | const handleEditEquipment = async (row) => { |
| | | resetEquipmentForm(); |
| | | try { |
| | | const res = await getEquipmentDetail(row.id); |
| | | if (res.code === 200) { |
| | | Object.assign(equipmentForm, res.data); |
| | | equipmentDialog.title = "ç¼è¾è®¾å¤è®¾æ½"; |
| | | equipmentDialog.visible = true; |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·å设å¤è¯¦æ
失败'); |
| | | } |
| | | }; |
| | | |
| | | const handleDeleteEquipment = (row) => { |
| | | ElMessageBox.confirm(`确认å é¤è®¾å¤ "${row.name}" åï¼`, "æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning" |
| | | }).then(async () => { |
| | | try { |
| | | const res = await deleteEquipment(row.id); |
| | | if (res.code === 200) { |
| | | ElMessage.success("å 餿å"); |
| | | getEquipmentData(); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error("å é¤å¤±è´¥"); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const submitEquipmentForm = async () => { |
| | | const valid = await equipmentFormRef.value.validate().catch(() => false); |
| | | if (!valid) return; |
| | | |
| | | equipmentDialog.loading = true; |
| | | try { |
| | | const api = equipmentForm.id ? updateEquipment : addEquipmentApi; |
| | | const res = await api(equipmentForm); |
| | | if (res.code === 200) { |
| | | ElMessage.success(equipmentForm.id ? "ä¿®æ¹æå" : "æ°å¢æå"); |
| | | equipmentDialog.visible = false; |
| | | getEquipmentData(); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error(equipmentForm.id ? "ä¿®æ¹å¤±è´¥" : "æ°å¢å¤±è´¥"); |
| | | } finally { |
| | | equipmentDialog.loading = false; |
| | | } |
| | | }; |
| | | |
| | | // ==================== ä½ä¸åºåæ¹æ³ ==================== |
| | | const getAreaData = async () => { |
| | | areaLoading.value = true; |
| | | try { |
| | | const res = await getWorkAreaList({ |
| | | pageNum: areaPage.current, |
| | | pageSize: areaPage.size, |
| | | ...areaFilters |
| | | }); |
| | | if (res.code === 200) { |
| | | areaList.value = res.data.rows || res.data.records || []; |
| | | areaPage.total = res.data.total || 0; |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·åä½ä¸åºå失败'); |
| | | } finally { |
| | | areaLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const resetAreaFilters = () => { |
| | | areaFilters.name = ""; |
| | | areaPage.current = 1; |
| | | getAreaData(); |
| | | }; |
| | | |
| | | const changeAreaPage = ({ page, limit }) => { |
| | | areaPage.current = page; |
| | | areaPage.size = limit; |
| | | getAreaData(); |
| | | }; |
| | | |
| | | const resetAreaForm = () => { |
| | | areaForm.id = null; |
| | | areaForm.name = ""; |
| | | areaForm.location = ""; |
| | | areaForm.manager = ""; |
| | | areaForm.remark = ""; |
| | | }; |
| | | |
| | | const addArea = () => { |
| | | resetAreaForm(); |
| | | areaDialog.title = "æ°å¢ä½ä¸åºå"; |
| | | areaDialog.visible = true; |
| | | }; |
| | | |
| | | const handleEditArea = async (row) => { |
| | | resetAreaForm(); |
| | | try { |
| | | const res = await getWorkAreaDetail(row.id); |
| | | if (res.code === 200) { |
| | | Object.assign(areaForm, res.data); |
| | | areaDialog.title = "ç¼è¾ä½ä¸åºå"; |
| | | areaDialog.visible = true; |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·åä½ä¸åºå详æ
失败'); |
| | | } |
| | | }; |
| | | |
| | | const handleDeleteArea = (row) => { |
| | | ElMessageBox.confirm(`确认å é¤åºå "${row.name}" åï¼`, "æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning" |
| | | }).then(async () => { |
| | | try { |
| | | const res = await deleteWorkArea(row.id); |
| | | if (res.code === 200) { |
| | | ElMessage.success("å 餿å"); |
| | | getAreaData(); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error("å é¤å¤±è´¥"); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const submitAreaForm = async () => { |
| | | const valid = await areaFormRef.value.validate().catch(() => false); |
| | | if (!valid) return; |
| | | |
| | | areaDialog.loading = true; |
| | | try { |
| | | const api = areaForm.id ? updateWorkArea : addWorkAreaApi; |
| | | const res = await api(areaForm); |
| | | if (res.code === 200) { |
| | | ElMessage.success(areaForm.id ? "ä¿®æ¹æå" : "æ°å¢æå"); |
| | | areaDialog.visible = false; |
| | | getAreaData(); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error(areaForm.id ? "ä¿®æ¹å¤±è´¥" : "æ°å¢å¤±è´¥"); |
| | | } finally { |
| | | areaDialog.loading = false; |
| | | } |
| | | }; |
| | | |
| | | // ==================== å²ä½é£é©æ¹æ³ ==================== |
| | | const getRiskData = async () => { |
| | | riskLoading.value = true; |
| | | try { |
| | | const res = await getRiskList({ |
| | | pageNum: riskPage.current, |
| | | pageSize: riskPage.size, |
| | | ...riskFilters |
| | | }); |
| | | if (res.code === 200) { |
| | | riskList.value = res.data.rows || res.data.records || []; |
| | | riskPage.total = res.data.total || 0; |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·åå²ä½é£é©å¤±è´¥'); |
| | | } finally { |
| | | riskLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const resetRiskFilters = () => { |
| | | riskFilters.type = ""; |
| | | riskPage.current = 1; |
| | | getRiskData(); |
| | | }; |
| | | |
| | | const changeRiskPage = ({ page, limit }) => { |
| | | riskPage.current = page; |
| | | riskPage.size = limit; |
| | | getRiskData(); |
| | | }; |
| | | |
| | | const resetRiskForm = () => { |
| | | riskForm.id = null; |
| | | riskForm.type = ""; |
| | | riskForm.level = ""; |
| | | riskForm.description = ""; |
| | | riskForm.post = ""; |
| | | riskForm.controlMeasures = ""; |
| | | riskForm.remark = ""; |
| | | }; |
| | | |
| | | const addRisk = () => { |
| | | resetRiskForm(); |
| | | riskDialog.title = "æ°å¢å²ä½é£é©"; |
| | | riskDialog.visible = true; |
| | | }; |
| | | |
| | | const handleEditRisk = async (row) => { |
| | | resetRiskForm(); |
| | | try { |
| | | const res = await getRiskDetail(row.id); |
| | | if (res.code === 200) { |
| | | Object.assign(riskForm, res.data); |
| | | riskDialog.title = "ç¼è¾å²ä½é£é©"; |
| | | riskDialog.visible = true; |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·åå²ä½é£é©è¯¦æ
失败'); |
| | | } |
| | | }; |
| | | |
| | | const handleDeleteRisk = (row) => { |
| | | ElMessageBox.confirm(`确认å é¤é£é© "${row.type}" åï¼`, "æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning" |
| | | }).then(async () => { |
| | | try { |
| | | const res = await deleteRisk(row.id); |
| | | if (res.code === 200) { |
| | | ElMessage.success("å 餿å"); |
| | | getRiskData(); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error("å é¤å¤±è´¥"); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const submitRiskForm = async () => { |
| | | const valid = await riskFormRef.value.validate().catch(() => false); |
| | | if (!valid) return; |
| | | |
| | | riskDialog.loading = true; |
| | | try { |
| | | const api = riskForm.id ? updateRisk : addRiskApi; |
| | | const res = await api(riskForm); |
| | | if (res.code === 200) { |
| | | ElMessage.success(riskForm.id ? "ä¿®æ¹æå" : "æ°å¢æå"); |
| | | riskDialog.visible = false; |
| | | getRiskData(); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error(riskForm.id ? "ä¿®æ¹å¤±è´¥" : "æ°å¢å¤±è´¥"); |
| | | } finally { |
| | | riskDialog.loading = false; |
| | | } |
| | | }; |
| | | |
| | | // ==================== åºæ¥èµæºæ¹æ³ ==================== |
| | | const getEmergencyData = async () => { |
| | | emergencyLoading.value = true; |
| | | try { |
| | | const res = await getEmergencyList({ |
| | | pageNum: emergencyPage.current, |
| | | pageSize: emergencyPage.size, |
| | | ...emergencyFilters |
| | | }); |
| | | if (res.code === 200) { |
| | | emergencyList.value = res.data.rows || res.data.records || []; |
| | | emergencyPage.total = res.data.total || 0; |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·ååºæ¥èµæºå¤±è´¥'); |
| | | } finally { |
| | | emergencyLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const resetEmergencyFilters = () => { |
| | | emergencyFilters.name = ""; |
| | | emergencyPage.current = 1; |
| | | getEmergencyData(); |
| | | }; |
| | | |
| | | const changeEmergencyPage = ({ page, limit }) => { |
| | | emergencyPage.current = page; |
| | | emergencyPage.size = limit; |
| | | getEmergencyData(); |
| | | }; |
| | | |
| | | const resetEmergencyForm = () => { |
| | | emergencyForm.id = null; |
| | | emergencyForm.name = ""; |
| | | emergencyForm.type = ""; |
| | | emergencyForm.quantity = 0; |
| | | emergencyForm.areaName = ""; |
| | | emergencyForm.location = ""; |
| | | emergencyForm.manager = ""; |
| | | emergencyForm.status = 1; |
| | | emergencyForm.remark = ""; |
| | | }; |
| | | |
| | | const addEmergency = () => { |
| | | resetEmergencyForm(); |
| | | emergencyDialog.title = "æ°å¢åºæ¥èµæº"; |
| | | emergencyDialog.visible = true; |
| | | }; |
| | | |
| | | const handleEditEmergency = async (row) => { |
| | | resetEmergencyForm(); |
| | | try { |
| | | const res = await getEmergencyDetail(row.id); |
| | | if (res.code === 200) { |
| | | Object.assign(emergencyForm, res.data); |
| | | emergencyDialog.title = "ç¼è¾åºæ¥èµæº"; |
| | | emergencyDialog.visible = true; |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·ååºæ¥èµæºè¯¦æ
失败'); |
| | | } |
| | | }; |
| | | |
| | | const handleDeleteEmergency = (row) => { |
| | | ElMessageBox.confirm(`确认å é¤èµæº "${row.name}" åï¼`, "æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning" |
| | | }).then(async () => { |
| | | try { |
| | | const res = await deleteEmergency(row.id); |
| | | if (res.code === 200) { |
| | | ElMessage.success("å 餿å"); |
| | | getEmergencyData(); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error("å é¤å¤±è´¥"); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const submitEmergencyForm = async () => { |
| | | const valid = await emergencyFormRef.value.validate().catch(() => false); |
| | | if (!valid) return; |
| | | |
| | | emergencyDialog.loading = true; |
| | | try { |
| | | const api = emergencyForm.id ? updateEmergency : addEmergencyApi; |
| | | const res = await api(emergencyForm); |
| | | if (res.code === 200) { |
| | | ElMessage.success(emergencyForm.id ? "ä¿®æ¹æå" : "æ°å¢æå"); |
| | | emergencyDialog.visible = false; |
| | | getEmergencyData(); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error(emergencyForm.id ? "ä¿®æ¹å¤±è´¥" : "æ°å¢å¤±è´¥"); |
| | | } finally { |
| | | emergencyDialog.loading = false; |
| | | } |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getPersonnelData(); |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | |
| | | <el-divider /> |
| | | <div class="stat-item"> |
| | | <span class="label">已宿å¹è®</span> |
| | | <span class="value">{{ userInfo.completedTrainings }} 次</span> |
| | | <span class="value">{{ statistics.completedTrainings }} 次</span> |
| | | </div> |
| | | <div class="stat-item"> |
| | | <span class="label">å¾
åå å¹è®</span> |
| | | <span class="value">{{ userInfo.pendingTrainings }} 次</span> |
| | | <span class="value">{{ statistics.pendingTrainings }} 次</span> |
| | | </div> |
| | | <div class="stat-item"> |
| | | <span class="label">å¹³åèæ ¸åæ°</span> |
| | | <span class="value">{{ userInfo.avgScore }} å</span> |
| | | <span class="value">{{ statistics.avgScore }} å</span> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="18"> |
| | | <el-tabs v-model="activeTab" type="border-card"> |
| | | <el-tab-pane label="æçå¦ä¹ è®°å½" name="records"> |
| | | <PIMTable :column="recordColumns" :tableData="recordList" :page="recordPage" @pagination="changeRecordPage" /> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="èæ ¸æ¥å" name="reports"> |
| | | <PIMTable :column="reportColumns" :tableData="reportList" :page="reportPage" @pagination="changeReportPage" /> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="å¨çº¿æµè¯" name="assessment"> |
| | | <div class="assessment-list"> |
| | | <el-card v-for="item in assessmentList" :key="item.id" class="assessment-card"> |
| | | <div class="assessment-header"> |
| | | <h4>{{ item.title }}</h4> |
| | | <el-tag :type="item.status === 'å¾
æµè¯' ? 'warning' : 'success'">{{ item.status }}</el-tag> |
| | | </div> |
| | | <p class="assessment-desc">{{ item.description }}</p> |
| | | <div class="assessment-footer"> |
| | | <span>æªæ¢æ¶é´ï¼{{ item.deadline }}</span> |
| | | <el-button type="primary" size="small" :disabled="item.status !== 'å¾
æµè¯'" @click="startAssessment(item)"> |
| | | {{ item.status === 'å¾
æµè¯' ? 'å¼å§æµè¯' : '已宿' }} |
| | | </el-button> |
| | | </div> |
| | | </el-card> |
| | | </div> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | <el-card> |
| | | <template #header> |
| | | <span>æçå¦ä¹ è®°å½</span> |
| | | </template> |
| | | <PIMTable :column="recordColumns" :tableData="recordList" :page="recordPage" @pagination="changeRecordPage" :tableLoading="recordLoading" /> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive } from "vue"; |
| | | import { ref, reactive, onMounted, computed } from "vue"; |
| | | import PIMTable from "@/components/PIMTable/PIMTable.vue"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { |
| | | getRecordList |
| | | } from "@/api/safetyManagement/trainingManage.js"; |
| | | import { ElMessage } from "element-plus"; |
| | | |
| | | defineOptions({ |
| | | name: "åå·¥å¦ä¹ ", |
| | | }); |
| | | |
| | | const activeTab = ref("records"); |
| | | const userStore = useUserStore(); |
| | | |
| | | const userInfo = reactive({ |
| | | name: "å¼ ä¸", |
| | | dept: "ç产é¨", |
| | | post: "æä½å·¥", |
| | | avatar: "", |
| | | completedTrainings: 12, |
| | | pendingTrainings: 3, |
| | | avgScore: 85, |
| | | const userInfo = computed(() => ({ |
| | | name: userStore.name || "-", |
| | | dept: userStore.currentFactoryName || "-", |
| | | post: userStore.roleName || "-", |
| | | avatar: userStore.avatar || "", |
| | | })); |
| | | |
| | | const statistics = reactive({ |
| | | completedTrainings: 0, |
| | | pendingTrainings: 0, |
| | | avgScore: 0, |
| | | }); |
| | | |
| | | // å¦ä¹ è®°å½ |
| | | // å¦ä¹ è®°å½ï¼æ¥èªå¹è®å®æè®°å½ï¼ |
| | | const recordList = ref([]); |
| | | const recordPage = reactive({ current: 1, size: 10, total: 0 }); |
| | | const recordLoading = ref(false); |
| | | const recordColumns = [ |
| | | { label: "å¹è®å
容", prop: "content", align: "center" }, |
| | | { label: "å¹è®æ¶é´", prop: "trainingTime", align: "center" }, |
| | | { label: "å¹è®æ¶é¿", prop: "duration", align: "center" }, |
| | | { label: "宿æ¶é´", prop: "completeTime", align: "center" }, |
| | | { label: "å¦ä¹ æ¶é¿", prop: "duration", align: "center" }, |
| | | { label: "å¹è®æ¹å¼", prop: "method", align: "center" }, |
| | | { label: "å®æç¶æ", prop: "status", align: "center" }, |
| | | { label: "åæ°", prop: "score", align: "center" }, |
| | | { |
| | | label: "èæ ¸ç»æ", |
| | | prop: "result", |
| | | align: "center", |
| | | dataType: "tag", |
| | | formatType: (val) => { |
| | | if (val === 'éè¿') return 'success'; |
| | | if (val === 'æªéè¿') return 'danger'; |
| | | return 'info'; |
| | | }, |
| | | formatData: (val) => val || '-' |
| | | } |
| | | ]; |
| | | |
| | | // èæ ¸æ¥å |
| | | const reportList = ref([]); |
| | | const reportPage = reactive({ current: 1, size: 10, total: 0 }); |
| | | const reportColumns = [ |
| | | { label: "èæ ¸åç§°", prop: "name", align: "center" }, |
| | | { label: "èæ ¸æ¶é´", prop: "assessTime", align: "center" }, |
| | | { label: "å¾å", prop: "score", align: "center" }, |
| | | { label: "ç级", prop: "grade", align: "center" }, |
| | | { label: "æ¯å¦åæ ¼", prop: "qualified", align: "center" }, |
| | | ]; |
| | | |
| | | // å¨çº¿æµè¯ |
| | | const assessmentList = ref([ |
| | | { id: 1, title: "å®å
¨æä½è§ç¨æµè¯", description: "èæ ¸å工对å®å
¨æä½è§ç¨çææ¡ç¨åº¦", deadline: "2026-05-30", status: "å¾
æµè¯" }, |
| | | { id: 2, title: "åºæ¥å¤ç½®è½åæµè¯", description: "èæ ¸åå·¥åºæ¥å¤ç½®è½å", deadline: "2026-06-15", status: "已宿" }, |
| | | ]); |
| | | |
| | | const changeRecordPage = ({ page, limit }) => { recordPage.current = page; recordPage.size = limit; }; |
| | | const changeReportPage = ({ page, limit }) => { reportPage.current = page; reportPage.size = limit; }; |
| | | const startAssessment = (item) => {}; |
| | | // 计ç®ç»è®¡æ°æ® |
| | | const calculateStatistics = (records) => { |
| | | const completedTrainings = records.filter(r => r.status === 1).length; |
| | | const pendingTrainings = records.filter(r => r.status === 0).length; |
| | | const scores = records.filter(r => r.score > 0).map(r => r.score); |
| | | const avgScore = scores.length > 0 ? (scores.reduce((a, b) => a + b, 0) / scores.length).toFixed(1) : 0; |
| | | |
| | | statistics.completedTrainings = completedTrainings; |
| | | statistics.pendingTrainings = pendingTrainings; |
| | | statistics.avgScore = avgScore; |
| | | }; |
| | | |
| | | // å¦ä¹ è®°å½æ¹æ³ï¼æ¥è¯¢å½åç¨æ·çå®æè®°å½ï¼ |
| | | const getRecordData = async () => { |
| | | recordLoading.value = true; |
| | | try { |
| | | const res = await getRecordList({ |
| | | pageNum: recordPage.current, |
| | | pageSize: recordPage.size, |
| | | employeeId: userStore.userId // åªæ¥è¯¢å½åç¨æ·çæ°æ® |
| | | }); |
| | | if (res.code === 200) { |
| | | recordList.value = res.data.rows || res.data.records || []; |
| | | recordPage.total = res.data.total || 0; |
| | | // æ ¹æ®æ¥è¯¢å°çæ°æ®è®¡ç®ç»è®¡ |
| | | calculateStatistics(recordList.value); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·åå¦ä¹ è®°å½å¤±è´¥'); |
| | | } finally { |
| | | recordLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const changeRecordPage = ({ page, limit }) => { |
| | | recordPage.current = page; |
| | | recordPage.size = limit; |
| | | getRecordData(); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getRecordData(); |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | |
| | | } |
| | | } |
| | | |
| | | .assessment-list { |
| | | .assessment-card { |
| | | margin-bottom: 15px; |
| | | .assessment-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | h4 { |
| | | margin: 0; |
| | | } |
| | | } |
| | | .assessment-desc { |
| | | color: #666; |
| | | margin: 10px 0; |
| | | } |
| | | .assessment-footer { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | span { |
| | | color: #999; |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ"> |
| | | <el-select v-model="filters.status" placeholder="è¯·éæ©" clearable style="width: 150px"> |
| | | <el-option label="æ£å¸¸" value="normal" /> |
| | | <el-option label="å¼å¸¸" value="abnormal" /> |
| | | <el-option label="æ¼æ£" value="missed" /> |
| | | <el-option label="æªæ§è¡" value="unexecuted" /> |
| | | <el-option label="æ£å¸¸" :value="0" /> |
| | | <el-option label="å¼å¸¸" :value="1" /> |
| | | <el-option label="æ¼æ£" :value="2" /> |
| | | <el-option label="æªæ§è¡" :value="3" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="getData">æç´¢</el-button> |
| | | <el-button @click="resetFilters">éç½®</el-button> |
| | | <el-button type="success" @click="handleSyncData" icon="Refresh">åæ¥æ°æ®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <PIMTable :column="columns" :tableData="dataList" :page="pagination" @pagination="changePage" /> |
| | | <PIMTable :column="columns" :tableData="dataList" :page="pagination" @pagination="changePage" :tableLoading="tableLoading" /> |
| | | </el-card> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ref, reactive, onMounted, nextTick } from "vue"; |
| | | import PIMTable from "@/components/PIMTable/PIMTable.vue"; |
| | | import * as echarts from "echarts"; |
| | | import { |
| | | getInspectionRecordList, |
| | | getTodayStatistics, |
| | | getTrendStatistics, |
| | | getTypeStatistics, |
| | | syncInspectionData |
| | | } from "@/api/safetyManagement/inspectionReport.js"; |
| | | import { ElMessage } from "element-plus"; |
| | | import dayjs from "dayjs"; |
| | | |
| | | defineOptions({ |
| | | name: "å·¡æ£æ°æ®æ¥è¡¨", |
| | | }); |
| | | |
| | | const todayStats = reactive({ |
| | | completionRate: 95, |
| | | inspectorCount: 8, |
| | | abnormalCount: 2, |
| | | missedCount: 1, |
| | | completionRate: 0, |
| | | inspectorCount: 0, |
| | | abnormalCount: 0, |
| | | missedCount: 0, |
| | | }); |
| | | |
| | | const filters = reactive({ |
| | | dateRange: [], |
| | | inspector: "", |
| | | status: "", |
| | | status: null, |
| | | }); |
| | | |
| | | const dataList = ref([]); |
| | | const pagination = reactive({ current: 1, size: 10, total: 0 }); |
| | | const tableLoading = ref(false); |
| | | |
| | | const columns = [ |
| | | { label: "å·¡æ£æ¶é´", prop: "inspectionTime", align: "center" }, |
| | | { label: "å·¡æ£äººå", prop: "inspector", align: "center" }, |
| | | { label: "å·¡æ£åºå", prop: "area", align: "center" }, |
| | | { label: "å·¡æ£ç±»å", prop: "type", align: "center" }, |
| | | { label: "ç¶æ", prop: "status", align: "center" }, |
| | | { |
| | | label: "å·¡æ£ç±»å", |
| | | prop: "type", |
| | | align: "center", |
| | | formatData: (val) => { |
| | | const typeMap = { |
| | | 'daily': 'æ¥å¸¸å·¡æ£', |
| | | 'equipment': '设å¤å·¡æ£', |
| | | 'fire': 'æ¶é²å·¡æ£', |
| | | 'night': 'å¤é´å·¡æ£', |
| | | 'safety': 'å®å
¨å·¡æ£', |
| | | 'environment': 'ç¯å¢å·¡æ£' |
| | | }; |
| | | return typeMap[val] || val; |
| | | } |
| | | }, |
| | | { |
| | | label: "ç¶æ", |
| | | prop: "status", |
| | | align: "center", |
| | | dataType: "tag", |
| | | formatType: (val) => { |
| | | if (val === 0) return 'success'; |
| | | if (val === 1) return 'danger'; |
| | | if (val === 2) return 'warning'; |
| | | return 'info'; |
| | | }, |
| | | formatData: (val) => { |
| | | const statusMap = { 0: 'æ£å¸¸', 1: 'å¼å¸¸', 2: 'æ¼æ£', 3: 'æªæ§è¡' }; |
| | | return statusMap[val] || val; |
| | | } |
| | | }, |
| | | { label: "å¼å¸¸æ
åµ", prop: "abnormalDesc", align: "center" }, |
| | | ]; |
| | | |
| | | const trendChartRef = ref(null); |
| | | const typeChartRef = ref(null); |
| | | let trendChart = null; |
| | | let typeChart = null; |
| | | |
| | | onMounted(() => { |
| | | initTrendChart(); |
| | | initTypeChart(); |
| | | getTodayStats(); |
| | | getData(); |
| | | nextTick(() => { |
| | | initTrendChart(); |
| | | initTypeChart(); |
| | | }); |
| | | }); |
| | | |
| | | const initTrendChart = () => { |
| | | const chart = echarts.init(trendChartRef.value); |
| | | const option = { |
| | | xAxis: { |
| | | type: "category", |
| | | data: ["å¨ä¸", "å¨äº", "å¨ä¸", "å¨å", "å¨äº", "å¨å
", "卿¥"], |
| | | }, |
| | | yAxis: { type: "value" }, |
| | | series: [ |
| | | { name: "已宿", type: "line", data: [120, 132, 101, 134, 90, 230, 210], smooth: true }, |
| | | { name: "æªå®æ", type: "line", data: [20, 12, 21, 14, 30, 20, 10], smooth: true }, |
| | | ], |
| | | legend: { data: ["已宿", "æªå®æ"], bottom: 0 }, |
| | | grid: { left: "3%", right: "4%", bottom: "10%", containLabel: true }, |
| | | }; |
| | | chart.setOption(option); |
| | | // è·å仿¥ç»è®¡ |
| | | const getTodayStats = async () => { |
| | | try { |
| | | const res = await getTodayStatistics(); |
| | | if (res.code === 200) { |
| | | Object.assign(todayStats, res.data); |
| | | } |
| | | } catch (error) { |
| | | console.error('è·å仿¥ç»è®¡å¤±è´¥', error); |
| | | } |
| | | }; |
| | | |
| | | const initTypeChart = () => { |
| | | const chart = echarts.init(typeChartRef.value); |
| | | const option = { |
| | | series: [ |
| | | { |
| | | type: "pie", |
| | | radius: ["40%", "70%"], |
| | | data: [ |
| | | { value: 335, name: "设å¤å·¡æ£" }, |
| | | { value: 310, name: "å®å
¨å·¡æ£" }, |
| | | { value: 234, name: "ç¯å¢å·¡æ£" }, |
| | | { value: 135, name: "æ¶é²å·¡æ£" }, |
| | | ], |
| | | // åå§åè¶å¿å¾è¡¨ |
| | | const initTrendChart = async () => { |
| | | if (!trendChartRef.value) return; |
| | | |
| | | trendChart = echarts.init(trendChartRef.value); |
| | | |
| | | try { |
| | | const endDate = dayjs().format('YYYY-MM-DD'); |
| | | const startDate = dayjs().subtract(6, 'day').format('YYYY-MM-DD'); |
| | | const res = await getTrendStatistics({ startDate, endDate }); |
| | | |
| | | let dates = []; |
| | | let completedData = []; |
| | | let abnormalData = []; |
| | | let missedData = []; |
| | | let unexecutedData = []; |
| | | |
| | | if (res.code === 200 && Array.isArray(res.data)) { |
| | | // ææ¥ææåº |
| | | const sortedData = res.data.sort((a, b) => a.statDate.localeCompare(b.statDate)); |
| | | dates = sortedData.map(item => dayjs(item.statDate).format('MM-DD')); |
| | | completedData = sortedData.map(item => item.completedCount || 0); |
| | | abnormalData = sortedData.map(item => item.abnormalCount || 0); |
| | | missedData = sortedData.map(item => item.missedCount || 0); |
| | | unexecutedData = sortedData.map(item => item.unexecutedCount || 0); |
| | | } else { |
| | | // 使ç¨é»è®¤æ°æ® |
| | | for (let i = 6; i >= 0; i--) { |
| | | dates.push(dayjs().subtract(i, 'day').format('MM-DD')); |
| | | } |
| | | completedData = [2, 1, 2, 2, 1, 4, 3]; |
| | | abnormalData = [1, 0, 0, 1, 0, 1, 0]; |
| | | missedData = [0, 0, 1, 0, 0, 1, 0]; |
| | | unexecutedData = [0, 1, 0, 0, 1, 0, 1]; |
| | | } |
| | | |
| | | const option = { |
| | | tooltip: { trigger: 'axis' }, |
| | | xAxis: { |
| | | type: "category", |
| | | data: dates, |
| | | }, |
| | | ], |
| | | legend: { orient: "vertical", left: "left" }, |
| | | }; |
| | | chart.setOption(option); |
| | | yAxis: { type: "value" }, |
| | | series: [ |
| | | { name: "已宿", type: "line", data: completedData, smooth: true }, |
| | | { name: "å¼å¸¸", type: "line", data: abnormalData, smooth: true }, |
| | | { name: "æ¼æ£", type: "line", data: missedData, smooth: true }, |
| | | { name: "æªæ§è¡", type: "line", data: unexecutedData, smooth: true }, |
| | | ], |
| | | legend: { data: ["已宿", "å¼å¸¸", "æ¼æ£", "æªæ§è¡"], bottom: 0 }, |
| | | grid: { left: "3%", right: "4%", bottom: "15%", containLabel: true }, |
| | | }; |
| | | trendChart.setOption(option); |
| | | } catch (error) { |
| | | console.error('è·åè¶å¿æ°æ®å¤±è´¥', error); |
| | | } |
| | | }; |
| | | |
| | | const getData = () => {}; |
| | | // ç±»åæ å° |
| | | const typeMap = { |
| | | 'daily': 'æ¥å¸¸å·¡æ£', |
| | | 'equipment': '设å¤å·¡æ£', |
| | | 'fire': 'æ¶é²å·¡æ£', |
| | | 'night': 'å¤é´å·¡æ£', |
| | | 'safety': 'å®å
¨å·¡æ£', |
| | | 'environment': 'ç¯å¢å·¡æ£' |
| | | }; |
| | | |
| | | // åå§åç±»åå¾è¡¨ |
| | | const initTypeChart = async () => { |
| | | if (!typeChartRef.value) return; |
| | | |
| | | typeChart = echarts.init(typeChartRef.value); |
| | | |
| | | try { |
| | | const endDate = dayjs().format('YYYY-MM-DD'); |
| | | const startDate = dayjs().subtract(30, 'day').format('YYYY-MM-DD'); |
| | | const res = await getTypeStatistics({ startDate, endDate }); |
| | | |
| | | let pieData = []; |
| | | |
| | | if (res.code === 200 && Array.isArray(res.data)) { |
| | | pieData = res.data.map(item => ({ |
| | | value: item.count || 0, |
| | | name: typeMap[item.type] || item.type |
| | | })); |
| | | } else { |
| | | // 使ç¨é»è®¤æ°æ® |
| | | pieData = [ |
| | | { value: 8, name: "æ¥å¸¸å·¡æ£" }, |
| | | { value: 4, name: "设å¤å·¡æ£" }, |
| | | { value: 3, name: "æ¶é²å·¡æ£" }, |
| | | { value: 3, name: "å¤é´å·¡æ£" }, |
| | | ]; |
| | | } |
| | | |
| | | const option = { |
| | | tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' }, |
| | | series: [ |
| | | { |
| | | type: "pie", |
| | | radius: ["40%", "70%"], |
| | | data: pieData, |
| | | label: { |
| | | formatter: '{b}\n{c}次 ({d}%)' |
| | | } |
| | | }, |
| | | ], |
| | | legend: { orient: "vertical", left: "left" }, |
| | | }; |
| | | typeChart.setOption(option); |
| | | } catch (error) { |
| | | console.error('è·åç±»åç»è®¡å¤±è´¥', error); |
| | | } |
| | | }; |
| | | |
| | | // è·åå·¡æ£è®°å½å表 |
| | | const getData = async () => { |
| | | tableLoading.value = true; |
| | | try { |
| | | const params = { |
| | | pageNum: pagination.current, |
| | | pageSize: pagination.size, |
| | | inspector: filters.inspector, |
| | | status: filters.status, |
| | | }; |
| | | |
| | | if (filters.dateRange && filters.dateRange.length === 2) { |
| | | params.startDate = filters.dateRange[0]; |
| | | params.endDate = filters.dateRange[1]; |
| | | } |
| | | |
| | | const res = await getInspectionRecordList(params); |
| | | if (res.code === 200) { |
| | | dataList.value = res.data.rows || res.data.records || []; |
| | | pagination.total = res.data.total || 0; |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·åå·¡æ£è®°å½å¤±è´¥'); |
| | | } finally { |
| | | tableLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const resetFilters = () => { |
| | | filters.dateRange = []; |
| | | filters.inspector = ""; |
| | | filters.status = ""; |
| | | filters.status = null; |
| | | pagination.current = 1; |
| | | getData(); |
| | | }; |
| | | |
| | | const changePage = ({ page, limit }) => { |
| | | pagination.current = page; |
| | | pagination.size = limit; |
| | | getData(); |
| | | }; |
| | | |
| | | // åæ¥å·¡æ£æ°æ® |
| | | const handleSyncData = async () => { |
| | | try { |
| | | const res = await syncInspectionData(); |
| | | if (res.code === 200) { |
| | | ElMessage.success(`忥æåï¼æ°å¢ ${res.data?.count || 0} æ¡è®°å½`); |
| | | // å·æ°å表åç»è®¡ |
| | | getData(); |
| | | getTodayStats(); |
| | | initTrendChart(); |
| | | initTypeChart(); |
| | | } else { |
| | | ElMessage.warning(res.msg || 'åæ¥å¤±è´¥'); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error(error.response?.data?.msg || 'åæ¥å¤±è´¥'); |
| | | } |
| | | }; |
| | | |
| | | // çªå£å¤§å°æ¹åæ¶éæ°æ¸²æå¾è¡¨ |
| | | window.addEventListener('resize', () => { |
| | | trendChart && trendChart.resize(); |
| | | typeChart && typeChart.resize(); |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-tabs v-model="activeTab" type="border-card"> |
| | | <el-tabs v-model="activeTab" type="border-card" @tab-change="handleTabChange"> |
| | | <el-tab-pane label="å¹è®èµæ" name="materials"> |
| | | <el-form :model="materialFilters" :inline="true"> |
| | | <el-form-item label="èµæåç§°"> |
| | |
| | | </el-form-item> |
| | | <el-form-item label="èµæç±»å"> |
| | | <el-select v-model="materialFilters.type" placeholder="è¯·éæ©" clearable style="width: 150px"> |
| | | <el-option label="å¶åº¦" value="system" /> |
| | | <el-option label="课件" value="courseware" /> |
| | | <el-option label="è§é¢" value="video" /> |
| | | <el-option label="æ¡ä¾" value="case" /> |
| | | <el-option label="PDF" value="PDF" /> |
| | | <el-option label="å¶åº¦" value="å¶åº¦" /> |
| | | <el-option label="课件" value="课件" /> |
| | | <el-option label="è§é¢" value="è§é¢" /> |
| | | <el-option label="æ¡ä¾" value="æ¡ä¾" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ"> |
| | | <el-select v-model="materialFilters.status" placeholder="è¯·éæ©" clearable style="width: 150px"> |
| | | <el-option label="å¯ç¨" :value="1" /> |
| | | <el-option label="åç¨" :value="0" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | |
| | | </el-form> |
| | | <div class="table_list"> |
| | | <div class="actions"> |
| | | <el-button type="primary" @click="uploadMaterial" icon="Upload">ä¸ä¼ èµæ</el-button> |
| | | <el-button type="primary" @click="openMaterialDialog" icon="Upload">ä¸ä¼ èµæ</el-button> |
| | | </div> |
| | | <PIMTable :column="materialColumns" :tableData="materialList" :page="materialPage" @pagination="changeMaterialPage" /> |
| | | <PIMTable :column="materialColumns" :tableData="materialList" :page="materialPage" @pagination="changeMaterialPage" :tableLoading="materialLoading" /> |
| | | </div> |
| | | </el-tab-pane> |
| | | |
| | |
| | | <el-form-item label="å²ä½"> |
| | | <el-input v-model="planFilters.post" placeholder="请è¾å
¥å²ä½" clearable style="width: 200px" /> |
| | | </el-form-item> |
| | | <el-form-item label="å¹è®ç级"> |
| | | <el-select v-model="planFilters.level" placeholder="è¯·éæ©" clearable style="width: 150px"> |
| | | <el-option label="ä¸çº§" value="ä¸çº§" /> |
| | | <el-option label="äºçº§" value="äºçº§" /> |
| | | <el-option label="ä¸çº§" value="ä¸çº§" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ"> |
| | | <el-select v-model="planFilters.status" placeholder="è¯·éæ©" clearable style="width: 150px"> |
| | | <el-option label="å¾
æ§è¡" :value="0" /> |
| | | <el-option label="æ§è¡ä¸" :value="1" /> |
| | | <el-option label="已宿" :value="2" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="getPlanData">æç´¢</el-button> |
| | | <el-button @click="resetPlanFilters">éç½®</el-button> |
| | |
| | | </el-form> |
| | | <div class="table_list"> |
| | | <div class="actions"> |
| | | <el-button type="primary" @click="addPlan" icon="Plus">å¶å®è®¡å</el-button> |
| | | <el-button type="primary" @click="openPlanDialog" icon="Plus">å¶å®è®¡å</el-button> |
| | | </div> |
| | | <PIMTable :column="planColumns" :tableData="planList" :page="planPage" @pagination="changePlanPage" /> |
| | | <PIMTable :column="planColumns" :tableData="planList" :page="planPage" @pagination="changePlanPage" :tableLoading="planLoading" /> |
| | | </div> |
| | | </el-tab-pane> |
| | | |
| | |
| | | <el-form-item label="åå·¥å§å"> |
| | | <el-input v-model="recordFilters.employeeName" placeholder="请è¾å
¥åå·¥å§å" clearable style="width: 200px" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ"> |
| | | <el-select v-model="recordFilters.status" placeholder="è¯·éæ©" clearable style="width: 150px"> |
| | | <el-option label="已宿" :value="1" /> |
| | | <el-option label="æªå®æ" :value="0" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="getRecordData">æç´¢</el-button> |
| | | <el-button @click="resetRecordFilters">éç½®</el-button> |
| | | <el-button type="primary" @click="openRecordDialog" icon="Plus">æ°å¢</el-button> |
| | | <el-button type="success" @click="exportRecords" icon="Download">导åº</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div class="table_list"> |
| | | <PIMTable :column="recordColumns" :tableData="recordList" :page="recordPage" @pagination="changeRecordPage" /> |
| | | <PIMTable :column="recordColumns" :tableData="recordList" :page="recordPage" @pagination="changeRecordPage" :tableLoading="recordLoading" /> |
| | | </div> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | |
| | | <!-- å¹è®èµæå¼¹çª --> |
| | | <el-dialog :title="materialDialog.title" v-model="materialDialog.visible" width="600px" append-to-body> |
| | | <el-form ref="materialFormRef" :model="materialForm" :rules="materialRules" label-width="100px"> |
| | | <el-form-item label="èµæåç§°" prop="name"> |
| | | <el-input v-model="materialForm.name" placeholder="请è¾å
¥èµæåç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="èµæç±»å" prop="type"> |
| | | <el-select v-model="materialForm.type" placeholder="è¯·éæ©èµæç±»å" style="width: 100%"> |
| | | <el-option label="PDF" value="PDF" /> |
| | | <el-option label="å¶åº¦" value="å¶åº¦" /> |
| | | <el-option label="课件" value="课件" /> |
| | | <el-option label="è§é¢" value="è§é¢" /> |
| | | <el-option label="æ¡ä¾" value="æ¡ä¾" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="æä»¶ä¸ä¼ " prop="fileUrl" v-if="!materialForm.id"> |
| | | <el-upload |
| | | ref="uploadRef" |
| | | action="/dev-api/common/upload" |
| | | :headers="uploadHeaders" |
| | | :on-success="handleUploadSuccess" |
| | | :on-error="handleUploadError" |
| | | :before-upload="beforeUpload" |
| | | :limit="1" |
| | | > |
| | | <el-button type="primary">éæ©æä»¶</el-button> |
| | | <template #tip> |
| | | <div class="el-upload__tip">æ¯æ PDFãWordãè§é¢çæ ¼å¼</div> |
| | | </template> |
| | | </el-upload> |
| | | </el-form-item> |
| | | <el-form-item label="æä»¶å¤§å°" prop="fileSize" v-if="materialForm.fileSize"> |
| | | <el-input v-model="materialForm.fileSize" disabled /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-radio-group v-model="materialForm.status"> |
| | | <el-radio :value="1">å¯ç¨</el-radio> |
| | | <el-radio :value="0">åç¨</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="materialForm.remark" type="textarea" :rows="3" placeholder="请è¾å
¥å¤æ³¨" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="materialDialog.visible = false">å æ¶</el-button> |
| | | <el-button type="primary" @click="submitMaterialForm" :loading="materialDialog.loading">ç¡® å®</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- å¹è®è®¡åå¼¹çª --> |
| | | <el-dialog :title="planDialog.title" v-model="planDialog.visible" width="700px" append-to-body> |
| | | <el-form ref="planFormRef" :model="planForm" :rules="planRules" label-width="100px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="计å年度" prop="year"> |
| | | <el-date-picker v-model="planForm.year" type="year" placeholder="éæ©å¹´åº¦" value-format="YYYY" style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éç¨å²ä½" prop="post"> |
| | | <el-input v-model="planForm.post" placeholder="请è¾å
¥éç¨å²ä½" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¹è®ç级" prop="level"> |
| | | <el-select v-model="planForm.level" placeholder="è¯·éæ©å¹è®ç级" style="width: 100%"> |
| | | <el-option label="ä¸çº§" value="ä¸çº§" /> |
| | | <el-option label="äºçº§" value="äºçº§" /> |
| | | <el-option label="ä¸çº§" value="ä¸çº§" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="计å课æ¶" prop="hours"> |
| | | <el-input-number v-model="planForm.hours" :min="1" style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-form-item label="å¹è®å
容" prop="content"> |
| | | <el-input v-model="planForm.content" type="textarea" :rows="3" placeholder="请è¾å
¥å¹è®å
容" /> |
| | | </el-form-item> |
| | | <el-form-item label="å¹è®èµæ" prop="materialIds"> |
| | | <el-select v-model="planForm.materialIds" multiple placeholder="è¯·éæ©å¹è®èµæ" style="width: 100%"> |
| | | <el-option v-for="item in materialOptions" :key="item.id" :label="item.name" :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-radio-group v-model="planForm.status"> |
| | | <el-radio :value="0">å¾
æ§è¡</el-radio> |
| | | <el-radio :value="1">æ§è¡ä¸</el-radio> |
| | | <el-radio :value="2">已宿</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="planForm.remark" type="textarea" :rows="3" placeholder="请è¾å
¥å¤æ³¨" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="planDialog.visible = false">å æ¶</el-button> |
| | | <el-button type="primary" @click="submitPlanForm" :loading="planDialog.loading">ç¡® å®</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- å®æè®°å½å¼¹çª --> |
| | | <el-dialog :title="recordDialog.title" v-model="recordDialog.visible" width="700px" append-to-body> |
| | | <el-form ref="recordFormRef" :model="recordForm" :rules="recordRules" label-width="100px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¹è®è®¡å" prop="planId"> |
| | | <el-select v-model="recordForm.planId" placeholder="è¯·éæ©å¹è®è®¡å" style="width: 100%" @change="handlePlanChange"> |
| | | <el-option v-for="item in planOptions" :key="item.id" :label="item.content" :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åå·¥å§å" prop="employeeId"> |
| | | <el-select v-model="recordForm.employeeId" placeholder="è¯·éæ©åå·¥" style="width: 100%" @change="handleEmployeeChange"> |
| | | <el-option v-for="item in employeeOptions" :key="item.userId" :label="item.userName" :value="item.userId" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="宿æ¶é´" prop="completeTime"> |
| | | <el-date-picker v-model="recordForm.completeTime" type="datetime" placeholder="鿩宿æ¶é´" value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¦ä¹ æ¶é¿" prop="duration"> |
| | | <el-input-number v-model="recordForm.duration" :min="0" :precision="1" style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¹è®æ¹å¼" prop="method"> |
| | | <el-select v-model="recordForm.method" placeholder="è¯·éæ©å¹è®æ¹å¼" style="width: 100%"> |
| | | <el-option label="çº¿ä¸æè¯¾" value="çº¿ä¸æè¯¾" /> |
| | | <el-option label="线ä¸å¦ä¹ " value="线ä¸å¦ä¹ " /> |
| | | <el-option label="宿æ¼ç»" value="宿æ¼ç»" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èæ ¸åæ°" prop="score"> |
| | | <el-input-number v-model="recordForm.score" :min="0" :max="100" style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èæ ¸ç»æ" prop="result"> |
| | | <el-select v-model="recordForm.result" placeholder="è¯·éæ©èæ ¸ç»æ" style="width: 100%"> |
| | | <el-option label="éè¿" value="éè¿" /> |
| | | <el-option label="æªéè¿" value="æªéè¿" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-radio-group v-model="recordForm.status"> |
| | | <el-radio :value="1">已宿</el-radio> |
| | | <el-radio :value="0">æªå®æ</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="recordForm.remark" type="textarea" :rows="3" placeholder="请è¾å
¥å¤æ³¨" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="recordDialog.visible = false">å æ¶</el-button> |
| | | <el-button type="primary" @click="submitRecordForm" :loading="recordDialog.loading">ç¡® å®</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive } from "vue"; |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import PIMTable from "@/components/PIMTable/PIMTable.vue"; |
| | | import { |
| | | getMaterialList, |
| | | uploadMaterial as uploadMaterialApi, |
| | | updateMaterial, |
| | | deleteMaterial, |
| | | getMaterialDetail, |
| | | getPlanList, |
| | | addPlan as addPlanApi, |
| | | updatePlan, |
| | | deletePlan, |
| | | getPlanDetail, |
| | | getRecordList, |
| | | addRecord as addRecordApi, |
| | | updateRecord, |
| | | deleteRecord, |
| | | getRecordDetail, |
| | | exportRecord |
| | | } from "@/api/safetyManagement/trainingManage.js"; |
| | | import { listUser } from "@/api/system/user"; |
| | | import { getToken } from "@/utils/auth"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | |
| | | defineOptions({ |
| | | name: "å¹è®ç®¡ç", |
| | |
| | | |
| | | const activeTab = ref("materials"); |
| | | |
| | | // å¹è®èµæ |
| | | const materialFilters = reactive({ name: "", type: "" }); |
| | | // ==================== å¹è®èµæ ==================== |
| | | const materialFilters = reactive({ name: "", type: "", status: null }); |
| | | const materialList = ref([]); |
| | | const materialPage = reactive({ current: 1, size: 10, total: 0 }); |
| | | const materialLoading = ref(false); |
| | | const materialColumns = [ |
| | | { label: "èµæåç§°", prop: "name", align: "center" }, |
| | | { label: "ç±»å", prop: "type", align: "center" }, |
| | | { |
| | | label: "ç±»å", |
| | | prop: "type", |
| | | align: "center", |
| | | dataType: "tag", |
| | | formatType: () => "primary", |
| | | formatData: (val) => val || '-' |
| | | }, |
| | | { label: "ä¸ä¼ 人", prop: "uploader", align: "center" }, |
| | | { label: "ä¸ä¼ æ¶é´", prop: "uploadTime", align: "center" }, |
| | | { label: "æä»¶å¤§å°", prop: "fileSize", align: "center" }, |
| | | { |
| | | label: "ç¶æ", |
| | | prop: "status", |
| | | align: "center", |
| | | dataType: "tag", |
| | | formatType: (val) => (val === 1 ? "success" : "info"), |
| | | formatData: (val) => (val === 1 ? "å¯ç¨" : "åç¨") |
| | | }, |
| | | { |
| | | label: "æä½", |
| | | prop: "action", |
| | | align: "center", |
| | | dataType: "action", |
| | | operation: [ |
| | | { name: "ç¼è¾", type: "text", clickFun: (row) => handleEditMaterial(row) }, |
| | | { name: "ä¸è½½", type: "text", clickFun: (row) => handleDownload(row) }, |
| | | { name: "å é¤", type: "text", clickFun: (row) => handleDeleteMaterial(row) } |
| | | ] |
| | | } |
| | | ]; |
| | | |
| | | // å¹è®è®¡å |
| | | const planFilters = reactive({ year: "", post: "" }); |
| | | const materialDialog = reactive({ visible: false, title: "", loading: false }); |
| | | const materialFormRef = ref(null); |
| | | const uploadRef = ref(null); |
| | | const materialForm = reactive({ |
| | | id: null, |
| | | name: "", |
| | | type: "", |
| | | fileUrl: "", |
| | | fileSize: "", |
| | | status: 1, |
| | | remark: "" |
| | | }); |
| | | const materialRules = { |
| | | name: [{ required: true, message: "请è¾å
¥èµæåç§°", trigger: "blur" }], |
| | | type: [{ required: true, message: "è¯·éæ©èµæç±»å", trigger: "change" }] |
| | | }; |
| | | |
| | | const uploadHeaders = reactive({ |
| | | Authorization: "Bearer " + getToken() |
| | | }); |
| | | |
| | | // ==================== å¹è®è®¡å ==================== |
| | | const planFilters = reactive({ year: "", post: "", level: "", status: null }); |
| | | const planList = ref([]); |
| | | const planPage = reactive({ current: 1, size: 10, total: 0 }); |
| | | const planLoading = ref(false); |
| | | const planColumns = [ |
| | | { label: "计å年度", prop: "year", align: "center" }, |
| | | { label: "å²ä½", prop: "post", align: "center" }, |
| | | { label: "å±çº§", prop: "level", align: "center" }, |
| | | { label: "å¹è®ç级", prop: "level", align: "center" }, |
| | | { label: "å¹è®å
容", prop: "content", align: "center" }, |
| | | { label: "计å课æ¶", prop: "hours", align: "center" }, |
| | | { |
| | | label: "ç¶æ", |
| | | prop: "status", |
| | | align: "center", |
| | | dataType: "tag", |
| | | formatType: (val) => { |
| | | if (val === 0) return 'info'; |
| | | if (val === 1) return 'warning'; |
| | | return 'success'; |
| | | }, |
| | | formatData: (val) => { |
| | | const statusMap = { 0: 'å¾
æ§è¡', 1: 'æ§è¡ä¸', 2: '已宿' }; |
| | | return statusMap[val] || val; |
| | | } |
| | | }, |
| | | { |
| | | label: "æä½", |
| | | prop: "action", |
| | | align: "center", |
| | | dataType: "action", |
| | | operation: [ |
| | | { name: "ç¼è¾", type: "text", clickFun: (row) => handleEditPlan(row) }, |
| | | { name: "å é¤", type: "text", clickFun: (row) => handleDeletePlan(row) } |
| | | ] |
| | | } |
| | | ]; |
| | | |
| | | // å®æè®°å½ |
| | | const recordFilters = reactive({ employeeName: "" }); |
| | | const planDialog = reactive({ visible: false, title: "", loading: false }); |
| | | const planFormRef = ref(null); |
| | | const planForm = reactive({ |
| | | id: null, |
| | | year: "", |
| | | post: "", |
| | | level: "", |
| | | content: "", |
| | | hours: 1, |
| | | materialIds: [], |
| | | status: 0, |
| | | remark: "" |
| | | }); |
| | | const planRules = { |
| | | year: [{ required: true, message: "è¯·éæ©è®¡å年度", trigger: "change" }], |
| | | post: [{ required: true, message: "请è¾å
¥éç¨å²ä½", trigger: "blur" }], |
| | | level: [{ required: true, message: "è¯·éæ©å¹è®ç级", trigger: "change" }], |
| | | content: [{ required: true, message: "请è¾å
¥å¹è®å
容", trigger: "blur" }], |
| | | hours: [{ required: true, message: "请è¾å
¥è®¡å课æ¶", trigger: "blur" }] |
| | | }; |
| | | const materialOptions = ref([]); |
| | | |
| | | // ==================== å®æè®°å½ ==================== |
| | | const recordFilters = reactive({ employeeName: "", status: null }); |
| | | const recordList = ref([]); |
| | | const recordPage = reactive({ current: 1, size: 10, total: 0 }); |
| | | const recordLoading = ref(false); |
| | | const recordColumns = [ |
| | | { label: "åå·¥å§å", prop: "employeeName", align: "center" }, |
| | | { label: "å¹è®å
容", prop: "content", align: "center" }, |
| | | { label: "宿æ¶é´", prop: "completeTime", align: "center" }, |
| | | { label: "èæ ¸ç»æ", prop: "result", align: "center" }, |
| | | { label: "å¦ä¹ æ¶é¿", prop: "duration", align: "center" }, |
| | | { label: "å¹è®æ¹å¼", prop: "method", align: "center" }, |
| | | { label: "åæ°", prop: "score", align: "center" }, |
| | | { |
| | | label: "èæ ¸ç»æ", |
| | | prop: "result", |
| | | align: "center", |
| | | dataType: "tag", |
| | | formatType: (val) => { |
| | | if (val === 'ä¼ç§' || val === 'éè¿') return 'success'; |
| | | if (val === 'è¯å¥½') return 'primary'; |
| | | if (val === 'åæ ¼') return 'warning'; |
| | | return 'danger'; |
| | | }, |
| | | formatData: (val) => val || '-' |
| | | }, |
| | | { |
| | | label: "æä½", |
| | | prop: "action", |
| | | align: "center", |
| | | dataType: "action", |
| | | operation: [ |
| | | { name: "ç¼è¾", type: "text", clickFun: (row) => handleEditRecord(row) }, |
| | | { name: "å é¤", type: "text", clickFun: (row) => handleDeleteRecord(row) } |
| | | ] |
| | | } |
| | | ]; |
| | | |
| | | const getMaterialData = () => {}; |
| | | const resetMaterialFilters = () => { materialFilters.name = ""; materialFilters.type = ""; }; |
| | | const uploadMaterial = () => {}; |
| | | const changeMaterialPage = ({ page, limit }) => { materialPage.current = page; materialPage.size = limit; }; |
| | | const recordDialog = reactive({ visible: false, title: "", loading: false }); |
| | | const recordFormRef = ref(null); |
| | | const recordForm = reactive({ |
| | | id: null, |
| | | planId: null, |
| | | employeeId: null, |
| | | employeeName: "", |
| | | content: "", |
| | | completeTime: "", |
| | | duration: 0, |
| | | method: "", |
| | | score: 0, |
| | | result: "", |
| | | status: 1, |
| | | remark: "" |
| | | }); |
| | | const recordRules = { |
| | | planId: [{ required: true, message: "è¯·éæ©å¹è®è®¡å", trigger: "change" }], |
| | | employeeId: [{ required: true, message: "è¯·éæ©åå·¥", trigger: "change" }], |
| | | completeTime: [{ required: true, message: "è¯·éæ©å®ææ¶é´", trigger: "change" }] |
| | | }; |
| | | const planOptions = ref([]); |
| | | const employeeOptions = ref([]); |
| | | |
| | | const getPlanData = () => {}; |
| | | const resetPlanFilters = () => { planFilters.year = ""; planFilters.post = ""; }; |
| | | const addPlan = () => {}; |
| | | const changePlanPage = ({ page, limit }) => { planPage.current = page; planPage.size = limit; }; |
| | | // ==================== éç¨æ¹æ³ ==================== |
| | | const loadData = () => { |
| | | switch (activeTab.value) { |
| | | case 'materials': |
| | | getMaterialData(); |
| | | break; |
| | | case 'plans': |
| | | getPlanData(); |
| | | break; |
| | | case 'records': |
| | | getRecordData(); |
| | | break; |
| | | } |
| | | }; |
| | | |
| | | const getRecordData = () => {}; |
| | | const resetRecordFilters = () => { recordFilters.employeeName = ""; }; |
| | | const changeRecordPage = ({ page, limit }) => { recordPage.current = page; recordPage.size = limit; }; |
| | | const handleTabChange = () => { |
| | | loadData(); |
| | | }; |
| | | |
| | | // ==================== å¹è®èµææ¹æ³ ==================== |
| | | const getMaterialData = async () => { |
| | | materialLoading.value = true; |
| | | try { |
| | | const res = await getMaterialList({ |
| | | pageNum: materialPage.current, |
| | | pageSize: materialPage.size, |
| | | ...materialFilters |
| | | }); |
| | | if (res.code === 200) { |
| | | materialList.value = res.data.records || res.data.rows || []; |
| | | materialPage.total = res.data.total || 0; |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·åå¹è®èµæå¤±è´¥'); |
| | | } finally { |
| | | materialLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const resetMaterialFilters = () => { |
| | | materialFilters.name = ""; |
| | | materialFilters.type = ""; |
| | | materialFilters.status = null; |
| | | materialPage.current = 1; |
| | | getMaterialData(); |
| | | }; |
| | | |
| | | const changeMaterialPage = ({ page, limit }) => { |
| | | materialPage.current = page; |
| | | materialPage.size = limit; |
| | | getMaterialData(); |
| | | }; |
| | | |
| | | const resetMaterialForm = () => { |
| | | materialForm.id = null; |
| | | materialForm.name = ""; |
| | | materialForm.type = ""; |
| | | materialForm.fileUrl = ""; |
| | | materialForm.fileSize = ""; |
| | | materialForm.status = 1; |
| | | materialForm.remark = ""; |
| | | if (uploadRef.value) { |
| | | uploadRef.value.clearFiles(); |
| | | } |
| | | }; |
| | | |
| | | const openMaterialDialog = () => { |
| | | resetMaterialForm(); |
| | | materialDialog.title = "ä¸ä¼ å¹è®èµæ"; |
| | | materialDialog.visible = true; |
| | | }; |
| | | |
| | | const handleEditMaterial = async (row) => { |
| | | resetMaterialForm(); |
| | | try { |
| | | const res = await getMaterialDetail(row.id); |
| | | if (res.code === 200) { |
| | | Object.assign(materialForm, res.data); |
| | | materialDialog.title = "ç¼è¾å¹è®èµæ"; |
| | | materialDialog.visible = true; |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·åèµæè¯¦æ
失败'); |
| | | } |
| | | }; |
| | | |
| | | const handleUploadSuccess = (response) => { |
| | | if (response.code === 200) { |
| | | materialForm.fileUrl = response.url; |
| | | materialForm.fileSize = formatFileSize(response.file?.size || 0); |
| | | ElMessage.success('æä»¶ä¸ä¼ æå'); |
| | | } else { |
| | | ElMessage.error(response.msg || 'ä¸ä¼ 失败'); |
| | | } |
| | | }; |
| | | |
| | | const handleUploadError = () => { |
| | | ElMessage.error('æä»¶ä¸ä¼ 失败'); |
| | | }; |
| | | |
| | | const beforeUpload = (file) => { |
| | | const maxSize = 50 * 1024 * 1024; // 50MB |
| | | if (file.size > maxSize) { |
| | | ElMessage.error('æä»¶å¤§å°ä¸è½è¶
è¿ 50MB'); |
| | | return false; |
| | | } |
| | | return true; |
| | | }; |
| | | |
| | | const formatFileSize = (size) => { |
| | | if (size < 1024) return size + ' B'; |
| | | if (size < 1024 * 1024) return (size / 1024).toFixed(2) + ' KB'; |
| | | if (size < 1024 * 1024 * 1024) return (size / (1024 * 1024)).toFixed(2) + ' MB'; |
| | | return (size / (1024 * 1024 * 1024)).toFixed(2) + ' GB'; |
| | | }; |
| | | |
| | | const submitMaterialForm = async () => { |
| | | const valid = await materialFormRef.value.validate().catch(() => false); |
| | | if (!valid) return; |
| | | |
| | | if (!materialForm.id && !materialForm.fileUrl) { |
| | | ElMessage.error('请ä¸ä¼ æä»¶'); |
| | | return; |
| | | } |
| | | |
| | | materialDialog.loading = true; |
| | | try { |
| | | const api = materialForm.id ? updateMaterial : uploadMaterialApi; |
| | | const res = await api(materialForm); |
| | | if (res.code === 200) { |
| | | ElMessage.success(materialForm.id ? 'ä¿®æ¹æå' : 'ä¸ä¼ æå'); |
| | | materialDialog.visible = false; |
| | | getMaterialData(); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error(materialForm.id ? 'ä¿®æ¹å¤±è´¥' : 'ä¸ä¼ 失败'); |
| | | } finally { |
| | | materialDialog.loading = false; |
| | | } |
| | | }; |
| | | |
| | | const handleDownload = (row) => { |
| | | if (row.fileUrl) { |
| | | // å¤çURLæ ¼å¼é®é¢ |
| | | let url = row.fileUrl; |
| | | // ä¿®å¤ç±»ä¼¼ http://host:portupload/ çéè¯¯æ ¼å¼ |
| | | url = url.replace(/^(http:\/\/[^/]+:\d+)(upload\/)/, '$1/$2'); |
| | | // 妿䏿¯å®æ´URLï¼æ·»å åç¼ |
| | | if (!url.startsWith('http')) { |
| | | url = '/dev-api/' + url.replace(/^\//, ''); |
| | | } |
| | | window.open(url, '_blank'); |
| | | } else { |
| | | ElMessage.warning('æä»¶å°åä¸åå¨'); |
| | | } |
| | | }; |
| | | |
| | | const handleDeleteMaterial = (row) => { |
| | | ElMessageBox.confirm(`确认å é¤èµæ "${row.name}" åï¼`, "æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning" |
| | | }).then(async () => { |
| | | try { |
| | | const res = await deleteMaterial(row.id); |
| | | if (res.code === 200) { |
| | | ElMessage.success("å 餿å"); |
| | | getMaterialData(); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error("å é¤å¤±è´¥"); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // ==================== å¹è®è®¡åæ¹æ³ ==================== |
| | | const getPlanData = async () => { |
| | | planLoading.value = true; |
| | | try { |
| | | const res = await getPlanList({ |
| | | pageNum: planPage.current, |
| | | pageSize: planPage.size, |
| | | ...planFilters |
| | | }); |
| | | if (res.code === 200) { |
| | | planList.value = res.data.records || res.data.rows || []; |
| | | planPage.total = res.data.total || 0; |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·åå¹è®è®¡å失败'); |
| | | } finally { |
| | | planLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const resetPlanFilters = () => { |
| | | planFilters.year = ""; |
| | | planFilters.post = ""; |
| | | planFilters.level = ""; |
| | | planFilters.status = null; |
| | | planPage.current = 1; |
| | | getPlanData(); |
| | | }; |
| | | |
| | | const changePlanPage = ({ page, limit }) => { |
| | | planPage.current = page; |
| | | planPage.size = limit; |
| | | getPlanData(); |
| | | }; |
| | | |
| | | const loadMaterialOptions = async () => { |
| | | try { |
| | | const res = await getMaterialList({ pageNum: 1, pageSize: 1000 }); |
| | | if (res.code === 200) { |
| | | materialOptions.value = res.data.records || res.data.rows || []; |
| | | } |
| | | } catch (error) { |
| | | console.error('å è½½å¹è®èµæé项失败', error); |
| | | } |
| | | }; |
| | | |
| | | const resetPlanForm = () => { |
| | | planForm.id = null; |
| | | planForm.year = ""; |
| | | planForm.post = ""; |
| | | planForm.level = ""; |
| | | planForm.content = ""; |
| | | planForm.hours = 1; |
| | | planForm.materialIds = []; |
| | | planForm.status = 0; |
| | | planForm.remark = ""; |
| | | }; |
| | | |
| | | const openPlanDialog = () => { |
| | | resetPlanForm(); |
| | | loadMaterialOptions(); |
| | | planDialog.title = "å¶å®å¹è®è®¡å"; |
| | | planDialog.visible = true; |
| | | }; |
| | | |
| | | const handleEditPlan = async (row) => { |
| | | resetPlanForm(); |
| | | loadMaterialOptions(); |
| | | try { |
| | | const res = await getPlanDetail(row.id); |
| | | if (res.code === 200) { |
| | | Object.assign(planForm, res.data); |
| | | // å° materialIds å符串转æ¢ä¸ºæ°ç» |
| | | if (planForm.materialIds && typeof planForm.materialIds === 'string') { |
| | | planForm.materialIds = planForm.materialIds.split(',').map(id => parseInt(id)); |
| | | } |
| | | planDialog.title = "ç¼è¾å¹è®è®¡å"; |
| | | planDialog.visible = true; |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·å计å详æ
失败'); |
| | | } |
| | | }; |
| | | |
| | | const submitPlanForm = async () => { |
| | | const valid = await planFormRef.value.validate().catch(() => false); |
| | | if (!valid) return; |
| | | |
| | | planDialog.loading = true; |
| | | try { |
| | | const submitData = { ...planForm }; |
| | | // å° materialIds æ°ç»è½¬æ¢ä¸ºéå·åéçå符串 |
| | | if (Array.isArray(submitData.materialIds)) { |
| | | submitData.materialIds = submitData.materialIds.join(','); |
| | | } |
| | | const api = planForm.id ? updatePlan : addPlanApi; |
| | | const res = await api(submitData); |
| | | if (res.code === 200) { |
| | | ElMessage.success(planForm.id ? 'ä¿®æ¹æå' : 'æ°å¢æå'); |
| | | planDialog.visible = false; |
| | | getPlanData(); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error(planForm.id ? 'ä¿®æ¹å¤±è´¥' : 'æ°å¢å¤±è´¥'); |
| | | } finally { |
| | | planDialog.loading = false; |
| | | } |
| | | }; |
| | | |
| | | const handleDeletePlan = (row) => { |
| | | ElMessageBox.confirm(`确认å é¤è¯¥å¹è®è®¡ååï¼`, "æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning" |
| | | }).then(async () => { |
| | | try { |
| | | const res = await deletePlan(row.id); |
| | | if (res.code === 200) { |
| | | ElMessage.success("å 餿å"); |
| | | getPlanData(); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error("å é¤å¤±è´¥"); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // ==================== å®æè®°å½æ¹æ³ ==================== |
| | | const getRecordData = async () => { |
| | | recordLoading.value = true; |
| | | try { |
| | | const res = await getRecordList({ |
| | | pageNum: recordPage.current, |
| | | pageSize: recordPage.size, |
| | | ...recordFilters |
| | | }); |
| | | if (res.code === 200) { |
| | | recordList.value = res.data.records || res.data.rows || []; |
| | | recordPage.total = res.data.total || 0; |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·åå®æè®°å½å¤±è´¥'); |
| | | } finally { |
| | | recordLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const resetRecordFilters = () => { |
| | | recordFilters.employeeName = ""; |
| | | recordFilters.status = null; |
| | | recordPage.current = 1; |
| | | getRecordData(); |
| | | }; |
| | | |
| | | const changeRecordPage = ({ page, limit }) => { |
| | | recordPage.current = page; |
| | | recordPage.size = limit; |
| | | getRecordData(); |
| | | }; |
| | | |
| | | const exportRecords = async () => { |
| | | try { |
| | | const res = await exportRecord(recordFilters); |
| | | // å¤çæä»¶ä¸è½½ |
| | | const blob = new Blob([res]); |
| | | const link = document.createElement('a'); |
| | | link.href = URL.createObjectURL(blob); |
| | | link.download = 'å¹è®å®æè®°å½.xlsx'; |
| | | link.click(); |
| | | ElMessage.success('å¯¼åºæå'); |
| | | } catch (error) { |
| | | ElMessage.error('导åºå¤±è´¥'); |
| | | } |
| | | }; |
| | | |
| | | // å®æè®°å½è¡¨åæ¹æ³ |
| | | const resetRecordForm = () => { |
| | | recordForm.id = null; |
| | | recordForm.planId = null; |
| | | recordForm.employeeId = null; |
| | | recordForm.employeeName = ""; |
| | | recordForm.content = ""; |
| | | recordForm.completeTime = ""; |
| | | recordForm.duration = 0; |
| | | recordForm.method = ""; |
| | | recordForm.score = 0; |
| | | recordForm.result = ""; |
| | | recordForm.status = 1; |
| | | recordForm.remark = ""; |
| | | }; |
| | | |
| | | // å è½½å¹è®è®¡åé项 |
| | | const loadPlanOptions = async () => { |
| | | try { |
| | | const res = await getPlanList({ pageNum: 1, pageSize: 1000 }); |
| | | if (res.code === 200) { |
| | | planOptions.value = res.data.records || res.data.rows || []; |
| | | } |
| | | } catch (error) { |
| | | console.error('å è½½å¹è®è®¡å失败', error); |
| | | } |
| | | }; |
| | | |
| | | // å è½½åå·¥é项ï¼ä»ç¨æ·ç®¡çè·åï¼ |
| | | const loadEmployeeOptions = async () => { |
| | | try { |
| | | const res = await listUser({ pageNum: 1, pageSize: 1000 }); |
| | | // ç¨æ·ç®¡çæ¥å£ç´æ¥è¿å rowsï¼æ²¡æ code åæ®µ |
| | | employeeOptions.value = res.rows || []; |
| | | } catch (error) { |
| | | console.error('å è½½åå·¥å表失败', error); |
| | | } |
| | | }; |
| | | |
| | | const handlePlanChange = (val) => { |
| | | const selectedPlan = planOptions.value.find(item => item.id === val); |
| | | if (selectedPlan) { |
| | | recordForm.content = selectedPlan.content; |
| | | } |
| | | }; |
| | | |
| | | const handleEmployeeChange = (val) => { |
| | | const selectedEmployee = employeeOptions.value.find(item => item.userId === val); |
| | | if (selectedEmployee) { |
| | | recordForm.employeeName = selectedEmployee.userName; |
| | | } |
| | | }; |
| | | |
| | | const openRecordDialog = () => { |
| | | resetRecordForm(); |
| | | loadPlanOptions(); |
| | | loadEmployeeOptions(); |
| | | recordDialog.title = "æ°å¢å®æè®°å½"; |
| | | recordDialog.visible = true; |
| | | }; |
| | | |
| | | const handleEditRecord = async (row) => { |
| | | resetRecordForm(); |
| | | try { |
| | | const res = await getRecordDetail(row.id); |
| | | if (res.code === 200) { |
| | | Object.assign(recordForm, res.data); |
| | | recordDialog.title = "ç¼è¾å®æè®°å½"; |
| | | recordDialog.visible = true; |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·åè®°å½è¯¦æ
失败'); |
| | | } |
| | | }; |
| | | |
| | | const submitRecordForm = async () => { |
| | | const valid = await recordFormRef.value.validate().catch(() => false); |
| | | if (!valid) return; |
| | | |
| | | recordDialog.loading = true; |
| | | try { |
| | | const api = recordForm.id ? updateRecord : addRecordApi; |
| | | const res = await api(recordForm); |
| | | if (res.code === 200) { |
| | | ElMessage.success(recordForm.id ? 'ä¿®æ¹æå' : 'æ°å¢æå'); |
| | | recordDialog.visible = false; |
| | | getRecordData(); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error(recordForm.id ? 'ä¿®æ¹å¤±è´¥' : 'æ°å¢å¤±è´¥'); |
| | | } finally { |
| | | recordDialog.loading = false; |
| | | } |
| | | }; |
| | | |
| | | const handleDeleteRecord = (row) => { |
| | | ElMessageBox.confirm(`确认å é¤è¯¥å®æè®°å½åï¼`, "æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning" |
| | | }).then(async () => { |
| | | try { |
| | | const res = await deleteRecord(row.id); |
| | | if (res.code === 200) { |
| | | ElMessage.success("å 餿å"); |
| | | getRecordData(); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error("å é¤å¤±è´¥"); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getMaterialData(); |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |