2 Commits 5058f78a9d ... 4ce199d48e

Author SHA1 Message Date
  zhengchengwu 4ce199d48e Merge branch 'master' of http://git.shengws.com/zhangbj/scrm-vue 5 years ago
  zhengchengwu df30ed7489 删除公众号菜单;自动回复:关键词,关注; 5 years ago

+ 24 - 0
src/api/mpwechat/mpmenus.js View File

@@ -0,0 +1,24 @@
1
+import request from '@/utils/request'
2
+
3
+export function GetMenus() {
4
+  return request({
5
+    url: '/api/mpwechat/menus',
6
+    method: 'get',
7
+  })
8
+}
9
+
10
+export function SaveMenus(data) {
11
+  return request({
12
+    url: '/api/mpwechat/savemenus',
13
+    method: 'put',
14
+    data:data,
15
+  })
16
+}
17
+
18
+export function DeleteMenu(data) {
19
+  return request({
20
+    url: '/api/mpwechat/deletemenus',
21
+    method: 'post',
22
+    data:data,
23
+  })
24
+}

+ 47 - 0
src/api/mpwechat/mpreply.js View File

@@ -0,0 +1,47 @@
1
+import request from '@/utils/request'
2
+
3
+export function GetSubscribeRplay() {
4
+    return request({
5
+        url: '/api/mpwechat/reply/subscribe',
6
+        method: 'get',
7
+    })
8
+}
9
+
10
+export function SaveSubscribeRplay(data) {
11
+    return request({
12
+        url: '/api/mpwechat/reply/subscribe',
13
+        method: 'put',
14
+        data:data,
15
+    })
16
+}
17
+    
18
+export function GetKeyWordReplys(params) {
19
+    return request({
20
+        url: '/api/mpwechat/reply/kewords',
21
+        method: 'get',
22
+        params:params,
23
+    })
24
+}
25
+
26
+export function CreateKeyWordReply(data) {
27
+    return request({
28
+        url: '/api/mpwechat/reply/keword',
29
+        method: 'post',
30
+        data:data,
31
+    })
32
+}
33
+export function EditKeyWordReply(id,data) {
34
+    return request({
35
+        url: '/api/mpwechat/reply/keword?id='+id,
36
+        method: 'put',
37
+        data:data,
38
+    })
39
+}
40
+
41
+export function DeleteReplys(data) {
42
+    return request({
43
+        url: '/api/mpwechat/replys',
44
+        method: 'delete',
45
+        data:data,
46
+    })
47
+}

+ 1 - 16
src/api/mpwechat/mpwechat.js View File

@@ -12,19 +12,4 @@ export function GetAuthUrl() {
12 12
     url: '/api/mpwechat/authurl',
13 13
     method: 'get',
14 14
   })
15
-}
16
-  
17
-export function GetMenus() {
18
-  return request({
19
-    url: '/api/mpwechat/menus',
20
-    method: 'get',
21
-  })
22
-}
23
-
24
-export function SaveMenus(data) {
25
-  return request({
26
-    url: '/api/mpwechat/savemenus',
27
-    method: 'put',
28
-    data:data,
29
-  })
30
-}
15
+}

+ 1 - 1
src/router/modules/member.js View File

