ytj 6 years ago
parent
commit
267cb306f3

BIN
src/assets/bottomMsg.png View File


+ 103
- 0
src/components/material.vue View File

@@ -0,0 +1,103 @@
1
+<template>
2
+  <div>
3
+    <div class="box" v-if="model === 'get'">
4
+      <div v-if="type === 'img'">
5
+        <div  v-for="(item,index) in img" :key="index" @click="emit(item,index)" :class="{checked:item.checked}">
6
+          <img :src="item.url" alt="">
7
+        </div>
8
+      </div>
9
+      <div v-if="type === 'view'">
10
+        <div v-for="(item,index) in view" :key="index" @click="emit(item,index)" :class="{checked:item.checked}">
11
+          <img :src="item.url" alt="">
12
+          <p>{{item.text}}</p>
13
+        </div>
14
+      </div>
15
+    </div>
16
+    <div v-if="model === 'set'">
17
+
18
+    </div>
19
+  </div>
20
+</template>
21
+
22
+<script>
23
+import { createNamespacedHelpers } from 'vuex'
24
+const { mapState: mapMaterialState, mapActions: mapMaterialActions } = createNamespacedHelpers('material')
25
+export default {
26
+  props: ['type', 'model'],
27
+  created () {
28
+    console.log('cre')
29
+    if (this.type === 'img') {
30
+      this.getImg()
31
+    } else {
32
+      this.getView()
33
+      console.log(this.view)
34
+    }
35
+  },
36
+  computed: {
37
+    ...mapMaterialState({
38
+      img: item => item.img,
39
+      view: item => item.view
40
+    })
41
+  },
42
+  methods: {
43
+    ...mapMaterialActions(['getImg', 'getView']),
44
+    emit (item, index) {
45
+      if (this.type === 'img') {
46
+        this.img.forEach((curr, ind) => {
47
+          curr.checked = false
48
+          if (index === ind) {
49
+            curr.checked = true
50
+          }
51
+        })
52
+      } else {
53
+        this.view.forEach((curr, ind) => {
54
+          curr.checked = false
55
+          if (index === ind) {
56
+            curr.checked = true
57
+          }
58
+        })
59
+      }
60
+
61
+      this.$emit('emit', item)
62
+    }
63
+  }
64
+}
65
+</script>
66
+
67
+<style lang="scss" scoped>
68
+.box {
69
+  width: 100%;
70
+  padding: 20px;
71
+  > div {
72
+    display: flex;
73
+    flex-flow: row wrap;
74
+    justify-content: flex-start;
75
+    align-items: center;
76
+    div {
77
+      width: 160px;
78
+      height: 160px;
79
+      margin: 10px;
80
+      padding: 10px;
81
+      border: 1px solid #eeeeee;
82
+      border-radius: 5px;
83
+      cursor: pointer;
84
+      img {
85
+        width: 80%;
86
+        height: 80%;
87
+        margin: 0 10%;
88
+        object-fit: cover;
89
+      }
90
+      p {
91
+        padding-top: 8px;
92
+        width: 100%;
93
+        overflow: hidden;
94
+        text-overflow: ellipsis;
95
+        white-space: nowrap;
96
+      }
97
+    }
98
+    .checked {
99
+      border: 1px solid orange;
100
+    }
101
+  }
102
+}
103
+</style>

+ 139
- 14
src/components/menuForm.vue View File

@@ -5,7 +5,7 @@
5 5
       <Input placeholder="字数不超过4个汉字或8个字母" size="large" v-model="menuTitle" clearable @input="toolClass.CutStr(menuTitle, 8, '字数不超过4个汉字或8个字母')" name="name" style="width: 300px"/>
6 6
       <span class="error">{{toolClass.CutStr(menuTitle, 8, '字数不超过4个汉字或8个字母')}}</span>
7 7
     </div>
8
-    <div class="form-item">
8
+    <div class="form-item" v-if="hasContent">
9 9
       <label for="name">菜单内容</label>
10 10
       <RadioGroup  v-model="type" >
11 11
         <Radio label="发送消息"></Radio>
