Sfoglia il codice sorgente

会员管理:编辑会员,单个会员设置标签,批量会员添加标签、删除,会员删除,会员设置会员卡

zhengchengwu 5 anni fa
parent
commit
b351059696

+ 2 - 10
index.html Vedi File

@@ -9,7 +9,7 @@
9 9
     <title>血透管理-酷医云</title>
10 10
   </head>
11 11
   <body>
12
-    <script src=<%= htmlWebpackPlugin.options.path %>/tinymce4.7.5/tinymce.min.js></script>
12
+    <script src="<%= htmlWebpackPlugin.options.path %>/tinymce4.7.5/tinymce.min.js"></script>
13 13
     <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
14 14
     <script src="<%= htmlWebpackPlugin.options.path %>/neditor/neditor.config.js"></script>
15 15
     <script src="<%= htmlWebpackPlugin.options.path %>/neditor/neditor.all.min.js"></script>
@@ -19,12 +19,4 @@
19 19
     <div id="app"></div>
20 20
     <!-- built files will be auto injected -->
21 21
   </body>
22
-</html>
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
->>>>>>> .theirs
22
+</html>

+ 58 - 1
src/api/member/member.js Vedi File

@@ -6,4 +6,61 @@ export function GetMembers(params) {
6 6
     method: 'get',
7 7
     params: params
8 8
   })
9
-}
9
+}
10
+
11
+export function CreateMember(data) {
12
+  return request({
13
+    url: '/api/member/create',
14
+    method: 'post',
15
+    data: data
16
+  })
17
+}
18
+
19
+export function EditMember(id, data) {
20
+  return request({
21
+    url: '/api/member/edit?id=' + id,
22
+    method: 'put',
23
+    data: data
24
+  })
25
+}
26
+
27
+export function EditMemberTags(id, data) {
28
+  return request({
29
+    url: '/api/member/tag/edit?id=' + id,
30
+    method: 'post',
31
+    data: data
32
+  })
33
+}
34
+
35
+export function AddMembersTags(data) {
36
+  return request({
37
+    url: '/api/members/tags/add',
38
+    method: 'post',
39
+    data: data
40
+  })
41
+}
42
+
43
+export function DeleteMembers(data) {
44
+  return request({
45
+    url: '/api/members/delete',
46
+    method: 'delete',
47
+    data: data
48
+  })
49
+}
50
+
51
+export function EditMemberCard(params) {
52
+  return request({
53
+    url: '/api/member/card/edit',
54
+    method: 'put',
55
+    params: params
56
+  })
57
+}
58
+
59
+export function GetTags() {
60
+  return request({
61
+    url: '/api/members/tags',
62
+    method: 'get',
63
+  })
64
+}
65
+
66
+

+ 7 - 1
src/router/modules/member.js Vedi File

@@ -13,10 +13,16 @@ export default {
13 13
   },
14 14
   children: [
15 15
     {
16
-      path: '/members',
16
+      path: '/member/members',
17 17
       component: () => import('@/scrm_pages/members/members'),
18 18
       name: 'memberslist',
19 19
       meta: { title: '会员管理', noCache: true }
20 20
     },
21
+    {
22
+      path: '/member/tags',
23
+      component: () => import('@/scrm_pages/members/tags'),
24
+      name: 'memberTaglist',
25
+      meta: { title: '标签管理', noCache: true }
26
+    },
21 27
   ]
22 28
 }

+ 128 - 0
src/scrm_pages/members/components/AddMembersTagsForm.vue Vedi File

@@ -0,0 +1,128 @@
1
+<template>
2
+    <div id="add-members-tags-form-box">
3
+        <el-dialog title="添加标签" :visible.sync="addMembersTagFormVisible" width="800px" >
4
+            <el-form ref="memberTagForm" :rules="tagsRules" :model="form" label-width="90px">
5
+                <el-row>
6
+                    <el-col :span="24">
7
+                        <el-form-item label="标签:"  prop="tags">
8
+                            <el-select
9
+                                v-model="form.tags"
10
+                                multiple
11
+                                style="width:100%"
12
+                                placeholder="请选择标签">
13
+                                <el-option
14
+                                v-for="item in tagOptions"
15
+                                :key="item.id"
16
+                                :label="item.tag_name"
17
+                                :value="item.id">
18
+                                </el-option>
19
+                            </el-select>
20
+                        </el-form-item>
21
+                    </el-col>
22
+                </el-row>
23
+            </el-form>
24
+            <div slot="footer" class="dialog-footer">
25
+                <el-button @click="addMembersTagFormVisible = false">取消</el-button>
26
+                <el-button
27
+                type="primary"
28
+                @click="submitForm('memberTagForm')"
29
+                >保 存
30
+                </el-button>
31
+            </div>
32
+        </el-dialog>  
33
+    </div>
34
+</template>
35
+
36
+<script>
37
+
38
+import {AddMembersTags} from "@/api/member/member";
39
+
40
+export default {
41
+    name:'AddMembersTagsForm',
42
+    props:{
43
+        tagOptions:{
44
+            type: Array,
45
+            default: function () {
46
+                return [];
47
+            }
48
+        },
49
+        form:{
50
+            tags:[],
51
+            ids:[],
52
+        },
53
+        membersData:{
54
+            type: Array,
55
+            default: function () {
56
+                return [];
57
+            }
58
+        },
59
+    },
60
+    data(){
61
+        return {
62
+            addMembersTagFormVisible:false,
63
+            
64
+            tagsRules: {
65
+                tags: [{required: true, message: "请选择标签",},],
66
+            },
67
+        }
68
+    },
69
+    methods:{
70
+        open:function(){
71
+            this.addMembersTagFormVisible = true;
72
+        },
73
+        resetForm(formName) {
74
+            if (typeof(this.$refs[formName]) !='undefined') {
75
+                this.$refs[formName].resetFields();
76
+            }
77
+        },
78
+        submitForm(formName){
79
+            this.$refs[formName].validate((valid) => {
80
+                if (valid) {
81
+                    AddMembersTags({ids:this.form.ids, tags:this.form.tags}).then(response=>{
82
+                        var res = response.data;
83
+                        if(res.state === 1) {
84
+                            var idsMap = {};
85
+                            for (const index in this.form.ids) {
86
+                                idsMap[this.form.ids[index]] = this.form.ids[index];
87
+                            }
88
+                            for (const memberIndex in this.membersData) {
89
+                                if (this.membersData[memberIndex].id in idsMap) {
90
+                                    var tagsMap = {};
91
+                                    for (const index in this.form.tags) {
92
+                                        tagsMap[this.form.tags[index]] = this.form.tags[index];
93
+                                    }
94
+                                    var tags = this.membersData[memberIndex].tags;
95
+                                    if (tags) {
96
+                                        for (const index in tags) {
97
+                                            if(tags[index].id in tagsMap) {
98
+                                                continue;
99
+                                            }
100
+                                            tagsMap[tags[index].id] = tags[index].id;
101
+                                        }
102
+                                    }
103
+                                    var memberTags = [];
104
+                                    for (const index in this.tagOptions) {
105
+                                        if(this.tagOptions[index].id in tagsMap) {
106
+                                            memberTags.push(this.tagOptions[index]);
107
+                                        }
108
+                                    }
109
+                                    this.$set(this.membersData[memberIndex], 'tags', memberTags);
110
+                                }
111
+                            }
112
+                            this.resetForm("memberTagForm");
113
+                            this.addMembersTagFormVisible = false;
114
+                            this.$message.success("编辑会员标签成功");
115
+                        }else {
116
+                            this.$message.error(res.msg);
117
+                        }
118
+                    }).catch(e=>{});
119
+
120
+                } else {
121
+                    return false;
122
+                }
123
+            });
124
+        },
125
+    }
126
+}
127
+</script>
128
+

+ 348 - 0
src/scrm_pages/members/components/CreateMemberForm.vue Vedi File