@@ -15,7 +15,7 @@ export default {
15 15
     {
16 16
       path: '/member/members',
17 17
       component: () => import('@/scrm_pages/members/members'),
18
-      name: 'memberslist',
18
+      name: 'memberslists',
19 19
       meta: { title: '会员管理', noCache: true }
20 20
     },
21 21
     {

+ 13 - 0
src/router/modules/system.js View File

@@ -23,6 +23,19 @@ export default {
23 23
       name: 'weixinMpMenus',
24 24
       meta: { title: '公众号菜单', noCache: true }
25 25
     },
26
+    {
27
+      path: '/weixinmp/reply/subscribe',
28
+      component: () => import('@/scrm_pages/weixinmp/subscribereply'),
29
+      name: 'weixinAutoReply',
30
+      meta: { title: '自动回复', noCache: true }
31
+    },
32
+    {
33
+      path: '/weixinmp/reply/keyword',
34
+      component: () => import('@/scrm_pages/weixinmp/keywordreply'),
35
+      name: 'weixinKeywordReply',
36
+      hidden: true,
37
+      meta: { title: '关键词回复', noCache: true }
38
+    },
26 39
     {
27 40
       path: '/Systemsetting/staffmanagement',
28 41
       component: () => import('@/scrm_pages/Systemsetting/staffmanagement'),

+ 101 - 0
src/scrm_pages/weixinmp/components/CreateKWReplyForm.vue View File

@@ -0,0 +1,101 @@
1
+<template>
2
+    <div id="create-kw-reply-form-box">
3
+        <el-dialog title="添加关键词回复" :visible.sync="createKWReplyFormVisible" width="700px" >
4
+            <el-form ref="replyForm" :rules="replyRules" :model="form" label-width="90px">
5
+                <el-form-item label="规则名称:" required prop="message_regular_name">
6
+                    <el-input v-model="form.message_regular_name"></el-input>
7
+                </el-form-item>
8
+                <el-form-item label="模式:" required prop="message_key_type">
9
+                    <el-radio-group v-model="form.message_key_type">
10
+                        <el-radio :label="item.id" :value="item.id" v-for="(item, index) in keyTypeOptions" :key="index" >{{item.name}}</el-radio>
11
+                    </el-radio-group>
12
+                </el-form-item>
13
+                <el-form-item label="关键字:" required prop="message_key_name">
14
+                    <el-input v-model="form.message_key_name"></el-input>
15
+                </el-form-item>
16
+                <el-form-item label="回复内容:" required prop="message_content">
17
+                    <el-input v-model="form.message_content" type="textarea" rows="4"></el-input>
18
+                </el-form-item>
19
+            </el-form>
20
+            <div slot="footer" class="dialog-footer">
21
+                <el-button @click="createKWReplyFormVisible = false">取消</el-button>
22
+                <el-button
23
+                type="primary"
24
+                @click="submitForm('replyForm')"
25
+                >保 存
26
+                </el-button>
27
+            </div>
28
+        </el-dialog>  
29
+    </div>
30
+</template>
31
+
32
+<script>
33
+import {CreateKeyWordReply} from "@/api/mpwechat/mpreply";
34
+
35
+export default {
36
+    name:'CreateReplyForm',
37
+    props:{
38
+        replysData:{
39
+            type: Array,
40
+            default: function () {
41
+                return [];
42
+            }
43
+        },
44
+    },
45
+    data(){
46
+        return {
47
+            createKWReplyFormVisible:false,
48
+            keyTypeOptions:[
49
+                {id:1, name:'半匹配'},
50
+                {id:2, name:'全匹配'},
51
+            ],
52
+            replyRules: {
53
+                message_regular_name: [{required: true, message: "请填写规则名称",},],
54
+                message_key_type: [{required: true, message: "请选择模式",},],
55
+                message_key_name: [{required: true, message: "请填写关键字",},],
56
+                message_content: [{required: true, message: "请填写回复内容",},],
57
+            },
58
+            form:{
59
+                message_regular_name:'',
60
+                message_key_type:1,
61
+                message_key_name:'',
62
+                message_content:'',
63
+            },
64
+            
65
+        }
66
+    },
67
+    methods:{
68
+        open:function(){
69
+            this.resetForm("replyForm");
70
+            this.createKWReplyFormVisible = true;
71
+        },
72
+        resetForm(formName) {
73
+            if (typeof(this.$refs[formName]) !='undefined') {
74
+                this.$refs[formName].resetFields();
75
+            }
76
+        },
77
+        submitForm(formName){
78
+            this.$refs[formName].validate((valid) => {
79
+                if (valid) {
80
+                    CreateKeyWordReply(this.form).then(response=>{
81
+                        var res = response.data;
82
+                        if(res.state === 1) {
83
+                            var message = res.data.message;
84
+                            this.replysData.unshift(message);
85
+                            this.resetForm("replyForm");
86
+                            this.createKWReplyFormVisible = false;
87
+                            this.$message.success("添加成功");
88
+                        }else {
89
+                            this.$message.error(res.msg);
90
+                        }
91
+                    }).catch(e=>{});
92
+
93
+                } else {
94
+                    return false;
95
+                }
96
+            });
97
+        },
98
+    }
99
+}
100
+</script>
101
+

+ 105 - 0
src/scrm_pages/weixinmp/components/EditKWReplyForm.vue View File

@@ -0,0 +1,105 @@
1
+<template>
2
+    <div id="edit-kw-reply-form-box">
3
+        <el-dialog title="编辑关键词回复" :visible.sync="editKWReplyFormVisible" width="700px" >
4
+            <el-form ref="replyForm" :rules="replyRules" :model="form" label-width="90px">
5
+                <el-form-item label="规则名称:" required prop="message_regular_name">
6
+                    <el-input v-model="form.message_regular_name"></el-input>
7
+                </el-form-item>
8
+                <el-form-item label="模式:" required prop="message_key_type">
9
+                    <el-radio-group v-model="form.message_key_type">
10
+                        <el-radio :label="item.id" :value="item.id" v-for="(item, index) in keyTypeOptions" :key="index" >{{item.name}}</el-radio>
11
+                    </el-radio-group>
12
+                </el-form-item>
13
+                <el-form-item label="关键字:" required prop="message_key_name">
14
+                    <el-input v-model="form.message_key_name"></el-input>
15
+                </el-form-item>
16
+                <el-form-item label="回复内容:" required prop="message_content">
17
+                    <el-input v-model="form.message_content" type="textarea" rows="4"></el-input>
18
+                </el-form-item>
19
+            </el-form>
20
+            <div slot="footer" class="dialog-footer">
21
+                <el-button @click="editKWReplyFormVisible = false">取消</el-button>
22
+                <el-button
23
+                type="primary"
24
+                @click="submitForm('replyForm')"
25
+                >保 存
26
+                </el-button>
27
+            </div>
28
+        </el-dialog>  
29
+    </div>
30
+</template>
31
+
32
+<script>
33
+import {EditKeyWordReply} from "@/api/mpwechat/mpreply";
34
+
35
+export default {
36
+    name:'EditReplyForm',
37
+    props:{
38
+        replysData:{
39
+            type: Array,
40
+            default: function () {
41
+                return [];
42
+            }
43
+        },
44
+        replyIndex:{
45
+            type:Number,
46
+            default:-1,
47
+        },
48
+        form:{
49
+            id:0,
50
+            message_regular_name:'',
51
+            message_key_type:1,
52
+            message_key_name:'',
53
+            message_content:'',
54
+        },
55
+    },
56
+    data(){
57
+        return {
58
+            editKWReplyFormVisible:false,
59
+            keyTypeOptions:[
60
+                {id:1, name:'半匹配'},
61
+                {id:2, name:'全匹配'},
62
+            ],
63
+            replyRules: {
64
+                message_regular_name: [{required: true, message: "请填写规则名称",},],
65
+                message_key_type: [{required: true, message: "请选择模式",},],
66
+                message_key_name: [{required: true, message: "请填写关键字",},],
67
+                message_content: [{required: true, message: "请填写回复内容",},],
68
+            },
69
+            
70
+        }
71
+    },
72
+    methods:{
73
+        open:function(){
74
+            this.editKWReplyFormVisible = true;
75
+        },
76
+        resetForm(formName) {
77
+            if (typeof(this.$refs[formName]) !='undefined') {
78
+                this.$refs[formName].resetFields();
79
+            }
80
+        },
81
+        submitForm(formName){
82
+            this.$refs[formName].validate((valid) => {
83
+                if (valid) {
84
+                    EditKeyWordReply(this.form.id, this.form).then(response=>{
85
+                        var res = response.data;
86
+                        if(res.state === 1) {
87
+                            var message = res.data.message;
88
+                            this.replysData.splice(this.replyIndex, 1, message);
89
+                            this.resetForm("replyForm");
90
+                            this.editKWReplyFormVisible = false;
91
+                            this.$message.success("编辑成功");
92
+                        }else {
93
+                            this.$message.error(res.msg);
94
+                        }
95
+                    }).catch(e=>{});
96
+
97
+                } else {
98
+                    return false;
99
+                }
100
+            });
101
+        },
102
+    }
103
+}
104
+</script>
105
+

+ 30 - 0
src/scrm_pages/weixinmp/components/replyNav.vue View File

@@ -0,0 +1,30 @@
1
+<template>
2
+    <el-tabs v-model="tabActiveName" @tab-click="handleTabClick" style="margin-bottom:10px">
3
+        <el-tab-pane label="关键词回复" name="keyword"></el-tab-pane>
4
+        <el-tab-pane label="关注后回复" name="subscribe"></el-tab-pane>
5
+    </el-tabs>
6
+</template>
7
+<script>
8
+export default {
9
+    props:{
10
+        activeName:{
11
+            type:String,
12
+            default: 'subscribe'
13
+        }
14
+    },
15
+    data(){
16
+        return{
17
+            tabActiveName:'subscribe',
18
+        }
19
+    }, 
20
+    methods:{
21
+        handleTabClick(tab, event) {
22
+            this.$router.push({ path: "/weixinmp/reply/"+this.tabActiveName });
23
+        }
24
+    },
25
+    created(){
26
+        this.tabActiveName = this.activeName
27
+    },
28
+}
29
+</script>
30
+

+ 234 - 0
src/scrm_pages/weixinmp/keywordreply.vue View File

@@ -0,0 +1,234 @@
1
+<template>
2
+  <div class="main-contain">
3
+    <div class="position">
4
+      <bread-crumb :crumbs='crumbs'></bread-crumb>
5
+      <el-button  style="float:right;" type="primary" size="small" icon="el-icon-circle-plus-outline" @click="openCreate">添加回复</el-button>
6
+    </div>
7
+    <div class="app-container">
8
+        <reply-nav activeName="keyword"></reply-nav>
9
+        <div style="margin-bottom: 10px">
10
+            <el-row :gutter="24">
11
+                <el-col :span="8">
12
+                    <el-input style="width: 300px" v-model="listQuery.search" placeholder="请输入您需要搜索的内容"></el-input>
13
+                    <el-button type="primary"  icon="el-icon-search" @click="changeKey">搜索</el-button>
14
+                </el-col>
15
+            </el-row>
16
+        </div>
17
+        <div class="filter-container" style="margin-top: 10px;margin-left: 5px">
18
+            <el-checkbox style="width: 30px" @change="changeCheck" v-model="checkAllStatus">全选</el-checkbox>
19
+            <el-button size="small" icon="el-icon-delete" @click="openDeleteReplys">批量删除</el-button>
20
+        </div>
21
+        <el-table ref="multipleTable"  @selection-change="handleSelectionChange"  :header-cell-style="{ backgroundColor: 'rgb(245, 247, 250)'}" :data="messagesData" border fit highlight-current-row  style="width: 100%;margin-top: 10px;">
22
+            <el-table-column
23
+                align="center"
24
+                type="selection"
25
+                width="55">
26
+             </el-table-column>
27
+            <el-table-column label="关键词" align="center">
28
+                <template slot-scope="scope">
29
+                    {{scope.row.message_key_name}}
30
+                </template>
31
+            </el-table-column>
32
+            <el-table-column label="回复内容" align="center">
33
+                <template slot-scope="scope">
34
+                <span>{{scope.row.message_content}}</span>
35
+                </template>
36
+            </el-table-column>
37
+            <el-table-column label="模式" align="center">
38
+                <template slot-scope="scope">
39
+                <span>{{keyTypeName(scope.row.message_key_type)}}</span>
40
+                </template>
41
+            </el-table-column>
42
+            <el-table-column label="操作" align="center">
43
+                <template slot-scope="scope">
44
+                    <el-tooltip class="item" effect="dark" content="编辑" placement="top">
45
+                        <el-button size="mini" type="primary" icon="el-icon-edit-outline" @click="openEdit(scope.row, scope.$index)" ></el-button>
46
+                    </el-tooltip>
47
+                    <el-tooltip class="item" effect="dark" content="删除" placement="top">
48
+                        <el-button size="mini" type="danger" icon="el-icon-delete" @click="openDelete(scope.row, scope.$index)" ></el-button>
49
+                    </el-tooltip>
50
+                </template>
51
+            </el-table-column>
52
+        </el-table>
53
+        <el-pagination
54
+            @size-change="handleSizeChange"
55
+            @current-change="handleCurrentChange"
56
+            :page-sizes="[10,20,50,100]"
57
+            :page-size="10"
58
+            background
59
+            style="margin-top:20px;"
60
+            align="right"
61
+            layout="total, sizes, prev, pager, next, jumper"
62
+            :total="total">
63
+        </el-pagination>
64
+        <!--添加-->
65
+        <create-k-w-reply-form ref="createKWReplyForm" :replysData="messagesData" ></create-k-w-reply-form>
66
+        <!--编辑-->
67
+        <edit-k-w-reply-form ref="editKWReplyForm" :replysData="messagesData" :replyIndex="replyIndex" :form="editForm"></edit-k-w-reply-form>
68
+    </div>
69
+  </div>
70
+</template>
71
+
72
+<script>
73
+  import {GetKeyWordReplys,DeleteReplys} from "@/api/mpwechat/mpreply";
74
+  import BreadCrumb from '../components/bread-crumb';
75
+  import CreateKWReplyForm from './components/CreateKWReplyForm';
76
+  import EditKWReplyForm from './components/EditKWReplyForm';
77
+import replyNav from "./components/replyNav";
78
+
79
+  export default {
80
+    name: 'keywordreply',
81
+    components:{
82
+      BreadCrumb,
83
+      replyNav,
84
+      CreateKWReplyForm,
85
+      EditKWReplyForm,
86
+    },
87
+    data(){
88
+      return{
89
+        crumbs: [
90
+        { path: false, name: "系统设置" },
91
+        { path: false, name: "关键词回复" }
92
+        ],
93
+        total:0,
94
+        listQuery:{
95
+            page:1,
96
+            limit:10,
97
+            search:'',
98
+        },
99
+        checkAllStatus:false,
100
+        selectedReplys:[],
101
+        messagesData:[],
102
+        replyIndex:-1,
103
+        editForm:{
104
+            id:0,
105
+            message_regular_name:'',
106
+            message_key_type:1,
107
+            message_key_name:'',
108
+            message_content:'',
109
+        },
110
+      }
111
+    },
112
+    methods:{
113
+        openCreate:function(){
114
+          this.$refs.createKWReplyForm.open();
115
+        },
116
+        openEdit:function(row,index){
117
+            this.replyIndex = index;
118
+            for (const key in this.editForm) {
119
+              this.editForm[key] = row[key];
120
+            }
121
+            this.$refs.editKWReplyForm.open();
122
+        },
123
+        openDeleteReplys:function(){
124
+          if (this.selectedReplys.length==0) {
125
+            this.$message.error("请选择要删除的回复");
126
+            return false;
127
+          }
128
+
129
+          this.$confirm('确认要删除所选的回复吗?<br>删除后,回复将无法恢复', '删除提示', {
130
+            dangerouslyUseHTMLString:true,
131
+            confirmButtonText: '确定',
132
+            cancelButtonText: '取消',
133
+            type: 'warning'
134
+          }).then(() => {
135
+            var ids = [];
136
+            var idMap = {};
137
+            for (const index in this.selectedReplys) {
138
+              ids.push(this.selectedReplys[index].id);
139
+              idMap[this.selectedReplys[index].id] = this.selectedReplys[index].id;
140
+            }
141
+            DeleteReplys({ids:ids}).then(response=>{
142
+              var res = response.data;
143
+              if (res.state === 1) {
144
+                var dataLength = this.messagesData.length;
145
+                for (let index = dataLength-1; index >= 0; index--) {
146
+                  if(this.messagesData[index].id in idMap) {
147
+                    this.messagesData.splice(index, 1);
148
+                  }                  
149
+                }
150
+                this.$message.success("删除成功");
151
+              }else {
152
+                this.$message.error(res.msg);
153
+              }
154
+            }).catch(e=>{});
155
+          }).catch(() => {
156
+            return false        
157
+          });
158
+        },
159
+        openDelete:function(row,index){
160
+          this.$confirm('确认要删除该回复吗?<br>删除后,该回复将无法恢复', '删除提示', {
161
+            dangerouslyUseHTMLString:true,
162
+            confirmButtonText: '确定',
163
+            cancelButtonText: '取消',
164
+            type: 'warning'
165
+          }).then(() => {
166
+            var ids = [];
167
+            ids.push(row.id);
168
+            DeleteReplys({ids:ids}).then(response=>{
169
+              var res = response.data;
170
+              if (res.state === 1) {
171
+                this.messagesData.splice(index, 1);
172
+                this.$message.success("删除成功");
173
+              }else {
174
+                this.$message.error(res.msg);
175
+              }
176
+            }).catch(e=>{});
177
+          }).catch(() => {
178
+            return false        
179
+          });
180
+        },
181
+        changeCheck:function(){
182
+          this.$refs.multipleTable.clearSelection();
183
+          if (this.checkAllStatus) {
184
+            this.$refs.multipleTable.toggleAllSelection();
185
+          }
186
+        },
187
+        handleSelectionChange:function (val) {
188
+          this.selectedReplys = val;
189
+        },
190
+        handleSizeChange(limit) {
191
+            this.listQuery.limit = limit;
192
+            this.GetKeyWordReplys();
193
+        },
194
+        handleCurrentChange(page) {
195
+            this.listQuery.page = page;
196
+            this.GetKeyWordReplys();
197
+        },
198
+        changeKey(){
199
+            this.GetKeyWordReplys();
200
+        },
201
+        keyTypeName:function(type){
202
+          return type == 1?'半匹配':'全匹配';
203
+        },
204
+        GetKeyWordReplys(){
205
+            GetKeyWordReplys(this.listQuery).then(response=>{
206
+                var res = response.data;
207
+                if(res.state===1) {
208
+                    this.messagesData = res.data.messages;
209
+                    this.total = res.data.total;
210
+                }
211
+            }).catch(e=>{})
212
+        }
213
+    },
214
+    computed:{
215
+    },
216
+    created(){
217
+        this.GetKeyWordReplys();
218
+    }
219
+  }
220
+</script>
221
+
222
+<style scoped>
223
+  /*.app-container .cell.clearfix .time ul li {*/
224
+    /*float: left;*/
225
+    /*list-style: none;*/
226
+    /*cursor: pointer;*/
227
+    /*padding: 6px 20px;*/
228
+    /*color: #606266;*/
229
+    /*border-radius: 4px;*/
230
+    /*margin: 0 8px 0 0;*/
231
+    /*font-size: 14px;*/
232
+    /*text-align: center;*/
233
+  /*}*/
234
+</style>

+ 173 - 12
src/scrm_pages/weixinmp/menus.vue View File

@@ -4,7 +4,7 @@
4 4
       <bread-crumb :crumbs="crumbs"></bread-crumb>
5 5
       <el-col :span="5" style="text-align: right;" v-show="initButtons">
6 6
         <el-button type="primary" size="small" :disabled="subload" icon="el-icon-upload" @click="submitSave">保存并发布</el-button>
7
-        <el-button  type="danger" size="small" :disabled="subload" icon="el-icon-delete" >停用菜单</el-button>
7
+        <el-button  type="danger" size="small" :disabled="subload" icon="el-icon-delete" @click="deleteMenus">停用菜单</el-button>
8 8
       </el-col>
9 9
     </div>
10 10
     <div class="app-container" id="winxin-menus-box">
@@ -41,7 +41,7 @@
41 41
                             </div> 
42 42
                         </li>
43 43
 
44
-                          <li class="jsAddMenu pre_menu_li" v-show="menus.button.length<3">
44
+                          <li class="jsAddMenu pre_menu_li" v-show="!menus.button||menus.button.length<3">
45 45
                               <a href="javascript:void(0);" class="pre_menu_link" @click="addItem(-1)">
46 46
                                   <i class="icon_menu_dot "></i>
47 47
                                   <span class="js_l1Title_">
@@ -84,7 +84,7 @@
84 84
                   <div class="menu_form_item menu_more_info" v-show="typeof(currentMenu.sub_button) == 'undefined' || !currentMenu.sub_button || currentMenu.sub_button.length==0">
85 85
                       <div class="menu_form__nav clearfix">
86 86
                           <label for="" class="tit">菜单内容</label>
87
-                          <el-radio-group v-model="menuType" class="radio_item" @change="changeMenuType">
87
+                          <el-radio-group v-model="menuType" class="radio_item" @change="changeBigType">
88 88
                             <el-radio v-for="(menu, index) in menuTypeOptions" :key="index" :label="menu.id" :value="menu.id">{{menu.name}}</el-radio>
89 89
                           </el-radio-group>
90 90
                       </div>
@@ -92,13 +92,41 @@
92 92
                         <div class="inner send_message " v-show="menuType==1">
93 93
                             <div class="send_message_tit">
94 94
                                 <div class="send_nav">
95
-                                    <i class="ico_size"></i>
96
-                                    文字
95
+                                    <el-button type="text" icon="el-icon-edit-outline" style="padding:0" :disabled="currentMenu.type=='click'" @click="selectMenuType(1)">文字</el-button>
96
+                                </div>
97
+                                <div class="send_nav">
98
+                                    <el-button type="text" icon="el-icon-picture-outline" style="padding:0" :disabled="currentMenu.type=='media_id'" @click="selectMenuType(2)">图片</el-button>
97 99
                                 </div>
98 100
                             </div>
99
-                            <textarea class="send_message_edit" id="click_menu_act" v-model="currentMenu.message" placeholder="请输入你需要的文字"></textarea>
100
-                            <span class="tips" id="acterrinfo" v-if="!messageError" >&nbsp;&nbsp;{{menuMessageTip}}</span>
101
-                            <span class="tips" id="acterrinfo" v-if="messageError"  style="color: #f00;">&nbsp;&nbsp;{{menuMessageTip}}</span>
101
+                            <textarea v-show="currentMenu.type=='click'" class="send_message_edit" id="click_menu_act" v-model="currentMenu.message" placeholder="请输入你需要的文字"></textarea>
102
+                            <span v-show="currentMenu.type=='click'" class="tips" id="acterrinfo" v-if="!messageError" >&nbsp;&nbsp;{{menuMessageTip}}</span>
103
+                            <span v-show="currentMenu.type=='click'" class="tips" id="acterrinfo" v-if="messageError"  style="color: #f00;">&nbsp;&nbsp;{{menuMessageTip}}</span>
104
+                            <div v-show="currentMenu.type=='media_id'" class="mediaID-box">
105
+                              <el-row>
106
+                                <el-col :span="12" >
107
+                                  <div class="mediaID-item">
108
+                                    <i class="el-icon-news"></i>
109
+                                    <span class="icon-name">从素材库选择</span>
110
+                                  </div>
111
+                                </el-col>
112
+                                <el-col :span="12" >
113
+                                  <div class="mediaID-item">
114
+                                    <el-upload
115
+                                      class="media-uploader"
116
+                                      :action="addMaterialUrl"
117
+                                      :show-file-list="false"
118
+                                      :with-credentials='true'
119
+                                      :on-success="handleMediaSuccess"
120
+                                      :before-upload="beforeMediaUpload"
121
+                                      >
122
+                                      <img v-if="currentMenu.media_url" :src="currentMenu.media_url" class="media">
123
+                                      <i v-else class="el-icon-plus media-uploader-icon"></i>
124
+                                    </el-upload>
125
+                                    <span class="icon-name">上传图片</span>
126
+                                  </div>
127
+                                </el-col>
128
+                              </el-row>
129
+                            </div>
102 130
                         </div>
103 131
                         <div class="inner  jump_page" v-show="menuType==2">
104 132
                             <span class="tips_size">订阅者点击该子菜单会跳到以下链接</span>
@@ -141,8 +169,10 @@
141 169
 </template>
142 170
 
143 171
 <script>
172
+import axios from 'axios';
144 173
 import BreadCrumb from "../components/bread-crumb";
145
-import {GetAuthorizationInfo,GetMenus,SaveMenus} from "@/api/mpwechat/mpwechat";
174
+import {GetAuthorizationInfo} from "@/api/mpwechat/mpwechat";
175
+import {GetMenus,SaveMenus,DeleteMenu} from "@/api/mpwechat/mpmenus";
146 176
 export default {
147 177
   name: "menus",
148 178
   components: {
@@ -159,10 +189,12 @@ export default {
159 189
         {id:2, name:' 跳转网页'},
160 190
         {id:3, name:' 跳转小程序'},
161 191
       ],
192
+      addMaterialUrl: process.env.BASE_API + '/api/mpwechat/media/add_material',
162 193
       initButtons:false,
163 194
       subload:false,
164 195
       menus:{button:[]},
165 196
       currentMenu:{
197
+        big_type:0,
166 198
         type:'',
167 199
         name:'',
168 200
         url:'',
@@ -172,6 +204,7 @@ export default {
172 204
         message:'',
173 205
         sub_button:[],
174 206
         media_id:'',
207
+        media_url:'',
175 208
       },
176 209
       menuType:0,
177 210
       currentPatient:-1,
@@ -228,6 +261,57 @@ export default {
228 261
           this.$message.error(res.msg);
229 262
         }
230 263
       }).catch(e=>{});
264
+    },
265
+     handleMediaSuccess:function(res, file) {
266
+       console.log(res, file);
267
+      },
268
+      beforeMediaUpload:function(file) {
269
+        var allow = {"image/bmp":1,"image/png":1,"image/jpeg":1,"image/jpg":1,"image/gif":1};
270
+        // const isJPG = file.type === 'image/jpeg';
271
+        const isImg = file.type in allow;
272
+        const isLt2M = file.size / 1024 / 1024 < 2;
273
+
274
+        if (!isImg) {
275
+          this.$message.error('上传图片只能是 bmp/png/jpeg/jpg/gif 格式!');
276
+        }
277
+        if (!isLt2M) {
278
+          this.$message.error('上传图片大小不能超过 2MB!');
279
+        }
280
+        return isImg && isLt2M;
281
+      },
282
+    deleteMenus:function(){
283
+      this.$confirm('删除后,公众号的菜单也将被删除', '删除提示', {
284
+        dangerouslyUseHTMLString:true,
285
+        confirmButtonText: '确定',
286
+        cancelButtonText: '取消',
287
+        type: 'warning'
288
+      }).then(() => {
289
+        DeleteMenu().then(response=>{
290
+          var res = response.data;
291
+          if (res.state==1) {
292
+            this.$message.success('删除成功');
293
+            this.currentMenu = {
294
+              type:'',
295
+              name:'',
296
+              url:'',
297
+              appid:'',
298
+              pagepath:'',
299
+              key:'',//key规则:V_[number]_click;VC_[number]_click
300
+              message:'',
301
+              sub_button:[],
302
+              media_id:'',
303
+              media_url:'',
304
+              big_type:0
305
+            };
306
+            this.currentPatient = -1;
307
+            this.currentChild = -1;
308
+            this.menus = {button:[]};
309
+          }else {
310
+            this.$message.error(res.msg);
311
+          }
312
+        }).catch(e=>{});
313
+      }).catch(() => {
314
+      });
231 315
     },
232 316
     submitSave:function () {
233 317
         this.subload = true;
@@ -309,6 +393,8 @@ export default {
309 393
               message:'',
310 394
               sub_button:[],
311 395
               media_id:'',
396
+              media_url:'',
397
+              big_type:0
312 398
             };
313 399
           }
314 400
         }
@@ -323,6 +409,7 @@ export default {
323 409
             this.menus = res.data.menus;
324 410
             for (const index in this.menus.button) {
325 411
               var button = this.menus.button[index];
412
+              this.menus.button[index]['big_type'] = typeof(button.type) !='undefined' && button.type ? this.setBigType(button.type):0;
326 413
               if(typeof(button.key) !='undefined' && button.key) {
327 414
                 var keys = button.key.split("_")
328 415
                 if (typeof(keys[1]) !='undefined') {
@@ -333,6 +420,7 @@ export default {
333 420
               if(typeof(button.sub_button) !='undefined' && button.sub_button) {
334 421
                 for (const chilid in button.sub_button) {
335 422
                   var cbutton = button.sub_button[chilid];
423
+                  this.menus.button[index].sub_button[chilid]['big_type'] = typeof(cbutton.type) !='undefined' && cbutton.type ? this.setBigType(cbutton.type):0;
336 424
                   if(typeof(cbutton.key) !='undefined' && cbutton.key) {
337 425
                     var keys = cbutton.key.split("_")
338 426
                     if (typeof(keys[1]) !='undefined') {
@@ -367,10 +455,29 @@ export default {
367 455
           break;
368 456
       }
369 457
     },
370
-    changeMenuType:function(value){
458
+    setBigType(type) {
459
+       var bitType = 0;
460
+       switch (this.currentMenu.type) {
461
+        case 'click':
462
+          bitType = 1;
463
+          break;
464
+        case 'media_id':
465
+          bitTypee = 2;
466
+          break;
467
+      }
468
+      return bitType;
469
+    },
470
+    changeBigType:function(value){
471
+      // this.currentMenu.big_type = value;
371 472
       switch (value) {
372 473
         case 1:
373
-          this.currentMenu.type = 'click';
474
+          if (this.currentMenu.big_type == 1 ) {
475
+            this.currentMenu.type = 'click';
476
+          } else if (this.currentMenu.big_type == 2) {
477
+            this.currentMenu.type = 'media_id';
478
+          } else {
479
+            this.currentMenu.type = 'click';
480
+          }
374 481
           break;
375 482
         case 2:
376 483
           this.currentMenu.type = 'view';
@@ -382,6 +489,14 @@ export default {
382 489
           break;
383 490
       }
384 491
     },
492
+    selectMenuType:function(type){
493
+      this.currentMenu.big_type = type;
494
+      if(type==1) {
495
+        this.currentMenu.type = 'click';
496
+      }else if(type==2) {
497
+        this.currentMenu.type = 'media_id';
498
+      }
499
+    },
385 500
     selectItem:function(mi, ni, node){
386 501
       this.currentPatient = mi;
387 502
       this.currentChild = ni;
@@ -395,6 +510,8 @@ export default {
395 510
         message:'',
396 511
         sub_button:[],
397 512
         media_id:'',
513
+        media_url:'',
514
+        big_type:0,
398 515
       };
399 516
       for (const key in node) {
400 517
         this.currentMenu[key] = node[key]; 
@@ -567,8 +684,10 @@ export default {
567 684
       }
568 685
     },  
569 686
     'currentMenu.type':function(){
687
+
570 688
       if (this.currentPatient>=0&&this.currentChild>=0) {
571 689
         this.menus.button[this.currentPatient].sub_button[this.currentChild].type = this.currentMenu.type;
690
+        this.menus.button[this.currentPatient].sub_button[this.currentChild].big_type = this.currentMenu.big_type;
572 691
         if (this.currentMenu.type == 'click' && this.currentMenu.key.length==0) {
573 692
           this.cclick += 1;
574 693
           var key = 'VC_' + this.cclick + "_click";
@@ -577,6 +696,7 @@ export default {
577 696
         }
578 697
       } else if (this.currentPatient>=0){
579 698
         this.menus.button[this.currentPatient].type = this.currentMenu.type;
699
+        this.menus.button[this.currentPatient].big_type = this.currentMenu.big_type;
580 700
         if (this.currentMenu.type == 'click' && this.currentMenu.key.length==0) {
581 701
           this.pclick += 1;
582 702
           var key = 'V_' + this.cclick + "_click";
@@ -630,7 +750,7 @@ export default {
630 750
 };
631 751
 </script>
632 752
 
633
-<style scoped>
753
+<style >
634 754
 #winxin-menus-box {
635 755
   font-size: 14px;
636 756
   color: #485b6d;
@@ -929,6 +1049,7 @@ export default {
929 1049
 }
930 1050
 #winxin-menus-box .menu_form_item .send_message_tit .send_nav {
931 1051
     width: 80px;
1052
+    display: inline-block;
932 1053
 }
933 1054
 #winxin-menus-box .menu_form_item .send_message_tit .ico_size {
934 1055
     width: 14px;
@@ -984,6 +1105,46 @@ export default {
984 1105
 #winxin-menus-box .menu_form__con .mitips {
985 1106
   display:block;left:84px;position:relative;margin-top:10px;color: #c0c8d4;
986 1107
 }
1108
+#winxin-menus-box .mediaID-item {
1109
+    text-align: center;
1110
+    padding: 10px;
1111
+    /* cursor: pointer; */
1112
+}
1113
+
1114
+/* #winxin-menus-box .mediaID-item:hover {
1115
+  background:#c0c8d4;
1116
+}  */
1117
+#winxin-menus-box .mediaID-item i {
1118
+  display: block;
1119
+}
1120
+#winxin-menus-box .mediaID-item .el-icon-news {
1121
+  font-size: 80px;
1122
+}
1123
+#winxin-menus-box .mediaID-item .media-uploader .el-upload {
1124
+  border: 1px dashed #d9d9d9 !important;
1125
+  border-radius: 6px;
1126
+  cursor: pointer;
1127
+  position: relative;
1128
+  overflow: hidden;
1129
+  margin: 10px;
1130
+}
1131
+#winxin-menus-box .mediaID-item  .media-uploader .el-upload:hover {
1132
+  border-color: #409EFF;
1133
+}
1134
+#winxin-menus-box .mediaID-item .media-uploader-icon {
1135
+  font-size: 28px;
1136
+  color: #8c939d;
1137
+  width: 55px;
1138
+  height: 55px;
1139
+  line-height: 55px;
1140
+  text-align: center;
1141
+}
1142
+#winxin-menus-box .mediaID-item  .media {
1143
+  width: 55px;
1144
+  height: 55px;
1145
+  display: block;
1146
+}
1147
+
987 1148
 /*.app-container .cell.clearfix .time ul li {*/
988 1149
 /*float: left;*/
989 1150
 /*list-style: none;*/

+ 117 - 0
src/scrm_pages/weixinmp/subscribereply.vue View File

@@ -0,0 +1,117 @@
1
+<template>
2
+  <div class="main-contain">
3
+    <div class="position">
4
+      <bread-crumb :crumbs="crumbs"></bread-crumb>
5
+    </div>
6
+    <div class="app-container" id="winxin-subscribe-replu-box">
7
+      <reply-nav activeName="subscribe"></reply-nav>
8
+      <el-form ref="form" :model="form" >
9
+        <el-form-item label="">
10
+          <el-input type="textarea" v-model="form.message_content" rows='5'></el-input>
11
+        </el-form-item>
12
+        <el-form-item>
13
+          <!-- <el-col :span="24" style="text-align: right;"> -->
14
+            <el-button type="primary" align="right" @click="saveReply">保存</el-button>
15
+          <!-- </el-col> -->
16
+        </el-form-item>
17
+      </el-form>
18
+    </div>
19
+  </div>
20
+</template>
21
+
22
+<script>
23
+import BreadCrumb from "../components/bread-crumb";
24
+import replyNav from "./components/replyNav";
25
+import {GetAuthorizationInfo} from "@/api/mpwechat/mpwechat";
26
+import {GetSubscribeRplay,SaveSubscribeRplay} from "@/api/mpwechat/mpreply";
27
+
28
+export default {
29
+  name: "subscribereply",
30
+  components: {
31
+    BreadCrumb,
32
+    replyNav,
33
+  },
34
+  data() {
35
+    return {
36
+      crumbs: [
37
+        { path: false, name: "系统设置" },
38
+        { path: false, name: "关注后回复" }
39
+      ],
40
+      initReply:false,
41
+      form:{
42
+        'message_content':'',
43
+      },
44
+    };
45
+  },
46
+  methods: {
47
+    GetAuthorizationInfo:function(){
48
+      GetAuthorizationInfo().then(response=>{
49
+        var res =  response.data;
50
+        if(res.state===1) {
51
+          if(res.data.authorization) {
52
+            this.authData = res.data.authorization;
53
+            if (this.authData.authorizer_status != 1) {
54
+              this.$message.error("公众号未授权");
55
+              this.$router.push({path:"/weixinmp/authorization"})
56
+              return false;
57
+            }else if (this.authData.authorizer_verify_type_info>=0 || this.authData.authorizer_service_type_info==2) {
58
+              this.initReply = true;
59
+            }
60
+          }else {
61
+              this.$message.error("公众号未授权");
62
+              this.$router.push({path:"/weixinmp/authorization"})
63
+          }
64
+        }else {
65
+          this.$message.error(res.msg);
66
+        }
67
+      }).catch(e=>{});
68
+    },
69
+    GetSubscribeRplay:function(){
70
+      GetSubscribeRplay().then(response=>{
71
+        var res = response.data;
72
+        if (res.state==1) {
73
+          if (res.data.message) {
74
+            this.form.message_content = res.data.message.message_content;
75
+          }
76
+        }else {
77
+          this.$message.error(res.msg);
78
+        }
79
+      }).catch(e=>{});
80
+    },
81
+    saveReply:function(){
82
+      SaveSubscribeRplay(this.form).then(response=>{
83
+        var res = response.data;
84
+        if (res.state === 1) {
85
+          this.$message.success('保存成功');
86
+        }else {
87
+          this.$message.error(res.msg);
88
+        }
89
+      }).catch(e=>{});
90
+    }
91
+  },
92
+  created() {
93
+    this.GetAuthorizationInfo();
94
+  },
95
+  computed:{
96
+  },
97
+  watch:{
98
+    'initReply':function(){
99
+      this.GetSubscribeRplay();
100
+    }
101
+  },
102
+};
103
+</script>
104
+
105
+<style scoped>
106
+/*.app-container .cell.clearfix .time ul li {*/
107
+/*float: left;*/
108
+/*list-style: none;*/
109
+/*cursor: pointer;*/
110
+/*padding: 6px 20px;*/
111
+/*color: #606266;*/
112
+/*border-radius: 4px;*/
113
+/*margin: 0 8px 0 0;*/
114
+/*font-size: 14px;*/
115
+/*text-align: center;*/
116
+/*}*/
117
+</style>