@@ -44,10 +44,28 @@
44 44
         </Modal>
45 45
       </div>
46 46
       <div v-show="active === '图片'">
47
-        2
47
+        <div>
48
+          <Button type="info" @click="chooseImg">从素材库中选取</Button>
49
+          <Button type="success" @click="uploadImg">从本地上传图片</Button>
50
+          <Modal width='800' v-model="showMaterial" @on-ok="checkImg" @on-cancel="closeImg">
51
+            <material v-if="showMaterial" :type='materialType' :model='model' @emit='setImg'></material>
52
+          </Modal>
53
+          <div class="img-view">
54
+            <img v-if="img.url" :src="img.url">
55
+          </div>
56
+        </div>
48 57
       </div>
49 58
       <div v-show="active === '图文'">
50
-        3
59
+        <div>
60
+          <Button type="info" @click="chooseView">从素材库中选取</Button>
61
+          <Modal width='800' v-model="showMaterialView" @on-ok="checkView" @on-cancel="closeView">
62
+            <material v-if="showMaterialView" :type='materialType' :model='model' @emit='setView'></material>
63
+          </Modal>
64
+          <div class="img-view">
65
+            <img v-if="view.url" :src="view.url">
66
+            <p v-if="view.text">{{view.text}}</p>
67
+          </div>
68
+        </div>
51 69
       </div>
52 70
     </div>
53 71
     <div v-if="type === '跳转网页'" class="type-content">
@@ -59,7 +77,7 @@
59 77
     </div>
60 78
     <div class="btn-group">
61 79
       <Button type="primary" @click="emit">确认</Button>
62
-      <Button @click="delMenu">删除当前菜单</Button>
80
+      <Button v-if="hasDelete" @click="delMenu">删除当前菜单</Button>
63 81
     </div>
64 82
   </div>
65 83
 </template>
@@ -67,8 +85,9 @@
67 85
 <script>
68 86
 
69 87
 import Emotion from '@/components/Emotion/index'
