yinchengnuo vor 4 Jahren
Ursprung
Commit
2882bfd28d
5 geänderte Dateien mit 168 neuen und 59 gelöschten Zeilen
  1. 5 0
      src/api/cl.js
  2. 1 1
      src/components/RightPanel/index.vue
  3. 1 1
      src/settings.js
  4. 161 52
      src/views/PageIndex/index.vue
  5. 0 5
      vue.config.js

+ 5 - 0
src/api/cl.js

@@ -3,3 +3,8 @@ import request from '@/utils/request'
 export const api_getClList = params => request({ url: '/cl/list', method: 'get', params })
 
 export const api_replyCl = params => request({ url: '/cl/reply', method: 'get', params })
+
+export const api_getShortList = params => request({ url: '/show?page=1', method: 'get', params })
+export const api_addShort = params => request({ url: '/created', method: 'get', params })
+export const api_updateShort = params => request({ url: '/created', method: 'get', params })
+export const api_delShort = params => request({ url: '/deleted', method: 'get', params })

+ 1 - 1
src/components/RightPanel/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div ref="rightPanel" :class="{show:show}" class="rightPanel-container">
     <div class="rightPanel-background" />
-    <div class="rightPanel">
+    <div class="rightPanel" :style="{ display: 'none' }">
       <div class="handle-button" :style="{'bottom':buttonBottom+'px','background-color':theme}" @click="show=!show">
         <i :class="show?'el-icon-close':'el-icon-setting'" />
       </div>

+ 1 - 1
src/settings.js