@@ -0,0 +1,348 @@
1
+<template>
2
+    <div id="create-member-form-box">
3
+        <el-dialog title="添加会员" :visible.sync="createMemberFormVisible" width="800px" >
4
+            <el-form ref="memberForm" :rules="memberRules" :model="form" label-width="90px">
5
+                <el-row>
6
+                    <el-col :span="12">
7
+                        <el-form-item label="姓名:" required prop="name">
8
+                        <el-input v-model="form.name"></el-input>
9
+                        </el-form-item>
10
+                    </el-col>
11
+                    <el-col :span="12">
12
+                        <el-form-item label="手机号:" required prop="mobile">
13
+                        <el-input v-model="form.mobile"></el-input>
14
+                        </el-form-item>
15
+                    </el-col>
16
+                </el-row>
17
+                <el-row>
18
+                    <el-col :span="12">
19
+                        <el-form-item label="性别:" required prop="gender">
20
+                            <el-radio-group v-model="form.gender" @change="selectGender">
21
+                                <el-radio :label="gender.id" :value="gender.id" v-for="(gender, index) in genderOptions" :key="index">{{gender.name}}</el-radio>
22
+                            </el-radio-group>
23
+                        </el-form-item>
24
+                    </el-col>
25
+                    <el-col :span="12">
26
+                        <el-form-item label="生日:" required prop="birthday">
27
+                            <el-date-picker v-model="form.birthday" prefix-icon="el-icon-date" :editable="false" style="width: 100%;" type="date" placeholder="请选择日期" align="right" format="yyyy-MM-dd" value-format="yyyy-MM-dd" ></el-date-picker>
28
+                        </el-form-item>
29
+                    </el-col>
30
+                </el-row>
31
+                <el-row>
32
+                    <el-col :span="12">
33
+                        <el-form-item label="城市:" required prop="city">
34
+                            <el-cascader
35
+                                v-model="form.city"
36
+                                :options="cityOptions"
37
+                                @active-item-change="handleChangeCity"
38
+                                @change="handleSelectedCity"
39
+                                style="width: 100%;" 
40
+                                :props="{
41
+                                    value: 'id',
42
+                                    label: 'name',
43
+                                    children: 'cities'
44
+                                }"
45
+                            ></el-cascader>
46
+                        </el-form-item>
47
+                    </el-col>
48
+                    <el-col :span="12">
49
+                        <el-form-item label="病种:" required prop="illness">
50
+                            <el-select
51
+                                v-model="form.illness"
52
+                                multiple
53
+                                collapse-tags
54
+                                style="width:100%"
55
+                                placeholder="请选择病种">
56
+                                <el-option
57
+                                v-for="item in illnessOptions"
58
+                                :key="item.id"
59
+                                :label="item.illness_name"
60
+                                :value="item.id">
61
+                                </el-option>
62
+                            </el-select>
63
+                        </el-form-item>
64
+                    </el-col>
65
+                </el-row>
66
+                <el-row>
67
+                    <el-col :span="12">
68
+                        <el-form-item label="患病时间:" required prop="ill_date">
69
+                            <el-date-picker v-model="form.ill_date" prefix-icon="el-icon-date" :editable="false" style="width: 100%;" type="date" placeholder="请选择日期" align="right" format="yyyy-MM-dd" value-format="yyyy-MM-dd" ></el-date-picker>
70
+                        </el-form-item>
71
+                    </el-col>
72
+                    <el-col :span="12">
73
+                        <el-form-item label="治疗方式:" required prop="treat_type">
74
+                            <el-select
75
+                                v-model="form.treat_type"
76
+                                style="width:100%"
77
+                                placeholder="请选择治疗方式">
78
+                                <el-option
79
+                                v-for="item in treatTypeOptions"
80
+                                :key="item.id"
81
+                                :label="item.name"
82
+                                :value="item.id">
83
+                                </el-option>
84
+                            </el-select>
85
+                        </el-form-item>
86
+                    </el-col>
87
+                </el-row>
88
+                <el-row>
89
+                    <el-col :span="24">
90
+                        <el-form-item label="标签:"  prop="tags">
91
+                            <el-select
92
+                                v-model="form.tags"
93
+                                multiple
94
+                                style="width:100%"
95
+                                placeholder="请选择标签">
96
+                                <el-option
97
+                                v-for="item in tagOptions"
98
+                                :key="item.id"
99
+                                :label="item.tag_name"
100
+                                :value="item.id">
101
+                                </el-option>
102
+                            </el-select>
103
+                        </el-form-item>
104
+                    </el-col>
105
+                </el-row>
106
+                <el-row>
107
+                    <el-col :span="24">
108
+                        <el-form-item label="备注:"  prop="remark">
109
+                            <el-input type="textarea" :rows="2" placeholder="请输入备注" v-model="form.remark">
110
+                            </el-input>
111
+                        </el-form-item>
112
+                    </el-col>
113
+                </el-row>
114
+            </el-form>
115
+            <div slot="footer" class="dialog-footer">
116
+                <el-button @click="createMemberFormVisible = false">取消</el-button>
117
+                <el-button
118
+                type="primary"
119
+                @click="submitForm('memberForm')"
120
+                >保 存
121
+                </el-button>
122
+            </div>
123
+        </el-dialog>  
124
+    </div>
125
+</template>
126
+
127
+<script>
128
+import {GetDistrictsByUpid} from  "@/api/district";
129
+import {checkMobile} from "@/utils/tools";
130
+import {CreateMember} from "@/api/member/member";
131
+
132
+export default {
133
+    name:'CreateMemberForm',
134
+    props:{
135
+        illnessOptions:{
136
+            type: Array,
137
+            default: function () {
138
+                return [];
139
+            }
140
+        },
141
+        treatTypeOptions:{
142
+            type: Object,
143
+            default: function () {
144
+                return {};
145
+            }
146
+        },
147
+        tagOptions:{
148
+            type: Array,
149
+            default: function () {
150
+                return [];
151
+            }
152
+        },
153
+        levelCards:{
154
+            type: Array,
155
+            default: function () {
156
+                return [];
157
+            }
158
+        },
159
+        membersData:{
160
+            type: Array,
161
+            default: function () {
162
+                return [];
163
+            }
164
+        },
165
+    },
166
+    data(){
167
+        var checkMobileRule = (rule, value, callback) => {
168
+            if (!checkMobile(value)) {
169
+                callback(new Error('请填写正确的手机号'));
170
+            }else {
171
+               callback(); 
172
+            }
173
+        };
174
+        return {
175
+            createMemberFormVisible:false,
176
+            
177
+            memberRules: {
178
+                name: [{required: true, message: "请填写姓名",},],
179
+                mobile: [{required: true, message: "请填写手机号",},{ validator: checkMobileRule}],
180
+                gender: [{required: true, message: "请选择性别",},],
181
+                birthday: [{required: true, message: "请选择生日",},],
182
+                city: [{required: true, message: "请选择城市",},],
183
+                illness: [{required: true, message: "请选择病种",},],
184
+                ill_date: [{required: true, message: "请选择患病时间",},],
185
+                treat_type: [{required: true, message: "请选择治疗方式",},],
186
+                
187
+            },
188
+            genderOptions:[
189
+                {id:1, name:'男'},
190
+                {id:2, name:'女'},
191
+            ],
192
+            cityOptions:[],
193
+            form:{
194
+                name:'',
195
+                mobile:'',
196
+                gender:0,
197
+                birthday:'',
198
+                city:[],
199
+                province_id:0,
200
+                city_id:0,
201
+                district_id:0,
202
+                illness:[],
203
+                ill_date:'',
204
+                treat_type:'',
205
+                tags:[],
206
+                remark:'',
207
+                card:null,
208
+                avatar:'',
209
+            },
210
+            
211
+        }
212
+    },
213
+    methods:{
214
+        open:function(){
215
+            this.GetDistrictsByUpid();
216
+            this.resetForm("memberForm");
217
+            this.createMemberFormVisible = true;
218
+        },
219
+        resetForm(formName) {
220
+            if (typeof(this.$refs[formName]) !='undefined') {
221
+                this.$refs[formName].resetFields();
222
+            }
223
+        },
224
+        submitForm(formName){
225
+            // if (this.levelCards.length>0) {
226
+            //     this.form.card = this.levelCards[0];
227
+            // }
228
+            this.$refs[formName].validate((valid) => {
229
+                if (valid) {
230
+                    CreateMember(this.form).then(response=>{
231
+                        var res = response.data;
232
+                        if(res.state === 1) {
233
+                            var member = res.data.member;
234
+                            if(member.user_tags) {
235
+                                member.tags = [];
236
+                                var userTagsMap = {};
237
+                                for (const index in member.user_tags) {
238
+                                    userTagsMap[member.user_tags[index].tag_id] = 1;
239
+                                }
240
+                                for (const index in this.tagOptions) {
241
+                                    if(this.tagOptions[index].id in userTagsMap) {
242
+                                        member.tags.push(this.tagOptions[index]);
243
+                                    }
244
+                                }
245
+                            }
246
+                            this.membersData.unshift(member);
247
+                            this.resetForm("memberForm");
248
+                            this.createMemberFormVisible = false;
249
+                            this.$message.success("添加会员成功");
250
+                        }else {
251
+                            this.$message.error(res.msg);
252
+                        }
253
+                    }).catch(e=>{});
254
+
255
+                } else {
256
+                    return false;
257
+                }
258
+            });
259
+        },
260
+        selectGender:function(gender) {
261
+            if(gender == 2) {
262
+                this.form.avatar = 'https://images.shengws.com/201809182128222.png';
263
+            }else {
264
+                this.form.avatar = 'https://images.shengws.com/201809182128111.png';
265
+            }
266
+        },
267
+        handleChangeCity:function(val) {
268
+            this.GetDistrictsByUpid(val);
269
+        },
270
+        handleSelectedCity:function(val) {
271
+            this.form.province_id = val[0];
272
+            this.form.city_id = val[1];
273
+            this.form.district_id = val[2];
274
+        },
275
+        GetDistrictsByUpid:function(val) {  
276
+            let idArea
277
+            let sizeArea
278
+            if (!val) {
279
+                idArea = 0
280
+                sizeArea = 0
281
+            } else if (val.length === 1) {
282
+                idArea = val[0]
283
+                sizeArea = val.length // 3:一级 4:二级 6:三级
284
+            } else if (val.length === 2) {
285
+                idArea = val[1]
286
+                sizeArea = val.length // 3:一级 4:二级 6:三级
287
+            }
288
+            
289
+            GetDistrictsByUpid({id:idArea}).then(response=>{
290
+                var res = response.data;
291
+                if (res.state===1) {
292
+                    var citys = res.data.citys;
293
+                    if (sizeArea === 0) { // 初始化 加载一级 省
294
+                        this.cityOptions = citys.map((value, i) => {
295
+                            return {
296
+                                id: value.id,
297
+                                name: value.name,
298
+                                cities: []
299
+                            }
300
+                        })
301
+                    } else if (sizeArea === 1) { // 点击一级 加载二级 市
302
+                        this.cityOptions.map((value, i) => {
303
+                            if (value.id === val[0]) {
304
+                                if (!value.cities.length) {
305
+                                    value.cities = citys.map((value, i) => {
306
+                                        return {
307
+                                            id: value.id,
308
+                                            name: value.name,
309
+                                            cities: []
310
+                                        }
311
+                                    })
312
+                                }
313
+                            }
314
+                        })
315
+                    } else if (sizeArea === 2) { // 点击二级 加载三级 区
316
+                        this.cityOptions.map((value, i) => {
317
+                            if (value.id === val[0]) {
318
+                                value.cities.map((value, i) => {
319
+                                    if (value.id === val[1]) {
320
+                                        if (!value.cities.length) {
321
+                                            if (citys.length) {
322
+                                                value.cities = citys.map((value, i) => {
323
+                                                    return {
324
+                                                        id: value.id,
325
+                                                        name: value.name
326
+                                                    }
327
+                                                })
328
+                                            }else {
329
+                                                value.cities = [
330
+                                                    {id:value.id, name:value.name}
331
+                                                ];
332
+                                            }
333
+                                            
334
+                                        }
335
+                                    }
336
+                                })
337
+                            }
338
+                        })
339
+                    }
340
+                }else {
341
+                    this.$message.error(res.msg);
342
+                }
343
+            }).catch(e=>{});
344
+        },
345
+    }
346
+}
347
+</script>
348
+

