Files
dvcp_v2_webapp/packages/3.0.0/AppReportAiWill/reportAtWillDetail.vue
yanran200730 9d4ef66fa5 26980
2022-01-24 15:21:54 +08:00

607 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<section class="reportAtWillDetail">
<ai-detail>
<template #title>
<ai-title
title="事件详情"
isShowBack
isShowBottomBorder
@onBackClick="$emit('back')">
<template #rightBtn>
<template v-if="hasHandled">
<el-button
icon="iconfont iconRepulsebeifen"
v-if="
report.permissions('app_appreportatwillinfo_edit') &&
detail.publicityStatus == 0
"
@click="handlePublic(detail)"
>公示事件
</el-button>
<el-button
icon="iconfont iconRepulse"
v-if="
report.permissions('app_appreportatwillinfo_edit') &&
detail.publicityStatus == 1
"
@click="handlePublic(detail)"
>
取消公示
</el-button>
</template>
<template v-else>
<ai-wechat-selecter :isMultiple="false" :instance="report.instance" v-model="userList" @change="v => handleAppoint(v, detail)">
<el-button
icon="iconfont iconPerson_Transfered"
v-if="report.permissions('app_appreportatwillinfo_edit')"
>指派人员
</el-button>
</ai-wechat-selecter>
<el-button
type="primary"
icon="iconfont iconRegister"
@click="dialogShow"
v-if="report.permissions('app_appreportatwillinfo_edit')"
>处理事件
</el-button>
<el-button
type="primary"
icon="iconfont iconClock"
@click.once="handleUrge"
v-if="
report.permissions('app_appreportatwillinfo_edit') &&
!!detail.assignUserId &&
detail.handleFlow.some(e => e.assignUserId == user.info.id)
"
>
短信催办
</el-button>
</template>
</template>
</ai-title>
</template>
<!-- 详情 -->
<template #content>
<div class="detail-content__wrapper">
<ai-card class="detail-content__wrapper--left" title="基础信息">
<template #content>
<ai-wrapper :columnsNumber="1">
<ai-info-item label="处理状态">
<span
:style="{
color: detail.status === '0' ? '#F79300' : '#222'
}"
>{{
report.dict.getLabel(
'reportAtWillHandleStatus',
detail.status
)
}}</span
>
</ai-info-item>
<ai-info-item label="上报时间">{{
detail.createTime
}}</ai-info-item>
<ai-info-item label="区域">{{ detail.areaName }}</ai-info-item>
<ai-info-item label="地点">{{ detail.address }}</ai-info-item>
<ai-info-item label="事件位置">
<div id="map" style="width: 400px; height: 240px;"></div>
</ai-info-item>
<ai-info-item label="事件描述">{{
detail.explain
}}</ai-info-item>
<ai-info-item label="现场照片">
<ai-uploader
:instance="instance"
disabled
v-model="detail.files"
></ai-uploader>
</ai-info-item>
</ai-wrapper>
</template>
</ai-card>
<div class="rightZone">
<ai-card title="处理结果">
<template #content>
<ai-wrapper :columnsNumber="1" label-width="60px">
<!-- <ai-info-item label="处理人员">{{ detail.handleUserName }}</ai-info-item>
<ai-info-item label="处理结果">{{ detail.handleResult || '-' }}</ai-info-item> -->
<ai-info-item label="上报类型">{{
dict.getLabel('atWillReportType', detail.reportType)
}}</ai-info-item>
<ai-info-item label="事件类型">{{
detail.ruleName || '-'
}}</ai-info-item>
<ai-info-item label="信用积分"
><span style="color: #2266FF;">{{
detail.integral > 0
? '+' + detail.integral
: detail.integral
}}</span></ai-info-item
>
<ai-info-item label="处理结果">{{
detail.handleResult || '-'
}}</ai-info-item>
<ai-info-item label="现场照片">
<div class="imgs" v-viewer="{ movable: true }">
<img
:src="item.url"
v-for="(item, index) in detail.handleFiles"
:key="index"
/>
</div>
</ai-info-item>
</ai-wrapper>
</template>
</ai-card>
<ai-card title="处理记录">
<template #content>
<el-steps direction="vertical" :active="1">
<el-step
v-for="(step, i) in handleLogs"
:key="i"
:title="step.title"
:description="step.description"
>
<template #title>
<h2
class="step-title"
style="font-weight: 500; font-size: 14px;"
>
{{ step.title }}
</h2>
</template>
<template #description>
<p
style="color: #888; margin: 0 4px 10px 0; font-size: 14px;"
>
{{ step.description }}
</p>
</template>
</el-step>
</el-steps>
</template>
</ai-card>
</div>
</div>
</template>
</ai-detail>
<ai-dialog
class="report-dialog"
:visible.sync="dialog"
width="800px"
title="处理事件"
@closed="form = {}"
@onConfirm="handleEvent"
>
<el-form
size="small"
label-width="100px"
label-suffix=""
:rules="rules"
:model="form"
ref="handleForm"
>
<el-form-item label="上报类型" prop="reportType">
<ai-select
style="width: 100%"
v-model="form.reportType"
@change="onChange"
placeholder="请选择上报类型"
:selectList="dict.getDict('atWillReportType')"
>
</ai-select>
</el-form-item>
<el-form-item label="事件类型" prop="ruleId">
<el-select
v-model="form.ruleId"
placeholder="请选择事件类型"
size="small"
>
<el-option
v-for="(item, index) in eventList"
:key="index"
:label="item.ruleName"
:value="item.id"
>
<span style="float: left">{{ item.ruleName }}</span>
<span style="float: right; color: #8492a6; font-size: 13px"
>积分{{ item.integral }}</span
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="处理结果" prop="handleResult">
<el-input
type="textarea"
:rows="5"
maxlength="200"
v-model="form.handleResult"
clearable
placeholder="请输入处理结果"
show-word-limit
/>
</el-form-item>
<el-form-item label="图片" prop="handleFiles">
<ai-uploader
:instance="instance"
v-model="form.handleFiles"
:limit="9"
isShowTip
></ai-uploader>
</el-form-item>
</el-form>
</ai-dialog>
</section>
</template>
<script>
import AMapLoader from '@amap/amap-jsapi-loader'
import { mapState } from 'vuex'
export default {
name: 'reportAtWillDetail',
props: ['dict', 'instance', 'permissions', 'id'],
computed: {
...mapState(['user']),
hasHandled() {
return this.detail.status == 1
},
handleLogs() {
let starter = {
title: `收到用户(${this.detail.nickName})上报的事件信息,等待处理。`,
description: this.detail.createTime
},
handleUser = [],
process =
this.detail.handleFlow?.map(e => ({
title: `${e.assignUserName} 查看了信息,并分配了${e.handleUserName}处理任务。`,
description: e.assignTime
})) || []
this.detail.status == 1 &&
this.detail.handleUserName &&
handleUser.push({
title: `${this.detail.handleUserName}反馈了处理结果。`,
description: this.detail.handleTime
})
return [starter, ...process, ...handleUser]
},
rules() {
return {
handleResult: [{ required: true, message: '请填写处理结果' }],
ruleId: [{ required: true, message: '请选择事件类型' }],
reportType: [{ required: true, message: '请选择上报类型' }]
}
}
},
data() {
return {
detail: {},
eventList: [],
dialog: false,
userList: [],
form: {
ruleId: '',
handleFiles: [],
reportType: ''
}
}
},
created() {
this.dict
.load(
'reportAtWillPublicityStatus',
'reportAtWillHandleStatus',
'atWillReportType'
)
.then(() => {
this.getDetail()
})
},
methods: {
getDetail() {
this.id &&
this.report.instance
.post('/app/appreportatwillinfo/queryDetailById', null, {
params: { id: this.id }
})
.then(res => {
if (res?.data) {
this.detail = res.data
this.$nextTick(() => {
this.initMap()
})
}
})
},
onChange(e) {
this.instance
.post(
`/app/appvillagerintegralrule/list?size=1000&classification=${e}&ruleStatus=1`
)
.then(res => {
if (res.code === 0) {
this.form.ruleId = ''
this.eventList = res.data.records
}
})
},
initMap() {
let { lng, lat } = this.detail,
center = [lng, lat]
lng &&
lat &&
AMapLoader.load({
key: 'b553334ba34f7ac3cd09df9bc8b539dc',
version: '2.0' // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
})
.then(AMap => {
let map = new AMap.Map('map', {
center,
zoom: 14
})
let marker = new AMap.Marker({
position: new AMap.LngLat(lng, lat),
title: this.detail.address
})
map.add(marker)
})
.catch(e => {
})
},
handlePublic(ev) {
this.$confirm(
`是否对该事件${ev.publicityStatus == 0 ? '进行公示' : '取消公示'}`
)
.then(() => {
this.report.instance
.post('/app/appreportatwillinfo/publicity', null, {
params: { id: ev.id }
})
.then(res => {
if (res?.code == 0) {
this.$message.success('操作成功!')
this.$emit('back')
}
})
})
.catch(() => 0)
},
handleAppoint(person, row) {
this.report.instance
.post('/app/appreportatwillinfo/assign', {
handleUserId: person?.[0].id,
handleUserName: person?.[0].name + ' ' + person?.[0].phone,
infoId: row.id
})
.then(res => {
this.userList = []
if (res?.code == 0) {
this.$message.success('指派成功!')
this.$emit('back')
}
}).catch(() => {
this.userList = []
})
},
handleUrge() {
this.$confirm('是否要进行短信催办?')
.then(() => {
this.report.instance
.post('/app/appreportatwillinfo/urging')
.then(res => {
if (res?.code == 0) {
this.$message.success('催办成功!')
this.$emit('back')
}
})
})
.catch(() => 0)
},
handleEvent() {
this.$refs.handleForm.validate(v => {
if (v) {
this.report.instance
.post('/app/appreportatwillinfo/handle', {
...this.detail,
...this.form
})
.then(res => {
if (res?.code == 0) {
this.$message.success('处理成功!')
this.$emit('back')
}
})
}
})
},
handleUpload({ file }) {
if (file) {
let formData = new FormData()
formData.append('file', file)
this.report.instance.post('/admin/file/add', formData).then(res => {
if (res?.data) {
let fileInfos = res.data?.[0]?.split(';')
this.form.handleFiles?.push({
id: fileInfos[1],
accessUrl: fileInfos[0],
filename: file.name,
size: file.size
}) ||
(this.form.handleFiles = [
{
id: fileInfos[1],
accessUrl: fileInfos[0],
filename: file.name,
size: file.size
}
])
}
})
}
},
handleUploadRemove(file) {
let index = this.form.handleFiles.findIndex(e => e.id == file.id)
index > -1 && this.form.handleFiles.splice(index, 1)
},
dialogShow() {
this.dialog = true
this.form.reportType = this.detail.reportType
this.onChange(this.detail.reportType)
}
},
inject: ['report']
}
</script>
<style lang="scss" scoped>
.reportAtWillDetail {
height: 100%;
.el-steps {
::v-deep .el-step__icon {
font-size: 12px;
color: #555555;
border-color: #d0d4dc;
}
::v-deep .el-step__head.is-finish {
.el-step__icon.is-text {
border: none;
color: #fff;
font-size: 12px;
background: #2266ff;
}
}
::v-deep .el-step__line {
background-color: #d0d4dc;
}
}
.imgs {
font-size: 0;
img {
width: 108px;
height: 108px;
margin-right: 4px;
margin-bottom: 4px;
cursor: pointer;
user-select: none;
&:hover {
opacity: 0.8;
}
&:nth-of-type(2n) {
margin-right: 0;
}
}
}
::v-deep .report-dialog {
.el-select {
width: 100%;
}
}
::v-deep .ailist-title {
.el-button {
margin-left: 0 !important;
}
}
::v-deep .el-step__head.is-process {
color: #555;
border-color: #555;
}
::v-deep .is-finish h2 {
color: #2266ff;
}
.step-title {
color: #555;
}
.detail-content__wrapper {
display: flex;
width: 100%;
.detail-content__wrapper--left {
flex: 1;
margin-right: 20px;
}
}
::v-deep .ai-detail__content {
background: #f3f6f9;
.ai-detail__content--wrapper {
display: flex;
gap: 16px;
width: 100%;
max-width: 100%;
padding: 16px;
box-sizing: border-box;
& > .el-card {
flex: 1;
min-width: 0;
}
.rightZone {
width: 400px;
flex-shrink: 0;
display: flex;
flex-direction: column;
gap: 16px;
}
}
}
::v-deep .el-card {
.el-card__header {
padding: 12px 16px;
font-weight: bold;
}
.el-card__body {
padding: 8px;
}
#amap {
width: 466px;
height: 232px;
}
.el-steps {
margin-left: 8px;
}
.imgFormItem > .el-form-item__content {
display: flex;
gap: 16px;
flex-wrap: wrap;
&:before {
content: none;
}
.el-image__inner {
width: 82px;
height: 82px;
}
}
}
}
</style>