@@ -2,7 +2,7 @@ module.exports = {
   title: '常来信箱管理后台',
   showSettings: true, // 是否显示设置选项
   tagsView: true, // 是否显示顶部tab
-  fixedHeader: true, // 是否固定顶部导航
+  fixedHeader: false, // 是否固定顶部导航
   sidebarLogo: true, // 是否显示侧边栏 Logo
   sidebarLogoURL: 'http://api.woaidakele.cn/public/uploads/cl.jpg',
   errorLog: 'production' // 错误日志生成环境

+ 161 - 52
src/views/PageIndex/index.vue

@@ -1,103 +1,153 @@
 <template>
   <div class="page-index">
+    <el-button class="manage" type="primary" @click="manageShorts">快捷短语管理</el-button>
     <el-tabs v-model="query.type" type="card">
       <el-tab-pane label="未回复">
-        <el-table ref="table1" :data="list" border stripe style="width: 100%" @row-click="clickRow">
-          <el-table-column type="expand" label="详情" width="0">
-            <template slot-scope="scope">
-              <div class="feedback-img" style="text-align: center; font-size: 18px; line-height: 2; font-weight: bold; border-bottom: 1px solid #dfe6ec;">反馈文字</div>
-              <div style="font-size: 16px; text-indent: 2em; line-height: 1.5; margin: 24px;">{{ scope.row.value }}</div>
-              <div class="feedback-img" style="text-align: center; font-size: 18px; line-height: 2; font-weight: bold; border-top: 1px solid #dfe6ec; border-bottom: 1px solid #dfe6ec;">反馈图片</div>
-              <div v-if="scope.row.imgList.length" style="margin: 24px; text-align: center;">
-                <el-image v-for="(url, index) in scope.row.imgList" :key="index" style="width: 120px; height: 200px; margin-right: 8px;" :src="url" :preview-src-list="scope.row.imgList" @click="preview(index)" />
-              </div>
-              <div v-else style="text-align: center; margin: 24px;">无</div>
-            </template>
-          </el-table-column>
+        <el-table ref="table1" :data="list" border stripe style="width: 100%">
           <el-table-column prop="time" align="center" label="反馈时间" />
-          <el-table-column prop="channel" align="center" label="反馈渠道" />
+          <el-table-column v-if="!phone" prop="channel" align="center" label="反馈渠道" />
           <el-table-column prop="avatar" align="center" label="微信头像">
             <template slot-scope="scope">
               <img class="avatar" :src="scope.row.avatar" :alt="scope.row.nickname">
             </template>
           </el-table-column>
           <el-table-column prop="nickname" align="center" label="微信昵称" />
-          <!-- <el-table-column prop="value" align="center" label="反馈内容" /> -->
+          <el-table-column v-if="!phone" prop="nickname" align="center" label="性别">
+            <template slot-scope="scope">
+              <span v-if="scope.row.sex === '1'">男</span>
+              <span v-else-if="scope.row.sex === '0'">女</span>
+              <span v-else>-</span>
+            </template>
+          </el-table-column>
+          <el-table-column v-if="!phone" prop="address" align="center" label="所在地区" />
           <el-table-column prop="imgList" align="center" label="详情">
             <template slot-scope="scope">
-              <el-button type="primary" @click.stop="handleReply(scope.row)">详情</el-button>
+              <el-button type="primary" @click.stop="detail(scope.row)">详情</el-button>
             </template>
           </el-table-column>
         </el-table>
       </el-tab-pane>
       <el-tab-pane label="已回复">
-        <el-table ref="table2" :data="list" border stripe style="width: 100%" @row-click="clickRow">
-          <el-table-column type="expand" label="详情" width="66">
+        <el-table ref="table2" :data="list" border stripe style="width: 100%">
+          <el-table-column prop="time" align="center" label="反馈时间" />
+          <el-table-column v-if="!phone" prop="channel" align="center" label="反馈渠道" />
+          <el-table-column prop="avatar" align="center" label="微信头像">
             <template slot-scope="scope">
-              <div class="feedback-img" style="text-align: center; font-size: 18px; line-height: 2; font-weight: bold; border-bottom: 1px solid #dfe6ec;">反馈文字</div>
-              <div style="font-size: 16px; text-indent: 2em; line-height: 1.5; margin: 24px;">{{ scope.row.value }}</div>
-              <div class="feedback-img" style="text-align: center; font-size: 18px; line-height: 2; font-weight: bold; border-top: 1px solid #dfe6ec; border-bottom: 1px solid #dfe6ec;">反馈图片</div>
-              <div v-if="scope.row.imgList.length" style="margin: 24px; text-align: center;">
-                <el-image v-for="(url, index) in scope.row.imgList" :key="index" style="width: 120px; height: 200px; margin-right: 8px;" :src="url" :preview-src-list="scope.row.imgList" @click="preview(index)" />
-              </div>
-              <div v-else style="text-align: center; margin: 24px;">无</div>
+              <img class="avatar" :src="scope.row.avatar" :alt="scope.row.nickname">
             </template>
           </el-table-column>
-          <el-table-column prop="time" align="center" label="反馈时间" width="160" />
-          <el-table-column prop="channel" align="center" label="反馈渠道" width="140" />
-          <el-table-column prop="avatar" align="center" label="微信头像" width="80">
+          <el-table-column prop="nickname" align="center" label="微信昵称" />
+          <el-table-column v-if="!phone" prop="nickname" align="center" label="性别">
             <template slot-scope="scope">
-              <img class="avatar" :src="scope.row.avatar" :alt="scope.row.nickname">
+              <span v-if="scope.row.sex === '1'">男</span>
+              <span v-else-if="scope.row.sex === '0'">女</span>
+              <span v-else>-</span>
+            </template>
+          </el-table-column>
+          <el-table-column v-if="!phone" prop="address" align="center" label="所在地区" />
+          <el-table-column prop="imgList" align="center" label="详情">
+            <template slot-scope="scope">
+              <el-button type="primary" @click.stop="detail(scope.row)">详情</el-button>
             </template>
           </el-table-column>
-          <el-table-column prop="nickname" align="center" label="微信昵称" width="210" />
-          <el-table-column prop="value" align="center" label="反馈内容" />
-          <el-table-column prop="reply" align="center" label="回复反馈" />
         </el-table>
       </el-tab-pane>
     </el-tabs>
-    <el-dialog title="回复反馈" :visible.sync="dialogFormVisible" :close-on-click-modal="false" :destroy-on-close="true">
+    <el-dialog title="反馈详情" width="90%" :visible.sync="dialogDetail" :close-on-click-modal="false" :destroy-on-close="true">
+      <div style="border: 1px solid #dfe6ec;">
+        <div class="feedback-img" style="text-align: center; font-size: 18px; line-height: 2; font-weight: bold; border-bottom: 1px solid #dfe6ec;">反馈文字</div>
+        <div style="font-size: 16px; text-indent: 2em; line-height: 1.5; margin: 24px;">{{ detailItem.value }}</div>
+        <div class="feedback-img" style="text-align: center; font-size: 18px; line-height: 2; font-weight: bold; border-top: 1px solid #dfe6ec; border-bottom: 1px solid #dfe6ec;">反馈图片</div>
+        <div v-if="detailItem.imgList.length" style="margin: 24px; text-align: center;">
+          <el-image v-for="(url, index) in detailItem.imgList" :key="index" style="width: 120px; height: 200px; margin-right: 8px;" :src="url" :preview-src-list="detailItem.imgList" @click="preview(index)" />
+        </div>
+        <div v-else style="text-align: center; margin: 24px;">无</div>
+        <div v-if="query.type === '1'" class="feedback-img" style="text-align: center; font-size: 18px; line-height: 2; font-weight: bold; border-top: 1px solid #dfe6ec; border-bottom: 1px solid #dfe6ec;">回复文字</div>
+        <div v-if="query.type === '1'" style="font-size: 16px; text-indent: 2em; line-height: 1.5; margin: 24px;">{{ detailItem.reply }}</div>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogDetail = false">关 闭</el-button>
+        <el-button v-if="query.type === '0'" type="primary" @click="handleReply">回 复</el-button>
+      </div>
+    </el-dialog>
+    <el-dialog title="回复反馈" :visible.sync="dialogReply" :close-on-click-modal="false" :destroy-on-close="true">
       <el-form :model="form">
         <el-form-item label="快捷短语" label-width="567">
-          <el-select v-model="form.value" placeholder="请选择快捷短语">
-            <el-option v-for="(item, index) in form.select" :key="index" :label="item" :value="item" />
+          <el-select v-model="selectVal" placeholder="请选择快捷短语">
+            <el-option v-for="(item, index) in form.select" :key="index" :label="item.body" :value="item.body" />
           </el-select>
         </el-form-item>
         <el-form-item label="回复内容" label-width="567">
           <el-input v-model="form.value" type="textarea" placeholder="请输入回复内容" :rows="5" autocomplete="off" />
+          <div v-for="(item, index) in e" :key="index" style="display: inline-block; user-select: none; cursor: pointer;font-size: 24px; margin: 2px; overflow: hidden;" @click="form.value += item">{{ item }}</div>
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
-        <el-button @click="dialogFormVisible = false">取 消</el-button>
+        <el-button @click="dialogReply = false">取 消</el-button>
         <el-button type="primary" @click="reply">确 定</el-button>
       </div>
     </el-dialog>
+    <el-dialog title="快捷短语管理" :visible.sync="dialogShorts" :close-on-click-modal="false" :destroy-on-close="true">
+      <el-table :data="form.select" border stripe>
+        <el-table-column prop="body" label="快捷短语" align="center" />
+        <el-table-column label="操作" align="center" width="240">
+          <template slot-scope="scope">
+            <el-button style="margin: 4px;" type="primary" size="mini" @click.stop="editShort(scope.row)">编辑</el-button>
+            <el-button style="margin: 4px;" type="danger" size="mini" @click.stop="delShort(scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogShorts = false">关 闭</el-button>
+        <el-button type="primary" @click.stop="addShort">新增短语</el-button>
+      </div>
+    </el-dialog>
+    <el-dialog :title="dialogAddShortType === 'add' ? '添加快捷短语' : '编辑快捷短语'" :visible.sync="dialogAddShort" :close-on-click-modal="false" :destroy-on-close="true">
+      <el-input v-model="willAddShort" type="textarea" placeholder="请输入回复内容" :rows="5" autocomplete="off" />
+      <div>
+        <div v-for="(item, index) in e" :key="index" style="display: inline-block; user-select: none; cursor: pointer;font-size: 24px; margin: 2px; overflow: hidden;" @click="willAddShort += item">{{ item }}</div>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogAddShort = false">关 闭</el-button>
+        <el-button type="primary" @click.stop="submitShort">提交</el-button>
+      </div>
+    </el-dialog>
     <el-pagination background layout="prev, pager, next" :current-page="page" :page-size="15" :total="total" @current-change="pageChange" />
   </div>
 </template>
 
 <script>
-import { api_getClList, api_replyCl } from '@/api/cl'
+import { api_getClList, api_replyCl, api_getShortList, api_addShort, api_updateShort, api_delShort } from '@/api/cl'
 export default {
   name: 'PageIndex',
-  props: {},
   data() {
     return {
+      myText: '',
+      phone: document.body.offsetWidth <= 460,
       total: 0,
       list: [],
       page: 1,
       query: { type: '0' },
-      dialogFormVisible: false,
+      willAddShort: '',
+      detailItem: { imgList: [] },
+      dialogReply: false,
+      dialogDetail: false,
+      dialogShorts: false,
+      dialogAddShort: false,
+      dialogAddShortType: 'add',
+      selectVal: '',
       form: {
         id: '',
-        select: [
-          '您好,您的建议我们已经收到,感谢您 的反馈。'
-        ],
+        select: [],
         value: ''
-      }
+      },
+      e: ['😀', '😃', '😄', '😁', '😆', '😅', '🤣', '😂', '🙂', '🙃', '😉', '😊', '😇', '🥰', '😍', '🤩', '😘', '😗', '😚', '😙', '😋', '😛', '😜', '🤪', '😝', '🤑', '🤗', '🤭', '🤫', '🤔', '🤐', '🤨', '😐', '😑', '😶', '😏', '😒', '🙄', '😬', '🤥', '😌', '😔', '😪', '🤤', '😴', '😷', '🤒', '🤕', '🤢', '🤮', '🤧', '🥵', '🥶', '🥴', '😵', '🤯', '🤠', '🥳', '😎', '🤓', '🧐', '😕', '😟', '🙁', '😮', '😯', '😲', '😳', '🥺', '😦', '😧', '😨', '😰', '😥', '😢', '😭', '😱', '😖', '😣', '😞', '😓', '😩', '😫', '🥱', '😤', '😡', '😠', '🤬', '😈', '👿', '💀', '☠', '💩', '🤡', '👹', '👺', '👻', '👽', '👾', '🤖', '😺', '😸', '😹', '😻', '😼', '😽', '🙀', '😿', '😾', '🙈', '🙉', '🙊', '💋', '💌', '💘', '💝', '💖', '💗', '💓', '💞', '💕', '💟', '❣', '💔', '❤', '🧡', '💛', '💚', '💙', '💜', '🤎', '🖤', '🤍', '💯', '💢', '💥', '💫', '💦', '💨', '🕳', '💣', '💬', '👁️‍🗨️', '🗨', '🗯', '💭', '💤', '👋', '🤚', '🖐', '✋', '🖖', '👌', '🤏', '✌', '🤞', '🤟', '🤘', '🤙', '👈', '👉', '👆', '🖕', '👇', '☝', '👍', '👎', '✊', '👊', '🤛', '🤜', '👏', '🙌']
     }
   },
   watch: {
+    selectVal(n) {
+      this.form.value = n
+    },
     query: {
       deep: true,
       immediate: true,
@@ -108,19 +158,67 @@ export default {
     }
   },
   methods: {
-    clickRow(row) {
-      this.query.type === '0' ? this.$refs.table1.toggleRowExpansion(row) : this.$refs.table2.toggleRowExpansion(row)
+    onAddInput({ data }) { // 当输入新增短语时
+      console.log(data)
+      this.willAddShort = data
+    },
+    addShort() {
+      this.willAddShort = ''
+      this.dialogAddShortType = 'add'
+      this.dialogAddShort = true
+    },
+    editShort({ id, body }) {
+      this.willAddShort = body
+      this.dialogAddShortType = id
+      this.dialogAddShort = true
+    },
+    delShort({ id }) {
+      this.$confirm('此操作将删除该短语, 是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.$request(api_delShort({ id }), () => {
+          this.$message.success('删除成功!')
+          this.getData()
+        }, { endStillLoading: true })
+      }).catch(() => this.$message.info('已取消删除'))
+    },
+    submitShort() {
+      if (!this.willAddShort.trim().length) {
+        this.$message.error('新增快捷短语不能为空')
+        return
+      }
+      this.dialogAddShortType === 'add' ? this.$request(api_addShort({ body: this.willAddShort.trim() }), () => {
+        this.getData()
+        this.dialogAddShort = false
+        this.$message.success('添加成功!')
+      }, { endStillLoading: true }) : this.$request(api_updateShort({ body: this.willAddShort.trim(), id: this.dialogAddShortType }), () => {
+        this.getData()
+        this.dialogAddShort = false
+        this.$message.success('编辑成功!')
+      }, { endStillLoading: true })
+    },
+    manageShorts() { // 点击快捷短语管理
+      this.dialogShorts = true
+    },
+    onInput({ data }) {
+      this.form.value = data
+    },
+    clearTextarea() {
+      this.$refs.emoji.clear()
     },
     getData() {
-      this.$request(api_getClList({ type: this.query.type, page: this.page }), ({ total, list }) => {
+      this.$request([api_getClList({ type: this.query.type, page: this.page }), api_getShortList()], ([{ total, list }, { list: select }]) => {
         this.total = total
         this.list = list
+        this.form.select = select
       })
     },
-    handleReply({ id }) {
-      this.form.id = id
+    handleReply() {
+      this.form.id = this.detailItem.id
       this.form.value = ''
-      this.dialogFormVisible = true
+      this.dialogReply = true
     },
     reply() {
       if (!this.form.value) {
@@ -129,9 +227,14 @@ export default {
       }
       this.$request(api_replyCl({ value: this.form.value, id: this.form.id }), () => {
         this.getData()
-        this.dialogFormVisible = false
+        this.dialogReply = false
+        this.dialogDetail = false
       }, { endStillLoading: true })
     },
+    detail(detailItem) {
+      this.detailItem = detailItem
+      this.dialogDetail = true
+    },
     preview(index) {
       this.$nextTick(() => {
         Array(index).fill(0).forEach(() => document.getElementsByClassName('el-image-viewer__next')[0].click())
@@ -150,6 +253,15 @@ export default {
 
 <style lang="scss" scoped>
   .page-index {
+    .manage {
+      top: 2px;
+      right: 8px;
+      z-index: 1;
+      position: absolute;
+    }
+    .el-select {
+      width: 100%;
+    }
     .el-table {
       .avatar {
         width: 32px;
@@ -160,9 +272,6 @@ export default {
         padding: 0;
       }
     }
-    // >>> .el-dialog {
-    //   width: 567px;
-    // }
     .el-image {
       >>> .el-icon-circle-close {
         color: white;

+ 0 - 5
vue.config.js

@@ -19,11 +19,6 @@ module.exports = {
     },
     proxy: {
       [process.env.VUE_APP_BASE_API]: {
-        // target: 'https://api.admin.jiuweiyun.cn/api',
-        // target: 'http://114.116.235.40/api',
-        // target: 'http://dwbs.dake.club/api',
-        // target: 'http://api.admin.dake.club/api',
-        // target: 'https://yinchengnuo.com/admin',
         // target: 'http://192.168.0.11/admin',
         target: 'http://changlai.jiuweiyun.cn/api',
         changeOrigin: true,