88
+import material from '@/components/material'
70 89
 export default {
71
-  props: ['menuConfig'],
90
+  props: ['data', 'menuConfig', 'hasContent', 'hasDelete'],
72 91
   data () {
73 92
     return {
74 93
       active: '文字',
@@ -80,13 +99,50 @@ export default {
80 99
       menuTitle: '',
81 100
       text: '',
82 101
       linkText: '',
83
-      linkHref: ''
102
+      linkHref: '',
103
+      showMaterial: false,
104
+      showMaterialView: false,
105
+      model: 'get',
106
+      materialType: 'img',
107
+      imghc: {},
108
+      viewhc: {},
109
+      img: {
110
+        media_id: '',
111
+        url: ''
112
+      },
113
+      view: {
114
+        media_id: '',
115
+        url: '',
116
+        text: ''
117
+      }
118
+    }
119
+  },
120
+  created () {
121
+    if (!this.hasContent) {
122
+      this.type = null
123
+    }
124
+    if (this.data) {
125
+      if (this.menuConfig) {
126
+        this.menuTitle = this.data.name
127
+      }
128
+      if (this.data.type === 'text') {
129
+        this.active = '文字'
130
+        this.text = this.data.value
131
+      } else if (this.data.type === 'media_id') {
132
+        this.active = '图片'
133
+        this.img.media_id = this.data.media_id
134
+        this.img.url = this.data.url
135
+      } else if (this.data.type === 'view_limited') {
136
+        this.active = '图文'
137
+        this.view.media_id = this.data.media_id
138
+        this.view.url = this.data.url
139
+      } else if (this.data.type === 'view') {
140
+        this.type = '跳转网页'
141
+        this.linkHref = this.data.url
142
+      }
84 143
     }
85 144
   },
86 145
   methods: {
87
-    check () {
88
-      console.log(this.error)
89
-    },
90 146
     checkLink () {
91 147
       if (!this.linkText) {
92 148
         this.$Message.warning('链接名称必填')
@@ -121,13 +177,48 @@ export default {
121 177
       let index = list.indexOf(word)
122 178
       return `<img src="https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/${index}.gif" align="middle">`
123 179
     },
180
+    setImg (img) {
181
+      this.imghc = img
182
+    },
183
+    checkImg () {
184
+      this.img = this.imghc
185
+      this.closeImg()
186
+    },
187
+    closeImg () {
188
+      this.imghc = {}
189
+      this.showMaterial = false
190
+    },
191
+    chooseImg () {
192
+      this.model = 'get'
193
+      this.materialType = 'img'
194
+      this.showMaterial = true
195
+    },
196
+    uploadImg () {
197
+
198
+    },
199
+    setView (view) {
200
+      this.viewhc = view
201
+    },
202
+    checkView () {
203
+      this.view = this.viewhc
204
+      this.closeView()
205
+    },
206
+    chooseView () {
207
+      this.model = 'get'
208
+      this.materialType = 'view'
209
+      this.showMaterialView = true
210
+    },
211
+    closeView () {
212
+      this.viewhc = {}
213
+      this.showMaterialView = false
214
+    },
124 215
     emit () {
125 216
       let emitData = {}
126 217
       if (this.menuConfig) {
127 218
         if (!this.menuTitle) {
128 219
           this.$Message.warning('菜单名称必填')
129 220
           return false
130
-        } else if (this.toolClass.CutStr(this.menuTitle, 8, '字数不超过4个汉字或8个字母') ) {
221
+        } else if (this.toolClass.CutStr(this.menuTitle, 8, '字数不超过4个汉字或8个字母')) {
131 222
           this.$Message.warning('菜单名称超过4个汉字或8个字母')
132 223
           return false
133 224
         }
@@ -135,12 +226,26 @@ export default {
135 226
       }
136 227
       if (this.type === '发送消息') {
137 228
         if (this.active === '文字') {
138
-          if (!this.text){
229
+          if (!this.text) {
139 230
             this.$Message.warning('消息文字必填')
140 231
             return false
141 232
           }
142 233
           emitData.type = 'text'
143 234
           emitData.value = this.text
235
+        } else if (this.active === '图片') {
236
+          if (!this.img.media_id) {
237
+            this.$Message.warning('请选择素材')
238
+            return false
239
+          }
240
+          emitData.type = 'media_id'
241
+          emitData.media_id = this.img.media_id
242
+        } else if (this.active === '图文') {
243
+          if (!this.view.media_id) {
244
+            this.$Message.warning('请选择素材')
245
+            return false
246
+          }
247
+          emitData.type = 'view_limited'
248
+          emitData.media_id = this.view.media_id
144 249
         }
145 250
       } else if (this.type === '跳转网页') {
146 251
         if (this.errors.first('link')) {
@@ -151,13 +256,15 @@ export default {
151 256
         emitData.type = 'view'
152 257
         emitData.url = this.linkHref
153 258
       }
259
+      this.$emit('emit', emitData)
154 260
     },
155 261
     delMenu () {
156 262
 
157
-    }
263
+    },
158 264
   },
159 265
   components: {
160
-    Emotion
266
+    Emotion,
267
+    material
161 268
   }
162 269
 }
163 270
 </script>
@@ -165,6 +272,7 @@ export default {
165 272
 <style lang="scss" scoped>
166 273
 .box {
167 274
   padding: 50px;
275
+  text-align: center;
168 276
   .form-item {
169 277
     display: flex;
170 278
     justify-content: flex-start;
@@ -188,7 +296,7 @@ export default {
188 296
     align-items: center;
189 297
   }
190 298
   button {
191
-    margin-right: 40px;
299
+    margin: 0 20px;
192 300
   }
193 301
   .expression {
194 302
     position: absolute;
@@ -201,5 +309,22 @@ export default {
201 309
     border-radius: 5px;
202 310
     text-align: center;
203 311
   }
312
+  .img-view {
313
+    width: 200px;
314
+    height: 200px;
315
+    margin: 20px auto 0;
316
+    img {
317
+      width: 100%;
318
+      height: 100%;
319
+      object-fit: cover;
320
+    }
321
+    p {
322
+      padding-top: 8px;
323
+      width: 100%;
324
+      overflow: hidden;
325
+      text-overflow: ellipsis;
326
+      white-space: nowrap;
327
+    }
328
+  }
204 329
 }
205 330
 </style>

+ 59
- 39
src/pages/main/index/index.vue View File

@@ -21,12 +21,15 @@
21 21
       </div>
22 22
     </div>
23 23
     <div class="content-item">
24
-      <menuForm :menuConfig='true'></menuForm>
24
+      <transition name="fade">
25
+        <menuForm v-if="formActive" :data='chooseItem' :menuConfig='true' :hasContent='hasContent' :hasDelete='hasDelete' @emit='checkForm'></menuForm>
26
+      </transition>
25 27
     </div>
26 28
   </div>
27 29
 </template>
28 30
 
29 31
 <script>
32
+import defultImg from '@/assets/bottomMsg.png'
30 33
 import bottomMenu from '@/components/bottomMenu.vue'
31 34
 import menuForm from '@/components/menuForm.vue'
32 35
 import { createNamespacedHelpers } from 'vuex'
@@ -34,6 +37,16 @@ const { mapState: mapIndexState, mapActions: mapIndexActions } = createNamespace
34 37
 export default {
35 38
   data () {
36 39
     return {
40
+      defultImg,
41
+      chooseItem: {},
42
+      chooseTag: {
43
+        type: 0,
44
+        index: 0,
45
+        parentIndex: 0
46
+      },
47
+      formActive: false,
48
+      hasContent: true,
49
+      hasDelete: true
37 50
     }
38 51
   },
39 52
   created () {
@@ -50,61 +63,66 @@ export default {
50 63
   },
51 64
   methods: {
52 65
     ...mapIndexActions(['getMenu', 'AddMainMenu', 'SetMainMenu', 'AddSubMenu', 'SetSubMenu', 'mainActive', 'subActive', 'mainPlusActive', 'subPlusActive']),
53
-    chengeForm () {
54
-      this.isRouterAlive = false
55
-      this.$nextTick(() => (this.isRouterAlive = true))
66
+    chengeForm (hasContent, hasDelete) {
67
+      this.formActive = false
68
+      this.hasContent = hasContent
69
+      this.hasDelete = hasDelete
70
+      this.$nextTick(() => {
71
+        setTimeout(() => {
72
+          this.formActive = true
73
+        }, 500)
74
+      })
75
+    },
76
+    checkForm (data) {
77
+      if (this.chooseTag.type === 0) {
78
+        this.addMainMenu(data)
79
+      } else if (this.chooseTag.type === 1) {
80
+        this.setMainMenu(data, this.chooseTag.index)
81
+      } else if (this.chooseTag.type === 2) {
82
+        this.addSubMenu(data, this.chooseTag.parentIndex)
83
+      } else if (this.chooseTag.type === 3) {
84
+        this.setSubMenu(data, this.chooseTag.index, this.chooseTag.parentIndex)
85
+      }
56 86
     },
57 87
     addMainMenuClick () {
88
+      this.chooseItem = {}
89
+      this.chooseTag.type = 0
90
+      this.chengeForm(true, false)
58 91
       this.mainPlusActive()
59 92
     },
60 93
     setMainMenuClick (item, index) {
94
+      this.chooseItem = item
95
+      this.chooseTag.type = 1
96
+      this.chooseTag.index = index
97
+      this.chengeForm(false, true)
61 98
       this.mainActive({ index })
62 99
     },
63 100
     addSubMenuClick (index) {
101
+      this.chooseItem = {}
102
+      this.chooseTag.type = 2
103
+      this.chooseTag.parentIndex = index
104
+      this.chengeForm(true, false)
64 105
       this.subPlusActive({ index })
65 106
     },
66 107
     setSubMenuClick (item, index, parentIndex) {
108
+      this.chooseItem = item
109
+      this.chooseTag.type = 3
110
+      this.chooseTag.index = index
111
+      this.chooseTag.parentIndex = parentIndex
112
+      this.chengeForm(true, true)
67 113
       this.subActive({ index, parentIndex })
68 114
     },
69
-    addMainMenu () {
70
-      let changeData = {
71
-        'name': '菜单'
72
-      }
115
+    addMainMenu (changeData) {
73 116
       this.AddMainMenu(changeData)
74 117
     },
75 118
     setMainMenu (item, index) {
76
-      item = {
77
-        'name': '菜单',
78
-        'sub_button': [
79
-          {
80
-            'type': 'view',
81
-            'name': '百度',
82
-            'url': 'http://www.baidu.com'
83
-          },
84
-          {
85
-            'type': 'view',
86
-            'name': '我的主页',
87
-            'url': 'http://www.tongtianguanriz.com/index.html'
88
-          },
89
-          {
90
-            'type': 'click',
91
-            'name': '为我们点赞!',
92
-            'key': 'V1001_GOOD'
93
-          }
94
-        ]
95
-      }
96 119
       let data = {
97 120
         item,
98 121
         index
99 122
       }
100 123
       this.SetMainMenu(data)
101 124
     },
102
-    addSubMenu (index) {
103
-      let item = {
104
-        'type': 'view',
105
-        'name': '百度',
106
-        'url': 'http://www.baidu.com'
107
-      }
125
+    addSubMenu (item, index) {
108 126
       let data = {
109 127
         item,
110 128
         index
@@ -112,11 +130,6 @@ export default {
112 130
       this.AddSubMenu(data)
113 131
     },
114 132
     setSubMenu (item, index, parentIndex) {
115
-      item = {
116
-        'type': 'view',
117
-        'name': '百度',
118
-        'url': 'http://www.baidu.com'
119
-      }
120 133
       let data = {
121 134
         item,
122 135
         index,
@@ -181,6 +194,13 @@ export default {
181 194
       color: #fff;
182 195
     }
183 196
   }
197
+  .fade-enter-active,
198
+  .fade-leave-active {
199
+    transition: opacity 0.5s;
200
+  }
201
+  .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
202
+    opacity: 0;
203
+  }
184 204
 }
185 205
 </style>
186 206
 

+ 1
- 0
src/store/index.js View File

@@ -17,6 +17,7 @@ export const modules = {
17 17
   login: () => require('./login').default,
18 18
   main: () => require('./main').default,
19 19
   pageIndex: () => require('./pageIndex').default,
20
+  material: () => require('./material').default,
20 21
 }
21 22
 
22 23
 Object.keys(modules).forEach((modKey) => {

+ 109
- 0
src/store/material.js View File

@@ -0,0 +1,109 @@
1
+// import ajax from '../util/ajax'
2
+// import api from '../util/api'
3
+
4
+export default {
5
+  namespaced: true,
6
+  state: {
7
+    img: [],
8
+    view: []
9
+  },
10
+  mutations: {
11
+    updateImg (state, data) {
12
+      state.img = data || []
13
+    },
14
+    updateView (state, data) {
15
+      state.view = data || []
16
+    }
17
+  },
18
+  actions: {
19
+    getImg (context, data) {
20
+      // return new Promise((resolve, reject) => {
21
+      //   ajax({
22
+      //     ...api.common.login,
23
+      //     data: {
24
+      //       ...data,
25
+      //     }
26
+      //   }).then(res => {
27
+      //     context.commit('updateList', res)
28
+      //     resolve(res)
29
+      //   }).catch(reject)
30
+      // })
31
+      data = [
32
+        {
33
+          "type": "media_id",
34
+          "name": "图片",
35
+          "media_id": "MEDIA_ID1",
36
+          url: 'http://mmbiz.qpic.cn/mmbiz_jpg/PiajxSqBRaEIQxibpLbyuSK4TssiajqknJS6dACV5IoTxppdoyfGEYScCFMqV3dgFzf2tGqy2IiciaysTlaZt6zchibA/0?wx_fmt=jpeg'
37
+        },
38
+        {
39
+          "type": "media_id",
40
+          "name": "图片",
41
+          "media_id": "MEDIA_ID1",
42
+          url: 'http://mmbiz.qpic.cn/mmbiz_jpg/PiajxSqBRaEIQxibpLbyuSK4TssiajqknJS6dACV5IoTxppdoyfGEYScCFMqV3dgFzf2tGqy2IiciaysTlaZt6zchibA/0?wx_fmt=jpeg'
43
+        },
44
+        {
45
+          "type": "media_id",
46
+          "name": "图片",
47
+          "media_id": "MEDIA_ID1",
48
+          url: 'http://mmbiz.qpic.cn/mmbiz_jpg/PiajxSqBRaEIQxibpLbyuSK4TssiajqknJS6dACV5IoTxppdoyfGEYScCFMqV3dgFzf2tGqy2IiciaysTlaZt6zchibA/0?wx_fmt=jpeg'
49
+        },
50
+        {
51
+          "type": "media_id",
52
+          "name": "图片",
53
+          "media_id": "MEDIA_ID1",
54
+          url: 'http://mmbiz.qpic.cn/mmbiz_jpg/PiajxSqBRaEIQxibpLbyuSK4TssiajqknJS6dACV5IoTxppdoyfGEYScCFMqV3dgFzf2tGqy2IiciaysTlaZt6zchibA/0?wx_fmt=jpeg'
55
+        },
56
+        {
57
+          "type": "media_id",
58
+          "name": "图片",
59
+          "media_id": "MEDIA_ID1",
60
+          url: 'http://mmbiz.qpic.cn/mmbiz_jpg/PiajxSqBRaEIQxibpLbyuSK4TssiajqknJS6dACV5IoTxppdoyfGEYScCFMqV3dgFzf2tGqy2IiciaysTlaZt6zchibA/0?wx_fmt=jpeg'
61
+        },
62
+      ]
63
+      data.forEach((curr) => {
64
+        curr.checked = false
65
+      })
66
+      context.commit('updateImg', data)
67
+    },
68
+    getView (context, data) {
69
+      // return new Promise((resolve, reject) => {
70
+      //   ajax({
71
+      //     ...api.common.login,
72
+      //     data: {
73
+      //       ...data,
74
+      //     }
75
+      //   }).then(res => {
76
+      //     context.commit('updateList', res)
77
+      //     resolve(res)
78
+      //   }).catch(reject)
79
+      // })
80
+      data = [
81
+        {
82
+          "type": "media_id",
83
+          "name": "图片",
84
+          "media_id": "MEDIA_ID1",
85
+          text: "1",
86
+          url: 'http://mmbiz.qpic.cn/mmbiz_jpg/PiajxSqBRaEIQxibpLbyuSK4TssiajqknJS6dACV5IoTxppdoyfGEYScCFMqV3dgFzf2tGqy2IiciaysTlaZt6zchibA/0?wx_fmt=jpeg'
87
+        },
88
+        {
89
+          "type": "media_id",
90
+          "name": "图片",
91
+          "media_id": "MEDIA_ID1",
92
+          text: "2",
93
+          url: 'http://mmbiz.qpic.cn/mmbiz_jpg/PiajxSqBRaEIQxibpLbyuSK4TssiajqknJS6dACV5IoTxppdoyfGEYScCFMqV3dgFzf2tGqy2IiciaysTlaZt6zchibA/0?wx_fmt=jpeg'
94
+        },
95
+        {
96
+          "type": "media_id",
97
+          "name": "图片",
98
+          "media_id": "MEDIA_ID1",
99
+          text: "3dhkshfhdskjfhjkshdfhdshkjfhshdfihsifjsdnvkhsihfioshifhisohfshi",
100
+          url: 'http://mmbiz.qpic.cn/mmbiz_jpg/PiajxSqBRaEIQxibpLbyuSK4TssiajqknJS6dACV5IoTxppdoyfGEYScCFMqV3dgFzf2tGqy2IiciaysTlaZt6zchibA/0?wx_fmt=jpeg'
101
+        },
102
+      ]
103
+      data.forEach((curr) => {
104
+        curr.checked = false
105
+      })
106
+      context.commit('updateView', data)
107
+    }
108
+  }
109
+}