|
|
@@ -0,0 +1,270 @@
|
|
|
+<template>
|
|
|
+ <div class="ele-body">
|
|
|
+ <el-card shadow="never">
|
|
|
+ <!-- 状态tabs -->
|
|
|
+ <el-tabs v-model="activeStatus" @tab-click="handleTabClick" class="status-tabs">
|
|
|
+ <el-tab-pane label="全部" name="">
|
|
|
+ <span slot="label"><i class="el-icon-s-grid"></i> 全部</span>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane label="待处理" name="1">
|
|
|
+ <span slot="label"><i class="el-icon-time"></i> 待处理</span>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane label="已处理" name="2">
|
|
|
+ <span slot="label"><i class="el-icon-check"></i> 已处理</span>
|
|
|
+ </el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+
|
|
|
+ <!-- 搜索表单 -->
|
|
|
+ <el-form :model="table.where" label-width="90px" class="ele-form-search"
|
|
|
+ @keyup.enter.native="$refs.table.reload()" @submit.native.prevent>
|
|
|
+ <el-row :gutter="15">
|
|
|
+ <el-col :md="6" :sm="12">
|
|
|
+ <el-form-item label="关键词:">
|
|
|
+ <el-input v-model="table.where.keyword" placeholder="姓名/手机号/内容" clearable />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :md="6" :sm="12">
|
|
|
+ <div class="ele-form-actions">
|
|
|
+ <el-button type="primary" @click="$refs.table.reload()" icon="el-icon-search"
|
|
|
+ class="ele-btn-icon">查询</el-button>
|
|
|
+ <el-button @click="handleReset">重置</el-button>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <!-- 数据表格 -->
|
|
|
+ <ele-data-table ref="table" :config="table" :choose.sync="choose" height="calc(100vh - 320px)"
|
|
|
+ highlight-current-row>
|
|
|
+ <template>
|
|
|
+ <el-table-column type="selection" width="45" align="center" fixed="left" />
|
|
|
+ <el-table-column prop="id" label="ID" width="60" align="center" fixed="left" show-overflow-tooltip />
|
|
|
+ <el-table-column prop="realname" label="姓名" width="100" align="center" />
|
|
|
+ <el-table-column prop="mobile" label="联系电话" width="120" align="center" />
|
|
|
+ <el-table-column prop="user_name" label="用户昵称" width="120" align="center" />
|
|
|
+ <el-table-column prop="content" label="反馈内容" show-overflow-tooltip min-width="200" />
|
|
|
+ <el-table-column label="图片" width="100" align="center">
|
|
|
+ <template slot-scope="{row}">
|
|
|
+ <el-image v-if="row.albums_array && row.albums_array.length > 0" :src="row.albums_array[0]"
|
|
|
+ style="width: 60px; height: 60px;" fit="cover" :preview-src-list="row.albums_array" />
|
|
|
+ <span v-else>-</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="状态" width="100" align="center">
|
|
|
+ <template slot-scope="{row}">
|
|
|
+ <el-switch v-model="row.status" @change="editStatus(row)" :active-value="2" :inactive-value="1"
|
|
|
+ active-color="#13ce66" inactive-color="#ff4949" />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="create_time" label="提交时间" show-overflow-tooltip min-width="160" align="center" />
|
|
|
+ <el-table-column label="操作" width="180px" align="center" :resizable="false" fixed="right">
|
|
|
+ <template slot-scope="{row}">
|
|
|
+ <el-link @click="viewDetail(row)" icon="el-icon-view" type="primary" :underline="false">查看</el-link>
|
|
|
+ <el-link @click="edit(row)" icon="el-icon-edit" type="primary" :underline="false"
|
|
|
+ v-if="permission.includes('sys:complaint:edit')">处理</el-link>
|
|
|
+ <el-popconfirm title="确定要删除此记录吗?" @confirm="remove(row)" class="ele-action">
|
|
|
+ <el-link slot="reference" icon="el-icon-delete" type="danger" :underline="false"
|
|
|
+ v-if="permission.includes('sys:complaint:delete')">删除</el-link>
|
|
|
+ </el-popconfirm>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </template>
|
|
|
+ </ele-data-table>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- 查看详情弹窗 -->
|
|
|
+ <el-dialog title="投诉详情" :visible.sync="showDetail" width="700px" :destroy-on-close="true"
|
|
|
+ custom-class="ele-dialog-form">
|
|
|
+ <div v-if="detailData.id" class="detail-content">
|
|
|
+ <el-descriptions :column="2" border>
|
|
|
+ <el-descriptions-item label="ID">{{ detailData.id }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="状态">
|
|
|
+ <el-tag v-if="detailData.status === 1" type="warning">待处理</el-tag>
|
|
|
+ <el-tag v-else-if="detailData.status === 2" type="success">已处理</el-tag>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="姓名">{{ detailData.realname }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="联系电话">{{ detailData.mobile }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="用户昵称" :span="2">{{ detailData.user_name || '-' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="反馈内容" :span="2">
|
|
|
+ <div style="white-space: pre-wrap;">{{ detailData.content }}</div>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="图片" :span="2" v-if="detailData.albums_array && detailData.albums_array.length > 0">
|
|
|
+ <div class="image-list">
|
|
|
+ <el-image v-for="(img, index) in detailData.albums_array" :key="index" :src="img"
|
|
|
+ style="width: 100px; height: 100px; margin-right: 10px;" fit="cover"
|
|
|
+ :preview-src-list="detailData.albums_array" />
|
|
|
+ </div>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="处理备注" :span="2" v-if="detailData.remark">
|
|
|
+ <div style="white-space: pre-wrap;">{{ detailData.remark }}</div>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="提交时间">{{ detailData.create_time }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="更新时间">{{ detailData.update_time }}</el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+ </div>
|
|
|
+ <div slot="footer">
|
|
|
+ <el-button @click="showDetail = false">关闭</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <!-- 处理弹窗 -->
|
|
|
+ <el-dialog title="处理投诉" :visible.sync="showEdit" width="600px" :destroy-on-close="true"
|
|
|
+ custom-class="ele-dialog-form" :close-on-click-modal="false">
|
|
|
+ <el-form :model="editForm" ref="editForm" label-width="100px">
|
|
|
+ <el-form-item label="姓名:">
|
|
|
+ <el-input v-model="editForm.realname" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="联系电话:">
|
|
|
+ <el-input v-model="editForm.mobile" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="反馈内容:">
|
|
|
+ <el-input v-model="editForm.content" type="textarea" :rows="3" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="状态:">
|
|
|
+ <el-radio-group v-model="editForm.status">
|
|
|
+ <el-radio :label="1">待处理</el-radio>
|
|
|
+ <el-radio :label="2">已处理</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="处理备注:">
|
|
|
+ <el-input v-model="editForm.remark" type="textarea" :rows="4" placeholder="请输入处理备注" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer">
|
|
|
+ <el-button @click="showEdit = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="save" :loading="editLoading">保存</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { mapGetters } from "vuex";
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "Complaint",
|
|
|
+ computed: {
|
|
|
+ ...mapGetters(["permission"]),
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ table: { url: '/complaint/index', where: { status: '' } },
|
|
|
+ choose: [],
|
|
|
+ activeStatus: '',
|
|
|
+ showDetail: false,
|
|
|
+ detailData: {},
|
|
|
+ showEdit: false,
|
|
|
+ editForm: {},
|
|
|
+ editLoading: false
|
|
|
+ };
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ handleTabClick(tab) {
|
|
|
+ this.table.where.status = tab.name;
|
|
|
+ this.$refs.table.reload();
|
|
|
+ },
|
|
|
+ handleReset() {
|
|
|
+ this.activeStatus = '';
|
|
|
+ this.table.where = { status: '' };
|
|
|
+ this.$refs.table.reload();
|
|
|
+ },
|
|
|
+ viewDetail(row) {
|
|
|
+ const loading = this.$loading({ lock: true });
|
|
|
+ this.$http.get('/complaint/info', { params: { id: row.id } }).then(res => {
|
|
|
+ loading.close();
|
|
|
+ if (res.data.code === 0) {
|
|
|
+ this.detailData = res.data.data;
|
|
|
+ this.showDetail = true;
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.data.msg);
|
|
|
+ }
|
|
|
+ }).catch(e => {
|
|
|
+ loading.close();
|
|
|
+ this.$message.error(e.message);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ edit(row) {
|
|
|
+ const loading = this.$loading({ lock: true });
|
|
|
+ this.$http.get('/complaint/info', { params: { id: row.id } }).then(res => {
|
|
|
+ loading.close();
|
|
|
+ if (res.data.code === 0) {
|
|
|
+ this.editForm = Object.assign({}, res.data.data);
|
|
|
+ this.showEdit = true;
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.data.msg);
|
|
|
+ }
|
|
|
+ }).catch(e => {
|
|
|
+ loading.close();
|
|
|
+ this.$message.error(e.message);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ save() {
|
|
|
+ this.editLoading = true;
|
|
|
+ this.$http.post('/complaint/edit', this.editForm).then(res => {
|
|
|
+ this.editLoading = false;
|
|
|
+ if (res.data.code === 0) {
|
|
|
+ this.showEdit = false;
|
|
|
+ this.$message({ type: 'success', message: res.data.msg });
|
|
|
+ this.$refs.table.reload();
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.data.msg);
|
|
|
+ }
|
|
|
+ }).catch(e => {
|
|
|
+ this.editLoading = false;
|
|
|
+ this.$message.error(e.message);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ remove(row) {
|
|
|
+ const loading = this.$loading({ lock: true });
|
|
|
+ this.$http.post('/complaint/delete', { id: row.id }).then(res => {
|
|
|
+ loading.close();
|
|
|
+ if (res.data.code === 0) {
|
|
|
+ this.$message({ type: 'success', message: res.data.msg });
|
|
|
+ this.$refs.table.reload();
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.data.msg);
|
|
|
+ }
|
|
|
+ }).catch(e => {
|
|
|
+ loading.close();
|
|
|
+ this.$message.error(e.message);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ editStatus(row) {
|
|
|
+ this.$message.closeAll();
|
|
|
+ const loading = this.$loading({ lock: true });
|
|
|
+ this.$http.post('/complaint/status', { id: row.id, status: row.status }).then(res => {
|
|
|
+ loading.close();
|
|
|
+ if (res.data.code === 0) {
|
|
|
+ this.$message({ type: 'success', message: res.data.msg });
|
|
|
+ } else {
|
|
|
+ row.status = row.status === 1 ? 2 : 1;
|
|
|
+ this.$message.error(res.data.msg);
|
|
|
+ }
|
|
|
+ }).catch(e => {
|
|
|
+ loading.close();
|
|
|
+ row.status = row.status === 1 ? 2 : 1;
|
|
|
+ this.$message.error(e.message);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.status-tabs {
|
|
|
+ margin-bottom: 15px;
|
|
|
+}
|
|
|
+
|
|
|
+.status-tabs>>>.el-tabs__header {
|
|
|
+ margin: 0 0 15px;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-content {
|
|
|
+ padding: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.image-list {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+}
|
|
|
+</style>
|