spring
2025-02-24 8f7fc389bab56f0d92a7f665b146391f20d69f51
客户满意度搬迁
已修改1个文件
已添加3个文件
725 ■■■■■ 文件已修改
src/api/cnas/systemManagement/customerSatisfaction.js 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/styles/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/systemManagement/customerSatisfaction/components/formDialog.vue 256 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/systemManagement/customerSatisfaction/index.vue 410 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/systemManagement/customerSatisfaction.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
// å®¢æˆ·æ»¡æ„åº¦ç›¸å…³æŽ¥å£
import request from "@/utils/request";
//客户满意度调查列表
export function pageClientSatisfaction(query) {
  return request({
    url: "/clientSatisfaction/pageClientSatisfaction",
    method: "get",
    params: query,
  });
}
//查询客户分析附件
export function pageAnalyseFile(query) {
  return request({
    url: "/clientSatisfaction/pageAnalyseFile",
    method: "get",
    params: query,
  });
}
//删除新增客户满意度调查
export function delClientSatisfaction(query) {
  return request({
    url: "/clientSatisfaction/delClientSatisfaction",
    method: "delete",
    params: query,
  });
}
//删除客户分析附件
export function delAnalyseFile(query) {
  return request({
    url: "/clientSatisfaction/delAnalyseFile",
    method: "delete",
    params: query,
  });
}
// æ–°å¢žå®¢æˆ·æ»¡æ„åº¦è°ƒæŸ¥
export function addClientSatisfaction(data) {
  return request({
    url: "/clientSatisfaction/addClientSatisfaction",
    method: "post",
    data: data,
  });
}
// ä¿®æ”¹æ–°å¢žå®¢æˆ·æ»¡æ„åº¦è°ƒæŸ¥
export function updateClientSatisfaction(data) {
  return request({
    url: "/clientSatisfaction/updateClientSatisfaction",
    method: "post",
    data: data,
  });
}
src/assets/styles/index.scss
@@ -195,3 +195,6 @@
.required-span {
  color: red;
}
table {
  border-collapse: collapse; /* å…³é”®å±žæ€§ï¼šåˆå¹¶è¾¹æ¡† */
}
src/views/CNAS/systemManagement/customerSatisfaction/components/formDialog.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,256 @@
<template>
  <div>
    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :visible.sync="formDia" title="客户满意度调查表"
      width="70%" @close="closeFormDia">
      <table border="1" cellspacing="10" class="tables">
        <tr>
          <td class="td-title">
            <p>单位名称:</p>
          </td>
          <td class="td-info" colspan="2">
            <el-input v-model="form.unitName" placeholder="请输入内容" size="small">
            </el-input>
          </td>
          <td class="td-title">
            <p>日期:</p>
          </td>
          <td class="td-info" colspan="2">
            <el-date-picker v-model="form.fillDate" format="yyyy-MM-dd" placeholder="选择日期" size="small" type="date"
              value-format="yyyy-MM-dd">
            </el-date-picker>
          </td>
        </tr>
        <tr>
          <td class="td-title">
            <p>姓名:</p>
          </td>
          <td class="td-info">
            <el-input v-model="form.userName" placeholder="请输入内容" size="small">
            </el-input>
          </td>
          <td class="td-title">
            <p>部门:</p>
          </td>
          <td class="td-info">
            <el-input v-model="form.department" placeholder="请输入内容" size="small">
            </el-input>
          </td>
          <td class="td-title">
            <p>联系电话:</p>
          </td>
          <td class="td-info">
            <el-input v-model="form.contactNumber" placeholder="请输入内容" size="small">
            </el-input>
          </td>
        </tr>
        <tr>
          <td class="td-title">
            <p>服务态度:</p>
          </td>
          <td class="td-info" colspan="2">
            <el-radio-group v-model="form.serviceAttitude" v-removeAriaHidden>
              <el-radio :label="0">满意</el-radio>
              <el-radio :label="1">一般</el-radio>
              <el-radio :label="2">不满意</el-radio>
            </el-radio-group>
          </td>
          <td class="td-title">
            <p>建议:</p>
          </td>
          <td class="td-info" colspan="2">
            <el-input v-model="form.serviceAttitudeSuggestion" placeholder="请输入内容" size="small">
            </el-input>
          </td>
        </tr>
        <tr>
          <td class="td-title">
            <p>技术能力:</p>
          </td>
          <td class="td-info" colspan="2">
            <el-radio-group v-model="form.technicalCompetence" v-removeAriaHidden>
              <el-radio :label="0">满意</el-radio>
              <el-radio :label="1">一般</el-radio>
              <el-radio :label="2">不满意</el-radio>
            </el-radio-group>
          </td>
          <td class="td-title">
            <p>建议:</p>
          </td>
          <td class="td-info" colspan="2">
            <el-input v-model="form.technicalCompetenceSuggestion" placeholder="请输入内容" size="small">
            </el-input>
          </td>
        </tr>
        <tr>
          <td class="td-title">
            <p>检测工作:</p>
          </td>
          <td class="td-info" colspan="2">
            <el-radio-group v-model="form.inspectionWork" v-removeAriaHidden>
              <el-radio :label="0">满意</el-radio>
              <el-radio :label="1">一般</el-radio>
              <el-radio :label="2">不满意</el-radio>
            </el-radio-group>
          </td>
          <td class="td-title">
            <p>建议:</p>
          </td>
          <td class="td-info" colspan="2">
            <el-input v-model="form.inspectionWorkSuggestion" placeholder="请输入内容" size="small">
            </el-input>
          </td>
        </tr>
        <tr>
          <td class="td-title">
            <p>收费合理性:</p>
          </td>
          <td class="td-info" colspan="2">
            <el-radio-group v-model="form.reasonableFees" v-removeAriaHidden>
              <el-radio :label="0">满意</el-radio>
              <el-radio :label="1">一般</el-radio>
              <el-radio :label="2">不满意</el-radio>
            </el-radio-group>
          </td>
          <td class="td-title">
            <p>建议:</p>
          </td>
          <td class="td-info" colspan="2">
            <el-input v-model="form.reasonableFeesSuggestion" placeholder="请输入内容" size="small">
            </el-input>
          </td>
        </tr>
        <tr>
          <td class="td-title">
            <p>您对我们的希望:</p>
          </td>
          <td class="td-info" colspan="5">
            <el-input v-model="form.remark" :rows="4" placeholder="请输入内容" size="small" type="textarea">
            </el-input>
          </td>
        </tr>
      </table>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closeFormDia">取 æ¶ˆ</el-button>
        <el-button :loading="editLoad" type="primary" @click="handleEdit">提 äº¤</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import {
  addClientSatisfaction,
  updateClientSatisfaction
} from '@/api/cnas/systemManagement/customerSatisfaction.js'
export default {
  name: 'formDialog',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {},
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      formDia: false,
      form: {
        unitName: '',
        fillDate: '',
        userName: '',
        department: '',
        contactNumber: '',
        serviceAttitude: '',
        technicalCompetence: '',
        technicalCompetenceSuggestion: '',
        inspectionWork: '',
        inspectionWorkSuggestion: '',
        reasonableFees: '',
        reasonableFeesSuggestion: '',
        remark: '',
        clientSatisfactionId: '',
      },
      operationType: '',
      editLoad: false,
    };
  },
  // æ–¹æ³•集合
  methods: {
    openDia(type, row) {
      this.formDia = true;
      this.operationType = type
      if (this.operationType === 'edit') {
        this.form = { ...row }
      }
    },
    handleEdit() {
      if (!this.form.unitName) {
        this.$message.warning('请填写单位名称')
        return
      }
      if (!this.form.department) {
        this.$message.warning('请填写部门')
        return
      }
      this.editLoad = true
      if (this.operationType === 'add') {
        addClientSatisfaction(this.form).then(res => {
          this.editLoad = false
          if (res.code === 201) return
          this.$message.success('提交成功')
          this.closeFormDia()
        }).catch(err => {
          console.log('err---', err);
          this.editLoad = false
        })
      } else {
        updateClientSatisfaction(this.form).then(res => {
          this.editLoad = false
          if (res.code === 201) return
          this.$message.success('提交成功')
          this.closeFormDia()
        }).catch(err => {
          console.log('err---', err);
          this.editLoad = false
        })
      }
    },
    closeFormDia() {
      this.formDia = false;
      this.$emit('closeFormDia')
    },
  }
};
</script>
<style scoped>
>>>.el-dialog {
  margin: 10vh auto 50px !important;
}
.tables {
  table-layout: fixed;
  width: 100%;
  margin-top: 10px;
}
.td-title {
  height: 40px;
  width: 170px;
  text-align: center;
  font-size: 14px;
  word-wrap: break-word;
  white-space: normal;
  padding: 6px;
}
.td-info {
  padding: 6px;
}
.td-info1 {
  display: inline-block;
  width: 100%;
  text-align: left;
  font-size: 14px;
  word-wrap: break-word;
  white-space: normal;
}
</style>
src/views/CNAS/systemManagement/customerSatisfaction/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,410 @@
<template>
  <div>
    <div>
      <div class="search-background">
        <span v-if="tabIndex === '0'" class="search-group">
          <span style="width: 150px">单位名称:</span>
          <el-input v-model="searchForm.unitName" clearable size="small"></el-input>
        </span>
        <span v-if="tabIndex === '1'" class="search-group">
          <span style="width: 150px">文件名称:</span>
          <el-input v-model="searchForm1.fileName" clearable size="small"></el-input>
        </span>
        <span class="search-group">
          <el-button size="small" @click="resetSearchForm">重 ç½®</el-button>
          <el-button size="small" type="primary" @click="searchList">查 è¯¢</el-button>
        </span>
        <div class="btn">
          <el-button v-if="tabIndex === '0'" size="small" type="primary" @click="openFormDia('add')">新 å¢ž</el-button>
          <el-upload v-if="tabIndex === '1'" ref='upload' :action="action" :before-upload="beforeUpload"
            :headers="headers" :on-error="onError" :on-success="handleSuccessUp" :show-file-list="false"
            accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar'>
            <el-button :loading="upLoading" size="small" type="primary">导入</el-button>
          </el-upload>
        </div>
      </div>
      <div class="table">
        <div class="table-tab">
          <el-radio-group v-model="tabIndex" @change="searchList" size="small">
            <el-radio-button label="0">客户满意度</el-radio-button>
            <el-radio-button label="1">综合分析</el-radio-button>
          </el-radio-group>
        </div>
        <div v-if="tabIndex === '0'">
          <TableCard :showForm="false" :showTitle="false">
            <template v-slot:table>
              <limsTable :column="tableColumn" :height="'calc(100vh - 22em)'" :table-data="tableData"
                :table-loading="tableLoading" style="padding: 0 15px;margin-bottom: 16px" @pagination="pagination">
              </limsTable>
            </template>
          </TableCard>
        </div>
        <div v-if="tabIndex === '1'">
          <TableCard :showForm="false" :showTitle="false">
            <template v-slot:table>
              <limsTable :column="tableColumn1" :height="'calc(100vh - 22em)'" :table-data="tableData1"
                :table-loading="tableLoading1" style="padding: 0 15px;margin-bottom: 16px" @pagination="pagination0">
              </limsTable>
            </template>
          </TableCard>
        </div>
      </div>
    </div>
    <el-dialog :visible.sync="lookDialogVisible" fullscreen title="查看附件" top="5vh" width="800px">
      <filePreview v-if="lookDialogVisible" :currentFile="{}" :fileUrl="javaApi + '/word/' + currentInfo.fileUrl"
        style="height: 90vh;overflow-y: auto;" />
    </el-dialog>
    <FormDialog v-if="formDialog" ref="formDialog" @closeFormDia="closeFormDia"></FormDialog>
  </div>
