From fb45193819e90f59c5f22a5f1e5a3f6a38c98c00 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期二, 25 二月 2025 17:48:27 +0800
Subject: [PATCH] 搬迁投诉列表
---
src/views/CNAS/process/complaint/index.vue | 629 ++++++++++++++++++++++++++++++++++++++++++++++++++++
src/api/cnas/process/complaint.js | 57 ++++
2 files changed, 686 insertions(+), 0 deletions(-)
diff --git a/src/api/cnas/process/complaint.js b/src/api/cnas/process/complaint.js
new file mode 100644
index 0000000..cd93e8d
--- /dev/null
+++ b/src/api/cnas/process/complaint.js
@@ -0,0 +1,57 @@
+// 鎶曡瘔姹囨�昏〃鐩稿叧鎺ュ彛
+import request from "@/utils/request";
+
+// 鎶曡瘔澶勭悊鏂板
+export function addProcessComplain(data) {
+ return request({
+ url: "/processComplain/addProcessComplain",
+ method: "post",
+ data: data,
+ });
+}
+
+//鎶曡瘔澶勭悊璇︽儏
+export function getProcessComplain(query) {
+ return request({
+ url: "/processComplain/getProcessComplain",
+ method: "get",
+ params: query,
+ });
+}
+
+// 鎶曡瘔澶勭悊淇敼
+export function doProcessComplain(data) {
+ return request({
+ url: "/processComplain/doProcessComplain",
+ method: "post",
+ data: data,
+ });
+}
+
+//鎶曡瘔澶勭悊瀵煎嚭
+export function exportProcessComplain(query) {
+ return request({
+ url: "/processComplain/exportProcessComplain",
+ method: "get",
+ responseType: "blob",
+ params: query,
+ });
+}
+
+//鎶曡瘔澶勭悊鍒嗛〉
+export function pageProcessComplain(query) {
+ return request({
+ url: "/processComplain/pageProcessComplain",
+ method: "get",
+ params: query,
+ });
+}
+
+//鎶曡瘔澶勭悊鍒犻櫎
+export function delProcessComplain(query) {
+ return request({
+ url: "/processComplain/delProcessComplain",
+ method: "delete",
+ params: query,
+ });
+}
diff --git a/src/views/CNAS/process/complaint/index.vue b/src/views/CNAS/process/complaint/index.vue
new file mode 100644
index 0000000..db76ec4
--- /dev/null
+++ b/src/views/CNAS/process/complaint/index.vue
@@ -0,0 +1,629 @@
+<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>璐d换褰掑睘鍙婃姇璇夋槸鍚︽垚绔�</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;">璐d换閮ㄩ棬璐熻矗浜�:</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;">璐d换閮ㄩ棬璐熻矗浜�:</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>
--
Gitblit v1.9.3