Compare commits

...

28 Commits

Author SHA1 Message Date
shanao 40ff86424f Merge remote-tracking branch 'origin/pet' into pet 2024-09-13 18:00:12 +08:00
shanao 09e64d39c0 Merge remote-tracking branch 'origin/dev-shanao' into pet
# Conflicts:
#	config/index.js
#	package-lock.json
#	package.json
#	static/config.js
2024-09-13 18:00:03 +08:00
shanao fdbb4d78da 测试完成 2024-09-13 17:57:57 +08:00
shanao 15a8303e21 修复全部问题 2024-09-13 17:57:57 +08:00
shanao 84451f1c7b 修复全部问题 2024-09-13 17:57:56 +08:00
mengfanliang 54845b2422 feat: 调试事故信息查询菜单图片回显路径问题 2024-09-13 17:57:49 +08:00
shanao 164f70a0a4 修复导出相关问题 2024-09-13 17:57:44 +08:00
shanao a116151652 导出还没通 2024-09-13 17:57:44 +08:00
mengfanliang 06920346f8 feat: 事故信息查询模块接口对接 2024-09-13 17:57:40 +08:00
shanao a77e81bbf0 调试 2024-09-13 17:57:35 +08:00
shanao 7847b69c62 事故调查管理代码提交 2024-09-13 17:57:30 +08:00
mengfanliang 6dbdf598c7 feat: 事故信息管理菜单重构 2024-09-13 17:57:17 +08:00
shanao f921dd8c52 事故调查管理代码提交 2024-09-13 17:57:02 +08:00
wangpeng f58761937f 事故调查管理代码提交 2024-09-13 17:57:02 +08:00
shanao 0f75e526de 测试完成 2024-09-13 17:18:25 +08:00
shanao 8062274b39 修复全部问题 2024-09-12 17:32:07 +08:00
shanao 270d0d3c86 修复全部问题 2024-09-12 14:10:14 +08:00
mengfanliang 638f6d4901 Merge branch 'dev-shanao' of http://47.92.113.182:3000/guoyuepeng/qa-prevention-gwj-vue into dev-shanao
fix: 解决分支合并冲突
2024-09-12 11:43:09 +08:00
mengfanliang b29e9ed249 feat: 调试事故信息查询菜单图片回显路径问题 2024-09-12 11:40:32 +08:00
shanao ce40b8f194 修复导出相关问题 2024-09-12 10:18:12 +08:00
shanao 4933738b6d 修复导出相关问题 2024-09-10 14:09:40 +08:00
shanao f7cb02d681 导出还没通 2024-09-09 18:04:04 +08:00
mengfanliang d07eaa7cfc feat: 事故信息查询模块接口对接 2024-09-09 15:17:43 +08:00
shanao 6e97caf3a4 调试 2024-09-08 22:08:29 +08:00
shanao 5aa6676248 事故调查管理代码提交 2024-09-06 19:38:37 +08:00
mengfanliang 2c930b42b2 feat: 事故信息管理菜单重构 2024-09-06 18:17:09 +08:00
shanao 991ef9ea52 事故调查管理代码提交 2024-09-06 16:19:59 +08:00
wangpeng 3d576a33ca 事故调查管理代码提交 2024-08-30 18:22:13 +08:00
4 changed files with 765 additions and 0 deletions

View File