+ 130 - 0
src/scrm_pages/members/components/EditMemberCardForm.vue Vedi File

@@ -0,0 +1,130 @@
1
+<template>
2
+    <div id="edit-member-card-form-box">
3
+        <el-dialog title="会员卡设置" :visible.sync="editMemberCardFormVisible" width="700px" >
4
+            <el-form ref="memberCardForm"  :model="form" label-width="60px">
5
+                <el-row>
6
+                    <el-col :span="24">
7
+                        <el-form-item label="会员卡:"  prop="card_id">
8
+                            <el-select
9
+                                v-model="form.card_id"
10
+                                style="width:100%"
11
+                                placeholder="请选择会员卡">
12
+                                 <el-option-group label="无卡">
13
+                                    <el-option
14
+                                        label="普通会员"
15
+                                        value="">
16
+                                    </el-option>
17
+                                </el-option-group>
18
+                                <el-option-group label="选择会员卡">
19
+                                    <el-option
20
+                                        v-for="item in cardOptions"
21
+                                        :key="item.id"
22
+                                        :label="item.card_name"
23
+                                        :value="item.id">
24
+                                    </el-option>
25
+                                </el-option-group>
26
+                            </el-select>
27
+                        </el-form-item>
28
+                    </el-col>
29
+                </el-row>
30
+            </el-form>
31
+            <div slot="footer" class="dialog-footer">
32
+                <el-button @click="editMemberCardFormVisible = false">取消</el-button>
33
+                <el-button
34
+                type="primary"
35
+                @click="submitForm('memberCardForm')"
36
+                >保 存
37
+                </el-button>
38
+            </div>
39
+        </el-dialog>  
40
+    </div>
41
+</template>
42
+
43
+<script>
44
+import {GetDistrictsByUpid} from  "@/api/district";
45
+import {checkMobile} from "@/utils/tools";
46
+import {EditMemberCard} from "@/api/member/member";
47
+
48
+export default {
49
+    name:'EditMemberCardForm',
50
+    props:{
51
+        cardOptions:{
52
+            type: Array,
53
+            default: function () {
54
+                return [];
55
+            }
56
+        },
57
+        memberIndex:{
58
+            type:Number,
59
+            default:-1,
60
+        },
61
+        form:{
62
+            id:0,
63
+            card_id:'',
64
+        },
65
+        membersData:{
66
+            type: Array,
67
+            default: function () {
68
+                return [];
69
+            }
70
+        },
71
+    },
72
+    data(){
73
+        return {
74
+            editMemberCardFormVisible:false,
75
+            cardMap: {},
76
+            oldCardId:0,
77
+        }
78
+    },
79
+    methods:{
80
+        open:function(){
81
+            this.oldCardId = this.form.card_id;
82
+            for (const index in this.cardOptions) {
83
+                this.cardMap[this.cardOptions[index].id] = this.cardOptions[index];
84
+            }
85
+            this.editMemberCardFormVisible = true;
86
+        },
87
+        resetForm(formName) {
88
+            if (typeof(this.$refs[formName]) !='undefined') {
89
+                this.$refs[formName].resetFields();
90
+            }
91
+        },
92
+        submitForm(formName){
93
+            this.$refs[formName].validate((valid) => {
94
+                if (valid) {
95
+                    if (this.oldCardId == this.form.card_id) {
96
+                        this.$message.success("会员卡未变化");
97
+                        this.editMemberCardFormVisible = false;
98
+                        return false;
99
+                    }
100
+                    var card_id = parseInt(this.form.card_id);
101
+                    if (isNaN(card_id) || card_id <0) {
102
+                        card_id = 0;
103
+                    }
104
+                    var form = {id:this.form.id, card_id:card_id};
105
+                    EditMemberCard(form).then(response=>{
106
+                        var res = response.data;
107
+                        if(res.state === 1) {
108
+                            var user_card = res.data.user_card;
109
+                            if (user_card) {
110
+                                user_card["card"] = this.cardMap[card_id];
111
+                            }
112
+                            // this.membersData[this.memberIndex].user_card = user_card; 
113
+                            this.$set(this.membersData[this.memberIndex], 'user_card', user_card);
114
+                            this.resetForm("memberCardForm");
115
+                            this.editMemberCardFormVisible = false;
116
+                            this.$message.success("会员卡设置成功");
117
+                        }else {
118
+                            this.$message.error(res.msg);
119
+                        }
120
+                    }).catch(e=>{});
121
+
122
+                } else {
123
+                    return false;
124
+                }
125
+            });
126
+        },
127
+    }
128
+}
129
+</script>
130
+

+ 351 - 0
src/scrm_pages/members/components/EditMemberForm.vue Vedi File

