5 changed files with 1354 additions and 0 deletions
@ -0,0 +1,20 @@
|
||||
import request from '@/utils/request' |
||||
|
||||
export function getHot(query: any) { |
||||
return request.get({ url: '/hot/list',query }) |
||||
} |
||||
|
||||
export function getHotDetail(params: Record<string, any>) { |
||||
return request.get({ url: '/hot/detail?',params}) |
||||
} |
||||
export function addIntoMail(body) { |
||||
return request.post({ url: '/hot/addIntoMail', body}) |
||||
} |
||||
export function addIntoBadMail(body) { |
||||
return request.post({ url: '/hot/addIntoBadMail', body}) |
||||
} |
||||
|
||||
|
||||
export function addHotMail(body) { |
||||
return request.post({ url: '/hot/add', body}) |
||||
} |
||||
@ -0,0 +1,281 @@
|
||||
<template> |
||||
<el-dialog |
||||
width="50vw" |
||||
align-center |
||||
title="12345投诉新建信件" |
||||
> |
||||
<el-form |
||||
ref="formRef" |
||||
:model="form" |
||||
label-width="80px" |
||||
:rules="rules" |
||||
style="width: 100%" |
||||
> |
||||
<el-form-item |
||||
label="信件信息" |
||||
|
||||
required |
||||
style=" |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: start; |
||||
" |
||||
> |
||||
<template #label> |
||||
<span |
||||
class="main-label" |
||||
style="text-align: left; width: 100%" |
||||
>话务信息</span |
||||
> |
||||
</template> |
||||
<el-row style="width: 100%;height: 40px;"> |
||||
<el-col :span="9" > |
||||
<el-form-item |
||||
label="来源" |
||||
class="info-input" |
||||
prop="source" |
||||
|
||||
|
||||
> |
||||
<el-input |
||||
v-model="form.source" |
||||
placeholder="请输入来源" |
||||
></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="9"> |
||||
<el-form-item |
||||
label="来电时间" |
||||
class="info-input" |
||||
prop="phoneTime" |
||||
|
||||
|
||||
> |
||||
|
||||
<el-date-picker v-model="form.phoneTime" value-format="YYYY-MM-DD HH:mm:ss" |
||||
type="datetime" format="YYYY-MM-DD HH:mm:ss" /> |
||||
</el-form-item> |
||||
|
||||
</el-col> |
||||
</el-row> |
||||
<el-row style="width: 100%;height: 40px;"> |
||||
<el-col :span="9"> |
||||
<el-form-item |
||||
label="市民姓名" |
||||
class="info-input" |
||||
prop="contactName" |
||||
required |
||||
|
||||
> |
||||
<el-input |
||||
v-model="form.contactName" |
||||
placeholder="请输入市民姓名" |
||||
></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
|
||||
<el-col :span="9"> |
||||
<el-form-item |
||||
label="来电电话" |
||||
class="info-input" |
||||
prop="contactPhone" |
||||
required |
||||
|
||||
> |
||||
<el-input |
||||
v-model="form.contactPhone" |
||||
placeholder="请输入来电电话" |
||||
></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row style="width: 100%;height: 40px;"> |
||||
<el-col :span="9"> |
||||
<el-form-item |
||||
label="证件号码" |
||||
class="info-input" |
||||
prop="contactIdCard" |
||||
|
||||
> |
||||
<el-input |
||||
v-model="form.contactIdCard" |
||||
placeholder="请输入证件号码" |
||||
></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="9"> |
||||
<el-form-item |
||||
label="话务类型" |
||||
class="info-input" |
||||
prop="contactType" |
||||
|
||||
|
||||
> |
||||
<el-input |
||||
v-model="form.contactType" |
||||
placeholder="请输入话务类型" |
||||
></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
</el-form-item> |
||||
<el-divider /> |
||||
<el-row class="title-label"> |
||||
<el-col> |
||||
<span class="main-label">来话内容</span> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col> |
||||
<el-form-item |
||||
label="来话内容" |
||||
style="width: 100%" |
||||
prop="content" |
||||
> |
||||
<el-input |
||||
type="textarea" |
||||
v-model="form.content" |
||||
placeholder="请输入来话内容" |
||||
></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
|
||||
<el-divider /> |
||||
<el-row class="title-label"> |
||||
<el-col> |
||||
<span class="main-label">案件信息</span> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="9"> |
||||
<el-form-item label="案件类型" prop="caseType" class="info-input"> |
||||
<el-input |
||||
v-model="form.caseType" |
||||
placeholder="请输入案件类型" |
||||
></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
|
||||
|
||||
<div |
||||
style=" |
||||
width: 100%; |
||||
display: flex; |
||||
justify-content: flex-end; |
||||
" |
||||
> |
||||
<el-button |
||||
type="primary" |
||||
@click="handleSubmit" |
||||
style="height: 40px" |
||||
>提交信件</el-button |
||||
> |
||||
</div> |
||||
</el-form> |
||||
</el-dialog> |
||||
</template> |
||||
<script lang="ts" setup> |
||||
import { ref, reactive } from "vue"; |
||||
import type { FormInstance, FormRules } from "element-plus"; |
||||
import { useDictOptions } from "@/hooks/useDictOptions"; |
||||
import { listSecond } from "@/api/org/department"; |
||||
import { useDictData } from "@/hooks/useDictOptions"; |
||||
import { addHotMail } from "@/api/hot"; |
||||
import feedback from "@/utils/feedback"; |
||||
import { validatorPhone } from "@/utils/util"; |
||||
|
||||
const { dictData } = useDictData(["mail_source"]); |
||||
|
||||
interface FormData { |
||||
source: string; |
||||
contactName: string; |
||||
contactIdCard: string; |
||||
contactPhone: string; |
||||
caseType: string; |
||||
content: string; |
||||
contactType:string; |
||||
phoneTime:string; |
||||
} |
||||
|
||||
const formRef = ref<FormInstance>(); |
||||
const form = ref({ |
||||
source: "", |
||||
contactName: "", |
||||
contactIdCard: "", |
||||
contactPhone: "", |
||||
caseType: "", |
||||
content: "", |
||||
contactType:"", |
||||
phoneTime:"", |
||||
}); |
||||
|
||||
const rules = reactive<FormRules<FormData>>({ |
||||
contactName: [ |
||||
{ required: true, message: "请输入姓名" }, |
||||
], |
||||
contactPhone: [ |
||||
{ required: true, validator: validatorPhone }, |
||||
], |
||||
content: [ |
||||
{ |
||||
required: true, |
||||
message: |
||||
"请输入来话内容", |
||||
trigger: "blur" |
||||
}, |
||||
], |
||||
}); |
||||
const { optionsData } = useDictOptions<{ |
||||
dept: any[]; |
||||
}>({ |
||||
dept: { |
||||
api: listSecond, |
||||
}, |
||||
}); |
||||
|
||||
const emit = defineEmits(["success", "close"]); |
||||
|
||||
|
||||
const handleSubmit = () => { |
||||
formRef.value.validate((valid: boolean) => { |
||||
if (valid) { |
||||
addHotMail(form.value).then(() => { |
||||
emit("success"); |
||||
emit("close"); |
||||
feedback.msgSuccess("操作成功"); |
||||
formRef.value.resetFields() |
||||
form.value.fileList = [] |
||||
form.value.involvedDeptName = '' |
||||
}); |
||||
} |
||||
}); |
||||
}; |
||||
|
||||
|
||||
</script> |
||||
<style lang="scss" scoped> |
||||
.main-label { |
||||
width: 80px; |
||||
height: 22px; |
||||
font-size: 20px; |
||||
font-family: PingFang-SC, PingFang-SC; |
||||
font-weight: bold; |
||||
color: #333333; |
||||
line-height: 22px; |
||||
} |
||||
|
||||
.title-label { |
||||
margin-bottom: 20px; |
||||
} |
||||
.info-input { |
||||
width: 100%; |
||||
} |
||||
|
||||
.el-upload__inner { |
||||
display: flex; |
||||
justify-content: center; |
||||
align-items: center; |
||||
} |
||||
</style> |
||||
@ -0,0 +1,375 @@
|
||||
<template> |
||||
<div class="flex gap-12 wrap file-container"> |
||||
<div |
||||
v-for="(item, index) in fileList" |
||||
:key="index" |
||||
class="item pointer" |
||||
> |
||||
<template v-if="item.type && item.type.indexOf('image') > -1"> |
||||
<div |
||||
class="img-box" |
||||
:style="{ |
||||
backgroundImage: `url(${VITE_API_URL}/file/stream/${item.filepath})`, |
||||
}" |
||||
@click="filePreview(item)" |
||||
></div> |
||||
<a |
||||
class="remove-btn" |
||||
@click="remove(index)" |
||||
v-if="removeEnable" |
||||
> |
||||
<img src="\imgs\close.png"/> |
||||
</a> |
||||
</template> |
||||
<div |
||||
class="item flex end v-center column text-center" |
||||
:title="item.orgiinFilename" |
||||
@click="filePreview(item)" |
||||
v-else |
||||
> |
||||
<icon :name="getIconName(item.type)" :size="40" /> |
||||
<span class="filename">{{ item.orgiinFilename }}</span> |
||||
<a |
||||
class="remove-btn" |
||||
@click.stop="remove(index)" |
||||
v-if="removeEnable" |
||||
> |
||||
<img src="\imgs\close.png"/> |
||||
</a> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
</template> |
||||
<script setup> |
||||
|
||||
import { watch } from "vue"; |
||||
|
||||
const { VITE_API_URL } = process.env; |
||||
const props = defineProps({ |
||||
files: { |
||||
type: Array, |
||||
default: () => [], |
||||
}, |
||||
removeEnable: { |
||||
type: Boolean, |
||||
default: false, |
||||
}, |
||||
}); |
||||
const emit = defineEmits(["update:files"]); |
||||
|
||||
const fileList = ref(props.files); |
||||
|
||||
watch( |
||||
() => props.files, |
||||
(files) => { |
||||
fileList.value = files; |
||||
} |
||||
); |
||||
|
||||
const activeFile = ref({}); |
||||
const fileRrror = ref(false); |
||||
const rotate = ref(0); |
||||
const scale = ref(0); |
||||
const translateX = ref(0); |
||||
const translateY = ref(0); |
||||
let moveFlag = false; |
||||
let initialX = 0; |
||||
let initialY = 0; |
||||
function prev() { |
||||
const index = fileList.value.indexOf(activeFile.value); |
||||
if (index === 0) { |
||||
filePreview(fileList.value[fileList.value.length - 1]); |
||||
} else { |
||||
filePreview(fileList.value[index - 1]); |
||||
} |
||||
} |
||||
function next() { |
||||
const index = fileList.value.indexOf(activeFile.value); |
||||
if (index === fileList.value.length - 1) { |
||||
filePreview(fileList.value[0]); |
||||
} else { |
||||
filePreview(fileList.value[index + 1]); |
||||
} |
||||
} |
||||
const preview = ref(false); |
||||
watch(preview, (val) => { |
||||
|
||||
}) |
||||
|
||||
function filePreview(file) { |
||||
preview.value = true; |
||||
fileRrror.value = false; |
||||
activeFile.value = file; |
||||
rotate.value = 0; |
||||
scale.value = 1; |
||||
translateX.value = 0; |
||||
translateY.value = 0; |
||||
moveFlag = false; |
||||
|
||||
} |
||||
|
||||
function wheel(event) { |
||||
if (activeFile.value.type.indexOf("image") === -1) { |
||||
return; |
||||
} |
||||
if (event.deltaY > 0 && scale.value > 0.5) { |
||||
scale.value -= 0.1; |
||||
} |
||||
if (event.deltaY < 0) { |
||||
scale.value += 0.1; |
||||
} |
||||
} |
||||
|
||||
function mousedown() { |
||||
moveFlag = true; |
||||
initialX = event.clientX; |
||||
initialY = event.clientY; |
||||
} |
||||
function mousemove(event) { |
||||
if (!moveFlag) { |
||||
return; |
||||
} |
||||
if (rotate.value % 360 === 0) { |
||||
translateX.value += event.clientX - initialX; |
||||
translateY.value += event.clientY - initialY; |
||||
} |
||||
if (rotate.value === 90) { |
||||
translateY.value -= event.clientX - initialX; |
||||
translateX.value += event.clientY - initialY; |
||||
} |
||||
if (rotate.value === 180) { |
||||
translateX.value -= event.clientX - initialX; |
||||
translateY.value -= event.clientY - initialY; |
||||
} |
||||
if (rotate.value === 270) { |
||||
translateY.value += event.clientX - initialX; |
||||
translateX.value -= event.clientY - initialY; |
||||
} |
||||
initialX = event.clientX; |
||||
initialY = event.clientY; |
||||
} |
||||
|
||||
function mouseup(event) { |
||||
moveFlag = false; |
||||
} |
||||
|
||||
function rotateLeft() { |
||||
if (rotate.value === 360) { |
||||
rotate.value = 0; |
||||
} else { |
||||
rotate.value += 90; |
||||
} |
||||
} |
||||
|
||||
function rotateRight() { |
||||
if (rotate.value === 0) { |
||||
rotate.value = 270; |
||||
} else { |
||||
rotate.value -= 90; |
||||
} |
||||
} |
||||
|
||||
function getIconName(filetype) { |
||||
if (!filetype) { |
||||
return "el-icon-document"; |
||||
} |
||||
if (filetype.indexOf("image") > -1) { |
||||
return "el-icon-Picture"; |
||||
} |
||||
if (filetype === "application/pdf") { |
||||
return "local-icon-pdf"; |
||||
} |
||||
if (filetype.indexOf("audio") > -1) { |
||||
return "local-icon-mp3"; |
||||
} |
||||
if (filetype.indexOf("word") > -1) { |
||||
return "local-icon-doc"; |
||||
} |
||||
if ( |
||||
filetype.indexOf("excel") > -1 || |
||||
filetype.indexOf("spreadsheetml.sheet") > -1 |
||||
) { |
||||
return "local-icon-xls"; |
||||
} |
||||
if ( |
||||
filetype.indexOf("video") > -1 |
||||
) { |
||||
return "local-icon-mp4"; |
||||
} |
||||
return "el-icon-document"; |
||||
} |
||||
|
||||
function remove(index) { |
||||
fileList.value.splice(index, 1); |
||||
emit("update:files", fileList.value); |
||||
} |
||||
|
||||
function download() { |
||||
window.open(`${VITE_API_URL}/api/file/stream/${activeFile.value.filepath}`); |
||||
} |
||||
|
||||
function getDocFilepath() { |
||||
if ( |
||||
activeFile.value.type === "application/msword" && |
||||
activeFile.value.docxFilepath |
||||
) { |
||||
return `${VITE_API_URL}/api/file/stream/${activeFile.value.docxFilepath}`; |
||||
} |
||||
return `${VITE_API_URL}/api/file/stream/${activeFile.value.filepath}`; |
||||
} |
||||
</script> |
||||
<style lang="scss" scoped> |
||||
.file-container { |
||||
min-height: 80px; |
||||
.item { |
||||
width: 80px; |
||||
height: 80px; |
||||
margin-bottom: 12px; |
||||
border-radius: 2px; |
||||
color: var(--primary-color); |
||||
position: relative; |
||||
&:hover { |
||||
background-color: #ededed; |
||||
span.filename { |
||||
font-weight: 700; |
||||
} |
||||
} |
||||
span.filename { |
||||
line-height: 1.2; |
||||
font-size: 12px; |
||||
width: 100%; |
||||
white-space: nowrap; |
||||
text-overflow: ellipsis; |
||||
margin-top: 10px; |
||||
overflow: hidden; |
||||
} |
||||
.img-box { |
||||
width: 80px; |
||||
height: 80px; |
||||
background-size: cover; |
||||
background-position: center; |
||||
border-radius: 2px; |
||||
&:hover { |
||||
outline: 2px solid #ff9800; |
||||
} |
||||
} |
||||
.remove-btn { |
||||
position: absolute; |
||||
top: -10px; |
||||
right: -10px; |
||||
display: block; |
||||
border-radius: 50%; |
||||
height: 20px; |
||||
background-color: #fff; |
||||
&:hover { |
||||
color: red; |
||||
cursor: pointer; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.file-preview-wrapper { |
||||
.file-list { |
||||
width: 15vw; |
||||
height: 100vh; |
||||
padding: 16px 8px; |
||||
background-color: #fff; |
||||
box-sizing: border-box; |
||||
section { |
||||
padding: 8px 16px; |
||||
border: 2px solid transparent; |
||||
&:hover { |
||||
color: var(--primary-color); |
||||
font-weight: 700; |
||||
} |
||||
&[active="true"] { |
||||
border-color: var(--primary-color); |
||||
} |
||||
span { |
||||
width: calc(100% - 32px); |
||||
overflow: hidden; |
||||
white-space: nowrap; |
||||
text-overflow: ellipsis; |
||||
} |
||||
} |
||||
} |
||||
.file-content { |
||||
width: 86vw; |
||||
position: relative; |
||||
|
||||
.img-container { |
||||
height: 100vh; |
||||
img { |
||||
max-height: 100%; |
||||
display: block; |
||||
&:hover { |
||||
cursor: pointer; |
||||
} |
||||
} |
||||
} |
||||
.error { |
||||
background-color: #fff; |
||||
img { |
||||
width: 500px; |
||||
} |
||||
} |
||||
} |
||||
.close-btn { |
||||
position: absolute; |
||||
top: 12px; |
||||
right: 8px; |
||||
background-color: transparent; |
||||
border: none; |
||||
color: #fff; |
||||
&:hover { |
||||
color: red; |
||||
} |
||||
} |
||||
.rotate-left-btn { |
||||
position: absolute; |
||||
top: 12px; |
||||
right: 118px; |
||||
background-color: transparent; |
||||
border: none; |
||||
color: #fff; |
||||
} |
||||
.rotate-right-btn { |
||||
position: absolute; |
||||
top: 12px; |
||||
right: 68px; |
||||
background-color: transparent; |
||||
border: none; |
||||
color: #fff; |
||||
} |
||||
.left-btn { |
||||
position: absolute; |
||||
top: 50%; |
||||
left: 0; |
||||
transform: translateY(-50%); |
||||
background-color: transparent; |
||||
border: none; |
||||
color: #fff; |
||||
} |
||||
.right-btn { |
||||
position: absolute; |
||||
top: 50%; |
||||
right: 0; |
||||
transform: translateY(-50%); |
||||
background-color: transparent; |
||||
border: none; |
||||
color: #fff; |
||||
} |
||||
.download-btn { |
||||
position: absolute; |
||||
bottom: 16px; |
||||
right: 18px; |
||||
} |
||||
.file-number { |
||||
position: absolute; |
||||
top: 16px; |
||||
left: 18px; |
||||
color: #fff; |
||||
} |
||||
} |
||||
</style> |
||||
@ -0,0 +1,444 @@
|
||||
<template> |
||||
<el-dialog |
||||
v-model="visible" |
||||
:show-close="false" |
||||
width="84vw" |
||||
top="2vh" |
||||
class="dialog-header-nopadding" |
||||
style="--el-dialog-padding-primary: 10px; margin-bottom: 2vh" |
||||
> |
||||
<template #header="{ close, titleId, titleClass }"> |
||||
<header class="flex between v-center dialog-header"> |
||||
<div class="ml-16"> |
||||
<span class="mr-8 second">受理编号{{hot.id}}</span> |
||||
</div> |
||||
<div class="flex"> |
||||
<!-- #FA8695 --> |
||||
<el-button |
||||
link |
||||
circle |
||||
size="large" |
||||
@click="close" |
||||
class="close-btn" |
||||
> |
||||
<template #icon> |
||||
<icon |
||||
name="el-icon-close" |
||||
:size="26" |
||||
:color="'#fff'" |
||||
/> |
||||
</template> |
||||
</el-button> |
||||
</div> |
||||
</header> |
||||
</template> |
||||
<main v-loading="loading"> |
||||
<el-row :gutter="20" style="height: 100%"> |
||||
<el-col :span="24" style="height: 100%"> |
||||
<el-scrollbar max-height="100%" class="main-container"> |
||||
<div> |
||||
<div class="ml-20 mt-20 mt-15 mr-20 report-card"> |
||||
<el-row > |
||||
<h3>话务信息</h3> |
||||
</el-row> |
||||
<el-row class="my-cow"> |
||||
<el-col :span="1" style="display: flex;justify-content: flex-end" > |
||||
<span>编号</span> |
||||
</el-col> |
||||
<el-col :span="5"> |
||||
<span class="span-item">{{hot.id}}</span> |
||||
</el-col> |
||||
<el-col :span="1" style="display: flex;justify-content: flex-end"> |
||||
<span>来源</span> |
||||
</el-col> |
||||
<el-col :span="5"> |
||||
<span class="span-item">{{hot.source}}</span> |
||||
</el-col> |
||||
<el-col :span="1" style="display: flex;justify-content: flex-end"> |
||||
<span>来电时间</span> |
||||
</el-col> |
||||
<el-col :span="5"> |
||||
<span class="span-item">{{hot.phoneTime}}</span> |
||||
</el-col> |
||||
<el-col :span="1" style="display: flex;justify-content: flex-end"> |
||||
<span>市民姓名</span> |
||||
</el-col> |
||||
<el-col :span="5"> |
||||
<span class="span-item">{{hot.contactName}}</span> |
||||
</el-col> |
||||
|
||||
</el-row> |
||||
<el-row class="my-cow" > |
||||
<el-col :span="1" style="display: flex;justify-content: flex-end"> |
||||
<span>来电电话</span> |
||||
</el-col> |
||||
<el-col :span="5"> |
||||
<span class="span-item">{{hot.contactPhone}}</span> |
||||
</el-col> |
||||
<el-col :span="1" style="display: flex;justify-content: flex-end"> |
||||
<span>证件号码</span> |
||||
</el-col> |
||||
<el-col :span="5"> |
||||
<span class="span-item">{{hot.contactIdCard}}</span></el-col> |
||||
<el-col :span="1" style="display: flex;justify-content: flex-end"> |
||||
<span>话务类型</span> |
||||
</el-col> |
||||
<el-col :span="5"> |
||||
<span class="span-item">{{hot.contactType}}</span> |
||||
</el-col> |
||||
</el-row> |
||||
|
||||
</div> |
||||
<div class="ml-20 mt-20 mt-15 mr-20 report-card"> |
||||
<el-row > |
||||
<h3>来话内容</h3> |
||||
</el-row> |
||||
<el-row class="cow-content" > |
||||
<el-col :span="20"> |
||||
<span class="span-item">{{hot.content}}</span> |
||||
</el-col> |
||||
</el-row> |
||||
</div> |
||||
<div class="ml-20 mt-20 mt-15 mr-20 report-card"> |
||||
<el-row > |
||||
<h3>案件信息</h3> |
||||
</el-row> |
||||
<el-row class="my-cow"> |
||||
<el-col :span="1" style="display: flex;justify-content: flex-end"> |
||||
<span>案件类型</span> |
||||
</el-col> |
||||
<el-col :span="5"> |
||||
<span class="span-item">{{hot.caseType}}</span> |
||||
</el-col> |
||||
</el-row> |
||||
</div> |
||||
</div> |
||||
|
||||
<div style="height: 20px"></div> |
||||
</el-scrollbar> |
||||
</el-col> |
||||
</el-row> |
||||
</main> |
||||
<footer class="flex between"> |
||||
<div></div> |
||||
<div style="margin-left: auto;"> |
||||
<el-button |
||||
type="danger" |
||||
size="large" |
||||
@click="addIntoBad" |
||||
>不纳入信件</el-button |
||||
> |
||||
<el-button |
||||
type="primary" |
||||
size="large" |
||||
@click="addInto" |
||||
>纳入信件</el-button |
||||
> |
||||
</div> |
||||
</footer> |
||||
|
||||
</el-dialog> |
||||
<Message ref="messageRef" /> |
||||
<IntoBad |
||||
v-model="returnShow" |
||||
v-model:data="requestData" |
||||
@submit="submitAction()" |
||||
@close="returnShow = false" |
||||
/> |
||||
</template> |
||||
<script setup> |
||||
import IntoBad from "./IntoBad.vue"; |
||||
import { useDictData } from "@/hooks/useDictOptions"; |
||||
import feedback from "@/utils/feedback"; |
||||
import { timeDiffSeconds, formatTimeText, getDictLable } from "@/utils/util"; |
||||
import { getHotDetail,addIntoMail,addIntoBadMail } from "@/api/hot"; |
||||
const loading = ref(false); |
||||
const messageRef = ref(); |
||||
|
||||
const emits = defineEmits(["update:show", "update"]); |
||||
const props = defineProps({ |
||||
show: { |
||||
type: Boolean, |
||||
default: false, |
||||
}, |
||||
hotId: { |
||||
type: String, |
||||
default: "", |
||||
}, |
||||
}); |
||||
const returnShow = ref(false); |
||||
const visible = ref(props.show); |
||||
const requestData = ref({}); |
||||
watch(visible, (val) => { |
||||
emits("update:show", val); |
||||
}); |
||||
watch( |
||||
() => props.show, |
||||
(val) => { |
||||
visible.value = val; |
||||
} |
||||
); |
||||
const hot = ref({}); |
||||
async function getDetail() { |
||||
loading.value = true; |
||||
// 信件详情 |
||||
let data; |
||||
data = await getHotDetail({id : props.hotId}); |
||||
loading.value = false; |
||||
hot.value = data; |
||||
} |
||||
|
||||
function addInto() { |
||||
loading.value = true; |
||||
addIntoMail({id : props.hotId}).then(() => { |
||||
messageRef.value.showMessage("已成功纳入信件"); |
||||
visible.value = false; |
||||
emits("update"); |
||||
loading.value = false; |
||||
return; |
||||
}); |
||||
} |
||||
|
||||
function addIntoBad() { |
||||
returnShow.value = true; |
||||
return; |
||||
} |
||||
|
||||
function submitAction() { |
||||
loading.value = true; |
||||
returnShow.value = false; |
||||
addIntoBadMail({id:props.hotId,reason:requestData.value.reason}).then(() => { |
||||
messageRef.value.showMessage("不纳入信件成功"); |
||||
emits("update"); |
||||
visible.value = false; |
||||
loading.value = false; |
||||
return; |
||||
}); |
||||
|
||||
} |
||||
|
||||
|
||||
watch( |
||||
() => props.hotId, |
||||
(val) => { |
||||
getDetail(); |
||||
} |
||||
); |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</script> |
||||
<style lang="scss" scoped> |
||||
|
||||
|
||||
.cow-content{ |
||||
margin-left: 20px; |
||||
margin-bottom: 8px; |
||||
} |
||||
.my-cow{ |
||||
|
||||
margin-left: 100px; |
||||
margin-bottom: 20px; |
||||
|
||||
} |
||||
.span-item{ |
||||
color: #333333; |
||||
margin-left: 15px; |
||||
} |
||||
.report-card{ |
||||
border-bottom: 1px solid #F0F0F0; |
||||
height: 150px; |
||||
} |
||||
.dialog-header { |
||||
--dialog-header-font-color: #acb7ff; |
||||
--dialog-header-font-size: 16px; |
||||
background-color: var(--primary-color); |
||||
color: #fff; |
||||
padding: 1em; |
||||
font-size: var(--dialog-header-font-size); |
||||
.second { |
||||
color: var(--dialog-header-font-color); |
||||
} |
||||
.step-box { |
||||
.step { |
||||
--setp-background-color: #3a4dc1; |
||||
--setp-border-color: #4b60e4; |
||||
--setp-font-color: var(--dialog-header-font-color); |
||||
--setp-font-size: var(--dialog-header-font-size); |
||||
padding-left: 30px; |
||||
padding-right: 16px; |
||||
&::after { |
||||
display: none; |
||||
} |
||||
&:first-child { |
||||
padding-left: 16px; |
||||
} |
||||
&[active="true"] { |
||||
--setp-background-color: #ff4242; |
||||
--setp-border-color: #ff7474; |
||||
--setp-font-color: #fff; |
||||
} |
||||
.bloder { |
||||
font-size: 24px; |
||||
font-weight: 700; |
||||
margin-right: 8px; |
||||
} |
||||
span { |
||||
z-index: 2; |
||||
} |
||||
} |
||||
} |
||||
.fav-btn { |
||||
--el-font-size-base: 18px; |
||||
--el-button-bg-color: #283aac; |
||||
--el-button-hover-bg-color: #c20921; |
||||
--el-button-hover-border-color: #fa8695; |
||||
&.active { |
||||
--el-button-bg-color: #c20921; |
||||
} |
||||
&:focus { |
||||
background-color: var(--el-button-bg-color); |
||||
} |
||||
} |
||||
.close-btn:hover { |
||||
:deep() { |
||||
.el-icon { |
||||
color: #c20921; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.left-container { |
||||
padding: 0 20px 0 40px; |
||||
} |
||||
.timer { |
||||
--large-font-color: var(--primary-color); |
||||
--default-font-color: #999; |
||||
color: var(--default-font-color); |
||||
.error { |
||||
--large-font-color: #fff; |
||||
--default-font-color: #fff; |
||||
background: linear-gradient(180deg, #ff7158 0%, #f40000 100%); |
||||
border: 4px solid #ffcdcd; |
||||
border-radius: 11px; |
||||
box-sizing: border-box; |
||||
margin-bottom: 20px; |
||||
height: 190px; |
||||
width: 100%; |
||||
} |
||||
} |
||||
.timer-box { |
||||
height: 210px; |
||||
} |
||||
.flow { |
||||
.flow-header { |
||||
background: #f5f6ff; |
||||
padding: 8px; |
||||
font-size: 12px; |
||||
} |
||||
.flow-container { |
||||
background-color: #eff0f5; |
||||
padding: 12px 8px; |
||||
min-height: 120px; |
||||
font-size: 12px; |
||||
.second { |
||||
color: #999; |
||||
} |
||||
.primary { |
||||
color: var(--primary-color); |
||||
font-weight: 500; |
||||
} |
||||
.flow-time { |
||||
display: inline-flex; |
||||
padding: 6px; |
||||
margin-left: 6px; |
||||
background-color: #f5f6ff; |
||||
border-left: 2px solid #00d050; |
||||
padding-left: 20px; |
||||
&[danger="true"] { |
||||
border-color: #ff0000; |
||||
span { |
||||
color: #ff0000; |
||||
} |
||||
} |
||||
} |
||||
.flow-info { |
||||
position: relative; |
||||
padding-left: 20px; |
||||
&::before { |
||||
display: block; |
||||
content: ""; |
||||
width: 10px; |
||||
height: 10px; |
||||
border-radius: 50%; |
||||
background-color: #bfbfbf; |
||||
position: absolute; |
||||
left: 0; |
||||
top: 50%; |
||||
transform: translateY(-50%); |
||||
} |
||||
} |
||||
& > div:first-child .flow-info::before { |
||||
width: 12px; |
||||
height: 12px; |
||||
background-color: var(--primary-color); |
||||
} |
||||
} |
||||
} |
||||
|
||||
main { |
||||
height: calc(96vh - 180px); |
||||
} |
||||
.main-container { |
||||
margin-top: -30px; |
||||
padding: 0 20px; |
||||
} |
||||
footer { |
||||
padding: 10px 20px 0; |
||||
} |
||||
:deep() { |
||||
h2 { |
||||
font-size: 24px; |
||||
font-weight: 500; |
||||
color: var(--primary-color); |
||||
margin: 12px 0; |
||||
} |
||||
h3 { |
||||
font-size: 16px; |
||||
font-weight: 500; |
||||
color: var(--primary-color); |
||||
} |
||||
.content { |
||||
font-size: 15px; |
||||
padding: 8px; |
||||
color: #333; |
||||
white-space: pre-wrap; |
||||
} |
||||
|
||||
.file-box { |
||||
img { |
||||
width: 80px; |
||||
height: 80px; |
||||
} |
||||
} |
||||
.el-button.is-disabled { |
||||
--el-button-disabled-bg-color: #b0b0b0; |
||||
--el-button-disabled-border-color: #b0b0b0; |
||||
--el-button-disabled-text-color: #fff; |
||||
} |
||||
.card-info { |
||||
background: #f4f5ff; |
||||
border: 1px solid rgba(195, 202, 245, 1); |
||||
padding: 12px 20px; |
||||
} |
||||
span[danger="true"] { |
||||
color: var(--danger-color); |
||||
} |
||||
.timer-box .el-progress-circle { |
||||
height: 240px !important; |
||||
width: 240px !important; |
||||
} |
||||
} |
||||
</style> |
||||
@ -0,0 +1,234 @@
|
||||
<template> |
||||
<div class="container"> |
||||
<header> |
||||
<el-form :label-width="120"> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="编号"> |
||||
<el-input |
||||
v-model="query.id" |
||||
placeholder="请输入编号" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来源"> |
||||
<el-input |
||||
v-model="query.source" |
||||
placeholder="请输入来源" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来电时间"> |
||||
<el-date-picker v-model="query.searchTime" value-format="YYYY-MM-DD HH:mm:ss" |
||||
type="datetimerange" format="YYYY-MM-DD HH:mm:ss" range-separator="~" |
||||
start-placeholder="开始日期" end-placeholder="结束日期" @change="handleMailTimeQuery" /> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="市名姓名"> |
||||
<el-input |
||||
v-model="query.contactName" |
||||
placeholder="请输入报警人名" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
|
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来电电话"> |
||||
<el-input |
||||
v-model="query.contactPhone" |
||||
placeholder="请输入来电电话" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="证件号码"> |
||||
<el-input |
||||
v-model="query.contactIdCard" |
||||
placeholder="请输入证件号码" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="话务类型"> |
||||
<el-input |
||||
v-model="query.contactType" |
||||
placeholder="请输入话务类型" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="案件类型"> |
||||
<el-input |
||||
v-model="query.caseType" |
||||
placeholder="请输入案件类型" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-button type="primary" @click="createMail" class="under-btn">自建信件</el-button> |
||||
</el-col> |
||||
</el-row> |
||||
<div class="flex end mb-20"> |
||||
<el-button type="primary" @click="getList">查询</el-button> |
||||
<el-button @click="reset">重置</el-button> |
||||
</div> |
||||
</el-form> |
||||
</header> |
||||
<main> |
||||
<!-- <el-tabs v-model="activeTab" @tab-click="handleClick"> |
||||
<el-tab-pane label="未处理" name="table1"> --> |
||||
<div class="table-container"> |
||||
<el-table :data="hot" style="width: 100%" > |
||||
<el-table-column prop="id" label="编号" align="center" width="160" /> |
||||
<el-table-column prop="source" label="来源" align="center" width="160" /> |
||||
<el-table-column prop="phoneTime" label="来电时间" align="center" width="160" /> |
||||
<el-table-column prop="contactName" label="市民姓名" align="center" /> |
||||
<el-table-column prop="contactPhone" label="来电电话" align="center"/> |
||||
<el-table-column prop="contactIdCard" label="证件号码" align="center"/> |
||||
<el-table-column prop="contactType" label="话务类型" align="center"/> |
||||
<el-table-column prop="content" show-overflow-tooltip label="来话内容" align="center"/> |
||||
<el-table-column prop="caseType" show-overflow-tooltip label="案件类型" align="center"/> |
||||
<el-table-column label="操作" fixed="right" align="center"> |
||||
<template #default="{ row }"> |
||||
<el-button |
||||
type="primary" |
||||
link |
||||
@click="handleMail(row)" |
||||
>立即处理</el-button |
||||
> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
</div> |
||||
<!-- </el-tab-pane> |
||||
<el-tab-pane label="已剔除" name="table2"> |
||||
<div class="table-container"> |
||||
<el-table :data="report" style="width: 100%" > |
||||
<el-table-column prop="contactPhone" label="报警电话" align="center" width="160" /> |
||||
<el-table-column prop="hzsj" label="话终时间" align="center" width="160" /> |
||||
<el-table-column prop="contactName" label="报警人名" align="center" /> |
||||
<el-table-column prop="jjlxdmms" label="报警类型" align="center"/> |
||||
<el-table-column prop="ysjqxzmc" label="接警性质" align="center"/> |
||||
<el-table-column prop="gxdwmc" label="管辖单位" align="center"/> |
||||
<el-table-column prop="content" show-overflow-tooltip label="报警内容" align="center"/> |
||||
<el-table-column prop="xchfnr" show-overflow-tooltip label="反馈结警" align="center"/> |
||||
</el-table> |
||||
</div> |
||||
</el-tab-pane> |
||||
</el-tabs> --> |
||||
|
||||
<div class="flex mt-4 end"> |
||||
<el-pagination @size-change="getList" @current-change="getList" :current-page="query.current" |
||||
:page-sizes="[10, 20, 50]" :page-size="query.size" v-model:current-page="query.current" |
||||
layout="total,sizes, prev, pager, next, jumper" :total="totalSize.total"> |
||||
</el-pagination> |
||||
</div> |
||||
</main> |
||||
</div> |
||||
|
||||
<HotDialog v-model:show="showModel" :disabled="true" :hotId="activehotId" |
||||
@update="getList" /> |
||||
<AddMail |
||||
v-model="addMailShow" |
||||
@close="addMailShow = false" |
||||
@success="getList" |
||||
/> |
||||
</template> |
||||
<script lang="ts" setup> |
||||
import HotDialog from "./HotDialog.vue"; |
||||
import { getHot} from '@/api/hot' |
||||
import { ref, reactive, watchEffect } from "vue"; |
||||
import { useDictOptions } from '@/hooks/useDictOptions' |
||||
import AddMail from "./AddMail.vue"; |
||||
const activehotId = ref(""); |
||||
const query = ref({ |
||||
size: 10, |
||||
current: 1 |
||||
}); |
||||
const totalSize = reactive({ |
||||
total: 0, |
||||
pages: 0 |
||||
}) |
||||
const activeTab = ref('table1'); |
||||
const hot = ref([]); |
||||
const showModel = ref(false); |
||||
function handleMail(row) { |
||||
showModel.value = true; |
||||
activehotId.value = row.id; |
||||
} |
||||
const addMailShow = ref(false); |
||||
const createMail = () => { |
||||
addMailShow.value = true; |
||||
}; |
||||
|
||||
function getList() { |
||||
// query.value.activeTab = activeTab.value; |
||||
getHot(query.value).then((data) => { |
||||
hot.value = data.records; |
||||
totalSize.total = data.total; |
||||
totalSize.pages = data.pages; |
||||
}); |
||||
} |
||||
|
||||
function handleClick(tab){ |
||||
if(tab.index == 0){ |
||||
activeTab.value = "table1" |
||||
}else{ |
||||
activeTab.value = "table2" |
||||
} |
||||
getList(); |
||||
} |
||||
function reset() { |
||||
query.value = {} |
||||
getList() |
||||
} |
||||
|
||||
getList() |
||||
|
||||
const handleMailTimeQuery = (val: any) => { |
||||
if (val) { |
||||
query.value.searchStartTime = val[0]; |
||||
query.value.searchEndTime = val[1]; |
||||
} else { |
||||
delete query.value.searchStartTime |
||||
delete query.value.searchEndTime |
||||
} |
||||
} |
||||
|
||||
</script> |
||||
<style lang="scss" scoped> |
||||
.success { |
||||
padding: 0 8px; |
||||
height: 24px; |
||||
line-height: 24px; |
||||
text-align: center; |
||||
|
||||
.text { |
||||
color: #128009; |
||||
} |
||||
} |
||||
|
||||
.error { |
||||
background-color: #ff0000; |
||||
color: #fff; |
||||
padding: 0 8px; |
||||
height: 24px; |
||||
line-height: 24px; |
||||
border-radius: 20px; |
||||
text-align: center; |
||||
} |
||||
</style> |
||||
Loading…
Reference in new issue