</template>
<script>
import TableCard from '@/components/TableCard/index.vue';
import limsTable from "@/components/Table/lims-table.vue";
import FormDialog from './components/formDialog.vue';
import filePreview from '@/components/Preview/filePreview.vue'
import {
  pageClientSatisfaction,
  pageAnalyseFile,
  delClientSatisfaction,
  delAnalyseFile,
} from '@/api/cnas/systemManagement/customerSatisfaction.js'
import { getToken } from "@/utils/auth";
export default {
  name: 'a8-customer-satisfaction',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { filePreview, FormDialog, limsTable, TableCard },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      searchForm: {
        unitName: '',
      },
      searchForm1: {
        fileName: '',
      },
      tabIndex: '0',
      tableColumn: [
        {
          label: '单位名称',
          prop: 'unitName',
          minWidth: '100'
        },
        {
          label: '日期',
          prop: 'fillDate',
          minWidth: '100'
        },
        {
          label: '姓名',
          prop: 'userName',
          minWidth: '100'
        },
        {
          label: '部门',
          prop: 'department',
          minWidth: '100'
        },
        {
          label: '联系电话',
          prop: 'contactNumber',
          minWidth: '100'
        },
        {
          label: '创建日期',
          prop: 'createTime',
          minWidth: '100',
        },
        {
          dataType: 'action',
          minWidth: '80',
          label: '操作',
          operation: [
            {
              name: '编辑',
              type: 'text',
              clickFun: (row) => {
                this.openFormDia('edit', row);
              },
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.delPlan(row)
              }
            }
          ]
        }
      ],
      tableData: [],
      tableLoading: false,
      page: {
        size: 20,
        current: 1,
      },
      total: 0,
      tableColumn1: [
        {
          label: '附件名称',
          prop: 'fileName',
          minWidth: '100'
        },
        {
          label: '创建人',
          prop: 'userName',
          minWidth: '100'
        },
        {
          label: '创建时间',
          prop: 'createTime',
          minWidth: '100'
        },
        {
          dataType: 'action',
          minWidth: '50',
          label: '操作',
          operation: [
            {
              name: '预览',
              type: 'text',
              clickFun: (row) => {
                this.handleLook(row)
              }
            },
            {
              name: '下载',
              type: 'text',
              clickFun: (row) => {
                this.upload(row);
              },
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.delFile(row)
              }
            }
          ]
        }
      ],
      tableData1: [],
      tableLoading1: false,
      page1: {
        size: 20,
        current: 1,
      },
      total1: 0,
      formDialog: false,
      upLoading: false,
      currentInfo: {},
      lookDialogVisible: false,
    };
  },
  mounted() {
    this.searchList()
  },
  // æ–¹æ³•集合
  methods: {
    // æŸ¥è¯¢åˆ—表
    searchList() {
      const entity = this.tabIndex === '0' ? this.searchForm : this.searchForm1
      const page = this.tabIndex === '0' ? this.page : this.page1
      if (this.tabIndex === '0') {
        this.tableLoading = true
        pageClientSatisfaction({ ...entity, ...page }).then(res => {
          this.tableLoading = false
          if (res.code === 201) return
          this.tableData = res.data.records
          this.total = res.data.total
        }).catch(err => {
          console.log('err---', err);
          this.tableLoading = false
        })
      } else {
        this.tableLoading1 = true
        pageAnalyseFile({ ...entity, ...page }).then(res => {
          this.tableLoading1 = false
          if (res.code === 201) return
          this.tableData1 = res.data.records
          this.total1 = res.data.total
        }).catch(err => {
          console.log('err---', err);
          this.tableLoading1 = false
        })
      }
    },
    openFormDia(type, row) {
      this.formDialog = true
      this.$nextTick(() => {
        this.$refs.formDialog.openDia(type, row);
      })
    },
    closeFormDia() {
      this.formDialog = false
      this.searchList()
    },
    // é‡ç½®æŸ¥è¯¢æ¡ä»¶
    resetSearchForm() {
      this.searchForm.unitName = '';
      this.searchForm1.fileName = '';
      this.searchList()
    },
    // å¯¼å…¥æµç¨‹
    beforeUpload(file) {
      if (file.size > 1024 * 1024 * 10) {
        this.$message.error('上传文件不超过10M');
        this.$refs.upload.clearFiles()
        return false;
      } else {
        this.upLoading = true;
        return true;
      }
    },
    onError(err, file, fileList) {
      this.$message.error('上传失败')
      this.$refs.upload.clearFiles()
    },
    handleSuccessUp(response) {
      this.upLoading = false;
      if (response.code == 200) {
        this.$message.success('上传成功');
        this.searchList()
      }
    },
    // åˆ é™¤å®¢æˆ·æ»¡æ„åº¦
    delPlan(row) {
      this.$confirm('此操作将永久删除该数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.tableLoading = true
        delClientSatisfaction({ clientSatisfactionId: row.clientSatisfactionId }).then(res => {
          this.tableLoading = false
          if (res.code === 201) return
          this.$message.success('删除成功')
          this.searchList()
        }).catch(err => {
          this.tableLoading = false
          console.log('err---', err);
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    // æŸ¥çœ‹æ–‡ä»¶
    handleLook(row) {
      this.currentInfo = row
      this.lookDialogVisible = true
    },
    // ä¸‹è½½å®¢æˆ·ç¦å»º
    upload(row) {
      let url = '';
      if (row.type == 1) {
        url = this.javaApi + '/img/' + row.fileUrl
        file.downloadIamge(url, row.fileName)
      } else {
        url = this.javaApi + '/word/' + row.fileUrl
        const link = document.createElement('a');
        link.href = url;
        link.download = row.fileName;
        link.click();
      }
    },
    // åˆ é™¤å®¢æˆ·åˆ†æžé™„ä»¶
    delFile(row) {
      this.$confirm('此操作将永久删除该数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.tableLoading = true
        delAnalyseFile({ analyseFileId: row.analyseFileId }).then(res => {
          this.tableLoading = false
          if (res.code === 201) return
          this.$message.success('删除成功')
          this.searchList()
        }).catch(err => {
          this.tableLoading = false
          console.log('err---', err);
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    // åˆ†é¡µ
    pagination({ page, limit }) {
      this.page.current = page;
      this.page.size = limit;
      this.searchList();
    },
    // åˆ†é¡µ
    pagination0({ page, limit }) {
      this.page.current = page;
      this.page.size = limit;
      this.searchList();
    },
  },
  // ç”¨äºŽä¸Šä¼ æ–‡ä»¶çš„信息
  computed: {
    headers() {
      return {
        'Authorization': "Bearer " + getToken()
      }
    },
    action() {
      return this.javaApi + '/clientSatisfaction/uploadAnalyseFile'
    }
  },
};
</script>
<style scoped>
.view-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 60px;
  padding-left: 20px;
}
.search-background {
  width: 100%;
  height: 80px;
  line-height: 80px;
  background-color: #ffffff;
  display: flex;
  position: relative;
}
.search-group {
  display: flex;
  align-items: center;
  margin: 0 20px;
}
.table {
  background-color: #ffffff;
}
.table-tab {
  margin: 0 20px 20px 20px;
}
.btn {
  position: absolute;
  top: 16px;
  right: 20px;
}
</style>