@@ -0,0 +1,351 @@
1
+<template>
2
+    <div id="edit-member-form-box">
3
+        <el-dialog title="编辑会员" :visible.sync="editMemberFormVisible" width="800px" >
4
+            <el-form ref="memberForm" :rules="memberRules" :model="form" label-width="90px">
5
+                <el-row>
6
+                    <el-col :span="12">
7
+                        <el-form-item label="姓名:" required prop="name">
8
+                        <el-input v-model="form.name"></el-input>
9
+                        </el-form-item>
10
+                    </el-col>
11
+                    <el-col :span="12">
12
+                        <el-form-item label="手机号:" required prop="mobile">
13
+                        <el-input v-model="form.mobile"></el-input>
14
+                        </el-form-item>
15
+                    </el-col>
16
+                </el-row>
17
+                <el-row>
18
+                    <el-col :span="12">
19
+                        <el-form-item label="性别:" required prop="gender">
20
+                            <el-radio-group v-model="form.gender" @change="selectGender">
21
+                                <el-radio :label="gender.id" :value="gender.id" v-for="(gender, index) in genderOptions" :key="index">{{gender.name}}</el-radio>
22
+                            </el-radio-group>
23
+                        </el-form-item>
24
+                    </el-col>
25
+                    <el-col :span="12">
26
+                        <el-form-item label="生日:" required prop="birthday">
27
+                            <el-date-picker v-model="form.birthday" prefix-icon="el-icon-date" :editable="false" style="width: 100%;" type="date" placeholder="请选择日期" align="right" format="yyyy-MM-dd" value-format="yyyy-MM-dd" ></el-date-picker>
28
+                        </el-form-item>
29
+                    </el-col>
30
+                </el-row>
31
+                <el-row>
32
+                    <el-col :span="12">
33
+                        <el-form-item label="城市:" required prop="city">
34
+                            <el-cascader
35
+                                v-model="form.city"
36
+                                :options="cityOptions"
37
+                                @active-item-change="handleChangeCity"
38
+                                @change="handleSelectedCity"
39
+                                style="width: 100%;" 
40
+                                :props="{
41
+                                    value: 'id',
42
+                                    label: 'name',
43
+                                    children: 'cities'
44
+                                }"
45
+                            ></el-cascader>
46
+                        </el-form-item>
47
+                    </el-col>
48
+                    <el-col :span="12">
49
+                        <el-form-item label="病种:" required prop="illness">
50
+                            <el-select
51
+                                v-model="form.illness"
52
+                                multiple
53
+                                collapse-tags
54
+                                style="width:100%"
55
+                                placeholder="请选择病种">
56
+                                <el-option
57
+                                v-for="item in illnessOptions"
58
+                                :key="item.id"
59
+                                :label="item.illness_name"
60
+                                :value="item.id">
61
+                                </el-option>
62
+                            </el-select>
63
+                        </el-form-item>
64
+                    </el-col>
65
+                </el-row>
66
+                <el-row>
67
+                    <el-col :span="12">
68
+                        <el-form-item label="患病时间:" required prop="ill_date">
69
+                            <el-date-picker v-model="form.ill_date" prefix-icon="el-icon-date" :editable="false" style="width: 100%;" type="date" placeholder="请选择日期" align="right" format="yyyy-MM-dd" value-format="yyyy-MM-dd" ></el-date-picker>
70
+                        </el-form-item>
71
+                    </el-col>
72
+                    <el-col :span="12">
73
+                        <el-form-item label="治疗方式:" required prop="treat_type">
74
+                            <el-select
75
+                                v-model="form.treat_type"
76
+                                style="width:100%"
77
+                                placeholder="请选择治疗方式">
78
+                                <el-option
79
+                                v-for="item in treatTypeOptions"
80
+                                :key="item.id"
81
+                                :label="item.name"
82
+                                :value="item.id">
83
+                                </el-option>
84
+                            </el-select>
85
+                        </el-form-item>
86
+                    </el-col>
87
+                </el-row>
88
+                <el-row>
89
+                    <el-col :span="24">
90
+                        <el-form-item label="备注:"  prop="remark">
91
+                            <el-input type="textarea" :rows="2" placeholder="请输入备注" v-model="form.remark">
92
+                            </el-input>
93
+                        </el-form-item>
94
+                    </el-col>
95
+                </el-row>
96
+            </el-form>
97
+            <div slot="footer" class="dialog-footer">
98
+                <el-button @click="editMemberFormVisible = false">取消</el-button>
99
+                <el-button
100
+                type="primary"
101
+                @click="submitForm('memberForm')"
102
+                >保 存
103
+                </el-button>
104
+            </div>
105
+        </el-dialog>  
106
+    </div>
107
+</template>
108
+
109
+<script>
110
+import {GetDistrictsByUpid} from  "@/api/district";
111
+import {checkMobile, uParseTime} from "@/utils/tools";
112
+import {EditMember} from "@/api/member/member";
113
+
114
+export default {
115
+    name:'EditMemberForm',
116
+    props:{
117
+        illnessOptions:{
118
+            type: Array,
119
+            default: function () {
120
+                return [];
121
+            }
122
+        },
123
+        treatTypeOptions:{
124
+            type: Object,
125
+            default: function () {
126
+                return {};
127
+            }
128
+        },
129
+        levelCards:{
130
+            type: Array,
131
+            default: function () {
132
+                return [];
133
+            }
134
+        },
135
+        membersData:{
136
+            type: Array,
137
+            default: function () {
138
+                return [];
139
+            }
140
+        },
141
+        form:{
142
+            name:'',
143
+            mobile:'',
144
+            gender:0,
145
+            birthday:'',
146
+            city:[],
147
+            province_id:0,
148
+            city_id:0,
149
+            district_id:0,
150
+            illness:[],
151
+            ill_date:'',
152
+            treat_type:'',
153
+            tags:[],
154
+            remark:'',
155
+            avatar:'',
156
+            id:0,
157
+        },
158
+        memberIndex:{
159
+            type:Number,
160
+            default:-1,
161
+        },
162
+    },
163
+    data(){
164
+        var checkMobileRule = (rule, value, callback) => {
165
+            if (!checkMobile(value)) {
166
+                callback(new Error('请填写正确的手机号'));
167
+            }else {
168
+               callback(); 
169
+            }
170
+        };
171
+        return {
172
+            editMemberFormVisible:false,
173
+            
174
+            memberRules: {
175
+                name: [{required: true, message: "请填写姓名",},],
176
+                mobile: [{required: true, message: "请填写手机号",},{ validator: checkMobileRule}],
177
+                gender: [{required: true, message: "请选择性别",},],
178
+                birthday: [{required: true, message: "请选择生日",},],
179
+                city: [{required: true, message: "请选择城市",},],
180
+                illness: [{required: true, message: "请选择病种",},],
181
+                ill_date: [{required: true, message: "请选择患病时间",},],
182
+                treat_type: [{required: true, message: "请选择治疗方式",},],
183
+                
184
+            },
185
+            genderOptions:[
186
+                {id:1, name:'男'},
187
+                {id:2, name:'女'},
188
+            ],
189
+            cityOptions:[],
190
+            illnessMap:{},
191
+        }
192
+    },
193
+    methods:{
194
+        open:function(){
195
+            let city = [];
196
+            this.GetDistrictsByUpid();
197
+            if (this.form.province_id>0) {
198
+                city.push(this.form.province_id);
199
+                this.GetDistrictsByUpid(city);
200
+            }
201
+            if (this.form.province_id>0 && this.form.city_id>0) {
202
+                city.push(this.form.city_id);
203
+                this.GetDistrictsByUpid(city);
204
+            }
205
+            this.form.birthday = this.form.birthday?this.form.birthday:'';
206
+            this.form.ill_date = this.form.ill_date?this.form.ill_date:'';
207
+            this.form.treat_type = this.form.treat_type?this.form.treat_type:'';
208
+            this.form.gender = this.form.gender?this.form.gender:'';
209
+            for (const index in this.illnessOptions) {
210
+                this.illnessMap[this.illnessOptions[index].id] = 1;
211
+            }
212
+            var illness = this.form.illness;
213
+            this.form.illness = [];
214
+            for (const index in illness) {
215
+                if (illness[index] in this.illnessMap) {
216
+                    this.form.illness.push(illness[index]);
217
+                }
218
+            }
219
+
220
+            this.editMemberFormVisible = true;
221
+        },
222
+        resetForm(formName) {
223
+            if (typeof(this.$refs[formName]) !='undefined') {
224
+                this.$refs[formName].resetFields();
225
+            }
226
+        },
227
+        submitForm(formName){
228
+            // if (this.levelCards.length>0) {
229
+            //     this.form.card = this.levelCards[0];
230
+            // }
231
+            this.$refs[formName].validate((valid) => {
232
+                if (valid) {
233
+                    EditMember(this.form.id, this.form).then(response=>{
234
+                        var res = response.data;
235
+                        if(res.state === 1) {
236
+                            var member = res.data.member;
237
+                            this.membersData[this.memberIndex].name = member.name;
238
+                            this.membersData[this.memberIndex].avatar = member.avatar;
239
+                            this.membersData[this.memberIndex].mobile = member.mobile;
240
+                            this.membersData[this.memberIndex].gender = member.gender;
241
+                            this.membersData[this.memberIndex].birthday = member.birthday;
242
+                            this.membersData[this.memberIndex].province_id = member.province_id;
243
+                            this.membersData[this.memberIndex].city_id = member.city_id;
244
+                            this.membersData[this.memberIndex].district_id = member.district_id;
245
+                            this.$set(this.membersData[this.memberIndex],'illness', member.illness);
246
+                            this.membersData[this.memberIndex].ill_date = member.ill_date;
247
+                            this.membersData[this.memberIndex].treat_type = member.treat_type;
248
+                            this.membersData[this.memberIndex].remark = member.remark;
249
+                            this.membersData[this.memberIndex].updated_time = member.updated_time;
250
+                            // this.resetForm("memberForm");
251
+                            this.editMemberFormVisible = false;
252
+                            this.$message.success("编辑会员成功");
253
+                        }else {
254
+                            this.$message.error(res.msg);
255
+                        }
256
+                    }).catch(e=>{});
257
+
258
+                } else {
259
+                    return false;
260
+                }
261
+            });
262
+        },
263
+        selectGender:function(gender) {
264
+            if(gender == 2) {
265
+                this.form.avatar = 'https://images.shengws.com/201809182128222.png';
266
+            }else {
267
+                this.form.avatar = 'https://images.shengws.com/201809182128111.png';
268
+            }
269
+        },
270
+        handleChangeCity:function(val) {
271
+            this.GetDistrictsByUpid(val);
272
+        },
273
+        handleSelectedCity:function(val) {
274
+            this.form.province_id = val[0];
275
+            this.form.city_id = val[1];
276
+            this.form.district_id = val[2];
277
+        },
278
+        GetDistrictsByUpid:function(val) {  
279
+            let idArea
280
+            let sizeArea
281
+            if (!val) {
282
+                idArea = 0
283
+                sizeArea = 0
284
+            } else if (val.length === 1) {
285
+                idArea = val[0]
286
+                sizeArea = val.length // 3:一级 4:二级 6:三级
287
+            } else if (val.length === 2) {
288
+                idArea = val[1]
289
+                sizeArea = val.length // 3:一级 4:二级 6:三级
290
+            }
291
+            
292
+            GetDistrictsByUpid({id:idArea}).then(response=>{
293
+                var res = response.data;
294
+                if (res.state===1) {
295
+                    var citys = res.data.citys;
296
+                    if (sizeArea === 0) { // 初始化 加载一级 省
297
+                        this.cityOptions = citys.map((value, i) => {
298
+                            return {
299
+                                id: value.id,
300
+                                name: value.name,
301
+                                cities: []
302
+                            }
303
+                        })
304
+                    } else if (sizeArea === 1) { // 点击一级 加载二级 市
305
+                        this.cityOptions.map((value, i) => {
306
+                            if (value.id === val[0]) {
307
+                                if (!value.cities.length) {
308
+                                    value.cities = citys.map((value, i) => {
309
+                                        return {
310
+                                            id: value.id,
311
+                                            name: value.name,
312
+                                            cities: []
313
+                                        }
314
+                                    })
315
+                                }
316
+                            }
317
+                        })
318
+                    } else if (sizeArea === 2) { // 点击二级 加载三级 区
319
+                        this.cityOptions.map((value, i) => {
320
+                            if (value.id === val[0]) {
321
+                                value.cities.map((value, i) => {
322
+                                    if (value.id === val[1]) {
323
+                                        if (!value.cities.length) {
324
+                                            if (citys.length) {
325
+                                                value.cities = citys.map((value, i) => {
326
+                                                    return {
327
+                                                        id: value.id,
328
+                                                        name: value.name
329
+                                                    }
330
+                                                })
331
+                                            }else {
332
+                                                value.cities = [
333
+                                                    {id:value.id, name:value.name}
334
+                                                ];
335
+                                            }
336
+                                            
337
+                                        }
338
+                                    }
339
+                                })
340
+                            }
341
+                        })
342
+                    }
343
+                }else {
344
+                    this.$message.error(res.msg);
345
+                }
346
+            }).catch(e=>{});
347
+        },
348
+    }
349
+}
350
+</script>
351
+

