Files
dvcp_v2_webapp/project/pingchang/apps/AppWishfulThinking/components/Detail.vue
2022-11-16 13:41:18 +08:00

581 lines
15 KiB
Vue

<template>
<ai-detail class="reportAtWillDetail" v-loading="isLoading">
<template #title>
<ai-title title="微心愿详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)">
<template #rightBtn>
<div class="title-btns">
<el-button type="primary" icon="iconfont iconPerson_Transfered" @click="isShowForward = true" v-if="detail.eventStatus < 2">指派事件</el-button>
<!-- <el-button type="primary" icon="iconfont iconRegister" @click="isShowAdd = true" v-if="detail.eventStatus < 2">处理事件</el-button> -->
</div>
</template>
</ai-title>
</template>
<template #content>
<div class="detail-content__wrapper">
<div class="detail-content__wrapper--left">
<ai-card title="基础信息">
<template #content>
<ai-wrapper>
<ai-info-item label="上报人员" :value="detail.name"></ai-info-item>
<ai-info-item label="当前状态" :value="dict.getLabel('clapEventStatus', detail.eventStatus)"></ai-info-item>
<ai-info-item label="联系方式">{{ detail.phone }}</ai-info-item>
<ai-info-item label="上报时间">{{ detail.createTime }}</ai-info-item>
<ai-info-item label="事件类型">{{ detail.groupName }}</ai-info-item>
<ai-info-item label="事件描述" isLine>{{ detail.content }}</ai-info-item>
<ai-info-item label="现场照片" isLine>
<ai-uploader :instance="instance" disabled v-model="detail.files"></ai-uploader>
</ai-info-item>
<ai-info-item label="所属地区">{{ detail.areaName }}</ai-info-item>
<ai-info-item label="事件位置" isLine>
<div id="map" style="width: 500px; height: 280px;"></div>
</ai-info-item>
</ai-wrapper>
</template>
</ai-card>
<ai-card title="办事评价" v-if="detail.eventStatus == 2">
<template #content>
<ai-wrapper>
<ai-info-item label="评价时间" :value="detail.name"></ai-info-item>
<ai-info-item label="评价分数"></ai-info-item>
<ai-info-item label="评价详情" isLine>{{ detail.content }}</ai-info-item>
</ai-wrapper>
</template>
</ai-card>
<ai-evaluation :bid="detail.id" :info.sync="evaluation"/>
</div>
<div class="rightZone">
<ai-card title="办理进度">
<template #content>
<el-steps direction="vertical" :active="1">
<el-step
v-for="(item, i) in process"
:key="i"
:title="item.systemExplain"
:description="item.doTime">
<template #title>
<h2 class="step-title" style="font-weight: 500; font-size: 14px;">
{{ item.systemExplain }}
</h2>
</template>
<template #description>
<p style="color: #888; margin: 0 4px 10px 0; font-size: 14px;">{{ item.doTime }}</p>
<div style="color: #444;margin-bottom: 10px;" v-if="item.doExplain">{{ item.doExplain }}</div>
<ai-uploader :instance="instance" disabled v-model="item.files"></ai-uploader>
</template>
</el-step>
</el-steps>
</template>
</ai-card>
</div>
</div>
<ai-dialog
:visible.sync="isShowAdd"
width="800px"
title="事件处理"
@closed="onClose"
@onConfirm="handleEvent">
<el-form class="ai-form" label-width="120px" :model="form" ref="form">
<el-form-item label="事件分类" prop="groupId" style="width: 100%;" :rules="[{ required: true, message: '请选择事件分类' }]">
<ai-select
v-model="form.groupId"
placeholder="请选择事件分类"
:selectList="dictList">
</ai-select>
</el-form-item>
<el-form-item label="处理结果" prop="eventStatus" style="width: 100%;" :rules="[{ required: true, message: '请选择处理结果' }]">
<el-radio-group v-model="form.eventStatus">
<el-radio label="2">已办结</el-radio>
<el-radio label="3">已拒绝</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="处理意见" prop="content" style="width: 100%;" :rules="[{ required: true, message: '请输入处理意见' }]">
<el-input type="textarea" :rows="5" :maxlength="500" v-model="form.content" clearable placeholder="请输入处理意见" show-word-limit></el-input>
</el-form-item>
<el-form-item label="图片" prop="files" style="width: 100%;">
<ai-uploader
:instance="instance"
isShowTip
v-model="form.files"
:limit="9">
</ai-uploader>
</el-form-item>
</el-form>
</ai-dialog>
<ai-dialog
:visible.sync="isShowForward"
width="800px"
@close="onClose"
title="事件指派"
@onConfirm="onForwardConfirm">
<el-form class="ai-form" label-width="120px" :model="forwardForm" ref="forwardForm">
<el-form-item label="转交" prop="name" style="width: 100%;" :rules="[{ required: true, message: '请选择人员' }]">
<el-input disabled size="small" v-model="forwardForm.name" clearable placeholder="请选择人员">
<template slot="append">
<ai-wechat-selecter refs="addTags" :props="{id:'wxUserId',label:'name'}" :isMultiple="false" :instance="instance" v-model="forwardForm.user" @change="onChooseUser">
<el-button size="small">选择人员</el-button>
</ai-wechat-selecter>
</template>
</el-input>
</el-form-item>
<el-form-item label="办理意见" prop="content" style="width: 100%;" :rules="[{ required: true, message: '请输入办理意见' }]">
<el-input type="textarea" :rows="5" :maxlength="500" v-model="forwardForm.content" clearable placeholder="请输入办理意见" show-word-limit></el-input>
</el-form-item>
<el-form-item label="图片" prop="files" style="width: 100%;">
<ai-uploader
:instance="instance"
v-model="forwardForm.files"
isShowTip
:limit="9">
</ai-uploader>
</el-form-item>
</el-form>
</ai-dialog>
</template>
</ai-detail>
</template>
<script>
import AMapLoader from '@amap/amap-jsapi-loader'
import {mapState} from 'vuex'
export default {
name: 'Detail',
props: ['dict', 'instance'],
data() {
return {
forwardForm: {
content: '',
user: [],
name: '',
files: []
},
isLoading: true,
name: '',
detail: {},
isShowUser: false,
eventList: [],
isShowAdd: false,
userList: [],
processList: [],
dictList: [],
isShowForward: false,
tree: [],
gridInfo: {},
form: {
files: [],
groupId: '',
groupName: '',
content: [],
eventStatus: '2'
},
evaluation: {},
}
},
computed: {
...mapState(['user']),
process: v => [v.evaluation.id ? {
systemExplain: `${v.evaluation.createUserName}完成评价 (${v.evaluation.score}星评价)`,
doTime: v.evaluation.createTime,
doExplain: v.evaluation.rateText
} : null, v.processList].flat().filter(Boolean)
},
created() {
this.getDict()
this.dict.load('clapEventStatus').then(() => {
this.getDetail()
})
},
methods: {
getDetail() {
this.instance.post('/app/appclapeventinfopingchang/queryDetailById', null, {
params: {id: this.$route.query.id}
}).then(res => {
if (res?.data) {
this.detail = res.data
this.processList = res.data.processList
this.form.groupId = res.data.groupId
this.$nextTick(() => {
this.initMap()
})
this.isLoading = false
}
}).catch(() => {
this.isLoading = false
})
},
onChooseUser(v) {
console.log(v)
this.forwardForm.user = v
this.forwardForm.name = v[0].name
},
onClose() {
this.form.files = []
this.form.groupId = ''
this.form.groupName = ''
this.form.content = ''
this.form.eventStatus = ''
this.forwardForm.content = ''
this.forwardForm.user = []
this.forwardForm.files = []
this.forwardForm.name = ''
},
onForwardConfirm() {
this.$refs.forwardForm.validate(v => {
if (v) {
this.instance.post('/app/appclapeventinfopingchang/transfer', {
...this.forwardForm,
id: this.$route.query.id
}).then(res => {
if (res?.code == 0) {
this.isShowForward = false
this.getDetail()
this.$message.success('转交成功!')
}
})
}
})
},
getDict() {
this.instance.post(`/app/appclapeventgrouppingchang/list?current=1&size=100000`).then(res => {
if (res.code == 0) {
this.dictList = res.data.records.map(v => {
return {
dictValue: v.id,
dictName: v.groupName
}
})
}
})
},
cancel(isRefresh) {
this.$emit('change', {
type: 'list',
isRefresh: !!isRefresh
})
},
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
let center = [lng, lat]
AMapLoader.load({
key: '54a02a43d9828a8f9cd4f26fe281e74e',
version: '2.0'
}).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)
})
},
handleEvent() {
this.$refs.form.validate(v => {
if (v) {
this.instance.post('/app/appclapeventinfo/finishByManager', {
...this.form,
groupName: this.dictList.filter(v => v.dictValue === this.form.groupId)[0].dictName,
id: this.$route.query.id
}).then(res => {
if (res?.code == 0) {
this.isShowAdd = false
this.getDetail()
this.$message.success('处理成功!')
}
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
.reportAtWillDetail {
height: 100%;
.grid-wrapper {
min-height: 360px;
}
.title-btns {
display: flex;
align-items: center;
}
::v-deep .el-tree {
background: transparent;
.el-tree-node__expand-icon.is-leaf {
color: transparent !important;
}
.el-tree-node__content > .el-tree-node__expand-icon {
padding: 4px;
}
.el-tree-node__content {
height: 32px;
}
.el-tree__empty-text {
color: #222;
font-size: 14px;
}
.el-tree-node__children .el-tree-node__content {
height: 32px;
}
.el-tree-node__content:hover {
background: #E8EFFF;
color: #222222;
border-radius: 2px;
}
.is-current > .el-tree-node__content {
&:hover {
background: #2266FF;
color: #fff;
}
background: #2266FF;
span {
color: #fff;
}
}
}
.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 .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%;
flex-wrap: wrap;
.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;
}
}
}
.AppAnnounceDetail-select {
display: flex;
align-items: center;
min-height: 32px;
line-height: 1;
background: #F5F5F5;
border-radius: 4px;
border: 1px solid #D0D4DC;
cursor: pointer;
overflow: hidden;
transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
&:hover {
border-color: #26f;
}
& > i {
flex: 1;
height: 100%;
line-height: 32px;
padding: 0 12px;
color: #888888;
font-size: 14px;
font-style: normal;
border-right: 1px solid #D0D4DC;
background: #fff;
}
.AppAnnounceDetail-select__input {
position: absolute;
left: 0;
top: 0;
z-index: -1;
opacity: 0;
height: 100%;
}
.select-right {
height: 100%;
padding: 0 12px;
color: #222222;
font-size: 12px;
cursor: pointer;
transition: all ease 0.3s;
&:hover {
opacity: 0.5;
}
}
.select-left {
display: flex;
flex-wrap: wrap;
flex: 1;
padding: 5px 0 0px 12px;
border-right: 1px solid #D0D4DC;
border-radius: 4px 0 0 4px;
background: #fff;
em {
height: 22px;
line-height: 22px;
margin: 0 4px 5px 0;
color: #222222;
font-size: 12px;
font-style: normal;
}
span {
height: 22px;
line-height: 22px;
margin: 0 4px 5px 0;
padding: 0 8px;
font-size: 12px;
color: #222222;
background: #F3F4F7;
border-radius: 2px;
border: 1px solid #D0D4DC;
}
}
}
}
</style>