¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="Complaint"> |
| | | <div class="search"> |
| | | <div class="search_thing"> |
| | | <div class="search_label">æ ·åç¼å·ï¼</div> |
| | | <div class="search_input"><el-input v-model="queryParams.sampleCode" clearable placeholder="请è¾å
¥" size="small" |
| | | @keyup.enter.native="refreshTable()"></el-input></div> |
| | | </div> |
| | | <div class="search_thing"> |
| | | <div class="search_label">æè¯åç§°ï¼</div> |
| | | <div class="search_input"> |
| | | <el-input v-model="queryParams.complainName" clearable placeholder="请è¾å
¥" size="small" |
| | | @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 class="btn"> |
| | | <el-button :loading="outLoading" size="small" type="primary" @click="handleDown">导åº</el-button> |
| | | <el-button size="small" type="primary" @click="openAdd">æ°å¢</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table"> |
| | | <lims-table :tableData="tableData" :column="column" :tableLoading="tableLoading" :height="'calc(100vh - 290px)'" |
| | | :page="page" @pagination="pagination"></lims-table> |
| | | </div> |
| | | <el-dialog :visible.sync="addDialogVisible" title="æ°å¢" 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 v-model="addInfo.complainName" clearable placeholder="请è¾å
¥" |
| | | size="small"></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 v-model="addInfo.code" clearable placeholder="请è¾å
¥" size="small"></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 v-model="addInfo.sampleCode" clearable placeholder="请è¾å
¥" |
| | | size="small"></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 v-model="addInfo.complainMethod" clearable placeholder="请è¾å
¥" |
| | | size="small"></el-input></div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | <span slot="footer" class="dialog-footer"> |
| | | <el-button @click="addDialogVisible = false">å æ¶</el-button> |
| | | <el-button :loading="addLoading" type="primary" @click="handleAdd">ç¡® å®</el-button> |
| | | </span> |
| | | </el-dialog> |
| | | <el-dialog :class="{ downPdf: title == '导åº' }" :modal="title != '导åº'" :title="title" |
| | | :visible.sync="handleDialogVisible" width="800px"> |
| | | <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" cellpadding="10" class="tables"> |
| | | <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.code }}</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 v-if="title == 'å¤çæè¯'" v-model="currentInfo0.problemRecords" :rows="3" placeholder="请è¾å
¥å
容" |
| | | type="textarea"> |
| | | </el-input> |
| | | <p v-else style="text-align: left;line-height: 26px;">{{ currentInfo0.problemRecords }}</p> |
| | | </div> |
| | | <div v-if="title != 'å¤çæè¯'" class="user-info"> |
| | | <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 v-if="title == 'å¤çæè¯'" v-model="currentInfo0.dutyOwnership" :rows="3" placeholder="请è¾å
¥å
容" |
| | | type="textarea"> |
| | | </el-input> |
| | | <p v-else style="text-align: left;line-height: 26px;">{{ currentInfo0.dutyOwnership }}</p> |
| | | </div> |
| | | <div v-if="title != 'å¤çæè¯'" class="user-info"> |
| | | <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 v-if="title == 'å¤çæè¯'" v-model="currentInfo0.causeAnalysis" :rows="3" placeholder="请è¾å
¥å
容" |
| | | type="textarea"> |
| | | </el-input> |
| | | <p v-else style="text-align: left;line-height: 26px;">{{ currentInfo0.causeAnalysis }}</p> |
| | | </div> |
| | | <div v-if="title != 'å¤çæè¯'" class="user-info"> |
| | | <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 v-if="title == 'å¤çæè¯'" v-model="currentInfo0.correctiveAction" :rows="3" placeholder="请è¾å
¥å
容" |
| | | type="textarea"> |
| | | </el-input> |
| | | <p v-else style="text-align: left;line-height: 26px;">{{ currentInfo0.correctiveAction }}</p> |
| | | </div> |
| | | <div v-if="title != 'å¤çæè¯'" class="user-info"> |
| | | <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 v-if="title == 'å¤çæè¯'" v-model="currentInfo0.correctiveActionConfirmation" :rows="3" |
| | | placeholder="请è¾å
¥å
容" type="textarea"> |
| | | </el-input> |
| | | <p v-else style="text-align: left;line-height: 26px;">{{ currentInfo0.correctiveActionConfirmation }} |
| | | </p> |
| | | </div> |
| | | <div v-if="title != 'å¤çæè¯'" class="user-info"> |
| | | <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 v-if="title == 'å¤çæè¯'" slot="footer" class="dialog-footer"> |
| | | <el-button @click="handleDialogVisible = false">å æ¶</el-button> |
| | | <el-button :loading="addLoading" type="primary" @click="submit">æ 交</el-button> |
| | | </span> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import limsTable from "@/components/Table/lims-table.vue"; |
| | | import { getYearAndMonthAndDays } from '@/utils/date' |
| | | import { exportHtmlToPDF } from '@/utils/downHtmlToPDF' |
| | | import { |
| | | addProcessComplain, |
| | | getProcessComplain, |
| | | doProcessComplain, |
| | | exportProcessComplain, |
| | | pageProcessComplain, |
| | | delProcessComplain |
| | | } from '@/api/cnas/process/complaint.js' |
| | | import { mapGetters } from "vuex"; |
| | | export default { |
| | | components: { |
| | | limsTable |
| | | }, |
| | | data() { |
| | | return { |
| | | addPower: false, |
| | | outLoading: false, |
| | | addDialogVisible: false, |
| | | addLoading: false, |
| | | handleDialogVisible: false, |
| | | title: 'å¤çæè¯', |
| | | addInfo: {},//æ°å¢ä¿¡æ¯ |
| | | currentInfo: null,//æ¥å£è¯·æ±åæ¥çä¿¡æ¯ |
| | | currentInfo0: {},//ç¨æ·ç¼è¾è¿åçä¿¡æ¯ |
| | | outPower: false, |
| | | queryParams: {}, |
| | | tableData: [], |
| | | column: [ |
| | | { label: "æè¯åç§°", prop: "complainName" }, |
| | | { label: "æè¯äºº", prop: "complainant" }, |
| | | { label: "æè¯æ¥æ", prop: "createTime" }, |
| | | { |
| | | dataType: "action", |
| | | fixed: "right", |
| | | label: "æä½", |
| | | operation: [ |
| | | { |
| | | name: "æ¥ç", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | this.handleLook(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "å¤ç", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | this.handleWork(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "导åº", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | this.handleOut(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "å é¤", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | this.handleDelete(row); |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | ], |
| | | page: { |
| | | total: 0, |
| | | size: 10, |
| | | current: 0, |
| | | }, |
| | | }; |
| | | }, |
| | | computed: { |
| | | ...mapGetters(["userId"]), |
| | | }, |
| | | mounted() { |
| | | // this.entityCopy = this.HaveJson(this.componentData.entity); |
| | | this.getList() |
| | | }, |
| | | 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 |
| | | }, |
| | | openAdd() { |
| | | this.addInfo = {} |
| | | this.addDialogVisible = true |
| | | }, |
| | | handleAdd() { |
| | | this.addLoading = true |
| | | addProcessComplain(this.addInfo).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) { |
| | | 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] |
| | | } |
| | | } |
| | | doProcessComplain(this.currentInfo0).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'] = this.userId |
| | | this.currentInfo0[type + 'Time'] = getYearAndMonthAndDays() |
| | | } |
| | | }, |
| | | // æ¥çæè¯ |
| | | handleLook(row) { |
| | | addProcessComplain({ id: row.id }).then((res) => { |
| | | this.currentInfo = res.data |
| | | this.currentInfo0 = this.HaveJson(res.data) |
| | | this.title = 'æ¥çæè¯' |
| | | this.handleDialogVisible = true |
| | | }) |
| | | }, |
| | | getList() { |
| | | this.tableLoading = true; |
| | | let param = { ...this.queryParams, ...this.page }; |
| | | delete param.total; |
| | | pageProcessComplain({ ...param }) |
| | | .then((res) => { |
| | | this.tableLoading = false; |
| | | if (res.code === 200) { |
| | | this.tableData = res.data.records; |
| | | this.page.total = res.data.total; |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | this.tableLoading = false; |
| | | }); |
| | | }, |
| | | pagination({ page, limit }) { |
| | | this.page.current = page; |
| | | this.page.size = limit; |
| | | this.getList(); |
| | | }, |
| | | refresh() { |
| | | this.queryParams = {}; |
| | | this.page.current = 1; |
| | | this.getList(); |
| | | }, |
| | | refreshTable() { |
| | | this.page.current = 1; |
| | | this.getList(); |
| | | }, |
| | | handleDown() { |
| | | this.outLoading = true |
| | | exportProcessComplain(this.queryParams).then(res => { |
| | | this.outLoading = false |
| | | if (res.code == 201) { |
| | | return |
| | | } |
| | | const blob = new Blob([res], { type: 'application/octet-stream' }); |
| | | this.$download.saveAs(blob, 'æè¯æ
嵿±æ»è¡¨.xlsx'); |
| | | }) |
| | | }, |
| | | handleOut(row) { |
| | | 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); |
| | | }) |
| | | }, |
| | | handleDelete(row) { |
| | | this.$confirm("æ¯å¦å é¤è¯¥æ¡æ°æ®?", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | delProcessComplain({ id: row.id }).then((res) => { |
| | | if (res.code == 201) return; |
| | | this.$message.success("å 餿å"); |
| | | this.refresh(); |
| | | }); |
| | | }) |
| | | .catch(() => { }); |
| | | }, |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .title { |
| | | height: 60px; |
| | | line-height: 60px; |
| | | } |
| | | |
| | | .search { |
| | | background-color: #fff; |
| | | height: 80px; |
| | | display: flex; |
| | | align-items: center; |
| | | position: relative; |
| | | } |
| | | |
| | | .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 { |
| | | background-color: #fff; |
| | | height: calc(100% - 60px - 80px - 10px - 40px); |
| | | padding: 20px; |
| | | } |
| | | |
| | | .dialog-body { |
| | | max-height: 75vh; |
| | | overflow-y: auto; |
| | | } |
| | | |
| | | .tables { |
| | | table-layout: fixed; |
| | | width: 100%; |
| | | } |
| | | |
| | | .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; |
| | | } |
| | | |
| | | .btn { |
| | | position: absolute; |
| | | top: 16px; |
| | | right: 20px; |
| | | } |
| | | </style> |