+ 128 - 0
src/scrm_pages/members/components/EditMemberTagsForm.vue Vedi File

@@ -0,0 +1,128 @@
1
+<template>
2
+    <div id="edit-member-tags-form-box">
3
+        <el-dialog title="编辑标签" :visible.sync="editMemberTagFormVisible" width="800px" >
4
+            <el-form ref="memberTagForm"  :model="form" label-width="90px">
5
+                <el-row>
6
+                    <el-col :span="24">
7
+                        <el-form-item label="标签:"  prop="tags">
8
+                            <el-select
9
+                                v-model="form.tags"
10
+                                multiple
11
+                                style="width:100%"
12
+                                placeholder="请选择标签">
13
+                                <el-option
14
+                                v-for="item in tagOptions"
15
+                                :key="item.id"
16
+                                :label="item.tag_name"
17
+                                :value="item.id">
18
+                                </el-option>
19
+                            </el-select>
20
+                        </el-form-item>
21
+                    </el-col>
22
+                </el-row>
23
+            </el-form>
24
+            <div slot="footer" class="dialog-footer">
25
+                <el-button @click="editMemberTagFormVisible = false">取消</el-button>
26
+                <el-button
27
+                type="primary"
28
+                @click="submitForm('memberTagForm')"
29
+                >保 存
30
+                </el-button>
31
+            </div>
32
+        </el-dialog>  
33
+    </div>
34
+</template>
35
+
36
+<script>
37
+import {GetDistrictsByUpid} from  "@/api/district";
38
+import {checkMobile} from "@/utils/tools";
39
+import {EditMemberTags} from "@/api/member/member";
40
+
41
+export default {
42
+    name:'EditMberTagForm',
43
+    props:{
44
+        tagOptions:{
45
+            type: Array,
46
+            default: function () {
47
+                return [];
48
+            }
49
+        },
50
+        memberIndex:{
51
+            type:Number,
52
+            default:-1,
53
+        },
54
+        form:{
55
+            name:'',
56
+            mobile:'',
57
+            gender:0,
58
+            birthday:'',
59
+            city:[],
60
+            province_id:0,
61
+            city_id:0,
62
+            district_id:0,
63
+            illness:[],
64
+            ill_date:'',
65
+            treat_type:'',
66
+            tags:[],
67
+            remark:'',
68
+            avatar:'',
69
+            id:0,
70
+        },
71
+        membersData:{
72
+            type: Array,
73
+            default: function () {
74
+                return [];
75
+            }
76
+        },
77
+    },
78
+    data(){
79
+        return {
80
+            editMemberTagFormVisible:false,
81
+        }
82
+    },
83
+    methods:{
84
+        open:function(){
85
+            this.editMemberTagFormVisible = true;
86
+        },
87
+        resetForm(formName) {
88
+            if (typeof(this.$refs[formName]) !='undefined') {
89
+                this.$refs[formName].resetFields();
90
+            }
91
+        },
92
+        submitForm(formName){
93
+            this.$refs[formName].validate((valid) => {
94
+                if (valid) {
95
+                    EditMemberTags(this.form.id, {tags:this.form.tags}).then(response=>{
96
+                        var res = response.data;
97
+                        if(res.state === 1) {
98
+                            var tags = res.data.tags;
99
+                            var memberTags = [];
100
+                            if(tags) {
101
+                                var userTagsMap = {};
102
+                                for (const index in tags) {
103
+                                    userTagsMap[tags[index]] = 1;
104
+                                }
105
+                                for (const index in this.tagOptions) {
106
+                                    if(this.tagOptions[index].id in userTagsMap) {
107
+                                        memberTags.push(this.tagOptions[index]);
108
+                                    }
109
+                                }
110
+                            }
111
+                            this.$set(this.membersData[this.memberIndex], 'tags', memberTags);
112
+                            this.resetForm("memberTagForm");
113
+                            this.editMemberTagFormVisible = false;
114
+                            this.$message.success("编辑会员标签成功");
115
+                        }else {
116
+                            this.$message.error(res.msg);
117
+                        }
118
+                    }).catch(e=>{});
119
+
120
+                } else {
121
+                    return false;
122
+                }
123
+            });
124
+        },
125
+    }
126
+}
127
+</script>
128
+

