31 changed files with 1826 additions and 1291 deletions
@ -0,0 +1,26 @@
|
||||
import { get, post} from "@/util/request" |
||||
|
||||
export function login(body) { |
||||
return post({ |
||||
url: '/admin/login', body |
||||
}) |
||||
} |
||||
|
||||
export function self() { |
||||
return get({ |
||||
url: '/admin/self' |
||||
}) |
||||
} |
||||
|
||||
|
||||
export function adminList() { |
||||
return get({ |
||||
url: '/admin' |
||||
}) |
||||
} |
||||
|
||||
export function addAdmin(body) { |
||||
return post({ |
||||
url: '/admin', body |
||||
}) |
||||
} |
||||
@ -1,8 +1,8 @@
|
||||
import { get, post} from "@/util/request" |
||||
|
||||
|
||||
import { get } from "@/util/request" |
||||
|
||||
export function listSecond() { |
||||
return get('/system/dept/second/list') |
||||
return get({ |
||||
url: '/system/dept/second/list' |
||||
}) |
||||
} |
||||
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
import { get, post} from "@/util/request" |
||||
|
||||
export function getdetail(id) { |
||||
return post('/mailbox/detail',id) |
||||
return post({ |
||||
url: '/mailbox/detail?id=' + id |
||||
}) |
||||
} |
||||
|
||||
@ -1,10 +1,17 @@
|
||||
import { get, post} from "@/util/request" |
||||
export function getholiday(search) { |
||||
return get('/outer/holiday/getholiday?search='+search) |
||||
return get({ |
||||
url: '/outer/holiday/getholiday?search='+search |
||||
}) |
||||
} |
||||
export function showholiday() { |
||||
return get('/outer/holiday/showholiday') |
||||
return get({ |
||||
url: '/outer/holiday/show-holiday' |
||||
}) |
||||
} |
||||
export function saveholiday(search) { |
||||
return post('/outer/holiday/saveholiday',search) |
||||
export function refreshHoliday(body) { |
||||
return post({ |
||||
url: '/outer/holiday/refresh-holiday', |
||||
body |
||||
}) |
||||
} |
||||
|
||||
@ -0,0 +1,19 @@
|
||||
import { get, post } from "@/util/request" |
||||
|
||||
export function mail12345List(query) { |
||||
return get({ |
||||
url: '/mail12345', query |
||||
}) |
||||
} |
||||
|
||||
export function mail12345Import(body) { |
||||
return post({ |
||||
url: '/mail12345/import', body |
||||
}) |
||||
} |
||||
|
||||
export function addMail12345(body) { |
||||
return post({ |
||||
url: '/mail12345/add', body |
||||
}) |
||||
} |
||||
@ -0,0 +1,13 @@
|
||||
import { get, post} from "@/util/request" |
||||
|
||||
export function listUser(query) { |
||||
return get({ |
||||
url: '/user/list', query |
||||
}) |
||||
} |
||||
|
||||
export function delUser(id) { |
||||
return post({ |
||||
url: '/user/del?id=' + id |
||||
}) |
||||
} |
||||
@ -1,8 +1,79 @@
|
||||
// @/styles/element/index.scss |
||||
@forward "element-plus/theme-chalk/src/common/var.scss" with ( |
||||
$colors: ( |
||||
"primary": ( |
||||
"base": #162582, |
||||
) |
||||
), |
||||
'success': ( |
||||
'base': #064D00, |
||||
), |
||||
'danger': ( |
||||
'base': #F60000, |
||||
), |
||||
'warning': ( |
||||
'base': #D05200, |
||||
), |
||||
) |
||||
); |
||||
); |
||||
|
||||
|
||||
|
||||
.el-date-editor.el-input__wrapper { |
||||
--el-date-editor-daterange-width: 260px; |
||||
} |
||||
|
||||
.el-select { |
||||
min-width: 80px; |
||||
} |
||||
.el-select-dropdown .el-select-dropdown__wrap { |
||||
max-height: 380px; |
||||
} |
||||
|
||||
.el-radio { |
||||
color: #333; |
||||
} |
||||
|
||||
.el-button--primary.is-link>span { |
||||
font-weight: bold; |
||||
} |
||||
|
||||
div.el-table { |
||||
--el-table-header-bg-color: #EBEEFC; |
||||
--el-table-header-text-color: var(--primary-color); |
||||
|
||||
.el-table__header .el-table__cell { |
||||
padding: 20px 0; |
||||
font-size: 15px; |
||||
} |
||||
.text-no-ellipsis .cell { |
||||
text-overflow: clip; |
||||
} |
||||
} |
||||
|
||||
div.el-card { |
||||
border: none; |
||||
} |
||||
|
||||
.el-dialog { |
||||
.el-dialog__header { |
||||
margin-right: 0; |
||||
.el-dialog__headerbtn { |
||||
font-size: 20px; |
||||
|
||||
&:hover .el-dialog__close { |
||||
color: var(--danger-color); |
||||
} |
||||
} |
||||
} |
||||
|
||||
&.dialog-header-nopadding { |
||||
&>.el-dialog__header { |
||||
padding: 0; |
||||
margin-right: 0; |
||||
} |
||||
|
||||
&>.el-dialog__body { |
||||
padding-left: 0; |
||||
padding-right: 0; |
||||
} |
||||
} |
||||
} |
||||
@ -1,140 +0,0 @@
|
||||
<template> |
||||
<div class="wrapper"> |
||||
<header class="text-center"> |
||||
<img src="/imgs/login_logo1.png" alt=""> |
||||
</header> |
||||
<div class="box flex v-center"> |
||||
<div class="left text-center"> |
||||
<img src="/imgs/pic.png" alt="" /> |
||||
</div> |
||||
<div class="right mb-40"> |
||||
<el-form :model="login" size="large"> |
||||
<h1>用户登录</h1> |
||||
<el-form-item label="账号"> |
||||
<el-input v-model="login.account" placeholder="请输入手机号" clearable @input="inputCheck" style="--el-input-height: 50px"> |
||||
<template #prefix> |
||||
<icon name="el-icon-UserFilled" :size="33" color="#c0c5e2" /> |
||||
</template> |
||||
</el-input> |
||||
</el-form-item> |
||||
<el-form-item label="密码"> |
||||
<el-container> |
||||
<el-input v-model="login.captcha" placeholder="请输入密码" type="password" show-password clearable @input="inputCheck" style="--el-input-height: 50px"> |
||||
<template #prefix> |
||||
<icon name="local-icon-lock-fill" :size="36" /> |
||||
</template> |
||||
</el-input> |
||||
<!-- <el-button type="primary" @click="sendCaptcha">发送验证码</el-button> --> |
||||
</el-container> |
||||
</el-form-item> |
||||
<div class="mt-30 mb-10"> |
||||
<el-button type="primary" @click="loginIn" style="width: 100%;">登录</el-button> |
||||
</div> |
||||
|
||||
|
||||
</el-form> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
</template> |
||||
|
||||
<script setup> |
||||
import { reactive } from 'vue' |
||||
import { request } from '../util/axios_config' |
||||
import router from '../router' |
||||
import { ElMessage } from 'element-plus' |
||||
import { useTokenStore } from '../stores/useTokenStore' |
||||
const { VITE_API_URL } = process.env; |
||||
const tokens = useTokenStore() |
||||
|
||||
const login = reactive({ |
||||
account: '', |
||||
captcha: '' |
||||
}) |
||||
|
||||
const inputCheck = () => { |
||||
login.account = login.account.replace(/[^\d]/g, '') |
||||
|
||||
} |
||||
|
||||
// const sendCaptcha = () => { |
||||
// request({ |
||||
// url: '/api/captcha', |
||||
// method: 'POST', |
||||
// data: login, |
||||
// headers: { 'Content-Type': 'application/json' } |
||||
// }).then(res => { |
||||
// ElMessage.success('验证码发送成功') |
||||
// login.captcha = res.data |
||||
// }).catch(err => { |
||||
// ElMessage.error('验证码发送失败') |
||||
// console.log(err) |
||||
// }) |
||||
// } |
||||
|
||||
const loginIn = () => { |
||||
const url = VITE_API_URL +'/login' |
||||
request({ |
||||
url: url, |
||||
method: 'POST', |
||||
data: login, |
||||
headers: { 'Content-Type': 'application/json' } |
||||
}).then(res => { |
||||
if (res.data.stateCode === 200) { |
||||
tokens.setAccessToken(res.data.accessToken) |
||||
tokens.setRefreshToken(res.data.refreshToken) |
||||
console.log("localStorage.getItem('user'):" + localStorage.getItem('user')) |
||||
ElMessage.success('登录成功') |
||||
router.push('/') |
||||
}else{ |
||||
ElMessage.error('登录失败,账号或密码错误') |
||||
} |
||||
}).catch(err => { |
||||
ElMessage.error('登录失败') |
||||
console.log(err) |
||||
}) |
||||
} |
||||
|
||||
</script> |
||||
|
||||
|
||||
<style lang="scss" scoped> |
||||
.wrapper { |
||||
height: 100vh; |
||||
background-image: url("/imgs/bg.png"); |
||||
background-size: cover; |
||||
header { |
||||
padding-top: 3.2vh; |
||||
margin-bottom: 8vh; |
||||
img { |
||||
height: 91px; |
||||
} |
||||
} |
||||
.box { |
||||
--login-box-width: 576px; |
||||
width: 80%; |
||||
margin: auto; |
||||
.left { |
||||
width: calc(100% - var(--login-box-width)); |
||||
img { |
||||
width: 33vw; |
||||
} |
||||
} |
||||
|
||||
.right { |
||||
background-color: #fff; |
||||
border: 18px solid #4169ea; |
||||
width: var(--login-box-width); |
||||
padding: 40px; |
||||
box-sizing: border-box; |
||||
h1 { |
||||
color: var(--primary-color); |
||||
font-size: 32px; |
||||
margin-top: 0; |
||||
margin-bottom: 32px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
||||
@ -1,216 +1,239 @@
|
||||
<template> |
||||
<div style="width: 90vw;margin: 0 auto;"> |
||||
<el-form :model="form" label-width="150px" style="margin-top: 20px; margin-right: -50px;;"> |
||||
<div class="container"> |
||||
<el-form :model="form" label-width="150px"> |
||||
<el-row> |
||||
|
||||
<el-col :span="6"> |
||||
<el-form-item label="数据库名"> |
||||
<el-select |
||||
v-model="MailTab" |
||||
placeholder="Select" |
||||
size="small" |
||||
style="width: 240px" |
||||
> |
||||
<el-option |
||||
v-for="item in options" |
||||
:key="item.value" |
||||
:label="item.label" |
||||
:value="item.value" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="etl编号"> |
||||
<el-input v-model="form.id" placeholder="请输入etl编号" max-length="200px"></el-input> |
||||
<el-form-item label="数据库名"> |
||||
<el-select |
||||
v-model="MailTab" |
||||
placeholder="Select" |
||||
size="small" |
||||
style="width: 240px" |
||||
> |
||||
<el-option |
||||
v-for="item in options" |
||||
:key="item.value" |
||||
:label="item.label" |
||||
:value="item.value" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="编号"> |
||||
<el-input |
||||
v-model="form.id" |
||||
placeholder="请输入编号" |
||||
max-length="200px" |
||||
></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="信件编号"> |
||||
<el-input v-model="form.mailId" placeholder="请输入信件编号"></el-input> |
||||
<el-input |
||||
v-model="form.mailId" |
||||
placeholder="请输入信件编号" |
||||
></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
|
||||
</el-row> |
||||
<el-row> |
||||
|
||||
<el-col :span="6"> |
||||
<el-form-item label="是否成功"> |
||||
<el-input v-model="form.success" placeholder=""></el-input> |
||||
<el-input |
||||
v-model="form.success" |
||||
placeholder="" |
||||
></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="3"></el-col> |
||||
<el-col :span="14" :style="{ display: 'inline-flex', alignItems: 'center' }"> |
||||
<el-row> |
||||
<el-col :span="6"></el-col> |
||||
<el-col :span="6"> |
||||
<el-button type="primary" @click="search" class="under-btn">搜索</el-button></el-col> |
||||
<el-col :span="6"> |
||||
<el-button type="default" style="position: relative; left: 100px;" @click="reset" class="under-btn">重置</el-button></el-col> |
||||
</el-row> |
||||
</el-col> |
||||
</el-row> |
||||
<div class="flex end mb-24"> |
||||
<el-button type="primary" @click="search" class="under-btn" |
||||
>搜索</el-button |
||||
> |
||||
<el-button |
||||
type="default" |
||||
@click="reset" |
||||
class="under-btn" |
||||
>重置</el-button |
||||
> |
||||
</div> |
||||
</el-form> |
||||
|
||||
<div class="table-box" ref="tableBoxHeight" v-loading="loading"> |
||||
<el-table :data="tableData" border :height="tableHeight" table-layout="fixed" |
||||
:header-cell-style="{ 'background-color': '#EBEEFC', 'color': '#1D2C86' }"> |
||||
<el-table-column fixed="left" prop="id" label="etl编号" width="200px"> |
||||
<el-table |
||||
:data="tableData" |
||||
border |
||||
:height="tableHeight" |
||||
table-layout="fixed" |
||||
:header-cell-style="{ |
||||
'background-color': '#EBEEFC', |
||||
color: '#1D2C86', |
||||
}" |
||||
> |
||||
<el-table-column |
||||
fixed="left" |
||||
prop="id" |
||||
label="编号" |
||||
width="80px" |
||||
> |
||||
</el-table-column> |
||||
<el-table-column fixed="left" prop="mailId" label="信件编号" width="200px"> |
||||
<el-table-column |
||||
fixed="left" |
||||
prop="mailId" |
||||
label="信件编号" |
||||
width="200px" |
||||
> |
||||
</el-table-column> |
||||
<el-table-column prop="success" label="是否成功" width="100px"> |
||||
<template #default="{ row }"> |
||||
<span>{{ row.success ? "成功" : "失败" }}</span> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="createTime" label="创建日期" width="120px"> |
||||
<el-table-column |
||||
prop="createTime" |
||||
label="创建日期" |
||||
width="120px" |
||||
> |
||||
</el-table-column> |
||||
<el-table-column prop="errMsg" label="错误信息" width="800px"> |
||||
<el-table-column prop="errMsg" label="错误信息"> |
||||
</el-table-column> |
||||
</el-table> |
||||
</div> |
||||
<div style="display: flex; justify-content: center;position: relative;top: 20px;"> |
||||
<el-pagination background @size-change="handleSizeChange" @current-change="handlePageChange" |
||||
:current-page="pageData.currentPage" :page-sizes="[4, 10, 20, 40, 50]" :page-size="pageData.pageSize" |
||||
layout="total,sizes, prev, pager, next, jumper" :total="pageData.totalSize"> |
||||
</el-pagination> |
||||
<div class="flex end mt-10"> |
||||
<el-pagination |
||||
background |
||||
@size-change="handleSizeChange" |
||||
@current-change="handlePageChange" |
||||
:current-page="pageData.currentPage" |
||||
:page-sizes="[4, 10, 20, 40, 50]" |
||||
:page-size="pageData.pageSize" |
||||
layout="total,sizes, prev, pager, next, jumper" |
||||
:total="pageData.totalSize" |
||||
> |
||||
</el-pagination> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script setup> |
||||
import { request } from '../util/axios_config' |
||||
import { onMounted, ref } from 'vue'; |
||||
import router from '../router'; |
||||
const MailTab = ref('mail_etl') |
||||
import { request } from "../util/axios_config"; |
||||
import { onMounted, ref } from "vue"; |
||||
import router from "../router"; |
||||
const MailTab = ref("mail_etl"); |
||||
const { VITE_API_URL } = process.env; |
||||
const options = [ |
||||
{ |
||||
value: 'mail_etl', |
||||
label: 'mail_etl', |
||||
}, |
||||
{ |
||||
value: 'mail_evaluate_etl', |
||||
label: 'mail_evaluate_etl', |
||||
}, |
||||
|
||||
] |
||||
{ |
||||
value: "mail_etl", |
||||
label: "mail_etl", |
||||
}, |
||||
{ |
||||
value: "mail_evaluate_etl", |
||||
label: "mail_evaluate_etl", |
||||
}, |
||||
]; |
||||
const loading = ref(true); |
||||
|
||||
const form = ref({ |
||||
id: '', |
||||
mailId: '', |
||||
success: '', |
||||
}) |
||||
id: "", |
||||
mailId: "", |
||||
success: "", |
||||
}); |
||||
|
||||
// 定义可变的tableData变量,并用axios请求数据 |
||||
const tableData = ref([]) |
||||
const tableData = ref([]); |
||||
|
||||
const pageData = ref({ |
||||
currentPage: 1, |
||||
pageSize: 8, |
||||
totalSize: 0 |
||||
}) |
||||
totalSize: 0, |
||||
}); |
||||
|
||||
const tableBoxHeight = ref(null) |
||||
const tableHeight = ref('100%') |
||||
const tableBoxHeight = ref(null); |
||||
const tableHeight = ref("100%"); |
||||
const flexColumnWidth = (label, prop) => { |
||||
const width = Math.max(label.length * 12, 120) |
||||
return `${width}px` |
||||
} |
||||
const width = Math.max(label.length * 12, 120); |
||||
return `${width}px`; |
||||
}; |
||||
|
||||
const handleResponse = (response) => { |
||||
tableData.value=[]; |
||||
if(MailTab.value=='mail_etl'){ |
||||
console.log("aaaa") |
||||
tableData.value = []; |
||||
if (MailTab.value == "mail_etl") { |
||||
console.log("aaaa"); |
||||
tableData.value = response.data.mails; |
||||
}else{ |
||||
console.log("bbbb") |
||||
} else { |
||||
console.log("bbbb"); |
||||
tableData.value = response.data.evaMails; |
||||
} |
||||
tableData.value.forEach(item => { |
||||
item.createTime = item.createTime.split('T')[0] |
||||
}) |
||||
tableData.value.forEach((item) => { |
||||
item.createTime = item.createTime.split("T")[0]; |
||||
}); |
||||
pageData.value.totalSize = response.data.pageSet.totalSize; |
||||
loading.value = false; |
||||
} |
||||
}; |
||||
|
||||
const makeRequest = (requestData, callback) => { |
||||
const data = JSON.stringify(requestData) |
||||
const url = VITE_API_URL +'/mailetl/list-submit' |
||||
const data = JSON.stringify(requestData); |
||||
const url = VITE_API_URL + "/mailetl/list-submit"; |
||||
request({ |
||||
url: url, |
||||
method: 'POST', |
||||
method: "POST", |
||||
data: data, |
||||
headers: { 'Content-Type': 'application/json' } |
||||
}).then(callback) |
||||
.catch(function (error) { console.log(error) }) |
||||
} |
||||
headers: { "Content-Type": "application/json" }, |
||||
}) |
||||
.then(callback) |
||||
.catch(function (error) { |
||||
console.log(error); |
||||
}); |
||||
}; |
||||
|
||||
const updateData = (requestData) => { |
||||
makeRequest(requestData, function (response) { |
||||
handleResponse(response) |
||||
}) |
||||
} |
||||
handleResponse(response); |
||||
}); |
||||
}; |
||||
|
||||
onMounted(() => { |
||||
const requestData = { |
||||
formData: form.value, |
||||
selectData:MailTab.value, |
||||
pageData: pageData.value |
||||
} |
||||
updateData(requestData) |
||||
}) |
||||
|
||||
|
||||
|
||||
selectData: MailTab.value, |
||||
pageData: pageData.value, |
||||
}; |
||||
updateData(requestData); |
||||
}); |
||||
|
||||
const handleSizeChange = (size) => { |
||||
const requestData = { |
||||
formData: form.value, |
||||
selectData:MailTab.value, |
||||
pageData: pageData.value |
||||
} |
||||
pageData.value.pageSize = size |
||||
updateData(requestData) |
||||
} |
||||
selectData: MailTab.value, |
||||
pageData: pageData.value, |
||||
}; |
||||
pageData.value.pageSize = size; |
||||
updateData(requestData); |
||||
}; |
||||
|
||||
const handlePageChange = (currentPage) => { |
||||
const requestData = { |
||||
formData: form.value, |
||||
selectData:MailTab.value, |
||||
pageData: pageData.value |
||||
} |
||||
pageData.value.currentPage = currentPage |
||||
updateData(requestData) |
||||
} |
||||
selectData: MailTab.value, |
||||
pageData: pageData.value, |
||||
}; |
||||
pageData.value.currentPage = currentPage; |
||||
updateData(requestData); |
||||
}; |
||||
|
||||
const search = () => { |
||||
const requestData = { |
||||
formData: form.value, |
||||
selectData:MailTab.value, |
||||
pageData: pageData.value |
||||
} |
||||
updateData(requestData) |
||||
} |
||||
selectData: MailTab.value, |
||||
pageData: pageData.value, |
||||
}; |
||||
updateData(requestData); |
||||
}; |
||||
|
||||
const reset = () => { |
||||
form.value = { |
||||
id: '', |
||||
mailId: '', |
||||
success: '', |
||||
} |
||||
} |
||||
|
||||
|
||||
</script> |
||||
|
||||
<style scoped> |
||||
.under-btn { |
||||
margin-right: 30px; |
||||
margin-bottom: 5px; |
||||
} |
||||
|
||||
.table-box { |
||||
/* 全屏时顶部元素总和316px */ |
||||
height: calc(100vh - 336px); |
||||
} |
||||
</style> |
||||
id: "", |
||||
mailId: "", |
||||
success: "", |
||||
}; |
||||
}; |
||||
</script> |
||||
@ -1,275 +0,0 @@
|
||||
<template> |
||||
<div style="width: 90vw;margin: 0 auto;"> |
||||
<el-form :model="form" label-width="150px" style="margin-top: 20px; margin-right: -50px;;"> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="群众姓名"> |
||||
<el-input v-model="form.contactName" placeholder="请输入群众姓名" max-length="200px"></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="群众手机号"> |
||||
<el-input v-model="form.contactPhone" placeholder="请输入群众手机号"></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="群众身份证号"> |
||||
<el-input v-model="form.contactIdCard" placeholder="请输入群众身份证号"></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="3"></el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="案件编号"> |
||||
<el-input v-model="form.id" placeholder="请输入案件编号"></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6" :style="{ flex: '1' }"> |
||||
<el-form-item label="信件内容"> |
||||
<el-input v-model="form.content" type="textarea" placeholder="请输入信件内容" |
||||
:autosize="{ minRows: 1, maxRows: 6 }" resize="none" style="width: 100%;"></el-input> |
||||
</el-form-item></el-col> |
||||
<el-col :span="6" :style="{ flex: '1' }"> |
||||
<el-form-item label="评价结果"> |
||||
<el-input v-model="form.evaluate" type="textarea" placeholder="请输入评价结果" |
||||
:autosize="{ minRows: 1, maxRows: 6 }" resize="none" style="width: 100%;"></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row type="flex"> |
||||
<el-col :span="8"> |
||||
<el-form-item label="来信时间"> |
||||
<el-date-picker v-model="form.date" type="daterange" range-separator="至" start-placeholder="开始日期" |
||||
end-placeholder="结束日期" value-format="YYYY-MM-DD"></el-date-picker> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="14"> |
||||
</el-col> |
||||
<el-col :span="8" :style="{ display: 'inline-flex', alignItems: 'center' }"> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-button type="primary" @click="createMail" class="under-btn">自建信件</el-button> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-button type="primary" @click="search" class="under-btn">搜索</el-button></el-col> |
||||
<el-col :span="6"> |
||||
<el-button type="default" @click="reset" class="under-btn">重置</el-button></el-col> |
||||
<el-col :span="6"> |
||||
<el-button type="primary" @click="out" class="under-btn">导出信件</el-button></el-col> |
||||
</el-row> |
||||
</el-col> |
||||
</el-row> |
||||
</el-form> |
||||
|
||||
<div class="table-box" ref="tableBoxHeight" v-loading="loading"> |
||||
<el-table :data="tableData" border :height="tableHeight" table-layout="fixed" |
||||
:header-cell-style="{ 'background-color': '#EBEEFC', 'color': '#1D2C86' }"> |
||||
<el-table-column fixed="left" prop="id" label="案件编号" width="200px"> |
||||
</el-table-column> |
||||
<el-table-column prop="createTime" label="来信日期" width="120px"> |
||||
</el-table-column> |
||||
<el-table-column prop="contactName" label="联系人姓名" width="100px"> |
||||
</el-table-column> |
||||
<!-- todo 联系人身份证号码和联系人手机号码的需要脱敏 --> |
||||
<el-table-column prop="contactIdCard" label="联系人身份证号码" width="300px"> |
||||
</el-table-column> |
||||
<el-table-column prop="contactPhone" label="联系人手机号码" width="200px"> |
||||
</el-table-column> |
||||
<el-table-column prop="content" label="信件内容" width="400px" :show-overflow-tooltip="true"> |
||||
</el-table-column> |
||||
<el-table-column prop="satisfaction" label="评价结果" width="100px"> |
||||
</el-table-column> |
||||
<el-table-column fixed="right" label="详情" width="100"> |
||||
<template v-slot="scope"> |
||||
<el-button @click="handleDetail(scope.$index + 1)">详情</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<div style="display: flex; justify-content: center;"> |
||||
<el-pagination background @size-change="handleSizeChange" @current-change="handlePageChange" |
||||
:current-page="pageData.currentPage" :page-sizes="[4, 10, 20, 40, 50]" :page-size="pageData.pageSize" |
||||
layout="total,sizes, prev, pager, next, jumper" :total="pageData.totalSize"> |
||||
</el-pagination> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<AddMail |
||||
v-model="addMailShow" |
||||
@close="addMailShow = false" |
||||
@success="search" |
||||
/> |
||||
<Detail |
||||
v-model="detailShow" |
||||
:hotId="activehotId" |
||||
@close="detailShow = false" |
||||
@success="search" |
||||
/> |
||||
</template> |
||||
|
||||
<script setup> |
||||
import { request } from '../util/axios_config' |
||||
import { onMounted, ref } from 'vue'; |
||||
import router from '../router'; |
||||
import AddMail from "../components/AddMail.vue"; |
||||
import Detail from "../components/Detail.vue"; |
||||
const loading = ref(true); |
||||
|
||||
const { VITE_API_URL } = process.env; |
||||
const activehotId = ref(""); |
||||
const form = ref({ |
||||
date: '', |
||||
contactName: '', |
||||
contactPhone: '', |
||||
contactIdCard: '', |
||||
id: '', |
||||
content: '', |
||||
evaluate: '' |
||||
}) |
||||
const addMailShow = ref(false); |
||||
const detailShow = ref(false); |
||||
// 定义可变的tableData变量,并用axios请求数据 |
||||
const tableData = ref([]) |
||||
const createMail = () => { |
||||
addMailShow.value = true; |
||||
}; |
||||
|
||||
const pageData = ref({ |
||||
currentPage: 1, |
||||
pageSize: 4, |
||||
totalSize: 0 |
||||
}) |
||||
|
||||
const tableBoxHeight = ref(null) |
||||
const tableHeight = ref('100%') |
||||
const flexColumnWidth = (label, prop) => { |
||||
const width = Math.max(label.length * 12, 120) |
||||
return `${width}px` |
||||
} |
||||
|
||||
const handleResponse = (response) => { |
||||
tableData.value = response.data.mails; |
||||
tableData.value.forEach(item => { |
||||
item.createTime = item.createTime.split('T')[0] |
||||
}) |
||||
pageData.value.totalSize = response.data.pageSet.totalSize; |
||||
loading.value = false; |
||||
} |
||||
|
||||
const makeRequest = (requestData, callback) => { |
||||
const data = JSON.stringify(requestData) |
||||
const url = VITE_API_URL +'/mailbox/list-submit' |
||||
request({ |
||||
url: url, |
||||
method: 'POST', |
||||
data: data, |
||||
headers: { 'Content-Type': 'application/json' } |
||||
}).then(callback) |
||||
.catch(function (error) { console.log(error) }) |
||||
} |
||||
|
||||
const updateData = (requestData) => { |
||||
makeRequest(requestData, function (response) { |
||||
handleResponse(response) |
||||
}) |
||||
} |
||||
|
||||
onMounted(() => { |
||||
const requestData = { |
||||
formData: form.value, |
||||
pageData: pageData.value |
||||
} |
||||
updateData(requestData) |
||||
}) |
||||
|
||||
|
||||
const handleDetail = (index) => { |
||||
detailShow.value = true; |
||||
activehotId.value = tableData.value[index - 1].id; |
||||
} |
||||
|
||||
const handleSizeChange = (size) => { |
||||
const requestData = { |
||||
formData: form.value, |
||||
pageData: pageData.value |
||||
} |
||||
pageData.value.pageSize = size |
||||
updateData(requestData) |
||||
} |
||||
|
||||
const handlePageChange = (currentPage) => { |
||||
const requestData = { |
||||
formData: form.value, |
||||
pageData: pageData.value |
||||
} |
||||
pageData.value.currentPage = currentPage |
||||
updateData(requestData) |
||||
} |
||||
|
||||
const search = () => { |
||||
const requestData = { |
||||
formData: form.value, |
||||
pageData: pageData.value |
||||
} |
||||
updateData(requestData) |
||||
} |
||||
|
||||
const reset = () => { |
||||
form.value = { |
||||
date: '', |
||||
name: '', |
||||
phone: '', |
||||
id_card: '', |
||||
mail_id: '', |
||||
mail_context: '', |
||||
mail_appraise: '' |
||||
} |
||||
} |
||||
|
||||
const out = () => { |
||||
const requestData = { |
||||
formData: form.value, |
||||
pageData: pageData.value |
||||
} |
||||
const data = JSON.stringify(requestData) |
||||
const url = VITE_API_URL +'/mailbox/exportexcel' |
||||
request({ |
||||
url: url, |
||||
method: 'POST', |
||||
data: data, |
||||
headers: { 'Content-Type': 'application/json' }, |
||||
responseType: 'blob' |
||||
}).then(function (res) { |
||||
var blob = new Blob([res.data], { type: 'application/octet-stream;charset=UTF-8' }) |
||||
var contentDisposition = res.headers['content-disposition'] |
||||
var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*') |
||||
var result = patt.exec(contentDisposition) |
||||
var filename = result[1] |
||||
var downloadElement = document.createElement('a') |
||||
var href = window.URL.createObjectURL(blob) // 创建下载的链接 |
||||
var reg = /^["](.*)["]$/g |
||||
downloadElement.style.display = 'none' |
||||
downloadElement.href = href |
||||
downloadElement.download = decodeURI(filename.replace(reg, '$1')) // 下载后文件名 |
||||
document.body.appendChild(downloadElement) |
||||
downloadElement.click() // 点击下载 |
||||
document.body.removeChild(downloadElement) // 下载完成移除元素 |
||||
window.URL.revokeObjectURL(href) |
||||
}).catch(function (error) { console.log(error) }) |
||||
} |
||||
|
||||
</script> |
||||
|
||||
<style scoped> |
||||
.under-btn { |
||||
margin-right: 30px; |
||||
margin-bottom: 5px; |
||||
} |
||||
|
||||
.table-box { |
||||
/* 全屏时顶部元素总和316px */ |
||||
height: calc(100vh - 336px); |
||||
} |
||||
</style> |
||||
@ -1,281 +0,0 @@
|
||||
<template> |
||||
<div style="width: 90vw; margin: 0 auto;"> |
||||
<el-form :model="form" label-width="150px" style="margin-top: 20px; margin-right: -50px;;"> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="群众姓名"> |
||||
<el-input v-model="form.realName" placeholder="请输入群众姓名" max-length="200px"></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="群众手机号"> |
||||
<el-input v-model="form.phone" placeholder="请输入群众手机号"></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="群众身份证号"> |
||||
<el-input v-model="form.idCard" placeholder="请输入群众身份证号"></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="3"></el-col> |
||||
</el-row> |
||||
<el-row type="flex"> |
||||
<el-col :span="8"> |
||||
<el-form-item label="创建时间"> |
||||
<el-date-picker v-model="form.date" type="daterange" range-separator="至" start-placeholder="开始日期" |
||||
end-placeholder="结束日期" value-format="YYYY-MM-DD"></el-date-picker> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="14"> |
||||
</el-col> |
||||
<el-col :span="8" :style="{ display: 'inline-flex', alignItems: 'center' }"> |
||||
<el-row> |
||||
<el-col :span="6"></el-col> |
||||
<el-col :span="6"> |
||||
<el-button type="primary" @click="search" class="under-btn">搜索</el-button></el-col> |
||||
<el-col :span="6"> |
||||
<el-button type="default" @click="reset" class="under-btn">重置</el-button></el-col> |
||||
<el-col :span="6"> |
||||
<el-button type="primary" @click="newUser = true" class="under-btn">新增用户</el-button></el-col> |
||||
<el-dialog v-model="newUser" title="新增用户" width="40%"> |
||||
<el-form :model="newForm" label-width="150px"> |
||||
<el-form-item label="新管理员姓名"> |
||||
<el-input v-model="newForm.realName" placeholder="请输入新管理员姓名" |
||||
max-length="200px"></el-input> |
||||
</el-form-item> |
||||
<el-form-item label="新管理员手机号"> |
||||
<el-input v-model="newForm.phone" placeholder="请输入新管理员手机号"></el-input> |
||||
</el-form-item> |
||||
<el-form-item label="新管理员身份证号"> |
||||
<el-input v-model="newForm.idCard" placeholder="请输入新管理员身份证号"></el-input> |
||||
</el-form-item></el-form> |
||||
<template #footer> |
||||
<span class="dialog-footer"> |
||||
<el-button @click="cancleNewUser">取消</el-button> |
||||
<el-button type="primary" @click="submitNewUser"> |
||||
提交 |
||||
</el-button> |
||||
</span> |
||||
</template> |
||||
</el-dialog> |
||||
</el-row> |
||||
</el-col> |
||||
</el-row> |
||||
</el-form> |
||||
|
||||
<div class="table-box" ref="tableBoxHeight" v-loading="loading"> |
||||
<el-table :data="tableData" border :height="tableHeight" table-layout="fixed" |
||||
:header-cell-style="{ 'background-color': '#EBEEFC', 'color': '#1D2C86' }"> |
||||
<el-table-column prop="createTime" label="用户创建日期" width="120px"> |
||||
</el-table-column> |
||||
<el-table-column prop="realName" label="联系人姓名" width="100px"> |
||||
</el-table-column> |
||||
<!-- todo 联系人身份证号码和联系人手机号码的需要脱敏 --> |
||||
<el-table-column prop="idCard" label="联系人身份证号码" width="300px"> |
||||
</el-table-column> |
||||
<el-table-column prop="phone" label="联系人手机号码" width="200px"> |
||||
</el-table-column> |
||||
<el-table-column fixed="right" label="详情" width="100"> |
||||
<template v-slot="scope"> |
||||
<el-popconfirm title="你确定要删除这个管理员吗?" @confirm="handleDelete(scope.$index + 1)"> |
||||
<template #reference> |
||||
<el-button type="danger">删除</el-button> |
||||
</template> |
||||
</el-popconfirm> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<div style="display: flex; justify-content: center;"> |
||||
<el-pagination background @size-change="handleSizeChange" @current-change="handlePageChange" |
||||
:current-page="pageData.currentPage" :page-sizes="[4, 10, 20, 40, 50]" :page-size="pageData.pageSize" |
||||
layout="total,sizes, prev, pager, next, jumper" :total="pageData.totalSize"> |
||||
</el-pagination> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script setup> |
||||
import { request } from '../util/axios_config' |
||||
import { onMounted, ref } from 'vue'; |
||||
import { ElMessage } from 'element-plus' |
||||
const { VITE_API_URL } = process.env; |
||||
const loading = ref(true); |
||||
const form = ref({ |
||||
date: '', |
||||
realName: '', |
||||
phone: '', |
||||
idCard: '', |
||||
}) |
||||
|
||||
const newForm = ref({ |
||||
realName: '', |
||||
phone: '', |
||||
idCard: '', |
||||
}) |
||||
|
||||
// 定义可变的tableData变量,并用axios请求数据 |
||||
const tableData = ref([]) |
||||
|
||||
const pageData = ref({ |
||||
currentPage: 1, |
||||
pageSize: 4, |
||||
totalSize: 0 |
||||
}) |
||||
|
||||
const getData = (data) => { |
||||
const url = VITE_API_URL +'/user/list-submit' |
||||
request({ |
||||
url: url, |
||||
method: 'POST', |
||||
data: data, |
||||
headers: { 'Content-Type': 'application/json' } |
||||
}).then(function (response) { |
||||
tableData.value = response.data.users; |
||||
tableData.value.forEach(item => { |
||||
item.createTime = item.createTime.split('T')[0] |
||||
}) |
||||
pageData.value.totalSize = response.data.pageSet.totalSize; |
||||
loading.value = false; |
||||
}) |
||||
.catch(function (error) { console.log(error) }) |
||||
} |
||||
|
||||
|
||||
onMounted(() => { |
||||
const requestData = { |
||||
formData: form.value, |
||||
pageData: pageData.value |
||||
} |
||||
const data = JSON.stringify(requestData) |
||||
getData(data) |
||||
}) |
||||
const tableBoxHeight = ref(null) |
||||
const tableHeight = ref('100%') |
||||
const flexColumnWidth = (label, prop) => { |
||||
const width = Math.max(label.length * 12, 120) |
||||
return `${width}px` |
||||
} |
||||
|
||||
const handleDelete = (index) => { |
||||
const url = VITE_API_URL +'/user/delete-user' |
||||
request({ |
||||
url: url, |
||||
method: 'POST', |
||||
data: { id: tableData.value[index - 1].id }, |
||||
}).then(function (response) { |
||||
if (response.status === 200 && response.data === 'success') { |
||||
search() |
||||
successMessage('删除用户成功') |
||||
} |
||||
}) |
||||
.catch(function (error) { |
||||
errorMessage('删除用户失败'); |
||||
console.log(error) |
||||
}) |
||||
} |
||||
|
||||
const handleSizeChange = (size) => { |
||||
const requestData = { |
||||
formData: form.value, |
||||
pageData: pageData.value |
||||
} |
||||
pageData.value.pageSize = size |
||||
const data = JSON.stringify(requestData) |
||||
getData(data) |
||||
} |
||||
|
||||
const handlePageChange = (currentPage) => { |
||||
const requestData = { |
||||
formData: form.value, |
||||
pageData: pageData.value |
||||
} |
||||
pageData.value.currentPage = currentPage |
||||
const data = JSON.stringify(requestData) |
||||
getData(data) |
||||
} |
||||
|
||||
const search = () => { |
||||
const requestData = { |
||||
formData: form.value, |
||||
pageData: pageData.value |
||||
} |
||||
const data = JSON.stringify(requestData) |
||||
getData(data) |
||||
} |
||||
|
||||
const reset = () => { |
||||
form.value = { |
||||
date: '', |
||||
name: '', |
||||
phone: '', |
||||
id_card: '', |
||||
mail_id: '', |
||||
mail_context: '', |
||||
mail_appraise: '' |
||||
} |
||||
} |
||||
|
||||
const newUser = ref(false) |
||||
const submitNewUser = () => { |
||||
const requestData = newForm.value |
||||
const data = JSON.stringify(requestData) |
||||
const url = VITE_API_URL +'/user/add-user' |
||||
request({ |
||||
url: url, |
||||
method: 'POST', |
||||
data: data, |
||||
headers: { 'Content-Type': 'application/json' } |
||||
}).then(function (response) { |
||||
if (response.status === 200 && response.data === 'success') { |
||||
newUser.value = false; |
||||
newFormReset(); |
||||
search(); |
||||
successMessage('新增用户成功') |
||||
} |
||||
}) |
||||
.catch(function (error) { |
||||
errorMessage('新增用户失败'); |
||||
console.log(error) |
||||
}) |
||||
} |
||||
|
||||
const cancleNewUser = () => { |
||||
newUser.value = false; |
||||
newFormReset(); |
||||
} |
||||
|
||||
const newFormReset = () => { |
||||
newForm.value = { |
||||
realName: '', |
||||
phone: '', |
||||
idCard: '', |
||||
} |
||||
} |
||||
|
||||
const successMessage = (msg) => { |
||||
ElMessage.success(msg) |
||||
} |
||||
|
||||
const errorMessage = (msg) => { |
||||
ElMessage.error(msg) |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
</script> |
||||
|
||||
<style scoped> |
||||
.under-btn { |
||||
margin-right: 30px; |
||||
margin-bottom: 5px; |
||||
} |
||||
|
||||
.table-box { |
||||
/* 全屏时顶部元素总和286px */ |
||||
height: calc(100vh - 286px); |
||||
} |
||||
</style> |
||||
@ -0,0 +1,22 @@
|
||||
const cache = { |
||||
//设置缓存(expire为缓存时效)
|
||||
set(key, value) { |
||||
try { |
||||
window.localStorage.setItem(key, value) |
||||
} catch (e) { |
||||
|
||||
} |
||||
}, |
||||
get(key) { |
||||
try { |
||||
return window.localStorage.getItem(key) |
||||
} catch (e) { |
||||
return null |
||||
} |
||||
}, |
||||
remove(key) { |
||||
window.localStorage.removeItem(key) |
||||
} |
||||
} |
||||
|
||||
export default cache |
||||
@ -1,54 +1,97 @@
|
||||
const basePath = '/api' |
||||
export function post(url, data) { |
||||
return new Promise((resolve, reject) => { |
||||
fetch(`${basePath}${url}`, { |
||||
method: 'POST', |
||||
body: data ? JSON.stringify(data) : '', |
||||
}) |
||||
// .then(res => {
|
||||
// return res.json();
|
||||
// }).then(res => {
|
||||
// if (res.ok()) {
|
||||
// resolve(res)
|
||||
// } else {
|
||||
// reject(res)
|
||||
// }
|
||||
// })
|
||||
.then(res => { |
||||
resolve(res); |
||||
}).catch(e => { |
||||
console.error("请求失败了,详细信息:" + JSON.stringify(e)); |
||||
reject(e); |
||||
}) |
||||
}) |
||||
|
||||
import { |
||||
ElMessage, |
||||
ElMessageBox |
||||
} from 'element-plus' |
||||
import { getToken } from './token' |
||||
|
||||
const BASE_PATH = '/admin-api' |
||||
export function get(options) { |
||||
options.method = 'GET'; |
||||
return ajax(options.url, options) |
||||
} |
||||
|
||||
export function post(options) { |
||||
options.method = 'POST'; |
||||
return ajax(options.url, options) |
||||
} |
||||
|
||||
function put(options) { |
||||
options.method = 'PUT'; |
||||
return ajax(options.url, options) |
||||
} |
||||
|
||||
function del(options) { |
||||
options.method = 'DELETE'; |
||||
return ajax(options.url, options) |
||||
} |
||||
export function get(url) { |
||||
|
||||
let isRelogin = false; |
||||
function ajax(url, options) { |
||||
const headers = { |
||||
"Content-Type": "application/json", |
||||
"Authorization": getToken() |
||||
}; |
||||
|
||||
let body; |
||||
if (options?.params && Object.keys(options.params).length > 0) { |
||||
if (options.method === 'GET') { |
||||
options.query = options.params; |
||||
} else { |
||||
body = JSON.stringify(options.params); |
||||
} |
||||
} |
||||
if (options?.query) { |
||||
url += (url.indexOf('?') > -1 ? '' : '?') + new URLSearchParams(options.query).toString(); |
||||
} |
||||
if (options?.body) { |
||||
if (options.body === 'string' || options.body instanceof FormData) { |
||||
body = options.body; |
||||
} else { |
||||
if (Object.keys(options.body).length > 0) { |
||||
body = JSON.stringify(options.body); |
||||
} |
||||
} |
||||
} |
||||
return new Promise((resolve, reject) => { |
||||
fetch(`${basePath}${url}`, { |
||||
method: 'GET', |
||||
fetch(`${BASE_PATH}${url}`, { |
||||
method: options.method, |
||||
body: body, |
||||
headers: { ...headers, ...options.headers } |
||||
}).then(response => { |
||||
if (response.status === 413) { |
||||
|
||||
return; |
||||
} |
||||
return response.json(); |
||||
}).then(res => { |
||||
if (res.code === 200) { |
||||
resolve(res.data) |
||||
} else { |
||||
let message = res.msg; |
||||
if (res.code === 401) { |
||||
if (url === '/admin/self') { |
||||
feedback.msgError('登录状态已过期') |
||||
reject(res) |
||||
return |
||||
} |
||||
if (!isRelogin) { |
||||
isRelogin = true |
||||
ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '温馨提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { |
||||
isRelogin = false; |
||||
// 调整登录
|
||||
location.href = process.env.VITE_BASE + "#/login"; |
||||
}).catch(() => { |
||||
isRelogin = false; |
||||
}); |
||||
} |
||||
reject(res) |
||||
return |
||||
} |
||||
ElMessage.error(message || '系统异常') |
||||
reject(res) |
||||
} |
||||
|
||||
}) |
||||
.then(res => { |
||||
let data = res.text();//转成字符串判断
|
||||
return data.then(r => { |
||||
if (r.length === 0) return null; |
||||
else return JSON.parse(r); |
||||
}) |
||||
}) |
||||
// .then(res => {
|
||||
// return res.json();
|
||||
// })
|
||||
// .then(res => {
|
||||
// if (res.ok()) {
|
||||
// resolve(res)
|
||||
// } else {
|
||||
// reject(res)
|
||||
// }
|
||||
// })
|
||||
.then(res => { |
||||
resolve(res); |
||||
}).catch(e => { |
||||
console.error("请求失败了,详细信息:" + JSON.stringify(e)); |
||||
reject(e); |
||||
}) |
||||
}) |
||||
} |
||||
@ -0,0 +1,10 @@
|
||||
import cache from './cache' |
||||
|
||||
const TOKEN_KEY = 'token'; |
||||
export function getToken() { |
||||
return cache.get(TOKEN_KEY) |
||||
} |
||||
|
||||
export function setToken(val) { |
||||
return cache.set(TOKEN_KEY, val) |
||||
} |
||||
@ -0,0 +1,153 @@
|
||||
<template> |
||||
<div class="container"> |
||||
<el-form :model="form" label-width="120px" style="margin-top: 20px"> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="姓名"> |
||||
<el-input |
||||
v-model="form.nickname" |
||||
placeholder="请输入姓名" |
||||
max-length="200px" |
||||
></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="手机号"> |
||||
<el-input |
||||
v-model="form.username" |
||||
placeholder="请输入手机号" |
||||
></el-input> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<div class="flex between mb-24"> |
||||
<el-button type="primary" @click="show = true" |
||||
>新增用户</el-button |
||||
> |
||||
<div> |
||||
<el-button type="primary" @click="getList">搜索</el-button> |
||||
<el-button type="default" @click="reset">重置</el-button> |
||||
</div> |
||||
</div> |
||||
</el-form> |
||||
|
||||
<div class="table-box" v-loading="loading"> |
||||
<el-table :data="list"> |
||||
<el-table-column prop="id" label="编号" /> |
||||
<el-table-column prop="nickname" label="姓名" /> |
||||
<el-table-column prop="username" label="手机号/用户名" /> |
||||
<el-table-column prop="createTime" label="创建日期" /> |
||||
</el-table> |
||||
<div class="flex end mt-10"> |
||||
<el-pagination |
||||
:total="total" |
||||
> |
||||
</el-pagination> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<el-dialog v-model="show" title="新增用户" width="600px"> |
||||
<el-form :model="newForm" label-width="150px" ref="formRef" :rules="rules"> |
||||
<el-form-item label="管理员姓名" prop="nickname"> |
||||
<el-input |
||||
v-model="newForm.nickname" |
||||
placeholder="请输入新管理员姓名" |
||||
max-length="200px" |
||||
></el-input> |
||||
</el-form-item> |
||||
<el-form-item label="管理员手机号" prop="username"> |
||||
<el-input |
||||
v-model="newForm.username" |
||||
placeholder="请输入管理员手机号" |
||||
></el-input> |
||||
</el-form-item> |
||||
<el-form-item label="密码" prop="password"> |
||||
<el-input |
||||
type="password" |
||||
v-model="newForm.password" |
||||
placeholder="请输入密码" |
||||
/> |
||||
</el-form-item> |
||||
</el-form> |
||||
<template #footer> |
||||
<span class="dialog-footer"> |
||||
<el-button @click="show = false">取消</el-button> |
||||
<el-button type="primary" @click="handleAdd"> |
||||
提交 |
||||
</el-button> |
||||
</span> |
||||
</template> |
||||
</el-dialog> |
||||
</template> |
||||
|
||||
<script setup> |
||||
import { ElMessage } from "element-plus"; |
||||
import { adminList, addAdmin } from "@/api/admin"; |
||||
const loading = ref(true); |
||||
const form = ref({ |
||||
current: 1, |
||||
pageSize: 10 |
||||
}); |
||||
|
||||
const list = ref([]); |
||||
const total = ref(0) |
||||
const getList = () => { |
||||
loading.value = true; |
||||
adminList(form.value).then((data) => { |
||||
list.value = data.records; |
||||
total.value = data.total |
||||
loading.value = false; |
||||
|
||||
}); |
||||
}; |
||||
|
||||
getList(); |
||||
|
||||
const reset = () => { |
||||
form.value = {}; |
||||
getList(); |
||||
}; |
||||
|
||||
const successMessage = (msg) => { |
||||
ElMessage.success(msg); |
||||
}; |
||||
|
||||
const show = ref(false) |
||||
const newForm = ref({}) |
||||
const formRef = ref() |
||||
const rules = { |
||||
username: [{ validator: validatorPhone }], |
||||
password: [ |
||||
{ |
||||
required: true, |
||||
message: "请输入密码(长度不能少于6位)", |
||||
min: 6 |
||||
} |
||||
], |
||||
}; |
||||
function handleAdd() { |
||||
formRef.value.validate((valid) => { |
||||
if (valid) { |
||||
addAdmin(newForm.value).then(() => { |
||||
show.value = false |
||||
newForm.value = {} |
||||
getList() |
||||
}) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
function validatorPhone(rule, phonenumber, callback) { |
||||
if (!phonenumber) { |
||||
return callback(new Error('请输入手机号码')) |
||||
} |
||||
if (phonenumber.length !== 11) { |
||||
return callback(new Error('请输入正确的手机号码')) |
||||
} |
||||
if (!/^1[3456789]\d{9}/.test(phonenumber)) { |
||||
return callback(new Error('请输入正确的手机号码')) |
||||
} |
||||
callback() |
||||
} |
||||
</script> |
||||
@ -0,0 +1,126 @@
|
||||
<template> |
||||
<div class="wrapper"> |
||||
<header class="text-center"> |
||||
<img src="/imgs/login_logo1.png" alt="" /> |
||||
</header> |
||||
<div class="box flex v-center"> |
||||
<div class="left text-center"> |
||||
<img src="/imgs/pic.png" alt="" /> |
||||
</div> |
||||
<div class="right mb-40"> |
||||
<el-form :model="form" ref="formRef" :rules="rules"> |
||||
<h1>用户登录</h1> |
||||
<el-form-item prop="username"> |
||||
<el-input |
||||
v-model="form.username" |
||||
placeholder="请输入用户名/手机号" |
||||
clearable |
||||
style="--el-input-height: 50px" |
||||
> |
||||
</el-input> |
||||
</el-form-item> |
||||
<el-form-item prop="password"> |
||||
<el-container> |
||||
<el-input |
||||
v-model="form.password" |
||||
placeholder="请输入密码" |
||||
type="password" |
||||
show-password |
||||
clearable |
||||
style="--el-input-height: 50px" |
||||
> |
||||
</el-input> |
||||
</el-container> |
||||
</el-form-item> |
||||
<div class="mt-30 mb-10"> |
||||
<el-button |
||||
type="primary" |
||||
@click="handleLogin" |
||||
size="large" |
||||
style=" |
||||
width: 100%; |
||||
--el-button-size: 54px; |
||||
--el-font-size-base: 18px; |
||||
" |
||||
v-loading="loading" |
||||
>登录</el-button |
||||
> |
||||
</div> |
||||
</el-form> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script setup> |
||||
import { login } from '@/api/admin' |
||||
import { setToken } from '@/util/token' |
||||
import { useRouter } from 'vue-router' |
||||
import cache from '@/util/cache' |
||||
const form = reactive({ |
||||
username: cache.get('username') |
||||
}) |
||||
const formRef = ref() |
||||
const router = useRouter() |
||||
const rules = { |
||||
username: [{ required: true, message: "请输入用户名/手机号" }], |
||||
password: [{ required: true, message: "请输入密码" }] |
||||
} |
||||
|
||||
const loading = ref(false) |
||||
function handleLogin() { |
||||
formRef.value.validate((valid) => { |
||||
if (valid) { |
||||
loading.value = true |
||||
cache.set('username', form.username) |
||||
login(form).then(data => { |
||||
setToken(data.token) |
||||
router.push('/') |
||||
loading.value = false |
||||
}).catch(() => { |
||||
loading.value = false |
||||
}) |
||||
} |
||||
}) |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.wrapper { |
||||
height: 100vh; |
||||
background-image: url("/imgs/bg.png"); |
||||
background-size: cover; |
||||
header { |
||||
padding-top: 3.2vh; |
||||
margin-bottom: 8vh; |
||||
img { |
||||
height: 91px; |
||||
} |
||||
} |
||||
.box { |
||||
--login-box-width: 576px; |
||||
width: 80%; |
||||
margin: auto; |
||||
.left { |
||||
width: calc(100% - var(--login-box-width)); |
||||
img { |
||||
width: 33vw; |
||||
} |
||||
} |
||||
|
||||
.right { |
||||
background-color: #fff; |
||||
border: 18px solid #4169ea; |
||||
width: var(--login-box-width); |
||||
padding: 40px; |
||||
box-sizing: border-box; |
||||
h1 { |
||||
color: var(--primary-color); |
||||
font-size: 32px; |
||||
margin-top: 0; |
||||
margin-bottom: 32px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
||||
@ -0,0 +1,325 @@
|
||||
<template> |
||||
<div class="container"> |
||||
<header class="mb-24"> |
||||
<el-form :label-width="120"> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="编号"> |
||||
<el-input placeholder="请输入" v-model="query.id" /> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来源"> |
||||
<el-input |
||||
placeholder="请输入" |
||||
v-model="query.source" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来电时间"> |
||||
<el-date-picker |
||||
type="datetimerange" |
||||
start-placeholder="开始时间" |
||||
end-placeholder="结束时间" |
||||
value-format="YYYY-MM-DD HH:mm:ss" |
||||
time-format="A hh:mm:ss" |
||||
v-model="query.phoneTime" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="市民姓名"> |
||||
<el-input |
||||
placeholder="请输入" |
||||
v-model="query.contactName" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来电电话"> |
||||
<el-input |
||||
placeholder="请输入" |
||||
v-model="query.contactPhone" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="证件号码"> |
||||
<el-input |
||||
placeholder="请输入" |
||||
v-model="query.contactIdCard" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="话务类型"> |
||||
<el-input |
||||
placeholder="请输入" |
||||
v-model="query.contactType" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="案件类型"> |
||||
<el-input |
||||
placeholder="请输入" |
||||
v-model="query.caseType" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
</el-form> |
||||
<div class="flex between"> |
||||
<div> |
||||
<el-button type="primary" @click="addMailShow = true" |
||||
>新增12345投诉</el-button |
||||
> |
||||
<el-button type="primary" @click="importShow = true" |
||||
>信件导入</el-button |
||||
> |
||||
</div> |
||||
<div> |
||||
<el-button type="primary" @click="getList">查询</el-button> |
||||
<el-button @click="reset">重置</el-button> |
||||
</div> |
||||
</div> |
||||
</header> |
||||
<div> |
||||
<el-table :data="list"> |
||||
<el-table-column prop="id" label="编号" width="220" /> |
||||
<el-table-column prop="contactName" label="市民姓名" width="120" /> |
||||
<el-table-column prop="contactPhone" label="来电电话" width="120" /> |
||||
<el-table-column prop="contactIdCard" label="证件号码" width="180" /> |
||||
<el-table-column |
||||
prop="content" |
||||
label="来话内容" |
||||
show-overflow-tooltip |
||||
/> |
||||
<el-table-column prop="contactType" label="话务类型" width="120" /> |
||||
|
||||
<el-table-column prop="source" label="来源" width="150" /> |
||||
<el-table-column prop="caseType" label="案件类型" width="120" /> |
||||
<el-table-column label="操作" width="120"> |
||||
<template #default="{ row }"> |
||||
<el-button |
||||
type="primary" |
||||
link |
||||
@click="handleMail(row)" |
||||
size="small" |
||||
>详情</el-button |
||||
> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<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" |
||||
:total="totalSize.total" |
||||
layout="total, sizes, prev, pager, next" |
||||
> |
||||
</el-pagination> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<AddMail |
||||
v-model="addMailShow" |
||||
@close="addMailShow = false" |
||||
@success="getList" |
||||
/> |
||||
|
||||
<el-dialog width="1000px" title="12345投诉导入" v-model="importShow"> |
||||
<header class="mb-20 flex gap"> |
||||
<el-upload |
||||
:action="`${VITE_API_URL}/mail12345/analyzeExcel`" |
||||
:headers="{ Authorization: getToken() }" |
||||
accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" |
||||
:on-success="onAnalyzeExcelSuccess" |
||||
:show-file-list="false" |
||||
> |
||||
<template #trigger> |
||||
<el-button type="primary" plain>选择文件</el-button> |
||||
</template> |
||||
</el-upload> |
||||
|
||||
<el-button type="primary" @click="downloadTemplate" plain |
||||
>下载模版</el-button |
||||
> |
||||
</header> |
||||
<el-table :data="importList" ref="importTable"> |
||||
<el-table-column type="selection" width="55" /> |
||||
<el-table-column prop="contactName" label="市民姓名" width="100" /> |
||||
<el-table-column prop="contactPhone" label="来电电话" width="120" /> |
||||
<el-table-column |
||||
prop="contactIdCard" |
||||
label="证件号码" |
||||
width="180" |
||||
/> |
||||
<el-table-column |
||||
prop="content" |
||||
label="来话内容" |
||||
show-overflow-tooltip |
||||
/> |
||||
<el-table-column prop="phoneTime" label="来电时间" /> |
||||
<el-table-column label="数据是否正确" align="center"> |
||||
<template #default="{ row }"> |
||||
<span v-if="row.flag">正确</span> |
||||
|
||||
<el-tooltip |
||||
class="box-item" |
||||
effect="dark" |
||||
:content="row.errMsg" |
||||
placement="top" |
||||
:raw-content="true" |
||||
v-else |
||||
> |
||||
<span class="text-danger">错误</span> |
||||
</el-tooltip> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<footer class="flex end mt-20"> |
||||
<el-button |
||||
type="primary" |
||||
@click="handleImport" |
||||
size="large" |
||||
:disabled="disabled" |
||||
>确认导入</el-button |
||||
> |
||||
</footer> |
||||
</el-dialog> |
||||
|
||||
<el-dialog title="信件详情" v-model="showDetail"> |
||||
<el-scrollbar max-height="600px" class="dialog-content"> |
||||
<div class="row"> |
||||
<div class="col-12 form-item"> |
||||
<label>姓名</label> |
||||
<div>{{ activeRow.contactName }}</div> |
||||
</div> |
||||
</div> |
||||
<div class="row"> |
||||
<div class="col-12 form-item"> |
||||
<label>手机号</label> |
||||
<div>{{ activeRow.contactPhone }}</div> |
||||
</div> |
||||
<div class="col-12 form-item"> |
||||
<label>身份证号码</label> |
||||
<div>{{ activeRow.contactIdCard }}</div> |
||||
</div> |
||||
</div> |
||||
<div class="form-item"> |
||||
<label>内容</label> |
||||
<div class="content text-wrap">{{ activeRow.content }}</div> |
||||
</div> |
||||
</el-scrollbar> |
||||
<footer class="flex end mt-20"> |
||||
<el-button @click="showDetail = false">关闭窗口</el-button> |
||||
</footer> |
||||
</el-dialog> |
||||
</template> |
||||
<script setup> |
||||
import AddMail from "@/components/AddMail.vue"; |
||||
import { mail12345List, mail12345Import } from "@/api/mail12345"; |
||||
import { getToken } from "@/util/token"; |
||||
import { ElMessage } from "element-plus"; |
||||
const { VITE_API_URL } = process.env; |
||||
|
||||
const query = ref({ |
||||
current: 1, |
||||
size: 10, |
||||
}); |
||||
const totalSize = ref({ |
||||
total: 0, |
||||
}); |
||||
const list = ref([]); |
||||
const addMailShow = ref(false); |
||||
const importShow = ref(false); |
||||
|
||||
function getList() { |
||||
if (query.value.phoneTime && query.value.phoneTime.length === 2) { |
||||
query.value.phoneTimeBegin = query.value.phoneTime[0]; |
||||
query.value.phoneTimeEnd = query.value.phoneTime[1]; |
||||
} else { |
||||
query.value.phoneTimeBegin = ""; |
||||
query.value.phoneTimeEnd = ""; |
||||
} |
||||
mail12345List(query.value).then((data) => { |
||||
list.value = data.records; |
||||
totalSize.value.total = data.total; |
||||
}); |
||||
} |
||||
|
||||
function reset() { |
||||
query.value = { |
||||
current: 1, |
||||
size: 10, |
||||
}; |
||||
getList(); |
||||
} |
||||
|
||||
getList(); |
||||
|
||||
const importList = ref([]); |
||||
const importTable = ref(); |
||||
function onAnalyzeExcelSuccess(response) { |
||||
console.log(response); |
||||
importList.value = response.data; |
||||
} |
||||
|
||||
function downloadTemplate() { |
||||
location.href = `${VITE_API_URL}/file/download/template/12345投诉模版.xlsx`; |
||||
} |
||||
|
||||
const disabled = ref(false); |
||||
function handleImport() { |
||||
const rows = importTable.value.getSelectionRows(); |
||||
console.log(rows); |
||||
if (!rows.length) { |
||||
ElMessage.warning("请选择至少一条数据"); |
||||
return; |
||||
} |
||||
disabled.value = true; |
||||
mail12345Import(rows).then(() => { |
||||
disabled.value = false; |
||||
ElMessage.success("导入成功"); |
||||
getList(); |
||||
importList.value = []; |
||||
importShow.value = false; |
||||
}); |
||||
} |
||||
|
||||
const showDetail = ref(false); |
||||
const activeRow = ref({}) |
||||
function handleMail(row) { |
||||
showDetail.value = true; |
||||
activeRow.value = row |
||||
} |
||||
</script> |
||||
<style lang="scss" scoped> |
||||
.form-item { |
||||
display: flex; |
||||
line-height: 22px; |
||||
margin: 10px 0; |
||||
gap: 20px; |
||||
label { |
||||
width: 137px; |
||||
text-align: right; |
||||
} |
||||
div { |
||||
color: #333; |
||||
max-width: calc(100% - 137px); |
||||
} |
||||
.content { |
||||
background: #EFF0F5; |
||||
padding: 0 20px; |
||||
} |
||||
} |
||||
</style> |
||||
@ -0,0 +1,302 @@
|
||||
<template> |
||||
<div class="container"> |
||||
<header class="mb-24"> |
||||
<el-form :label-width="120"> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来信时间"> |
||||
<el-date-picker |
||||
type="datetimerange" |
||||
start-placeholder="开始时间" |
||||
end-placeholder="结束时间" |
||||
value-format="YYYY-MM-DD HH:mm:ss" |
||||
time-format="A hh:mm:ss" |
||||
v-model="query.createTime" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来信人姓名"> |
||||
<el-input |
||||
placeholder="请输入" |
||||
v-model="query.contactName" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来信人电话"> |
||||
<el-input |
||||
placeholder="请输入" |
||||
v-model="query.contactPhone" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来信人证件号码"> |
||||
<el-input |
||||
placeholder="请输入" |
||||
v-model="query.contactIdCard" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="信件内容"> |
||||
<el-input |
||||
placeholder="请输入" |
||||
v-model="query.content" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="评价结果"> |
||||
<el-select v-model="query.satisfactionSms"> |
||||
<el-option value="satisfied" label="非常满意" /> |
||||
<el-option |
||||
value="basically_satisfied" |
||||
label="基本满意" |
||||
/> |
||||
<el-option |
||||
value="not_satisfied" |
||||
label="不满意" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
</el-form> |
||||
<div class="flex end"> |
||||
<div> |
||||
<el-button type="primary" @click="getList">查询</el-button> |
||||
<el-button @click="reset">重置</el-button> |
||||
</div> |
||||
</div> |
||||
</header> |
||||
<div> |
||||
<el-table :data="list"> |
||||
<el-table-column prop="id" label="编号" width="220" /> |
||||
<el-table-column |
||||
prop="createTime" |
||||
label="来信时间" |
||||
width="180" |
||||
/> |
||||
<el-table-column |
||||
prop="contactName" |
||||
label="来信人姓名" |
||||
width="120" |
||||
/> |
||||
<el-table-column |
||||
prop="contactPhone" |
||||
label="来信人电话" |
||||
width="120" |
||||
/> |
||||
<el-table-column |
||||
prop="contactIdCard" |
||||
label="来信人证件号码" |
||||
width="180" |
||||
/> |
||||
<el-table-column |
||||
prop="content" |
||||
label="信件内容" |
||||
show-overflow-tooltip |
||||
/> |
||||
<el-table-column |
||||
prop="caseNumber" |
||||
label="案件编号" |
||||
width="120" |
||||
/> |
||||
|
||||
<el-table-column |
||||
prop="involvedDeptName" |
||||
label="被投诉/涉及单位" |
||||
width="150" |
||||
/> |
||||
<el-table-column |
||||
label="评价结果" |
||||
width="150" |
||||
> |
||||
<template #default="{ row }"> |
||||
<span>{{ getSatisfactionLabel(row.satisfactionSms) }}</span> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column |
||||
label="操作" |
||||
width="150" |
||||
> |
||||
<template #default="{ row }"> |
||||
<el-button |
||||
type="primary" |
||||
link |
||||
@click="handleMail(row)" |
||||
size="small" |
||||
>详情</el-button |
||||
> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<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" |
||||
:total="totalSize.total" |
||||
layout="total, sizes, prev, pager, next" |
||||
> |
||||
</el-pagination> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<el-dialog title="信件详情" v-model="show"> |
||||
<div class="row"> |
||||
<div class="col"> |
||||
<label>信件编号</label> |
||||
<span>{{ activeRow.id }}</span> |
||||
</div> |
||||
<div class="col"> |
||||
<label>来信时间</label> |
||||
<span>{{ activeRow.createTime }}</span> |
||||
</div> |
||||
</div> |
||||
<div class="row"> |
||||
<div class="col"> |
||||
<label>来信人姓名</label> |
||||
<span>{{ activeRow.contactName }}</span> |
||||
</div> |
||||
<div class="col"> |
||||
<label>来信人电话</label> |
||||
<span>{{ activeRow.contactPhone }}</span> |
||||
</div> |
||||
</div> |
||||
<div class="row"> |
||||
<div class="col"> |
||||
<label>证件号码</label> |
||||
<span>{{ activeRow.contactIdCard }}</span> |
||||
</div> |
||||
</div> |
||||
<div class="row"> |
||||
<div class="col" style="width: 100%"> |
||||
<label>信件内容</label> |
||||
<div class="content">{{ activeRow.content }}</div> |
||||
</div> |
||||
</div> |
||||
<div class="row"> |
||||
<div class="col"> |
||||
<label>案件编号</label> |
||||
<span>{{ activeRow.caseNumber }}</span> |
||||
</div> |
||||
<div class="col"> |
||||
<label>被投诉/举报单位</label> |
||||
<span>{{ activeRow.involvedDeptName }}</span> |
||||
</div> |
||||
</div> |
||||
<div class="row" v-if="activeRow.attachments"> |
||||
<div class="col" style="width: 100%"> |
||||
<label>附件</label> |
||||
<div class="flex gap wrap attachments" v-if="JSON.parse(activeRow.attachments).length"> |
||||
<img v-for="(item, index) in JSON.parse(activeRow.attachments)" :key="index" :src="`https://jzxx.hncsga.cn/api/file/stream/${item.filepath}`" alt="" @click="open(`https://jzxx.hncsga.cn/api/file/stream/${item.filepath}`)"> |
||||
</div> |
||||
<el-empty description="无附件" v-else /> |
||||
</div> |
||||
</div> |
||||
<footer></footer> |
||||
</el-dialog> |
||||
</template> |
||||
<script setup> |
||||
import { listMail } from "@/api/mail"; |
||||
const query = ref({ |
||||
current: 1, |
||||
size: 10, |
||||
}); |
||||
const totalSize = ref({ |
||||
total: 0, |
||||
}); |
||||
const list = ref([]); |
||||
|
||||
function getList() { |
||||
listMail(query.value).then((data) => { |
||||
list.value = data.records; |
||||
totalSize.value.total = data.total; |
||||
}); |
||||
} |
||||
|
||||
function reset() { |
||||
query.value = { |
||||
current: 1, |
||||
size: 10, |
||||
}; |
||||
getList(); |
||||
} |
||||
|
||||
getList(); |
||||
|
||||
function getSatisfactionLabel(satisfaction) { |
||||
if (satisfaction === "satisfied") { |
||||
return "非常满意"; |
||||
} else if (satisfaction === "not_satisfied") { |
||||
return "不满意"; |
||||
} else if (satisfaction === "basically_satisfied") { |
||||
return "基本满意"; |
||||
} else { |
||||
return "暂无评价"; |
||||
} |
||||
} |
||||
|
||||
const show = ref(false) |
||||
const activeRow = ref({}) |
||||
function handleMail(row) { |
||||
activeRow.value = row |
||||
show.value = true |
||||
} |
||||
|
||||
function open(url) { |
||||
window.open(url) |
||||
} |
||||
</script> |
||||
<style lang="scss" scoped> |
||||
.row { |
||||
display: flex; |
||||
padding: 10px 0; |
||||
.col { |
||||
width: 50%; |
||||
display: flex; |
||||
gap: 10px; |
||||
label { |
||||
width: 160px; |
||||
text-align: right; |
||||
color: #666; |
||||
+ * { |
||||
width: calc(100% - 170px); |
||||
} |
||||
} |
||||
span { |
||||
color: #333; |
||||
} |
||||
.content { |
||||
background: #EFF0F5; |
||||
padding: 8px 20px; |
||||
white-space: pre-wrap; |
||||
} |
||||
|
||||
} |
||||
} |
||||
.attachments { |
||||
img { |
||||
max-width: 160px; |
||||
max-height: 300px; |
||||
border: 1px solid transparent; |
||||
|
||||
&:hover { |
||||
cursor: pointer; |
||||
border-color: red; |
||||
} |
||||
} |
||||
} |
||||
footer { |
||||
min-height: 20px; |
||||
} |
||||
</style> |
||||
@ -0,0 +1,152 @@
|
||||
<template> |
||||
<div class="container"> |
||||
<header class="mb-24"> |
||||
<el-form :label-width="120"> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来信时间"> |
||||
<el-date-picker |
||||
type="datetimerange" |
||||
start-placeholder="开始时间" |
||||
end-placeholder="结束时间" |
||||
value-format="YYYY-MM-DD HH:mm:ss" |
||||
time-format="A hh:mm:ss" |
||||
v-model="query.createTime" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="真实姓名"> |
||||
<el-input |
||||
placeholder="请输入" |
||||
v-model="query.realName" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="电话"> |
||||
<el-input |
||||
placeholder="请输入" |
||||
v-model="query.phone" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="证件号码"> |
||||
<el-input |
||||
placeholder="请输入" |
||||
v-model="query.idCard" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
</el-form> |
||||
<div class="flex end"> |
||||
<div> |
||||
<el-button type="primary" @click="getList">查询</el-button> |
||||
<el-button @click="reset">重置</el-button> |
||||
</div> |
||||
</div> |
||||
</header> |
||||
<div> |
||||
<el-table :data="list"> |
||||
<el-table-column |
||||
prop="id" |
||||
label="编号" |
||||
width="80" |
||||
align="center" |
||||
/> |
||||
<el-table-column prop="openid" label="openid" /> |
||||
<el-table-column prop="createTime" label="创建时间" /> |
||||
<el-table-column prop="realName" label="真实姓名" width="120" /> |
||||
<el-table-column prop="phone" label="电话" width="120" /> |
||||
<el-table-column prop="idCard" label="证件号码" /> |
||||
<el-table-column prop="faceAuthTime" label="认证时间" /> |
||||
<el-table-column label="操作" width="160"> |
||||
<template #default="{ row }"> |
||||
<el-popconfirm title="确认删除该用户?" @confirm="handleDel(row.id)"> |
||||
<template #reference> |
||||
<el-button |
||||
type="danger" |
||||
link |
||||
size="small" |
||||
>删除用户</el-button |
||||
> |
||||
</template> |
||||
</el-popconfirm> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<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" |
||||
:total="totalSize.total" |
||||
layout="total, sizes, prev, pager, next" |
||||
> |
||||
</el-pagination> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
<script setup> |
||||
import { listUser, delUser } from "@/api/user"; |
||||
import { ElMessage } from "element-plus"; |
||||
|
||||
const query = ref({ |
||||
current: 1, |
||||
size: 10, |
||||
}); |
||||
const totalSize = ref({ |
||||
total: 0, |
||||
}); |
||||
const list = ref([]); |
||||
|
||||
function getList() { |
||||
listUser(query.value).then((data) => { |
||||
list.value = data.records; |
||||
totalSize.value.total = data.total; |
||||
}); |
||||
} |
||||
|
||||
function reset() { |
||||
query.value = { |
||||
current: 1, |
||||
size: 10, |
||||
}; |
||||
getList(); |
||||
} |
||||
|
||||
getList(); |
||||
|
||||
function handleDel(id) { |
||||
delUser(id).then(() => { |
||||
ElMessage.success('删除成功') |
||||
getList() |
||||
}) |
||||
} |
||||
</script> |
||||
<style lang="scss" scoped> |
||||
.form-item { |
||||
display: flex; |
||||
line-height: 22px; |
||||
margin: 10px 0; |
||||
gap: 20px; |
||||
label { |
||||
width: 137px; |
||||
text-align: right; |
||||
} |
||||
div { |
||||
color: #333; |
||||
max-width: calc(100% - 137px); |
||||
} |
||||
.content { |
||||
background: #eff0f5; |
||||
padding: 0 20px; |
||||
} |
||||
} |
||||
</style> |
||||
Loading…
Reference in new issue