@ -100,6 +100,12 @@ export const constantRoutes = [
hidden: true, hidden: true,
component: () => import('@/views/map/index') component: () => import('@/views/map/index')
} }
// {
// path: '/accident/records',
// name: 'apiAccidentRecords',
// meta: { name: '事故调查' },
// component: () => import('@/views/accident/records/index.vue')
// }
] ]
const createRouter = () => new Router({ const createRouter = () => new Router({
// mode: 'history', // require service support // mode: 'history', // require service support

View File

@ -0,0 +1,384 @@
<template>
<div class="app-container">
<el-form
ref="form"
:model="infoForm"
:rules="rules"
label-width="180px"
style="width: 900px"
>
<el-form-item :label-width="formLabelWidth" label="事故案号" prop="incidentNumber">
<el-input v-model="infoForm.incidentNumber" :disabled="isDisabled" autocomplete="off"/>
</el-form-item>
<el-form-item :label-width="formLabelWidth" label="事故名称" prop="incidentName">
<el-input v-model="infoForm.incidentName" :disabled="isDisabled" autocomplete="off"/>
</el-form-item>
<el-form-item :label-width="formLabelWidth" label="事故类型" prop="incidentType">
<el-select v-model="infoForm.incidentType" :disabled="isDisabled" placeholder="请选择">
<el-option v-for="item in incidentTypes" :key="item.id" :label="item.name" :value="item.id"/>
</el-select>
</el-form-item>
<el-form-item :label-width="formLabelWidth" label="事故级别" prop="incidentLevel">
<el-select v-model="infoForm.incidentLevel" :disabled="isDisabled" placeholder="请选择">
<el-option v-for="item in incidentLevels" :key="item.id" :label="item.name" :value="item.id"/>
</el-select>
</el-form-item>
<el-form-item :label-width="formLabelWidth" label="事故发生地点" prop="location">
<el-input v-model="infoForm.location" :disabled="isDisabled" autocomplete="off"/>
</el-form-item>
<el-form-item :label-width="formLabelWidth" label="事故发生时间" prop="incidentDate">
<el-date-picker
:disabled="isDisabled"
v-model="infoForm.incidentDate"
type="datetime"
placeholder="选择事故发生时间"
style="width: 100%;"
/>
</el-form-item>
<el-form-item :label-width="formLabelWidth" label="直接经济损失(万元)" prop="directLoss">
<el-input v-model="infoForm.directLoss" :disabled="isDisabled" type="number" autocomplete="off"/>
</el-form-item>
<el-form-item :label-width="formLabelWidth" label="受伤人数" prop="injured">
<el-input v-model="infoForm.injured" :disabled="isDisabled" type="number" autocomplete="off"/>
</el-form-item>
<el-form-item :label-width="formLabelWidth" label="死亡人数" prop="fatalities">
<el-input v-model="infoForm.fatalities" :disabled="isDisabled" type="number" autocomplete="off"/>
</el-form-item>
<el-form-item :label-width="formLabelWidth" label="重伤人数" prop="seriouslyInjured">
<el-input v-model="infoForm.seriouslyInjured" :disabled="isDisabled" type="number" autocomplete="off"/>
</el-form-item>
<el-form-item :label-width="formLabelWidth" label="事故起因" prop="cause">
<el-input v-model="infoForm.cause" :disabled="isDisabled" autocomplete="off"/>
</el-form-item>
<el-form-item :label-width="formLabelWidth" label="事故概述" prop="summary">
<el-input v-model="infoForm.summary" :disabled="isDisabled" autocomplete="off"/>
</el-form-item>
<el-form-item :label-width="formLabelWidth" label="事故照片" prop="fileList">
<el-upload
ref="upload"
:disabled="isDisabled"
:file-list="infoForm.fileList"
:multiple="false"
:auto-upload="true"
:limit="limitNum"
:on-remove="handleRemovePicture"
:on-preview="handlePictureCardPreview"
:before-upload="beforeAccidentUpload"
:on-error="handleError"
:on-exceed="handleExceed"
name="file"
action="#"
accept=".jpg,.jpeg,.png"
list-type="picture-card">
<i class="el-icon-plus"/>
</el-upload>
</el-form-item>
<el-form-item :label-width="formLabelWidth" label="原因分析及责任认定" prop="analysis">
<el-input v-model="infoForm.analysis" :disabled="isDisabled" autocomplete="off"/>
</el-form-item>
<el-form-item :label-width="formLabelWidth" label="考核建议" prop="suggestions">
<el-input v-model="infoForm.suggestions" :disabled="isDisabled" autocomplete="off"/>
</el-form-item>
<el-form-item :label-width="formLabelWidth" label="整改措施" prop="measures">
<el-input v-model="infoForm.measures" :disabled="isDisabled" autocomplete="off"/>
</el-form-item>
<el-form-item :label-width="formLabelWidth" label="填表人" prop="creator">
<el-input v-model="infoForm.creator" :disabled="isDisabled" autocomplete="off"/>
</el-form-item>
<el-form-item :label-width="formLabelWidth" label="报出日期" prop="reportDate">
<el-date-picker
v-model="infoForm.reportDate"
:disabled="isDisabled"
type="datetime"
placeholder="请选择报出日期"
style="width: 100%;"
/>
</el-form-item>
</el-form>
<el-dialog :visible.sync="dialogImgVisible">
<div v-if="infoForm.fileList.length > 0">
<img :src="infoForm.fileList[0].url" width="100%" alt="">
</div>
</el-dialog>
<div class="ui-height"/>
<div class="ui-foot">
<el-button
type="primary"
icon="el-icon-arrow-left"
plain
@click="goBack">返回
</el-button>
<el-button type="primary" @click="confirm"> </el-button>
</div>
</div>
</template>
<script>
import { requestFN } from '../../../../utils/request'
import { upload } from '@/utils/upload'
export default {
data() {
return {
config: config,
infoForm: {
id: '', // ID
incidentNumber: '', //
incidentName: '', //
incidentType: null, //
companyName: '', //
incidentLevel: '', //
incidentNature: '', //
location: '', //
incidentDate: null, //
directLoss: '', //
injured: null, //
fatalities: null, //
seriouslyInjured: null, //
cause: '', //
summary: '', //
fileList: [], //
analysis: '', //
suggestions: '', //
measures: '', //
creator: '', //
reportDate: null //
},
formLabelWidth: '140px',
/** 事故类型 */
incidentTypes: [],
/** 事故等级 */
incidentLevels: [],
tableName: '',
/** 图片上传限制个数 */
limitNum: 1,
/** 预览弹窗 */
dialogImgVisible: false,
rules: {
incidentNumber: [{ required: true, message: '事故案号不能为空', trigger: 'blur' }],
incidentName: [{ required: true, message: '事故名称不能为空', trigger: 'blur' }],
incidentType: [{ required: true, message: '事故类型不能为空', trigger: 'blur' }],
incidentLevel: [{ required: true, message: '事故级别不能为空', trigger: 'blur' }],
incidentNature: [{ required: true, message: '事故性质不能为空', trigger: 'blur' }],
location: [{ required: true, message: '事故发生地点不能为空', trigger: 'blur' }],
incidentDate: [{ required: true, message: '事故发生时间不能为空', trigger: 'blur' }],
directLoss: [{ required: true, message: '直接经济损失(万元)不能为空', trigger: 'blur' }],
injured: [{ required: true, message: '受伤人数不能为空', trigger: 'blur' }],
seriouslyInjured: [{ required: true, message: '隐患类型不能为空', trigger: 'blur' }],
cause: [{ required: true, message: '事故起因不能为空', trigger: 'blur' }],
summary: [{ required: true, message: '事故概述不能为空', trigger: 'blur' }],
fileList: [{ required: true, message: '事故照片不能为空', trigger: 'blur' }],
analysis: [{ required: true, message: '原因分析及责任认定不能为空', trigger: 'blur' }],
suggestions: [{ required: true, message: '考核建议不能为空', trigger: 'blur' }],
measures: [{ required: true, message: '整改措施不能为空', trigger: 'blur' }],
creator: [{ required: true, message: '填表人不能为空', trigger: 'blur' }],
reportDate: [{ required: true, message: '报出日期不能为空', trigger: 'blur' }]
}
}
},
computed: {
isDisabled() {
return this.$parent.tableName === '查看'
}
},
created() {
this.getDict()
const id = this.$parent.id
this.tableName = this.$parent.tableName
if (id == null || id === '') {
this.infoForm = this.$options.data().infoForm
} else {
// ID,
requestFN('/accident/' + id, {}).then((data) => {
this.infoForm = {
...data.info,
fileList: [
{
name: 'photo',
url: config.fileUrl + data.info.photos,
remotePathName: data.info.photos
}
]
}
}).catch((e) => {
})
}
},
methods: {
/**
* 文件列表移除文件时的钩子
*/
handleRemovePicture(file) {
if (file.remotePathName) {
requestFN(`/accident/delete/photos`, {
path: file.remotePathName
}).then((res) => {
if (res.result === 'success') {
this.infoForm.fileList = []
this.$message({
message: '文件删除成功',
type: 'info',
duration: 2000
})
}
})
}
},
/**
* 点击文件列表中已上传的文件时的钩子
*/
handlePictureCardPreview(file) {
this.dialogImgVisible = true
this.dialogImageUrl = file.url
},
/**
* 文件上传失败时的钩子处理
*/
// eslint-disable-next-line handle-callback-err
handleError(err, file, fileList) {
this.$message({
message: `${file.name}上传失败, 请稍后重试`,
type: 'error',
duration: 2000
})
},
/**
* 文件超出个数限制的钩子处理
*/
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 ${this.limitNum} 个文件,本次选择了 ${files.length} 个文件`)
},
/**
* 上传文件之前的钩子参数为上传的文件若返回 false 或者返回 Promise 且被 reject则停止上传
*/
beforeAccidentUpload(file) {
if (!file) {
this.$message({
message: '请上传图片',
type: 'error'
})
return false
}
const types = ['image/jpeg', 'image/jpg', 'image/png']
const isImage = types.includes(file.type)
if (!isImage) {
this.$message.error('上传图片只能是 JPG、JPEG、PNG 格式!')
return false
} else {
const formData = new FormData()
formData.append('file', file)
upload('/accident/import/photos', formData).then((data) => {
if (data.result === 'success') {
this.infoForm = {
...this.infoForm,
fileList: [{
name: file.name,
url: config.fileUrl + data.path,
remotePathName: data.path
}]
}
}
})
return false
}
},
/**
* 返回到列表页面
*/
goBack() {
this.handleResetInitForm()
this.image = []
this.dialogImageUrl = ''
this.$parent.activeName = 'List'
},
/**
* 表单清空处理
*/
handleResetInitForm() {
this.infoForm = {
id: '', // ID
incidentNumber: '', //
incidentName: '', //
incidentType: null, //
companyName: '', //
incidentLevel: '', //
incidentNature: '', //
location: '', //
incidentDate: null, //
directLoss: '', //
injured: null, //
fatalities: null, //
seriouslyInjured: null, //
cause: '', //
summary: '', //
fileList: [], //
analysis: '', //
suggestions: '', //
measures: '', //
creator: '', //
reportDate: null //
}
},
/**
* 表单确认按钮
*/
confirm() {
this.$refs.form.validate(valid => {
if (!valid) {
return false
}
const params = {
...this.infoForm,
photos: this.infoForm.fileList[0].remotePathName
}
delete params.fileList
requestFN('/accident' + (this.tableName === '修改' ? '/update' : '/save'), params)
.then((response) => {
//
this.$message.success(this.tableName + '成功')
this.infoForm = this.$options.data().infoForm
this.$parent.activeName = 'List'
// eslint-disable-next-line handle-callback-err
}).catch((error) => {
this.$message.error(this.tableName + '失败')
})
})
},
/**
* 获取字典
*/
getDict() {
const url = '/dictionaries/listSelectTree'
requestFN(url,
{
DICTIONARIES_ID: '8d4140a900184b60836ad1a6490fd510'
}
).then((data) => {
this.incidentTypes = JSON.parse(data.zTreeNodes)
})
requestFN(url,
{
DICTIONARIES_ID: 'b61a1edc59c0430c8741c5f51aa26c3c'
}
).then((data) => {
this.incidentLevels = JSON.parse(data.zTreeNodes)
})
}
}
}
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,338 @@
<template>
<div class="app-container">
<el-form ref="searchForm" :model="searchForm" label-width="100px">
<el-row :gutter="12">
<el-col :span="4">
<el-form-item label="事故名称" prop="incidentName">
<el-input v-model="searchForm.incidentName" placeholder="请输入事故名称" class="filter-item"/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="发生时间" prop="incidentDates">
<el-date-picker
v-model="searchForm.incidentDates"
:default-time="['00:00:00', '23:59:59']"
value-format="yyyy-MM-dd HH:mm:ss"
format="yyyy-MM-dd"
style="width: 100%"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="发生地点" prop="location">
<el-input v-model="searchForm.location" placeholder="请输入发生地点" />
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="事故类型" prop="incidentType">
<el-select v-model="searchForm.incidentType" placeholder="请选择">
<el-option v-for="item in incidentTypes" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="事故等级" prop="incidentLevel">
<el-select v-model="searchForm.incidentLevel" placeholder="请选择">
<el-option v-for="item in incidentLevels" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="3">
<el-button v-waves type="primary" icon="el-icon-search" @click="searchList"></el-button>
<el-button v-waves icon="el-icon-refresh" @click="handleReset"></el-button>
</el-col>
</el-row>
<!-- 搜索查询 end -->
<!-- 顶部操作按钮 start -->
<el-row :gutter="24">
<el-col :span="24">
<el-button type="primary" icon="el-icon-circle-plus" @click="goView('', '新增')">新增</el-button>
<el-button icon="el-icon-s-promotion" @click="handleAllExport"></el-button>
<el-button type="danger" icon="el-icon-delete-solid" @click="handleBatchDel"></el-button>
</el-col>
</el-row>
<!-- 顶部操作按钮 end -->
</el-form>
<!-- table 表格 start -->
<div style="margin-top: 16px;">
<el-table
v-loading="listLoading"
ref="multipleTable"
:data="varList"
tooltip-effect="dark"
style="width: 100%"
border
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55"/>
<el-table-column label="事故名称" prop="incidentName"/>
<el-table-column label="所属公司" prop="companyName"/>
<el-table-column label="发生时间" prop="incidentDate">
<template v-slot="{row}">
{{ formatDate(row.incidentDate,'YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column label="发生地点" prop="location"/>
<el-table-column label="操作" width="300">
<template v-slot="{row}">
<el-button icon="el-icon-view" size="mini" @click="goView(row.id, '查看')">查看</el-button>
<el-button icon="el-icon-edit" size="mini" @click="goEdit(row.id, '修改')">修改</el-button>
<el-button icon="el-icon-delete-solid" type="danger" size="mini" @click="deleteRow(row.id)"></el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- table 表格 end -->
<div class="pagination-group">
<pagination :total="listQuery.total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="searchList" />
</div>
</div>
</template>
<script>
import Pagination from '@/components/Pagination'
import waves from '@/directive/waves'
import formatDate from '@/utils/dateformat'
import { requestFN } from '../../../../utils/request'
export default {
components: { Pagination },
directives: { waves },
data() {
return {
//
searchForm: {
/** 事故名称 */
incidentName: '',
/** 发生时间 */
incidentDates: [],
/** 开始时间 */
startTime: null,
/** 结束时间 */
endTime: null,
/** 发生地点 */
location: '',
/** 事故类型 */
incidentType: '',
/** 事故等级 */
incidentLevel: ''
},
/** 当前选中行 */
multipleSelection: [],
/** 列表加载态 */
listLoading: false,
/** 源列表数据项 */
varList: [],
/** 事故类型 */
incidentTypes: [],
/** 事故等级 */
incidentLevels: [],
//
listQuery: {
/** 当前页数 */
page: 1,
/** 分页数 */
limit: 20,
/** 总页数 */
total: 0
}
}
},
created() {
this.getDict()
this.searchList()
},
methods: {
/**
* 查询搜索
*/
searchList() {
this.listLoading = true
const dates = this.searchForm.incidentDates
if (dates != null && dates.length === 2) {
this.searchForm.startTime = dates[0]
this.searchForm.endTime = dates[1]
}
const url = '/accident/page?showCount=' + this.listQuery.limit + '&currentPage=' + this.listQuery.page
requestFN(url, { ...this.searchForm }).then((data) => {
this.listLoading = false
this.varList = data.varList
this.listQuery.total = data.page.totalResult
}).catch((e) => {
this.listLoading = false
})
},
/**
* 重置搜索条件
*/
handleReset() {
this.searchForm = this.$options.data().searchForm
this.searchList()
},
/**
* 表格行选择器处理
*/
handleSelectionChange(val) {
this.multipleSelection = val
},
/**
* 跳转查看详情页面
*/
goView(id, name) {
this.$parent.id = id
this.$parent.tableName = name
this.$parent.activeName = 'AddOrEdit'
},
/**
* 跳转修改页面
*/
goEdit(id, name) {
this.$parent.id = id
this.$parent.tableName = name
this.$parent.activeName = 'AddOrEdit'
},
/**
* 删除行数据
*/
deleteRow(id) {
if (id === null || id === '') {
this.$message.warning('请选择要删除的行')
return
}
//
this.$confirm('确定要删除这调记录吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//
const url = '/accident/delete/' + '' + id
requestFN(url).then((response) => {
//
this.$message.success('删除成功')
this.searchList()
// eslint-disable-next-line handle-callback-err
}).catch((error) => {
this.$message.error('删除失败')
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
},
/**
* 全部导出
*/
handleAllExport() {
this.$confirm('确定要下载excel模板吗?', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.listLoading = false
window.location.href = config.httpurl + '/accident/export/excel'
}).catch(() => {
this.listLoading = false
})
this.listLoading = false
},
/**
* 刷新
*/
handleRefresh() {
this.searchForm = this.$options.data().searchForm
this.searchList()
// this.toggleSelection()
},
/**
* 批量删除
*/
handleBatchDel() {
//
const selectedRows = this.multipleSelection
//
if (this.multipleSelection === '' || selectedRows.length === 0) {
this.$message.warning('请选择要删除的行')
return
}
//
this.$confirm('确定要删除这些记录吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// ID
let ids = ''
selectedRows.forEach(row => { ids += row.id + ',' })
//
const url = '/accident/delete/' + '' + ids
requestFN(url).then((response) => {
//
this.$message.success('删除成功')
this.searchList()
// eslint-disable-next-line handle-callback-err
}).catch(() => {
this.$message.error('删除失败')
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
},
/**
* 查询字典
*/
getDict() {
const url = '/dictionaries/listSelectTree'
requestFN(url,
{
DICTIONARIES_ID: '8d4140a900184b60836ad1a6490fd510'
}
).then((data) => {
this.incidentTypes = JSON.parse(data.zTreeNodes)
})
requestFN(url,
{
DICTIONARIES_ID: 'b61a1edc59c0430c8741c5f51aa26c3c'
}
).then((data) => {
this.incidentLevels = JSON.parse(data.zTreeNodes)
})
},
formatDate(date, format) {
return formatDate(date, format)
}
}
}
</script>
<style lang="scss" scoped>
.pagination-group {
margin-top: 14px;
}
</style>

View File

@ -0,0 +1,37 @@
<template>
<div>
<List v-if="activeName === 'List'" ref="List" />
<Add v-if="activeName === 'AddOrEdit'" ref="AddOrEdit" />
</div>
</template>
<script>
import List from './components/list.vue'
import Add from './components/addOrEdit.vue'
export default {
components: {
List: List,
Add: Add
},
data() {
return {
activeName: 'List',
id: '',
tableName: ''
}
},
watch: {
activeName(val) {
if (val === 'List') {
this.$nextTick(() => {
this.$refs.List.searchList()
})
}
}
}
}
</script>
<style scoped>
</style>