+ 263 - 25
src/scrm_pages/members/members.vue Vedi File

@@ -2,7 +2,7 @@
2 2
   <div class="main-contain">
3 3
     <div class="position">
4 4
       <bread-crumb :crumbs='crumbs'></bread-crumb>
5
-      <el-button  style="float:right;" type="primary" size="small" icon="el-icon-circle-plus-outline">添加会员</el-button>
5
+      <el-button  style="float:right;" type="primary" size="small" icon="el-icon-circle-plus-outline" @click="openCreate">添加会员</el-button>
6 6
     </div>
7 7
     <div class="app-container">
8 8
           <div style="margin-bottom: 10px">
@@ -49,51 +49,62 @@
49 49
              </div>
50 50
           </div>
51 51
           <div class="filter-container" style="margin-top: 10px;margin-left: 5px">
52
-            <el-checkbox style="width: 30px"  >全选</el-checkbox>
53
-            <el-button size="small" icon="el-icon-delete" >删除</el-button>
54
-            <el-button size="small" icon="el-icon-delete" >删除</el-button>
52
+            <el-checkbox style="width: 30px"  @change="changeCheck" v-model="checkAllStatus">全选</el-checkbox>
53
+            <el-button size="small" icon="el-icon-delete" @click="openDeleteMembers">批量删除</el-button>
54
+            <el-button size="small" icon="el-icon-edit" @click="openAddMembersTags">添加标签</el-button>
55
+            <el-button size="small" icon="el-icon-message" @click="openSendMessage">发送短信</el-button>
55 56
           </div>
56
-          <el-table ref="multipleTable" :cell-class-name="cellStyleName" :header-cell-style="{ backgroundColor: 'rgb(245, 247, 250)'}" :data="membersData" border fit highlight-current-row  style="width: 100%;margin-top: 10px;">
57
+          <el-table ref="multipleTable"  @selection-change="handleSelectionChange" :cell-class-name="cellStyleName" :header-cell-style="{ backgroundColor: 'rgb(245, 247, 250)'}" :data="membersData" border fit highlight-current-row  style="width: 100%;margin-top: 10px;">
57 58
              <el-table-column
58 59
                 align="center"
59 60
                 type="selection"
60 61
                 width="55">
61 62
              </el-table-column>
62
-             <el-table-column label="会员" align="center">
63
+             <el-table-column label="会员" align="center" >
63 64
                <template slot-scope="scope">
64
-                   <img :src="memberAvatar(scope.row)" alt="" srcset="" style="width:50px;height:50px; border-radius:50%" >
65
-                   <span>{{scope.row.name}}</span>
65
+                 <div style="display:flex;align-items: center;">
66
+                   <img :src="memberAvatar(scope.row)" alt="" srcset="" style="width:50px;height:50px; border-radius:50%;margin-right:5px;" >
67
+                    <div>
68
+                     <span>{{scope.row.name}}</span>
69
+                    </div>
70
+                 </div>
66 71
                </template>
67 72
              </el-table-column>
68
-            <el-table-column label="文章标题" align="center">
73
+            <el-table-column label="等级" align="center">
69 74
               <template slot-scope="scope">
70
-
75
+                <img v-if="scope.row.user_card && scope.row.user_card.card" :src="vip" alt="" srcset="" style="width:16px;height:16px;margin-bottom: -2px;" >
76
+                <span>{{memberLevel(scope.row)}}</span>
71 77
               </template>
72 78
             </el-table-column>
73
-            <el-table-column label="阅读量" align="center">
79
+            <el-table-column label="标签" align="center">
74 80
               <template slot-scope="scope">
81
+                <el-tag size="small"  v-for="(tag, index) in scope.row.tags" :key="index">{{tag.tag_name}}</el-tag>
75 82
 
76 83
               </template>
77 84
             </el-table-column>
78
-            <el-table-column label="评论数" align="center">
85
+            <el-table-column label="创建时间" align="center">
79 86
               <template slot-scope="scope">
80
-
87
+                <span>{{memberCreateTime(scope.row.created_time)}}</span>
81 88
               </template>
82 89
             </el-table-column>
83
-            <el-table-column label="点赞数" align="center">
90
+            <el-table-column label="来源方式" align="center">
84 91
               <template slot-scope="scope">
85
-
92
+                <span>{{memberSource(scope.row.sources)}}</span>
86 93
               </template>
87 94
             </el-table-column>
88 95
             <el-table-column label="操作" align="center">
89 96
               <template slot-scope="scope">
90 97
                 <el-tooltip class="item" effect="dark" content="编辑" placement="top">
91
-                  <el-button
92
-                    size="mini"
93
-                    type="primary"
94
-                    icon="el-icon-edit-outline"
95
-                    >
96
-                  </el-button>
98
+                  <el-button size="mini" type="primary" icon="el-icon-edit-outline" @click="openEdit(scope.row, scope.$index)" ></el-button>
99
+                </el-tooltip>
100
+                <el-tooltip class="item" effect="dark" content="标签" placement="top">
101
+                  <el-button size="mini" type="warning" icon="el-icon-edit" @click="openTags(scope.row, scope.$index)" ></el-button>
102
+                </el-tooltip>
103
+                <el-tooltip class="item" effect="dark" content="会员卡" placement="top">
104
+                  <el-button size="mini" type="success" icon="el-icon-tickets" @click="openCard(scope.row, scope.$index)" ></el-button>
105
+                </el-tooltip>
106
+                <el-tooltip class="item" effect="dark" content="删除" placement="top">
107
+                  <el-button size="mini" type="danger" icon="el-icon-delete" @click="openDelete(scope.row, scope.$index)" ></el-button>
97 108
                 </el-tooltip>
98 109
               </template>
99 110
             </el-table-column>
@@ -104,21 +115,44 @@
104 115
             :page-sizes="[10,20,50,100]"
105 116
             :page-size="10"
106 117
             background
107
-            style="margin-top:20px;float: right"
118
+            style="margin-top:20px;"
119
+            align="right"
108 120
             layout="total, sizes, prev, pager, next, jumper"
109 121
             :total="total">
110 122
           </el-pagination>
123
+
124
+          <!--create-member-form 添加会员-->
125
+          <create-member-form ref="createMemberForm" :levelCards="levelCards" :membersData="membersData" :illnessOptions="illnessOptions" :treatTypeOptions="treatTypeOptions" :tagOptions="tagOptions"></create-member-form>
126
+          <!--edit-member-form 编辑会员-->
127
+          <edit-member-form ref="editMemberForm" :levelCards="levelCards" :memberIndex="memberIndex" :form="memberData" :membersData="membersData" :illnessOptions="illnessOptions" :treatTypeOptions="treatTypeOptions" :tagOptions="tagOptions"></edit-member-form>
128
+          <!--edit-member-tags-form 为单个会员编辑标签-->
129
+          <edit-member-tags-form ref="editMemberTagsForm" :memberIndex="memberIndex" :form="memberData" :membersData="membersData" :tagOptions="tagOptions"></edit-member-tags-form>
130
+          <!--add-members-tags-form 为所选会员添加标签-->
131
+          <add-members-tags-form ref="addMembersTagsForm" :form="memberData" :membersData="membersData" :tagOptions="tagOptions"></add-members-tags-form>
132
+          <!--edit-member-card-form 为单个会员设置会员卡-->
133
+          <edit-member-card-form ref="editMemberCardForm" :form="cardFormData" :memberIndex="memberIndex" :membersData="membersData" :cardOptions="levelCards"></edit-member-card-form>
111 134
     </div>
