<template>
|
<div class="Complaint">
|
<el-row class="title">
|
<el-col :span="12" style="padding-left: 20px;text-align: left;">投诉</el-col>
|
<el-col :span="12" style="text-align: right;">
|
<el-button size="medium" type="primary" @click="handleDown" :loading="outLoading" v-if="outPower">导出</el-button>
|
<el-button size="medium" type="primary" @click="openAdd" v-if="addPower">新增</el-button>
|
</el-col>
|
</el-row>
|
<div class="search">
|
<div class="search_thing">
|
<div class="search_label">样品编号:</div>
|
<div class="search_input"><el-input size="small" placeholder="请输入" clearable v-model="componentData.entity.sampleCode"
|
@keyup.enter.native="refreshTable()"></el-input></div>
|
</div>
|
<div class="search_thing">
|
<div class="search_label">投诉名称:</div>
|
<div class="search_input">
|
<!-- <el-date-picker
|
v-model="componentData.entity.createTime"
|
type="date"
|
size="small"
|
placeholder="选择日期"
|
format="yyyy-MM-dd HH:mm:ss"
|
value-format="yyyy-MM-dd HH:mm:ss" @change="refreshTable()">
|
</el-date-picker> -->
|
<el-input size="small" placeholder="请输入" clearable v-model="componentData.entity.complainName"
|
@keyup.enter.native="refreshTable()"></el-input>
|
</div>
|
</div>
|
<div class="search_thing" style="padding-left: 30px;">
|
<el-button size="small" @click="refresh()">重 置</el-button>
|
<el-button size="small" type="primary" @click="refreshTable()">查 询</el-button>
|
</div>
|
</div>
|
<div class="table">
|
<ValueTable ref="ValueTable" :url="$api.processComplain.pageProcessComplain"
|
:delUrl="$api.processComplain.delProcessComplain"
|
:componentData="componentData" :key="upIndex"/>
|
</div>
|
<el-dialog
|
title="新增"
|
:visible.sync="addDialogVisible"
|
width="400px">
|
<el-row>
|
<el-col :span="24" style="margin-bottom: 16px;">
|
<div class="search_thing">
|
<div class="search_label">投诉方名称:</div>
|
<div class="search_input"><el-input size="small" placeholder="请输入" clearable v-model="addInfo.complainName"></el-input></div>
|
</div>
|
</el-col>
|
<el-col :span="24" style="margin-bottom: 16px;">
|
<div class="search_thing">
|
<div class="search_label">检验报告编号:</div>
|
<div class="search_input">
|
<el-input size="small" placeholder="请输入" clearable v-model="addInfo.insReport"></el-input>
|
<!-- <el-select v-model="addInfo.insReportId" filterable placeholder="请选择" size="small" style="width: 100%;">
|
<el-option
|
v-for="item in reportList"
|
:key="item.id"
|
:label="item.code"
|
:value="item.id">
|
</el-option>
|
</el-select> -->
|
</div>
|
</div>
|
</el-col>
|
<el-col :span="24" style="margin-bottom: 16px;">
|
<div class="search_thing">
|
<div class="search_label">样品编号:</div>
|
<div class="search_input"><el-input size="small" placeholder="请输入" clearable v-model="addInfo.sampleCode"></el-input></div>
|
</div>
|
</el-col>
|
<el-col :span="24">
|
<div class="search_thing">
|
<div class="search_label">投诉方式:</div>
|
<div class="search_input"><el-input size="small" placeholder="请输入" clearable v-model="addInfo.complainMethod"></el-input></div>
|
</div>
|
</el-col>
|
</el-row>
|
<span slot="footer" class="dialog-footer">
|
<el-button @click="addDialogVisible = false">取 消</el-button>
|
<el-button type="primary" @click="handleAdd" :loading="addLoading">确 定</el-button>
|
</span>
|
</el-dialog>
|
<el-dialog
|
:title="title"
|
:visible.sync="handleDialogVisible"
|
width="800px" :class="{downPdf:title=='导出'}" :modal="title!='导出'">
|
<div class="dialog-body">
|
<div id="dialogBody">
|
<h4 style="display: flex;align-items: center;flex-direction: column;justify-content: center;">
|
<span style="font-size: 20px;">客户投诉受理单</span>
|
<span>Customer complaint receipts</span>
|
</h4>
|
<p style="display: flex;justify-content: space-between;margin-top: 16px;">
|
<span>{{ currentInfo0.complainNo }}</span>
|
<span>NO:</span>
|
</p>
|
<table border="1" class="tables" cellpadding="10">
|
<tr>
|
<td colspan="3">
|
<p>投诉方名称</p>
|
<p class="en">Name of the complaining party</p>
|
</td>
|
<td colspan="3">{{ currentInfo0.complainName }}</td>
|
</tr>
|
<tr>
|
<td>
|
<p>检测报告编号</p>
|
<p class="en">Test report number</p>
|
</td>
|
<td colspan="3">{{ currentInfo0.insReport }}</td>
|
<td >
|
<p>样品编号</p>
|
<p class="en">Sample number</p>
|
</td>
|
<td>{{ currentInfo0.sampleCode }}</td>
|
</tr>
|
<tr>
|
<td>
|
<p>投诉人</p>
|
<p class="en">Complainant</p>
|
</td>
|
<td>{{ currentInfo0.createUser }}</td>
|
<td>
|
<p>电话</p>
|
<p class="en">Phone</p>
|
</td>
|
<td>{{ currentInfo0.phone }}</td>
|
<td>
|
<p>E-Mail</p>
|
<p class="en">E-mail</p>
|
</td>
|
<td>{{ currentInfo0.email }}</td>
|
</tr>
|
<tr>
|
<td>
|
<p>投诉方式</p>
|
<p class="en">Complaint method</p>
|
</td>
|
<td colspan="3">{{ currentInfo0.complainMethod }}</td>
|
<td >
|
<p>投诉日期</p>
|
<p class="en">Date of complaint</p>
|
</td>
|
<td>{{ currentInfo0.createTime?currentInfo0.createTime.split(' ')[0]:'' }}</td>
|
</tr>
|
<tr>
|
<td>
|
<p>问题记录</p>
|
<p class="en">Problem logging</p>
|
</td>
|
<td colspan="5">
|
<div class="user-content">
|
<el-input
|
type="textarea"
|
:rows="3"
|
placeholder="请输入内容"
|
v-model="currentInfo0.problemRecords" v-if="title=='处理投诉'">
|
</el-input>
|
<p v-else style="text-align: left;line-height: 26px;">{{ currentInfo0.problemRecords }}</p>
|
</div>
|
<div class="user-info" v-if="title!='处理投诉'">
|
<div style="width: 200px;margin-right: 10px;">
|
<p style="text-align: end;">质量负责人:</p>
|
<p class="en" style="text-align: end;">Quality Manager:</p>
|
</div>
|
<span>{{ currentInfo0.problemRecordsUserName }}</span>
|
<div style="width: 70px;">
|
<p>日期:</p>
|
<p class="en">Date:</p>
|
</div>
|
<span style="margin-right: 16px;">{{ currentInfo0.problemRecordsTime }}</span>
|
</div>
|
</td>
|
</tr>
|
<tr>
|
<td>
|
<p>责任归属及投诉是否成立</p>
|
<p class="en">Attribution of responsibility and whether the complaint is established</p>
|
</td>
|
<td colspan="5">
|
<div class="user-content">
|
<el-input
|
type="textarea"
|
:rows="3"
|
placeholder="请输入内容"
|
v-model="currentInfo0.dutyOwnership" v-if="title=='处理投诉'">
|
</el-input>
|
<p v-else style="text-align: left;line-height: 26px;">{{ currentInfo0.dutyOwnership }}</p>
|
</div>
|
<div class="user-info" v-if="title!='处理投诉'">
|
<div style="width: 200px;margin-right: 10px;">
|
<p style="text-align: end;">质量负责人:</p>
|
<p class="en" style="text-align: end;">Quality Manager:</p>
|
</div>
|
<span>{{ currentInfo0.dutyOwnershipUserName }}</span>
|
<div style="width: 70px;">
|
<p>日期:</p>
|
<p class="en">Date:</p>
|
</div>
|
<span style="margin-right: 16px;">{{ currentInfo0.dutyOwnershipTime }}</span>
|
</div>
|
</td>
|
</tr>
|
<tr>
|
<td>
|
<p>原因分析</p>
|
<p class="en">Cause analysis</p>
|
</td>
|
<td colspan="5">
|
<div class="user-content">
|
<el-input
|
type="textarea"
|
:rows="3"
|
placeholder="请输入内容"
|
v-model="currentInfo0.causeAnalysis" v-if="title=='处理投诉'">
|
</el-input>
|
<p v-else style="text-align: left;line-height: 26px;">{{ currentInfo0.causeAnalysis }}</p>
|
</div>
|
<div class="user-info" v-if="title!='处理投诉'">
|
<div style="width: 200px;margin-right: 10px;">
|
<p style="text-align: end;">责任部门负责人:</p>
|
<p class="en" style="text-align: end;">Head of Responsible Department:</p>
|
</div>
|
<span>{{ currentInfo0.causeAnalysisUserName }}</span>
|
<div style="width: 70px;">
|
<p>日期:</p>
|
<p class="en">Date:</p>
|
</div>
|
<span style="margin-right: 16px;">{{ currentInfo0.causeAnalysisTime }}</span>
|
</div>
|
</td>
|
</tr>
|
<tr>
|
<td>
|
<p>纠正措施</p>
|
<p class="en">Corrective actions</p>
|
</td>
|
<td colspan="5">
|
<div class="user-content">
|
<el-input
|
type="textarea"
|
:rows="3"
|
placeholder="请输入内容"
|
v-model="currentInfo0.correctiveAction" v-if="title=='处理投诉'">
|
</el-input>
|
<p v-else style="text-align: left;line-height: 26px;">{{ currentInfo0.correctiveAction }}</p>
|
</div>
|
<div class="user-info" v-if="title!='处理投诉'">
|
<div style="width: 200px;margin-right: 10px;">
|
<p style="text-align: end;">责任部门负责人:</p>
|
<p class="en" style="text-align: end;">Head of Responsible Department:</p>
|
</div>
|
<span>{{ currentInfo0.correctiveActionUserName }}</span>
|
<div style="width: 70px;">
|
<p>日期:</p>
|
<p class="en">Date:</p>
|
</div>
|
<span style="margin-right: 16px;">{{ currentInfo0.correctiveActionTime }}</span>
|
</div>
|
</td>
|
</tr>
|
<tr>
|
<td>
|
<p>纠正措施确认</p>
|
<p class="en">Corrective actions confirmation</p>
|
</td>
|
<td colspan="5">
|
<div class="user-content">
|
<el-input
|
type="textarea"
|
:rows="3"
|
placeholder="请输入内容"
|
v-model="currentInfo0.correctiveActionConfirmation" v-if="title=='处理投诉'">
|
</el-input>
|
<p v-else style="text-align: left;line-height: 26px;">{{ currentInfo0.correctiveActionConfirmation }}</p>
|
</div>
|
<div class="user-info" v-if="title!='处理投诉'">
|
<div style="width: 200px;margin-right: 10px;">
|
<p style="text-align: end;">质量负责人:</p>
|
<p class="en" style="text-align: end;">Quality Manager:</p>
|
</div>
|
<span>{{ currentInfo0.correctiveActionConfirmationUserName }}</span>
|
<div style="width: 70px;">
|
<p>日期:</p>
|
<p class="en">Date:</p>
|
</div>
|
<span style="margin-right: 16px;">{{ currentInfo0.correctiveActionConfirmationTime }}</span>
|
</div>
|
</td>
|
</tr>
|
</table>
|
</div>
|
</div>
|
<span slot="footer" class="dialog-footer" v-if="title=='处理投诉'">
|
<el-button @click="handleDialogVisible = false">取 消</el-button>
|
<el-button type="primary" @click="submit" :loading="addLoading">提 交</el-button>
|
</span>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script>
|
import ValueTable from '../tool/value-table.vue'
|
import {getYearAndMonthAndDays} from '../../util/date'
|
import {exportHtmlToPDF} from '../../util/downHtmlToPDF'
|
export default {
|
components: {
|
ValueTable
|
},
|
data() {
|
return {
|
addPower:false,
|
outLoading:false,
|
addDialogVisible:false,
|
addLoading:false,
|
handleDialogVisible:false,
|
title:'处理投诉',
|
componentData: {
|
entity: {
|
sampleCode: null,
|
complainName: null,
|
orderBy: {
|
field: 'id',
|
order: 'asc'
|
}
|
},
|
isIndex: true,
|
showSelect: false,
|
select: false,
|
do: [{
|
id: 'handleLook',
|
font: '查看',
|
type: 'text',
|
method: 'handleLook',
|
}, {
|
id: 'delete',
|
font: '删除',
|
type: 'text',
|
method: 'doDiy'
|
}, {
|
id: 'handleWork',
|
font: '处理',
|
type: 'text',
|
method: 'handleWork'
|
}, {
|
id: 'handleOut',
|
font: '导出',
|
type: 'text',
|
method: 'handleOut'
|
}],
|
tagField: {},
|
selectField: {
|
},
|
requiredAdd: [],
|
requiredUp: [],
|
needSort: [],
|
inputType: ''
|
},
|
entityCopy: {},
|
upIndex: 0,
|
addInfo:{},//新增信息
|
currentInfo:null,//接口请求回来的信息
|
currentInfo0:{},//用户编辑过后的信息
|
reportList:[],//报告列表
|
outPower:false,
|
};
|
},
|
mounted() {
|
this.entityCopy = this.HaveJson(this.componentData.entity);
|
this.getPower()
|
},
|
methods: {
|
// 权限分配
|
getPower() {
|
let power = JSON.parse(sessionStorage.getItem('power'))
|
let up = false
|
let del = false
|
let add = false
|
let out = false
|
for (var i = 0; i < power.length; i++) {
|
if (power[i].menuMethod == 'doProcessComplain') {
|
up = true
|
}
|
if (power[i].menuMethod == 'addProcessComplain') {
|
add = true
|
}
|
if (power[i].menuMethod == 'delProcessComplain') {
|
del = true
|
}
|
if (power[i].menuMethod == 'exportProcessComplain') {
|
out = true
|
}
|
}
|
if (!up) {
|
this.componentData.do.splice(2, 1)
|
}
|
if (!del) {
|
this.componentData.do.splice(1, 1)
|
}
|
this.outPower = out
|
this.addPower = add
|
},
|
getPageInsReport(){
|
this.$axios.post(this.$api.insReport.pageInsReport,
|
{
|
entity:{
|
orderBy:{
|
field: "id",
|
order: "desc"
|
}
|
},
|
page:{
|
current:-1,
|
size:-1
|
}
|
},{headers: { 'Content-Type': 'application/json' }}).then((res)=>{
|
this.reportList = res.data.body.records
|
})
|
},
|
openAdd() {
|
this.addInfo = {}
|
this.addDialogVisible = true
|
},
|
handleAdd(){
|
this.addLoading = true
|
this.$axios.post(this.$api.processComplain.addProcessComplain,
|
this.addInfo ,{headers: { 'Content-Type': 'application/json' }}
|
).then((res)=>{
|
this.addLoading = false
|
if(res.code==201){
|
this.$message({
|
type: 'error',
|
message: '新增失败'
|
})
|
return
|
}
|
this.$message({
|
type: 'success',
|
message: '新增成功'
|
})
|
this.addDialogVisible = false
|
this.refresh()
|
})
|
},
|
// 处理投诉
|
handleWork(row){
|
this.$axios.post(this.$api.processComplain.getProcessComplain,
|
{id:row.id}).then((res)=>{
|
this.currentInfo = res.data
|
this.currentInfo0 = this.HaveJson(res.data)
|
this.title = '处理投诉'
|
this.handleDialogVisible = true
|
})
|
},
|
submit(){
|
this.handleParam('problemRecords')
|
this.handleParam('dutyOwnership')
|
this.handleParam('causeAnalysis')
|
this.handleParam('correctiveAction')
|
this.handleParam('correctiveActionConfirmation')
|
this.addLoading = true
|
for(let i in this.currentInfo0){
|
if(!this.currentInfo0[i]){
|
delete this.currentInfo0[i]
|
}
|
}
|
this.$axios.post(this.$api.processComplain.doProcessComplain,
|
this.currentInfo0 ,{headers: { 'Content-Type': 'application/json' }}
|
).then((res)=>{
|
this.addLoading = false
|
if(res.code==201){
|
this.$message({
|
type: 'error',
|
message: '提交失败'
|
})
|
return
|
}
|
this.$message({
|
type: 'success',
|
message: '提交成功'
|
})
|
this.handleDialogVisible = false
|
this.refresh()
|
})
|
},
|
/**
|
* 处理参数
|
*
|
* @param {string} type - 需要处理的参数类型
|
*/
|
handleParam(type){
|
if(this.currentInfo0[type]!=this.currentInfo[type]){
|
this.currentInfo0[type+'User'] = JSON.parse(localStorage.getItem("user")).userId
|
this.currentInfo0[type+'Time'] = getYearAndMonthAndDays()
|
}
|
},
|
// 查看投诉
|
handleLook(row){
|
this.$axios.post(this.$api.processComplain.getProcessComplain,
|
{id:row.id}).then((res)=>{
|
this.currentInfo = res.data
|
this.currentInfo0 = this.HaveJson(res.data)
|
this.title = '查看投诉'
|
this.handleDialogVisible = true
|
})
|
},
|
refreshTable() {
|
this.$refs['ValueTable'].selectList()
|
},
|
refresh() {
|
this.componentData.entity = this.HaveJson(this.entityCopy)
|
this.upIndex++
|
this.refreshTable()
|
},
|
handleDown(){
|
this.outLoading = true
|
this.$axios.post(this.$api.processComplain.exportProcessComplain,{entity:{sampleCode:this.componentData.entity.sampleCode,complainName:this.componentData.entity.complainName}},{responseType: "blob",headers: { 'Content-Type': 'application/json' }}).then(res => {
|
this.outLoading = false
|
if(res.code==201){
|
return
|
}
|
const blob = new Blob([res],{ type: 'application/octet-stream' });
|
//将Blob 对象转换成字符串
|
let reader = new FileReader();
|
reader.readAsText(blob, 'utf-8');
|
reader.onload = () => {
|
try {
|
let result = JSON.parse(reader.result);
|
if (result.message) {
|
this.$message.error(result.message);
|
} else {
|
const url = URL.createObjectURL(blob);
|
const link = document.createElement('a');
|
link.href = url;
|
link.download = '投诉情况汇总表.xlsx';
|
link.click();
|
this.$message.success('导出成功')
|
}
|
} catch (err) {
|
console.log(err);
|
const url = URL.createObjectURL(blob);
|
const link = document.createElement('a');
|
link.href = url;
|
link.download = '投诉情况汇总表.xlsx';
|
link.click();
|
this.$message.success('导出成功')
|
}
|
}
|
})
|
},
|
handleOut(row){
|
this.$axios.post(this.$api.processComplain.getProcessComplain,
|
{id:row.id}).then((res)=>{
|
if(res.code==201){
|
return
|
}
|
this.currentInfo = res.data
|
this.currentInfo0 = this.HaveJson(res.data)
|
this.title = '导出'
|
this.handleDialogVisible = true
|
setTimeout(() => {
|
this.$nextTick(() => {
|
const element = document.getElementById("dialogBody");
|
exportHtmlToPDF(element,'投诉详情').then(res=>{
|
this.handleDialogVisible = false
|
})
|
})
|
}, 500);
|
})
|
}
|
},
|
}
|
</script>
|
|
<style scoped>
|
.title {
|
height: 60px;
|
line-height: 60px;
|
}
|
.search {
|
background-color: #fff;
|
height: 80px;
|
display: flex;
|
align-items: center;
|
}
|
|
.search_thing {
|
width: 350px;
|
display: flex;
|
align-items: center;
|
}
|
|
.search_label {
|
width: 110px;
|
font-size: 14px;
|
text-align: right;
|
}
|
|
.search_input {
|
width: calc(100% - 110px);
|
}
|
|
.table {
|
margin-top: 10px;
|
background-color: #fff;
|
width: calc(100% - 40px);
|
height: calc(100% - 60px - 80px - 10px - 40px);
|
padding: 20px;
|
}
|
.dialog-body{
|
max-height: 75vh;
|
overflow-y: auto;
|
}
|
.tables {
|
table-layout: fixed;
|
width: 100%;
|
margin-top: 10px;
|
}
|
|
.tables td {
|
height: 40px;
|
width: 100px;
|
text-align: center;
|
font-size: 14px;
|
word-wrap: break-word;
|
white-space: normal;
|
}
|
.en{
|
font-size: 12px;
|
word-break: break-word; /* 自动断行 */
|
overflow-wrap: break-word; /* 防止溢出 */
|
white-space: normal; /* 默认换行 */
|
}
|
.user-info{
|
display: flex;
|
align-items: center;
|
justify-content: end;
|
}
|
.user-content{
|
min-height: 60px;
|
}
|
.downPdf{
|
opacity: 0 !important;
|
}
|
</style>
|