112 135
   </div>
113 136
 </template>
114 137
 
115 138
 <script>
116
-  import {GetMembers} from "@/api/member/member";
139
+  import {GetMembers,DeleteMembers} from "@/api/member/member";
117 140
   import BreadCrumb from '../components/bread-crumb'
141
+  import {uParseTime} from "@/utils/tools";
142
+  import CreateMemberForm from "./components/CreateMemberForm";
143
+  import EditMemberForm from "./components/EditMemberForm";
144
+  import EditMemberTagsForm from "./components/EditMemberTagsForm";
145
+  import AddMembersTagsForm from "./components/AddMembersTagsForm";
146
+  import EditMemberCardForm from "./components/EditMemberCardForm";
118 147
   export default {
119 148
     name: 'commentList',
120 149
     components:{
121
-      BreadCrumb
150
+      BreadCrumb,
151
+      CreateMemberForm,
152
+      EditMemberForm,
153
+      EditMemberTagsForm,
154
+      AddMembersTagsForm,
155
+      EditMemberCardForm,
122 156
     },
123 157
     data(){
124 158
       return{
@@ -127,14 +161,42 @@
127 161
           { path: false, name: '会员列表' }
128 162
         ],
129 163
         time: '',
164
+        vip:'https://images.shengws.com/member-ship-card-vip.png',
165
+        checkAllStatus:false,
130 166
         active: true,
131 167
         levelType: 0,
132 168
         levelCards:[],
133 169
         sourceType: 0,
134 170
         sourceOptions:{},
171
+        treatTypeOptions:{},
135 172
         tagType: 0,
136 173
         tagOptions:[],
137 174
         membersData:[],
175
+        illnessOptions:[],
176
+        memberData:{
177
+            name:'',
178
+            mobile:'',
179
+            gender:0,
180
+            birthday:'',
181
+            city:[],
182
+            province_id:0,
183
+            city_id:0,
184
+            district_id:0,
185
+            illness:[],
186
+            ill_date:'',
187
+            treat_type:'',
188
+            tags:[],
189
+            remark:'',
190
+            avatar:'',
191
+            id:0,
192
+            ids:[],
193
+        },
194
+        cardFormData:{
195
+            id:0,
196
+            card_id:''
197
+        },
198
+        selectedMembers:[],
199
+        memberIndex:-1,
138 200
         total:0,
139 201
         listQuery:{
140 202
             page:1,
@@ -162,12 +224,158 @@
162 224
                     if(typeof(res.data.tags) != 'undefined') {
163 225
                         this.tagOptions = res.data.tags;
164 226
                     }
227
+                    if(typeof(res.data.illness) != 'undefined') {
228
+                        this.illnessOptions = res.data.illness;
229
+                    }
165 230
                     this.listQuery.init = 0;
166 231
                 }else {
167 232
                     this.$message.error(res.msg);
168 233
                 }
169 234
             }).catch(e=>{});
170 235
         },
236
+        openSendMessage(){
237
+          
238
+          this.$message.error("功能开发中...");
239
+          return false;
240
+          if (this.selectedMembers.length==0) {
241
+            this.$message.error("请选择要发送短信的会员");
242
+            return false;
243
+          }
244
+          
245
+        },
246
+        openAddMembersTags() {
247
+          if (this.selectedMembers.length==0) {
248
+            this.$message.error("请选择要添加标签的会员");
249
+            return false;
250
+          }
251
+          
252
+          this.memberData.tags = [];
253
+          this.memberData.ids = [];
254
+          for (const index in this.selectedMembers) {
255
+            this.memberData.ids.push(this.selectedMembers[index].id);
256
+          }
257
+          this.$refs.addMembersTagsForm.open();
258
+        },
259
+        openDeleteMembers(){
260
+          if (this.selectedMembers.length==0) {
261
+            this.$message.error("请选择要删除的会员");
262
+            return false;
263
+          }
264
+
265
+          this.$confirm('确认要删除所选的会员吗?<br>删除后,会员信息将无法恢复', '删除提示', {
266
+            dangerouslyUseHTMLString:true,
267
+            confirmButtonText: '确定',
268
+            cancelButtonText: '取消',
269
+            type: 'warning'
270
+          }).then(() => {
271
+            var ids = [];
272
+            var idMap = {};
273
+            for (const index in this.selectedMembers) {
274
+              ids.push(this.selectedMembers[index].id);
275
+              idMap[this.selectedMembers[index].id] = this.selectedMembers[index].id;
276
+            }
277
+            DeleteMembers({ids:ids}).then(response=>{
278
+              var res = response.data;
279
+              if (res.state === 1) {
280
+                var membersDataLength = this.membersData.length;
281
+                for (let index = membersDataLength-1; index >= 0; index--) {
282
+                  if(this.membersData[index].id in idMap) {
283
+                    this.membersData.splice(index, 1);
284
+                  }                  
285
+                }
286
+                this.$message.success("删除会员成功");
287
+              }else {
288
+                this.$message.error(res.msg);
289
+              }
290
+            }).catch(e=>{});
291
+          }).catch(() => {
292
+            return false        
293
+          });
294
+
295
+        },
296
+        openDelete(row, index) {
297
+          this.$confirm('确认要删除该会员吗?<br>删除后,该会员信息将无法恢复', '删除提示', {
298
+            dangerouslyUseHTMLString:true,
299
+            confirmButtonText: '确定',
300
+            cancelButtonText: '取消',
301
+            type: 'warning'
302
+          }).then(() => {
303
+            var ids = [];
304
+            ids.push(row.id);
305
+            DeleteMembers({ids:ids}).then(response=>{
306
+              var res = response.data;
307
+              if (res.state === 1) {
308
+                this.membersData.splice(index, 1);
309
+                this.$message.success("删除会员成功");
310
+              }else {
311
+                this.$message.error(res.msg);
312
+              }
313
+            }).catch(e=>{});
314
+          }).catch(() => {
315
+            return false        
316
+          });
317
+        },
318
+        openCard(row, index){
319
+          this.cardFormData.id = row.id;
320
+          this.cardFormData.card_id = '';
321
+          this.memberIndex = index;
322
+          if (row.user_card && row.user_card.card) {
323
+            this.cardFormData.card_id = row.user_card.card_id;
324
+          }
325
+          this.$refs.editMemberCardForm.open();
326
+        },
327
+        openTags(row, index) {
328
+          this.memberData.tags = [];
329
+          this.memberData.id = row.id;
330
+          let tags = row.tags;
331
+          for (const index in tags) {
332
+              this.memberData.tags.push(tags[index].id);
333
+          }
334
+          
335
+          this.memberIndex = index;
336
+          this.$refs.editMemberTagsForm.open();
337
+        },
338
+        openEdit(row, index){
339
+          this.memberData.illness = [];
340
+          this.memberData.city = [];
341
+          this.memberData.birthday = '';
342
+          this.memberData.ill_date = '';
343
+          this.memberData.treat_type = '';
344
+          for (const key in this.memberData) {
345
+              if (key === "illness" && row.illness) {
346
+                  let illness = row.illness;
347
+                  for (const index in illness) {
348
+                      this.memberData.illness.push(illness[index].illness_id);
349
+                  }
350
+              } else if (key === "tags" && row.tags) {
351
+                  let tags = row.tags;
352
+                  for (const index in tags) {
353
+                      this.memberData.tags.push(tags[index].id);
354
+                  }
355
+              } else if (key === "treat_type" && row.treat_type>0) {
356
+                  this.memberData.treat_type = row.treat_type;
357
+              } else if (key === "city") {
358
+                if (row.province_id > 0) {
359
+                  this.memberData.city.push(row.province_id);
360
+                  this.memberData.city.push(row.city_id);
361
+                  this.memberData.city.push(row.district_id);
362
+                }
363
+              } else if (key === "birthday" && row.birthday!=0) {
364
+                  this.memberData.birthday = uParseTime(row.birthday, "{y}-{m}-{d}");
365
+              } else if (key === "ill_date" && row.ill_date!=0) {
366
+                  this.memberData.ill_date = uParseTime(row.ill_date, "{y}-{m}-{d}");
367
+              } else if (key in row) {
368
+                  this.memberData[key] = row[key];                  
369
+              }
370
+          }
371
+          
372
+          // this.memberData = row;
373
+          this.memberIndex = index;
374
+          this.$refs.editMemberForm.open();
375
+        },
376
+        openCreate(){
377
+          this.$refs.createMemberForm.open();
378
+        },
171 379
         memberAvatar(row) {
172 380
             if(typeof(row.avatar) == "undefined" || !row.avatar || row.avatar.length==0) {
173 381
                 if(row.gender == 2) {
@@ -179,6 +387,32 @@
179 387
                 return row.avatar
180 388
             }
181 389
         },
390
+        memberLevel(row) {
391
+          if(row.user_card && row.user_card.card) {
392
+            return row.user_card.card.card_name;
393
+          } else {
394
+            return '普通会员'
395
+          }
396
+        },
397
+        memberCreateTime(time) {
398
+          return uParseTime(time, "{y}-{m}-{d} {h}:{i}:{s}");
399
+        },
400
+        memberSource(source) {
401
+          if (source in this.sourceOptions) {
402
+            return this.sourceOptions[source].name;
403
+          }else {
404
+            return '--';
405
+          }
406
+        },
407
+        changeCheck(){
408
+          this.$refs.multipleTable.clearSelection();
409
+          if (this.checkAllStatus) {
410
+            this.$refs.multipleTable.toggleAllSelection();
411
+          }
412
+        },
413
+        handleSelectionChange(val){
414
+          this.selectedMembers = val;
415
+        },
182 416
         cellStyleName({row, column, rowIndex, columnIndex}){
183 417
             if (columnIndex===1) {
184 418
                 return 'member-name-box';
@@ -216,13 +450,17 @@
216 450
         }
217 451
     },
218 452
     created(){
219
-        this.sourceOptions = this.$store.getters.sources;
453
+        this.sourceOptions = this.$store.getters.members.sources;
454
+        this.treatTypeOptions = this.$store.getters.members.treat_type;
220 455
         this.GetMembers();
221 456
     }
222 457
   }
223 458
 </script>
224 459
 
225 460
 <style scoped>
461
+  .el-tag {
462
+    margin: 1px;
463
+  }
226 464
   /*.app-container .cell.clearfix .time ul li {*/
227 465
     /*float: left;*/
228 466
     /*list-style: none;*/

+ 126 - 0
src/scrm_pages/members/tags.vue Vedi File

@@ -0,0 +1,126 @@
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
+        <div style="margin-bottom: 10px">
9
+            <el-row :gutter="24">
10
+                <el-col :span="8">
11
+                    <el-input style="width: 300px" v-model="listQuery.search" placeholder="请输入您需要搜索的内容"></el-input>
12
+                    <el-button type="primary"  icon="el-icon-search" @click="changeKey">搜索</el-button>
13
+                </el-col>
14
+            </el-row>
15
+        </div>
16
+        <div class="filter-container" style="margin-top: 10px;margin-left: 5px">
17
+            <el-checkbox style="width: 30px" @change="changeCheck" v-model="checkAllStatus">全选</el-checkbox>
18
+            <el-button size="small" icon="el-icon-delete" >批量删除</el-button>
19
+        </div>
20
+        <el-table ref="multipleTable"  @selection-change="handleSelectionChange"  :header-cell-style="{ backgroundColor: 'rgb(245, 247, 250)'}" :data="tagsData" border fit highlight-current-row  style="width: 100%;margin-top: 10px;">
21
+            <el-table-column
22
+                align="center"
23
+                type="selection"
24
+                width="55">
25
+             </el-table-column>
26
+            <el-table-column label="标签" align="center">
27
+                <template slot-scope="scope">
28
+                    {{scope.row.tag_name}}
29
+                </template>
30
+            </el-table-column>
31
+            <el-table-column label="会员数" align="center">
32
+                <template slot-scope="scope">
33
+                <span>{{scope.row.created_time}}</span>
34
+                </template>
35
+            </el-table-column>
36
+            <el-table-column label="操作" align="center">
37
+                <template slot-scope="scope">
38
+                    <el-tooltip class="item" effect="dark" content="编辑" placement="top">
39
+                        <el-button size="mini" type="primary" icon="el-icon-edit-outline" @click="openEdit(scope.row, scope.$index)" ></el-button>
40
+                    </el-tooltip>
41
+                    <el-tooltip class="item" effect="dark" content="删除" placement="top">
42
+                        <el-button size="mini" type="danger" icon="el-icon-delete" @click="openDelete(scope.row, scope.$index)" ></el-button>
43
+                    </el-tooltip>
44
+                </template>
45
+            </el-table-column>
46
+        </el-table>
47
+    </div>
48
+  </div>
49
+</template>
50
+
51
+<script>
52
+  import {GetTags} from "@/api/member/member";
53
+  import BreadCrumb from '../components/bread-crumb';
54
+  
55
+  export default {
56
+    name: 'memberTagList',
57
+    components:{
58
+      BreadCrumb,
59
+    },
60
+    data(){
61
+      return{
62
+        crumbs: [
63
+          { path: false, name: '会员管理' },
64
+          { path: false, name: '标签列表' }
65
+        ],
66
+        total:0,
67
+        listQuery:{
68
+            page:1,
69
+            limit:10,
70
+            search:'',
71
+        },
72
+        checkAllStatus:false,
73
+       
74
+        tagsData:[],
75
+      }
76
+    },
77
+    methods:{
78
+        openCreate:function(){
79
+            this.tagsData.push({id:1,tag_name:'2'});
80
+        },
81
+        openEdit:function(row,index){},
82
+        openDelete:function(row,index){},
83
+        changeCheck:function(){
84
+
85
+        },
86
+        handleSelectionChange:function (val) {
87
+            
88
+        },
89
+        changeKey(){
90
+            this.GetTags();
91
+        },
92
+        GetTags(){
93
+            GetTags().then(response=>{
94
+                var res = response.data;
95
+                if(res.state===1) {
96
+                    this.tagsData = res.data.tags;
97
+                }
98
+            }).catch(e=>{})
99
+        }
100
+    },
101
+    computed:{
102
+        activeTagsData:function(){
103
+        var tags = [];
104
+        
105
+        return tags;
106
+        }
107
+    },
108
+    created(){
109
+        this.GetTags();
110
+    }
111
+  }
112
+</script>
113
+
114
+<style scoped>
115
+  /*.app-container .cell.clearfix .time ul li {*/
116
+    /*float: left;*/
117
+    /*list-style: none;*/
118
+    /*cursor: pointer;*/
119
+    /*padding: 6px 20px;*/
120
+    /*color: #606266;*/
121
+    /*border-radius: 4px;*/
122
+    /*margin: 0 8px 0 0;*/
123
+    /*font-size: 14px;*/
124
+    /*text-align: center;*/
125
+  /*}*/
126
+</style>

+ 3 - 2
src/store/getters.js Vedi File

@@ -8,8 +8,9 @@ const getters = {
8 8
   addRouters: state => state.xt_permission.addRouters,
9 9
   errorLogs: state => state.errorLog.logs,
10 10
 
11
-  
12
-  sources: state => state.members.sources,
11
+  members: state => state.members,
12
+  // sources: state => state.members.sources,
13
+  // treat_type: state => state.members.treat_type,
13 14
 
14 15
   xt_permission: state => state.xt_permission,
15 16
   xt_user: state => state.xt_user,

+ 8 - 0
src/store/modules/members.js Vedi File

@@ -12,6 +12,14 @@ const members = {
12 12
             10:{id:10, name:"圣卫士"},
13 13
             11:{id:11, name:"血透"},
14 14
         },
15
+        treat_type:{
16
+            1:{id:1, name:'西医治疗'},
17
+            2:{id:2, name:'中医治疗'},
18
+            3:{id:3, name:'血液透析'},
19
+            4:{id:4, name:'腹膜透析'},
20
+            5:{id:5, name:'肾移植'},
21
+            6:{id:6, name:'其他'},
22
+        },
15 23
     },
16 24
     mutations: {
17 25
       

+ 8 - 1
src/utils/tools.js Vedi File

@@ -168,4 +168,11 @@ export function uParseTime(time, cFormat) {
168 168
           return 0
169 169
       }
170 170
       return (shouji + (shichang-t) * weichi).toFixed(1);
171
-  }
171
+  }
172
+
173
+  export function checkMobile(mobile){ 
174
+    if(!(/^1[2-9][0-9]\d{8}$/.test(mobile))){ 
175
+        return false; 
176
+    } 
177
+    return true;
178
+  }